Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ changes accumulate. Track in-flight protocol changes via PRs touching

### Added

- `ToolResultTerminalCompleteContent` for terminal-style completion metadata in tool
results.
- Optional `reviewed` field on `ChangesetFile`. Omitting it (or setting it to
`undefined`) signals that the server does not support the file "review"
functionality.
Expand Down
2 changes: 2 additions & 0 deletions clients/go/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Implements AHP 0.5.2.

### Added

- `ToolResultTerminalCompleteContent` for terminal-style completion metadata in tool
results.
- Optional `Enabled` field on the child customization types
(`AgentCustomization`, `SkillCustomization`, `PromptCustomization`,
`RuleCustomization`, `HookCustomization`).
Expand Down
33 changes: 33 additions & 0 deletions clients/go/ahptypes/state.generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ const (
ToolResultContentTypeResource ToolResultContentType = "resource"
ToolResultContentTypeFileEdit ToolResultContentType = "fileEdit"
ToolResultContentTypeTerminal ToolResultContentType = "terminal"
ToolResultContentTypeTerminalComplete ToolResultContentType = "terminalComplete"
ToolResultContentTypeSubagent ToolResultContentType = "subagent"
)

Expand Down Expand Up @@ -1996,6 +1997,31 @@ type ToolResultTerminalContent struct {
Title string `json:"title"`
}

// Record of a command executed by a terminal-style tool (e.g. a shell tool),
// appended to the tool result when the command exits.
//
// This records the command's exit, not the terminal's — the terminal may
// keep running afterwards.
//
// When live output was exposed through a terminal channel (a
// {@link ToolResultTerminalContent} block in the same tool result),
// {@link resource} identifies that channel; otherwise this block stands alone
// as the retained command result.
type ToolResultTerminalCompleteContent struct {
Type ToolResultContentType `json:"type"`
// URI of the `ahp-terminal:` channel that carried live output for this
// command, if one was exposed.
Resource *URI `json:"resource,omitempty"`
// Exit code from the completed command, if reported by the runtime
ExitCode *int64 `json:"exitCode,omitempty"`
// Working directory where the command was executed
Cwd *URI `json:"cwd,omitempty"`
// Preview of the command's output, if available
Preview *string `json:"preview,omitempty"`
// Whether `preview` is known to be incomplete or truncated
Truncated *bool `json:"truncated,omitempty"`
}

// A reference, embedded in a tool result, to a worker chat spawned by the tool
// call (a sub-agent delegation), referenced by a chat URI (`ahp-chat:/...`).
//
Expand Down Expand Up @@ -3657,6 +3683,7 @@ func (*ToolResultEmbeddedResourceContent) isToolResultContent() {}
func (*ToolResultResourceContent) isToolResultContent() {}
func (*ToolResultFileEditContent) isToolResultContent() {}
func (*ToolResultTerminalContent) isToolResultContent() {}
func (*ToolResultTerminalCompleteContent) isToolResultContent() {}
func (*ToolResultSubagentContent) isToolResultContent() {}

// ToolResultContentUnknown carries an unrecognized ToolResultContent variant — typically a discriminator value introduced by a newer protocol version. The original JSON object is preserved verbatim so that re-encoding round-trips faithfully.
Expand Down Expand Up @@ -3703,6 +3730,12 @@ func (u *ToolResultContent) UnmarshalJSON(data []byte) error {
return err
}
u.Value = &value
case "terminalComplete":
var value ToolResultTerminalCompleteContent
if err := json.Unmarshal(data, &value); err != nil {
return err
}
u.Value = &value
case "subagent":
var value ToolResultSubagentContent
if err := json.Unmarshal(data, &value); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions clients/kotlin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Implements AHP 0.5.2.

### Added

- `ToolResultTerminalCompleteContent` for terminal-style completion metadata in tool
results.
- Optional `enabled` field on the child customization types
(`AgentCustomization`, `SkillCustomization`, `PromptCustomization`,
`RuleCustomization`, `HookCustomization`).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,8 @@ enum class ToolResultContentType {
FILE_EDIT,
@SerialName("terminal")
TERMINAL,
@SerialName("terminalComplete")
TERMINAL_COMPLETE,
@SerialName("subagent")
SUBAGENT
}
Expand Down Expand Up @@ -2843,6 +2845,32 @@ data class ToolResultTerminalContent(
val title: String
)

