fix(protocol): backport approval and model-list parity updates

This commit is contained in:
James Peter
2026-02-15 14:51:13 +10:00
parent 1bb3393072
commit a541f404e7
21 changed files with 219 additions and 9 deletions
@@ -443,6 +443,13 @@
"null"
]
},
"includeHidden": {
"description": "When true, include models that are hidden from the default picker list.",
"type": [
"boolean",
"null"
]
},
"limit": {
"description": "Optional page size; defaults to a reasonable server-side value.",
"format": "uint32",
@@ -1461,6 +1461,17 @@
"null"
]
},
"network_approval_context": {
"description": "Optional network context for a blocked request that can be approved.",
"anyOf": [
{
"$ref": "#/definitions/NetworkApprovalContext"
},
{
"type": "null"
}
]
},
"turn_id": {
"default": "",
"description": "Turn ID that this command belongs to. Uses `#[serde(default)]` for backwards compatibility.",
@@ -3346,6 +3357,30 @@
],
"type": "string"
},
"NetworkApprovalContext": {
"properties": {
"host": {
"type": "string"
},
"protocol": {
"$ref": "#/definitions/NetworkApprovalProtocol"
}
},
"required": [
"host",
"protocol"
],
"type": "object"
},
"NetworkApprovalProtocol": {
"enum": [
"http",
"https",
"socks5_tcp",
"socks5_udp"
],
"type": "string"
},
"ParsedCommand": {
"oneOf": [
{
@@ -2130,6 +2130,17 @@
"null"
]
},
"network_approval_context": {
"description": "Optional network context for a blocked request that can be approved.",
"anyOf": [
{
"$ref": "#/definitions/NetworkApprovalContext"
},
{
"type": "null"
}
]
},
"turn_id": {
"default": "",
"description": "Turn ID that this command belongs to. Uses `#[serde(default)]` for backwards compatibility.",
@@ -4216,6 +4227,30 @@
],
"type": "string"
},
"NetworkApprovalContext": {
"properties": {
"host": {
"type": "string"
},
"protocol": {
"$ref": "#/definitions/NetworkApprovalProtocol"
}
},
"required": [
"host",
"protocol"
],
"type": "object"
},
"NetworkApprovalProtocol": {
"enum": [
"http",
"https",
"socks5_tcp",
"socks5_udp"
],
"type": "string"
},
"ParsedCommand": {
"oneOf": [
{
@@ -5989,7 +6024,8 @@
{
"enum": [
"review",
"compact"
"compact",
"memory_consolidation"
],
"type": "string"
},
@@ -3474,6 +3474,17 @@
"null"
]
},
"network_approval_context": {
"description": "Optional network context for a blocked request that can be approved.",
"anyOf": [
{
"$ref": "#/definitions/NetworkApprovalContext"
},
{
"type": "null"
}
]
},
"turn_id": {
"default": "",
"description": "Turn ID that this command belongs to. Uses `#[serde(default)]` for backwards compatibility.",
@@ -6247,6 +6258,30 @@
],
"type": "string"
},
"NetworkApprovalContext": {
"properties": {
"host": {
"type": "string"
},
"protocol": {
"$ref": "#/definitions/NetworkApprovalProtocol"
}
},
"required": [
"host",
"protocol"
],
"type": "object"
},
"NetworkApprovalProtocol": {
"enum": [
"http",
"https",
"socks5_tcp",
"socks5_udp"
],
"type": "string"
},
"NewConversationParams": {
"properties": {
"approvalPolicy": {
@@ -9075,7 +9110,8 @@
{
"enum": [
"review",
"compact"
"compact",
"memory_consolidation"
],
"type": "string"
},
@@ -12572,6 +12608,9 @@
"displayName": {
"type": "string"
},
"hidden": {
"type": "boolean"
},
"id": {
"type": "string"
},
@@ -12612,6 +12651,7 @@
"defaultReasoningEffort",
"description",
"displayName",
"hidden",
"id",
"isDefault",
"model",
@@ -12629,6 +12669,13 @@
"null"
]
},
"includeHidden": {
"description": "When true, include models that are hidden from the default picker list.",
"type": [
"boolean",
"null"
]
},
"limit": {
"description": "Optional page size; defaults to a reasonable server-side value.",
"format": "uint32",
@@ -14408,7 +14455,8 @@
{
"enum": [
"review",
"compact"
"compact",
"memory_consolidation"
],
"type": "string"
},
@@ -8,6 +8,13 @@
"null"
]
},
"includeHidden": {
"description": "When true, include models that are hidden from the default picker list.",
"type": [
"boolean",
"null"
]
},
"limit": {
"description": "Optional page size; defaults to a reasonable server-side value.",
"format": "uint32",
@@ -31,6 +31,9 @@
"displayName": {
"type": "string"
},
"hidden": {
"type": "boolean"
},
"id": {
"type": "string"
},
@@ -71,6 +74,7 @@
"defaultReasoningEffort",
"description",
"displayName",
"hidden",
"id",
"isDefault",
"model",
@@ -2,6 +2,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
import type { NetworkApprovalContext } from "./NetworkApprovalContext";
import type { ParsedCommand } from "./ParsedCommand";
export type ExecApprovalRequestEvent = {
@@ -26,6 +27,10 @@ cwd: string,
* Optional human-readable reason for the approval (e.g. retry without sandbox).
*/
reason: string | null,
/**
* Optional network context for a blocked request that can be approved.
*/
network_approval_context?: NetworkApprovalContext,
/**
* Proposed execpolicy amendment that can be applied to allow future runs.
*/
@@ -0,0 +1,6 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { NetworkApprovalProtocol } from "./NetworkApprovalProtocol";
export type NetworkApprovalContext = { host: string, protocol: NetworkApprovalProtocol, };
@@ -0,0 +1,5 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type NetworkApprovalProtocol = "http" | "https" | "socks5_tcp" | "socks5_udp";
@@ -3,4 +3,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ThreadId } from "./ThreadId";
export type SubAgentSource = "review" | "compact" | { "thread_spawn": { parent_thread_id: ThreadId, depth: number, } } | { "other": string };
export type SubAgentSource = "review" | "compact" | { "thread_spawn": { parent_thread_id: ThreadId, depth: number, } } | "memory_consolidation" | { "other": string };
@@ -125,6 +125,8 @@ export type { McpToolCallEndEvent } from "./McpToolCallEndEvent";
export type { MessagePhase } from "./MessagePhase";
export type { ModeKind } from "./ModeKind";
export type { NetworkAccess } from "./NetworkAccess";
export type { NetworkApprovalContext } from "./NetworkApprovalContext";
export type { NetworkApprovalProtocol } from "./NetworkApprovalProtocol";
export type { NewConversationParams } from "./NewConversationParams";
export type { NewConversationResponse } from "./NewConversationResponse";
export type { ParsedCommand } from "./ParsedCommand";
@@ -5,4 +5,4 @@ import type { InputModality } from "../InputModality";
import type { ReasoningEffort } from "../ReasoningEffort";
import type { ReasoningEffortOption } from "./ReasoningEffortOption";
export type Model = { id: string, model: string, upgrade: string | null, displayName: string, description: string, supportedReasoningEfforts: Array<ReasoningEffortOption>, defaultReasoningEffort: ReasoningEffort, inputModalities: Array<InputModality>, supportsPersonality: boolean, isDefault: boolean, };
export type Model = { id: string, model: string, upgrade: string | null, displayName: string, description: string, hidden: boolean, supportedReasoningEfforts: Array<ReasoningEffortOption>, defaultReasoningEffort: ReasoningEffort, inputModalities: Array<InputModality>, supportsPersonality: boolean, isDefault: boolean, };
@@ -10,4 +10,8 @@ cursor?: string | null,
/**
* Optional page size; defaults to a reasonable server-side value.
*/
limit?: number | null, };
limit?: number | null,
/**
* When true, include models that are hidden from the default picker list.
*/
includeHidden?: boolean | null, };
@@ -1091,7 +1091,8 @@ mod tests {
"id": 6,
"params": {
"limit": null,
"cursor": null
"cursor": null,
"includeHidden": null
}
}),
serde_json::to_value(&request)?,
@@ -1201,4 +1202,3 @@ mod tests {
assert_eq!(reason, Some("thread/start.mockExperimentalField"));
}
}
@@ -1056,6 +1056,9 @@ pub struct ModelListParams {
/// Optional page size; defaults to a reasonable server-side value.
#[ts(optional = nullable)]
pub limit: Option<u32>,
/// When true, include models that are hidden from the default picker list.
#[ts(optional = nullable)]
pub include_hidden: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
@@ -1067,6 +1070,7 @@ pub struct Model {
pub upgrade: Option<String>,
pub display_name: String,
pub description: String,
pub hidden: bool,
pub supported_reasoning_efforts: Vec<ReasoningEffortOption>,
pub default_reasoning_effort: ReasoningEffort,
#[serde(default = "default_input_modalities")]
@@ -1516,6 +1516,7 @@ async fn apply_bespoke_event_handling(
command,
cwd,
reason,
network_approval_context: _,
}) => {
let params = ExecCommandApprovalParams {
conversation_id,
+1
View File
@@ -1150,6 +1150,7 @@ impl Session {
command,
cwd,
reason,
network_approval_context: None,
}),
);
let _ = self.tx_event.send(event).await;
+19
View File
@@ -1247,6 +1247,22 @@ pub enum ExecOutputStream {
Stderr,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum NetworkApprovalProtocol {
Http,
#[serde(alias = "https_connect", alias = "http-connect")]
Https,
Socks5Tcp,
Socks5Udp,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct NetworkApprovalContext {
pub host: String,
pub protocol: NetworkApprovalProtocol,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ExecCommandOutputDeltaEvent {
/// Identifier for the ExecCommandBegin that produced this chunk.
@@ -1273,6 +1289,9 @@ pub struct ExecApprovalRequestEvent {
/// Optional human-readable reason for the approval (e.g. retry without sandbox).
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
/// Optional network context for a blocked request that can be approved.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub network_approval_context: Option<NetworkApprovalContext>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
+22 -1
View File
@@ -37,6 +37,24 @@ impl From<Vec<String>> for ExecPolicyAmendment {
}
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "snake_case")]
pub enum NetworkApprovalProtocol {
// TODO(viyatb): Add websocket protocol variants when managed proxy policy
// decisions expose websocket traffic as a distinct approval context.
Http,
#[serde(alias = "https_connect", alias = "http-connect")]
Https,
Socks5Tcp,
Socks5Udp,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
pub struct NetworkApprovalContext {
pub host: String,
pub protocol: NetworkApprovalProtocol,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
pub struct ExecApprovalRequestEvent {
/// Identifier for the associated exec call, if available.
@@ -52,6 +70,10 @@ pub struct ExecApprovalRequestEvent {
/// Optional human-readable reason for the approval (e.g. retry without sandbox).
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
/// Optional network context for a blocked request that can be approved.
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub network_approval_context: Option<NetworkApprovalContext>,
/// Proposed execpolicy amendment that can be applied to allow future runs.
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
@@ -94,4 +116,3 @@ pub struct ApplyPatchApprovalRequestEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub grant_root: Option<PathBuf>,
}
+4
View File
@@ -53,6 +53,8 @@ pub use crate::approvals::ApplyPatchApprovalRequestEvent;
pub use crate::approvals::ElicitationAction;
pub use crate::approvals::ExecApprovalRequestEvent;
pub use crate::approvals::ExecPolicyAmendment;
pub use crate::approvals::NetworkApprovalContext;
pub use crate::approvals::NetworkApprovalProtocol;
pub use crate::mcp_protocol::InputItem;
pub use crate::request_user_input::RequestUserInputEvent;
@@ -1705,6 +1707,7 @@ pub enum SubAgentSource {
parent_thread_id: ThreadId,
depth: i32,
},
MemoryConsolidation,
Other(String),
}
@@ -1726,6 +1729,7 @@ impl fmt::Display for SubAgentSource {
match self {
SubAgentSource::Review => f.write_str("review"),
SubAgentSource::Compact => f.write_str("compact"),
SubAgentSource::MemoryConsolidation => f.write_str("memory_consolidation"),
SubAgentSource::ThreadSpawn {
parent_thread_id,
depth,
+1
View File
@@ -463,6 +463,7 @@ fn smoke_exec_approval_event_structure() {
command: vec!["echo".into(), "hi".into()],
cwd: PathBuf::from("/tmp"),
reason: Some("verify".into()),
network_approval_context: None,
};
let encoded = serde_json::to_string(&approval).expect("serialize exec approval");