@Serializable
data class ToolResultTerminalCompleteContent(
val type: ToolResultContentType,
/**
* URI of the `ahp-terminal:` channel that carried live output for this
* command, if one was exposed.
*/
val resource: String? = null,
/**
* Exit code from the completed command, if reported by the runtime
*/
val exitCode: Long? = null,
/**
* Working directory where the command was executed
*/
val cwd: String? = null,
/**
* Preview of the command's output, if available
*/
val preview: String? = null,
/**
* Whether `preview` is known to be incomplete or truncated
*/
val truncated: Boolean? = null
)

@Serializable
data class ToolResultSubagentContent(
val type: ToolResultContentType,
Expand Down Expand Up @@ -5022,6 +5050,7 @@ sealed interface ToolResultContent {
@JvmInline value class Resource(val value: ToolResultResourceContent) : ToolResultContent
@JvmInline value class FileEdit(val value: ToolResultFileEditContent) : ToolResultContent
@JvmInline value class Terminal(val value: ToolResultTerminalContent) : ToolResultContent
@JvmInline value class TerminalComplete(val value: ToolResultTerminalCompleteContent) : ToolResultContent
@JvmInline value class Subagent(val value: ToolResultSubagentContent) : ToolResultContent

/**
Expand Down Expand Up @@ -5051,6 +5080,7 @@ internal object ToolResultContentSerializer : KSerializer<ToolResultContent> {
"resource" -> ToolResultContent.Resource(input.json.decodeFromJsonElement(ToolResultResourceContent.serializer(), element))
"fileEdit" -> ToolResultContent.FileEdit(input.json.decodeFromJsonElement(ToolResultFileEditContent.serializer(), element))
"terminal" -> ToolResultContent.Terminal(input.json.decodeFromJsonElement(ToolResultTerminalContent.serializer(), element))
"terminalComplete" -> ToolResultContent.TerminalComplete(input.json.decodeFromJsonElement(ToolResultTerminalCompleteContent.serializer(), element))
"subagent" -> ToolResultContent.Subagent(input.json.decodeFromJsonElement(ToolResultSubagentContent.serializer(), element))
else -> ToolResultContent.Unknown(obj)
}
Expand All @@ -5065,6 +5095,7 @@ internal object ToolResultContentSerializer : KSerializer<ToolResultContent> {
is ToolResultContent.Resource -> output.json.encodeToJsonElement(ToolResultResourceContent.serializer(), value.value)
is ToolResultContent.FileEdit -> output.json.encodeToJsonElement(ToolResultFileEditContent.serializer(), value.value)
is ToolResultContent.Terminal -> output.json.encodeToJsonElement(ToolResultTerminalContent.serializer(), value.value)
is ToolResultContent.TerminalComplete -> output.json.encodeToJsonElement(ToolResultTerminalCompleteContent.serializer(), value.value)
is ToolResultContent.Subagent -> output.json.encodeToJsonElement(ToolResultSubagentContent.serializer(), value.value)
is ToolResultContent.Unknown -> value.raw
}
Expand Down
2 changes: 2 additions & 0 deletions clients/rust/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Implements AHP 0.5.2.

### Added

- `ToolResultTerminalCompleteContent` for terminal-style completion metadata in tool
results.
- Optional `enabled` field on the child customization types
(`AgentCustomization`, `SkillCustomization`, `PromptCustomization`,
`RuleCustomization`, `HookCustomization`).
Expand Down
35 changes: 35 additions & 0 deletions clients/rust/crates/ahp-types/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ pub enum ToolResultContentType {
FileEdit,
#[serde(rename = "terminal")]
Terminal,
#[serde(rename = "terminalComplete")]
TerminalComplete,
#[serde(rename = "subagent")]
Subagent,
}
Expand Down Expand Up @@ -2493,6 +2495,37 @@ pub struct ToolResultTerminalContent {
pub title: String,
}

/// Record of a command executed by a terminal-style tool (e.g. a shell tool),
/// appended to the tool result when the command exits.
///
/// This records the command's exit, not the terminal's — the terminal may
/// keep running afterwards.
///
/// When live output was exposed through a terminal channel (a
/// {@link ToolResultTerminalContent} block in the same tool result),
/// {@link resource} identifies that channel; otherwise this block stands alone
/// as the retained command result.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ToolResultTerminalCompleteContent {
/// URI of the `ahp-terminal:` channel that carried live output for this
/// command, if one was exposed.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub resource: Option<Uri>,
/// Exit code from the completed command, if reported by the runtime
#[serde(default, skip_serializing_if = "Option::is_none")]
pub exit_code: Option<i64>,
/// Working directory where the command was executed
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cwd: Option<Uri>,
/// Preview of the command's output, if available
#[serde(default, skip_serializing_if = "Option::is_none")]
pub preview: Option<String>,
/// Whether `preview` is known to be incomplete or truncated
#[serde(default, skip_serializing_if = "Option::is_none")]
pub truncated: Option<bool>,
}

/// A reference, embedded in a tool result, to a worker chat spawned by the tool
/// call (a sub-agent delegation), referenced by a chat URI (`ahp-chat:/...`).
///
Expand Down Expand Up @@ -3894,6 +3927,8 @@ pub enum ToolResultContent {
FileEdit(ToolResultFileEditContent),
#[serde(rename = "terminal")]
Terminal(ToolResultTerminalContent),
#[serde(rename = "terminalComplete")]
TerminalComplete(ToolResultTerminalCompleteContent),
#[serde(rename = "subagent")]
Subagent(ToolResultSubagentContent),
/// Unknown or future variant — preserved as raw JSON for round-trip fidelity.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ public enum ToolResultContentType: String, Codable, Sendable {
case resource = "resource"
case fileEdit = "fileEdit"
case terminal = "terminal"
case terminalComplete = "terminalComplete"
case subagent = "subagent"
}

Expand Down Expand Up @@ -3021,6 +3022,37 @@ public struct ToolResultTerminalContent: Codable, Sendable {
}
}

public struct ToolResultTerminalCompleteContent: Codable, Sendable {
public var type: ToolResultContentType
/// URI of the `ahp-terminal:` channel that carried live output for this
/// command, if one was exposed.
public var resource: String?
/// Exit code from the completed command, if reported by the runtime
public var exitCode: Int?
/// Working directory where the command was executed
public var cwd: String?
/// Preview of the command's output, if available
public var preview: String?
/// Whether `preview` is known to be incomplete or truncated
public var truncated: Bool?

public init(
type: ToolResultContentType,
resource: String? = nil,
exitCode: Int? = nil,
cwd: String? = nil,
preview: String? = nil,
truncated: Bool? = nil
) {
self.type = type
self.resource = resource
self.exitCode = exitCode
self.cwd = cwd
self.preview = preview
self.truncated = truncated
}
}

public struct ToolResultSubagentContent: Codable, Sendable {
public var type: ToolResultContentType
/// Worker chat URI (subscribable for full chat state)
Expand Down Expand Up @@ -5189,6 +5221,7 @@ public enum ToolResultContent: Codable, Sendable {
case resource(ToolResultResourceContent)
case fileEdit(ToolResultFileEditContent)
case terminal(ToolResultTerminalContent)
case terminalComplete(ToolResultTerminalCompleteContent)
case subagent(ToolResultSubagentContent)
/// Unknown or future tool result content type; the raw payload is preserved
/// and re-encoded verbatim for forward-compatibility.
Expand All @@ -5212,6 +5245,8 @@ public enum ToolResultContent: Codable, Sendable {
self = .fileEdit(try ToolResultFileEditContent(from: decoder))
case "terminal":
self = .terminal(try ToolResultTerminalContent(from: decoder))
case "terminalComplete":
self = .terminalComplete(try ToolResultTerminalCompleteContent(from: decoder))
case "subagent":
self = .subagent(try ToolResultSubagentContent(from: decoder))
default:
Expand All @@ -5232,6 +5267,7 @@ public enum ToolResultContent: Codable, Sendable {
case .resource(let v): try v.encode(to: encoder)
case .fileEdit(let v): try v.encode(to: encoder)
case .terminal(let v): try v.encode(to: encoder)
case .terminalComplete(let v): try v.encode(to: encoder)
case .subagent(let v): try v.encode(to: encoder)
case .unknown(let v): try v.encode(to: encoder)
}
Expand Down
2 changes: 2 additions & 0 deletions clients/swift/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Implements AHP 0.5.2.

### Added

- `ToolResultTerminalCompleteContent` for terminal-style completion metadata in tool
results.
- Optional `enabled` field on the child customization types
(`AgentCustomization`, `SkillCustomization`, `PromptCustomization`,
`RuleCustomization`, `HookCustomization`).
Expand Down
2 changes: 2 additions & 0 deletions clients/typescript/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Implements AHP 0.5.2.

### Added

- `ToolResultTerminalCompleteContent` for terminal-style completion metadata in tool
results.
- Optional `enabled` field on the child customization types
(`AgentCustomization`, `SkillCustomization`, `PromptCustomization`,
`RuleCustomization`, `HookCustomization`).
Expand Down
39 changes: 37 additions & 2 deletions schema/actions.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,7 @@
"description": "Update the {@link ChangesetFile.reviewed} flag for one or more files,\nidentified by their {@link ChangesetFile.id}.\n\nDispatched by the server as the user marks files reviewed or unreviewed\n(e.g. toggling a single file, or a \"mark all as reviewed\" affordance).\nOnly servers that support the \"review\" functionality dispatch this; a\nserver that leaves {@link ChangesetFile.reviewed} `undefined` never does.\n\nThe reducer sets `reviewed` on every matching file and ignores any\n`fileIds` entry that does not correspond to a current file.",
"properties": {
"type": {
"$ref": "#/$defs/ActionType.ChangesetFilesReviewedChanged"
"const": "changeset/filesReviewedChanged"
},
"fileIds": {
"type": "array",
Expand Down Expand Up @@ -5856,6 +5856,38 @@
"title"
]
},
"ToolResultTerminalCompleteContent": {
"type": "object",
"description": "Record of a command executed by a terminal-style tool (e.g. a shell tool),\nappended to the tool result when the command exits.\n\nThis records the command's exit, not the terminal's — the terminal may\nkeep running afterwards.\n\nWhen live output was exposed through a terminal channel (a\n{@link ToolResultTerminalContent} block in the same tool result),\n{@link resource} identifies that channel; otherwise this block stands alone\nas the retained command result.",
"properties": {
"type": {
"const": "terminalComplete"
},
"resource": {
"$ref": "#/$defs/URI",
"description": "URI of the `ahp-terminal:` channel that carried live output for this\ncommand, if one was exposed."
},
"exitCode": {
"type": "number",
"description": "Exit code from the completed command, if reported by the runtime"
},
"cwd": {
"$ref": "#/$defs/URI",
"description": "Working directory where the command was executed"
},
"preview": {
"type": "string",
"description": "Preview of the command's output, if available"
},
"truncated": {
"type": "boolean",
"description": "Whether `preview` is known to be incomplete or truncated"
}
},
"required": [
"type"
]
},
"ToolResultSubagentContent": {
"type": "object",
"description": "A reference, embedded in a tool result, to a worker chat spawned by the tool\ncall (a sub-agent delegation), referenced by a chat URI (`ahp-chat:/...`).\n\nThis is the spawning tool call's forward view of the worker. The worker chat\nrecords the same edge in reverse via its {@link ChatOrigin} (`kind: 'tool'`),\nwhose `toolCallId` identifies the tool call that emitted this content.",
Expand Down Expand Up @@ -6741,11 +6773,14 @@
{
"$ref": "#/$defs/ToolResultTerminalContent"
},
{
"$ref": "#/$defs/ToolResultTerminalCompleteContent"
},
{
"$ref": "#/$defs/ToolResultSubagentContent"
}
],
"description": "Content block in a tool result.\n\nMirrors the content blocks in MCP `CallToolResult.content`, plus\n`ToolResultResourceContent` for lazy-loading large results,\n`ToolResultFileEditContent` for file edit diffs,\n`ToolResultTerminalContent` for live terminal output, and\n`ToolResultSubagentContent` for tool-spawned worker chats (AHP extensions)."
"description": "Content block in a tool result.\n\nMirrors the content blocks in MCP `CallToolResult.content`, plus\n`ToolResultResourceContent` for lazy-loading large results,\n`ToolResultFileEditContent` for file edit diffs,\n`ToolResultTerminalContent` for live terminal output,\n`ToolResultTerminalCompleteContent` for terminal-style completion metadata, and\n`ToolResultSubagentContent` for tool-spawned worker chats (AHP extensions)."
},
"TerminalClaim": {
"oneOf": [
Expand Down
Loading
Loading