From d6499594fafaf34a7eb96ce0b067a149a925dc5b Mon Sep 17 00:00:00 2001 From: "David Sterling (VS)" Date: Tue, 26 May 2026 12:57:08 -0700 Subject: [PATCH 01/10] feat: expose clientName in SDK session metadata Adds clientName field to SessionMetadata across all SDK languages (Node, Python, Go, .NET, Rust, Java) to expose the runtime client identifier that created or last resumed a session. Changes: - Updated generated RPC types to include clientName field - Added clientName to public SessionMetadata models - Added serialization tests for new field The clientName field allows SDK consumers to identify which client (CLI, SDK app, extension) owns a session when listing sessions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/src/Generated/Rpc.cs | 4 + dotnet/src/Types.cs | 4 + dotnet/test/Unit/SerializationTests.cs | 24 ++++++ go/client_test.go | 27 +++++++ go/rpc/zrpc.go | 2 + go/types.go | 1 + .../sdk/generated/rpc/SessionMetadata.java | 2 + .../copilot/sdk/json/SessionMetadata.java | 22 ++++++ .../com/github/copilot/sdk/ModelInfoTest.java | 3 + nodejs/src/client.ts | 3 + nodejs/src/generated/rpc.ts | 4 + nodejs/src/types.ts | 2 + nodejs/test/client.test.ts | 74 +++++++++++++++++++ python/copilot/client.py | 5 ++ python/copilot/generated/rpc.py | 8 +- python/test_client.py | 18 +++++ rust/src/generated/api_types.rs | 3 + rust/src/types.rs | 3 + rust/tests/session_test.rs | 4 + 19 files changed, 212 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index 470fae6cb..c47112caf 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -721,6 +721,10 @@ public sealed class SessionMetadata [JsonPropertyName("mcTaskId")] public string? McTaskId { get; set; } + /// Identifier of the client driving the session. + [JsonPropertyName("clientName")] + public string? ClientName { get; set; } + /// Last-modified time of the session's persisted state, as ISO 8601. [JsonPropertyName("modifiedTime")] public string ModifiedTime { get; set; } = string.Empty; diff --git a/dotnet/src/Types.cs b/dotnet/src/Types.cs index a02a5db3a..c3c9340fa 100644 --- a/dotnet/src/Types.cs +++ b/dotnet/src/Types.cs @@ -2667,6 +2667,10 @@ public sealed class SessionMetadata /// public string? Summary { get; set; } /// + /// Identifier of the client driving the session. + /// + public string? ClientName { get; set; } + /// /// Whether the session is running on a remote server. /// public bool IsRemote { get; set; } diff --git a/dotnet/test/Unit/SerializationTests.cs b/dotnet/test/Unit/SerializationTests.cs index f225fe4ee..9c5d7c4b8 100644 --- a/dotnet/test/Unit/SerializationTests.cs +++ b/dotnet/test/Unit/SerializationTests.cs @@ -171,6 +171,30 @@ public void ResumeSessionRequest_CanSerializeInstructionDirectories_WithSdkOptio Assert.Equal("C:\\resume-instructions", root.GetProperty("instructionDirectories")[0].GetString()); } + [Fact] + public void SessionMetadata_CanRoundTripClientName_WithSdkOptions() + { + var options = GetSerializerOptions(); + var original = new SessionMetadata + { + SessionId = "session-1", + StartTime = DateTimeOffset.Parse("2025-01-01T00:00:00Z"), + ModifiedTime = DateTimeOffset.Parse("2025-01-01T01:00:00Z"), + Summary = "loaded session", + ClientName = "my-app", + IsRemote = false + }; + + var json = JsonSerializer.Serialize(original, options); + using var document = JsonDocument.Parse(json); + var root = document.RootElement; + Assert.Equal("my-app", root.GetProperty("clientName").GetString()); + + var deserialized = JsonSerializer.Deserialize(json, options); + Assert.NotNull(deserialized); + Assert.Equal("my-app", deserialized.ClientName); + } + [Fact] public void CreateSessionRequest_CanSerializeEnableSessionTelemetry_WithSdkOptions() { diff --git a/go/client_test.go b/go/client_test.go index 39358a72a..efd41146b 100644 --- a/go/client_test.go +++ b/go/client_test.go @@ -402,6 +402,33 @@ func TestResumeSessionRequest_ClientName(t *testing.T) { }) } +func TestSessionMetadata_ClientName(t *testing.T) { + t.Run("round-trips clientName in JSON", func(t *testing.T) { + var metadata SessionMetadata + if err := json.Unmarshal([]byte(`{ + "sessionId":"s1", + "startTime":"2025-01-01T00:00:00Z", + "modifiedTime":"2025-01-01T01:00:00Z", + "summary":"loaded session", + "clientName":"my-app", + "isRemote":false + }`), &metadata); err != nil { + t.Fatalf("Failed to unmarshal: %v", err) + } + if metadata.ClientName == nil || *metadata.ClientName != "my-app" { + t.Fatalf("Expected clientName to be my-app, got %v", metadata.ClientName) + } + + data, err := json.Marshal(metadata) + if err != nil { + t.Fatalf("Failed to marshal: %v", err) + } + if !strings.Contains(string(data), `"clientName":"my-app"`) { + t.Fatalf("Expected marshaled JSON to include clientName, got %s", string(data)) + } + }) +} + func TestCreateSessionRequest_Agent(t *testing.T) { t.Run("includes agent in JSON when set", func(t *testing.T) { req := createSessionRequest{Agent: "test-agent"} diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index 0b947df35..3ae48167b 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -4222,6 +4222,8 @@ type SessionMetadata struct { // GitHub task ID, when this local session is bound to one. Only present for local sessions // exported to remote control. McTaskID *string `json:"mcTaskId,omitempty"` + // Identifier of the client driving the session. + ClientName *string `json:"clientName,omitempty"` // Last-modified time of the session's persisted state, as ISO 8601 ModifiedTime string `json:"modifiedTime"` // Optional human-friendly name set via /rename diff --git a/go/types.go b/go/types.go index fe7f9d93c..1bbf2f53a 100644 --- a/go/types.go +++ b/go/types.go @@ -1360,6 +1360,7 @@ type SessionMetadata struct { StartTime time.Time `json:"startTime"` ModifiedTime time.Time `json:"modifiedTime"` Summary *string `json:"summary,omitempty"` + ClientName *string `json:"clientName,omitempty"` IsRemote bool `json:"isRemote"` Context *SessionContext `json:"context,omitempty"` } diff --git a/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java b/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java index 6069f8ab4..60709f933 100644 --- a/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java +++ b/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java @@ -31,6 +31,8 @@ public record SessionMetadata( @JsonProperty("summary") String summary, /** Optional human-friendly name set via /rename */ @JsonProperty("name") String name, + /** Runtime client name that created/last resumed this session */ + @JsonProperty("clientName") String clientName, /** True for remote (GitHub) sessions; false for local */ @JsonProperty("isRemote") Boolean isRemote, /** Schema for the `SessionContext` type. */ diff --git a/java/src/main/java/com/github/copilot/sdk/json/SessionMetadata.java b/java/src/main/java/com/github/copilot/sdk/json/SessionMetadata.java index cb2690d19..12c382b16 100644 --- a/java/src/main/java/com/github/copilot/sdk/json/SessionMetadata.java +++ b/java/src/main/java/com/github/copilot/sdk/json/SessionMetadata.java @@ -46,6 +46,9 @@ public class SessionMetadata { @JsonProperty("summary") private String summary; + @JsonProperty("clientName") + private String clientName; + @JsonProperty("isRemote") private boolean isRemote; @@ -130,6 +133,25 @@ public void setSummary(String summary) { this.summary = summary; } + /** + * Gets the identifier of the client driving the session. + * + * @return the client name, or {@code null} if not available + */ + public String getClientName() { + return clientName; + } + + /** + * Sets the client identifier for the session. + * + * @param clientName + * the client name + */ + public void setClientName(String clientName) { + this.clientName = clientName; + } + /** * Returns whether this session is stored remotely. * diff --git a/java/src/test/java/com/github/copilot/sdk/ModelInfoTest.java b/java/src/test/java/com/github/copilot/sdk/ModelInfoTest.java index f36d0c4bd..b4323c37f 100644 --- a/java/src/test/java/com/github/copilot/sdk/ModelInfoTest.java +++ b/java/src/test/java/com/github/copilot/sdk/ModelInfoTest.java @@ -60,8 +60,11 @@ void sessionMetadataGettersAndSetters() { assertNull(meta.getStartTime()); assertNull(meta.getModifiedTime()); assertNull(meta.getSummary()); + assertNull(meta.getClientName()); assertFalse(meta.isRemote()); + meta.setClientName("my-app"); + assertEquals("my-app", meta.getClientName()); meta.setRemote(true); assertTrue(meta.isRemote()); } diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts index 3e8a4cfa3..70130c32d 100644 --- a/nodejs/src/client.ts +++ b/nodejs/src/client.ts @@ -1347,6 +1347,7 @@ export class CopilotClient { startTime: string; modifiedTime: string; summary?: string; + clientName?: string; isRemote: boolean; context?: { cwd: string; gitRoot?: string; repository?: string; branch?: string }; }>; @@ -1402,6 +1403,7 @@ export class CopilotClient { startTime: string; modifiedTime: string; summary?: string; + clientName?: string; isRemote: boolean; context?: { cwd: string; gitRoot?: string; repository?: string; branch?: string }; }): SessionMetadata { @@ -1411,6 +1413,7 @@ export class CopilotClient { startTime: new Date(raw.startTime), modifiedTime: new Date(raw.modifiedTime), summary: raw.summary, + clientName: raw.clientName, isRemote: raw.isRemote, context: context ? { diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index 229fd4ff0..9a3b8e71d 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -6431,6 +6431,10 @@ export interface SessionMetadata { * Short summary of the session, when one has been derived */ summary?: string; + /** + * Identifier of the client driving the session. + */ + clientName?: string; /** * Optional human-friendly name set via /rename */ diff --git a/nodejs/src/types.ts b/nodejs/src/types.ts index 623a4cabd..df9f53333 100644 --- a/nodejs/src/types.ts +++ b/nodejs/src/types.ts @@ -1970,6 +1970,8 @@ export interface SessionMetadata { startTime: Date; modifiedTime: Date; summary?: string; + /** Identifier of the client driving the session */ + clientName?: string; isRemote: boolean; /** Working directory context (working directory, git info) from session creation */ context?: SessionContext; diff --git a/nodejs/test/client.test.ts b/nodejs/test/client.test.ts index ff46c75b3..ea6cf9c9a 100644 --- a/nodejs/test/client.test.ts +++ b/nodejs/test/client.test.ts @@ -278,6 +278,80 @@ describe("CopilotClient", () => { spy.mockRestore(); }); + it("maps clientName from session.list responses", async () => { + const client = new CopilotClient(); + await client.start(); + onTestFinished(() => client.forceStop()); + + vi.spyOn((client as any).connection!, "sendRequest").mockImplementation( + async (method: string) => { + if (method === "session.list") { + return { + sessions: [ + { + sessionId: "session-1", + startTime: "2025-01-01T00:00:00Z", + modifiedTime: "2025-01-01T01:00:00Z", + summary: "test session", + clientName: "my-app", + isRemote: false, + }, + ], + }; + } + throw new Error(`Unexpected method: ${method}`); + } + ); + + const sessions = await client.listSessions(); + + expect(sessions).toEqual([ + expect.objectContaining({ + sessionId: "session-1", + clientName: "my-app", + summary: "test session", + }), + ]); + expect(sessions[0].startTime).toBeInstanceOf(Date); + expect(sessions[0].modifiedTime).toBeInstanceOf(Date); + }); + + it("maps clientName from session.getMetadata responses", async () => { + const client = new CopilotClient(); + await client.start(); + onTestFinished(() => client.forceStop()); + + vi.spyOn((client as any).connection!, "sendRequest").mockImplementation( + async (method: string) => { + if (method === "session.getMetadata") { + return { + session: { + sessionId: "session-1", + startTime: "2025-01-01T00:00:00Z", + modifiedTime: "2025-01-01T01:00:00Z", + summary: "loaded session", + clientName: "my-app", + isRemote: false, + }, + }; + } + throw new Error(`Unexpected method: ${method}`); + } + ); + + const metadata = await client.getSessionMetadata("session-1"); + + expect(metadata).toEqual( + expect.objectContaining({ + sessionId: "session-1", + clientName: "my-app", + summary: "loaded session", + }) + ); + expect(metadata?.startTime).toBeInstanceOf(Date); + expect(metadata?.modifiedTime).toBeInstanceOf(Date); + }); + it("forwards enableSessionTelemetry in session.create request", async () => { const client = new CopilotClient(); await client.start(); diff --git a/python/copilot/client.py b/python/copilot/client.py index 5e795bdde..12dd7fcf6 100644 --- a/python/copilot/client.py +++ b/python/copilot/client.py @@ -784,6 +784,7 @@ class SessionMetadata: modified_time: datetime # Timestamp when session was last modified is_remote: bool # Whether the session is remote summary: str | None = None # Optional summary of the session + client_name: str | None = None # Identifier of the client driving the session context: SessionContext | None = None # Working directory context @staticmethod @@ -799,6 +800,7 @@ def from_dict(obj: Any) -> SessionMetadata: f"startTime={start_time}, modifiedTime={modified_time}, isRemote={is_remote}" ) summary = obj.get("summary") + client_name = obj.get("clientName") context_dict = obj.get("context") context = SessionContext.from_dict(context_dict) if context_dict else None return SessionMetadata( @@ -807,6 +809,7 @@ def from_dict(obj: Any) -> SessionMetadata: modified_time=_parse_session_timestamp(modified_time), is_remote=bool(is_remote), summary=summary, + client_name=str(client_name) if client_name is not None else None, context=context, ) @@ -818,6 +821,8 @@ def to_dict(self) -> dict: result["isRemote"] = self.is_remote if self.summary is not None: result["summary"] = self.summary + if self.client_name is not None: + result["clientName"] = self.client_name if self.context is not None: result["context"] = self.context.to_dict() return result diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index b438ae5dc..7b7e814db 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -12068,6 +12068,9 @@ class SessionMetadata: """GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. """ + client_name: str | None = None + """Identifier of the client driving the session.""" + name: str | None = None """Optional human-friendly name set via /rename""" @@ -12083,9 +12086,10 @@ def from_dict(obj: Any) -> 'SessionMetadata': start_time = from_str(obj.get("startTime")) context = from_union([SessionContext.from_dict, from_none], obj.get("context")) mc_task_id = from_union([from_str, from_none], obj.get("mcTaskId")) + client_name = from_union([from_str, from_none], obj.get("clientName")) name = from_union([from_str, from_none], obj.get("name")) summary = from_union([from_str, from_none], obj.get("summary")) - return SessionMetadata(is_remote, modified_time, session_id, start_time, context, mc_task_id, name, summary) + return SessionMetadata(is_remote, modified_time, session_id, start_time, context, mc_task_id, client_name, name, summary) def to_dict(self) -> dict: result: dict = {} @@ -12097,6 +12101,8 @@ def to_dict(self) -> dict: result["context"] = from_union([lambda x: to_class(SessionContext, x), from_none], self.context) if self.mc_task_id is not None: result["mcTaskId"] = from_union([from_str, from_none], self.mc_task_id) + if self.client_name is not None: + result["clientName"] = from_union([from_str, from_none], self.client_name) if self.name is not None: result["name"] = from_union([from_str, from_none], self.name) if self.summary is not None: diff --git a/python/test_client.py b/python/test_client.py index 14320b3a2..fbbcefd25 100644 --- a/python/test_client.py +++ b/python/test_client.py @@ -21,6 +21,7 @@ ModelInfo, ModelLimits, ModelSupports, + SessionMetadata, ) from copilot.session import PermissionHandler from e2e.testharness import CLI_PATH @@ -601,6 +602,23 @@ async def mock_request(method, params): finally: await client.force_stop() + +class TestSessionMetadataParsing: + def test_session_metadata_round_trips_client_name(self): + metadata = SessionMetadata.from_dict( + { + "sessionId": "session-1", + "startTime": "2025-01-01T00:00:00Z", + "modifiedTime": "2025-01-01T01:00:00Z", + "summary": "loaded session", + "clientName": "my-app", + "isRemote": False, + } + ) + + assert metadata.client_name == "my-app" + assert metadata.to_dict()["clientName"] == "my-app" + @pytest.mark.asyncio async def test_create_session_forwards_provider_headers(self): client = CopilotClient(connection=RuntimeConnection.for_stdio(path=CLI_PATH)) diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index 9f2da297e..294372664 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -5863,6 +5863,9 @@ pub struct SessionMetadata { /// GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. #[serde(skip_serializing_if = "Option::is_none")] pub mc_task_id: Option, + /// Identifier of the client driving the session. + #[serde(skip_serializing_if = "Option::is_none")] + pub client_name: Option, /// Last-modified time of the session's persisted state, as ISO 8601 pub modified_time: String, /// Optional human-friendly name set via /rename diff --git a/rust/src/types.rs b/rust/src/types.rs index d841096c5..05747faf1 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -3331,6 +3331,9 @@ pub struct SessionMetadata { /// Agent-generated session summary. #[serde(skip_serializing_if = "Option::is_none")] pub summary: Option, + /// Identifier of the client driving the session. + #[serde(skip_serializing_if = "Option::is_none")] + pub client_name: Option, /// Whether the session is running remotely. pub is_remote: bool, } diff --git a/rust/tests/session_test.rs b/rust/tests/session_test.rs index 050c5898d..874796df3 100644 --- a/rust/tests/session_test.rs +++ b/rust/tests/session_test.rs @@ -594,6 +594,7 @@ async fn list_sessions_returns_typed_metadata() { "startTime": "2025-01-01T00:00:00Z", "modifiedTime": "2025-01-01T01:00:00Z", "summary": "test session", + "clientName": "my-app", "isRemote": false, }] }, @@ -604,6 +605,7 @@ async fn list_sessions_returns_typed_metadata() { assert_eq!(sessions.len(), 1); assert_eq!(sessions[0].session_id, "s1"); assert_eq!(sessions[0].summary, Some("test session".to_string())); + assert_eq!(sessions[0].client_name.as_deref(), Some("my-app")); } #[tokio::test] @@ -1097,6 +1099,7 @@ async fn get_session_metadata_returns_typed_metadata() { "startTime": "2025-01-01T00:00:00Z", "modifiedTime": "2025-01-01T01:00:00Z", "summary": "loaded session", + "clientName": "my-app", "isRemote": false, } }, @@ -1107,6 +1110,7 @@ async fn get_session_metadata_returns_typed_metadata() { let metadata = metadata.expect("server returned a session"); assert_eq!(metadata.session_id, "s1"); assert_eq!(metadata.summary.as_deref(), Some("loaded session")); + assert_eq!(metadata.client_name.as_deref(), Some("my-app")); } #[tokio::test] From d29822d6659c12c48c211b2cf88d9883c22c3615 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 19:57:42 +0000 Subject: [PATCH 02/10] Regenerate Java codegen output Auto-committed by java-codegen-check workflow. --- .../com/github/copilot/sdk/generated/rpc/SessionMetadata.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java b/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java index 60709f933..6069f8ab4 100644 --- a/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java +++ b/java/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMetadata.java @@ -31,8 +31,6 @@ public record SessionMetadata( @JsonProperty("summary") String summary, /** Optional human-friendly name set via /rename */ @JsonProperty("name") String name, - /** Runtime client name that created/last resumed this session */ - @JsonProperty("clientName") String clientName, /** True for remote (GitHub) sessions; false for local */ @JsonProperty("isRemote") Boolean isRemote, /** Schema for the `SessionContext` type. */ From b3405ec9733451f8b188749843fbb2c0fe579c49 Mon Sep 17 00:00:00 2001 From: "David Sterling (VS)" Date: Tue, 26 May 2026 14:05:28 -0700 Subject: [PATCH 03/10] fix: add clientName to session.getMetadata response type The type assertion for session.getMetadata response was missing the clientName field, making it inconsistent with listSessions and less type-safe. Added clientName?: string to the inline session type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- nodejs/src/client.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts index 70130c32d..fc5714ba4 100644 --- a/nodejs/src/client.ts +++ b/nodejs/src/client.ts @@ -1386,6 +1386,7 @@ export class CopilotClient { startTime: string; modifiedTime: string; summary?: string; + clientName?: string; isRemote: boolean; context?: { cwd: string; gitRoot?: string; repository?: string; branch?: string }; }; From 684d1ca56b8cea9892d23b14779a45727a5b0777 Mon Sep 17 00:00:00 2001 From: "David Sterling (VS)" Date: Tue, 26 May 2026 14:36:18 -0700 Subject: [PATCH 04/10] chore: regenerate RPC types to match schema Regenerate all SDK generated types to align with the current schema from @github/copilot package. This ensures the codegen check passes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/src/Generated/Rpc.cs | 16 ++++++++++++---- go/rpc/zrpc.go | 7 +++++-- nodejs/src/generated/rpc.ts | 13 +++++++++---- python/copilot/generated/rpc.py | 28 +++++++++++++++++++--------- rust/src/generated/api_types.rs | 19 +++++++++++++++---- 5 files changed, 60 insertions(+), 23 deletions(-) diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index b59d4413d..d87d992eb 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -709,6 +709,10 @@ public sealed class SessionContext [Experimental(Diagnostics.Experimental)] public sealed class SessionMetadata { + /// Runtime client name that created/last resumed this session. + [JsonPropertyName("clientName")] + public string? ClientName { get; set; } + /// Schema for the `SessionContext` type. [JsonPropertyName("context")] public SessionContext? Context { get; set; } @@ -721,10 +725,6 @@ public sealed class SessionMetadata [JsonPropertyName("mcTaskId")] public string? McTaskId { get; set; } - /// Identifier of the client driving the session. - [JsonPropertyName("clientName")] - public string? ClientName { get; set; } - /// Last-modified time of the session's persisted state, as ISO 8601. [JsonPropertyName("modifiedTime")] public string ModifiedTime { get; set; } = string.Empty; @@ -2520,6 +2520,10 @@ public sealed class WorkspacesGetWorkspaceResultWorkspace [JsonPropertyName("chronicle_sync_dismissed")] public bool? ChronicleSyncDismissed { get; set; } + /// Gets or sets the client_name value. + [JsonPropertyName("client_name")] + public string? ClientName { get; set; } + /// Gets or sets the created_at value. [JsonPropertyName("created_at")] public DateTimeOffset? CreatedAt { get; set; } @@ -6527,6 +6531,10 @@ public sealed class SessionMetadataSnapshot [JsonPropertyName("alreadyInUse")] public bool AlreadyInUse { get; set; } + /// Runtime client name associated with the session (telemetry identifier). + [JsonPropertyName("clientName")] + public string? ClientName { get; set; } + /// The current agent mode for this session (e.g., 'interactive', 'plan', 'autopilot'). [JsonPropertyName("currentMode")] public MetadataSnapshotCurrentMode CurrentMode { get; set; } diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index 937428bf2..162e5111d 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -4390,6 +4390,8 @@ type SessionMcpReloadResult struct { // Schema for the `SessionMetadata` type. // Experimental: SessionMetadata is part of an experimental API and may change or be removed. type SessionMetadata struct { + // Runtime client name that created/last resumed this session + ClientName *string `json:"clientName,omitempty"` // Schema for the `SessionContext` type. Context *SessionContext `json:"context,omitempty"` // True for remote (GitHub) sessions; false for local @@ -4397,8 +4399,6 @@ type SessionMetadata struct { // GitHub task ID, when this local session is bound to one. Only present for local sessions // exported to remote control. McTaskID *string `json:"mcTaskId,omitempty"` - // Identifier of the client driving the session. - ClientName *string `json:"clientName,omitempty"` // Last-modified time of the session's persisted state, as ISO 8601 ModifiedTime string `json:"modifiedTime"` // Optional human-friendly name set via /rename @@ -4419,6 +4419,8 @@ type SessionMetadataSnapshot struct { // Local consumers may surface a confirmation prompt before fully attaching. Always false // for new sessions. AlreadyInUse bool `json:"alreadyInUse"` + // Runtime client name associated with the session (telemetry identifier). + ClientName *string `json:"clientName,omitempty"` // The current agent mode for this session (e.g., 'interactive', 'plan', 'autopilot') CurrentMode MetadataSnapshotCurrentMode `json:"currentMode"` // User-provided name supplied at session construction (via `--name`), if any. Immutable @@ -6285,6 +6287,7 @@ type WorkspacesGetWorkspaceResult struct { type WorkspacesGetWorkspaceResultWorkspace struct { Branch *string `json:"branch,omitempty"` ChronicleSyncDismissed *bool `json:"chronicle_sync_dismissed,omitempty"` + ClientName *string `json:"client_name,omitempty"` CreatedAt *time.Time `json:"created_at,omitempty"` Cwd *string `json:"cwd,omitempty"` GitRoot *string `json:"git_root,omitempty"` diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index 39c965e67..df5117f7c 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -6604,14 +6604,14 @@ export interface SessionMetadata { * Short summary of the session, when one has been derived */ summary?: string; - /** - * Identifier of the client driving the session. - */ - clientName?: string; /** * Optional human-friendly name set via /rename */ name?: string; + /** + * Runtime client name that created/last resumed this session + */ + clientName?: string; /** * True for remote (GitHub) sessions; false for local */ @@ -7219,6 +7219,10 @@ export interface SessionMetadataSnapshot { * User-provided name supplied at session construction (via `--name`), if any. Immutable after construction. */ initialName?: string; + /** + * Runtime client name associated with the session (telemetry identifier). + */ + clientName?: string; remoteMetadata?: MetadataSnapshotRemoteMetadata; /** * Short human-readable summary of the session, if known. Omitted when no summary has been generated. @@ -9524,6 +9528,7 @@ export interface WorkspacesGetWorkspaceResult { host_type?: WorkspacesWorkspaceDetailsHostType; branch?: string; name?: string; + client_name?: string; user_named?: boolean; summary_count?: number; created_at?: string; diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index ac13369f1..4c7db8d77 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -8578,6 +8578,7 @@ class Workspace: id: str branch: str | None = None chronicle_sync_dismissed: bool | None = None + client_name: str | None = None created_at: datetime | None = None cwd: str | None = None git_root: str | None = None @@ -8600,6 +8601,7 @@ def from_dict(obj: Any) -> 'Workspace': id = from_str(obj.get("id")) branch = from_union([from_str, from_none], obj.get("branch")) chronicle_sync_dismissed = from_union([from_bool, from_none], obj.get("chronicle_sync_dismissed")) + client_name = from_union([from_str, from_none], obj.get("client_name")) created_at = from_union([from_datetime, from_none], obj.get("created_at")) cwd = from_union([from_str, from_none], obj.get("cwd")) git_root = from_union([from_str, from_none], obj.get("git_root")) @@ -8613,7 +8615,7 @@ def from_dict(obj: Any) -> 'Workspace': summary_count = from_union([from_int, from_none], obj.get("summary_count")) updated_at = from_union([from_datetime, from_none], obj.get("updated_at")) user_named = from_union([from_bool, from_none], obj.get("user_named")) - return Workspace(id, branch, chronicle_sync_dismissed, created_at, cwd, git_root, host_type, mc_last_event_id, mc_session_id, mc_task_id, name, remote_steerable, repository, summary_count, updated_at, user_named) + return Workspace(id, branch, chronicle_sync_dismissed, client_name, created_at, cwd, git_root, host_type, mc_last_event_id, mc_session_id, mc_task_id, name, remote_steerable, repository, summary_count, updated_at, user_named) def to_dict(self) -> dict: result: dict = {} @@ -8622,6 +8624,8 @@ def to_dict(self) -> dict: result["branch"] = from_union([from_str, from_none], self.branch) if self.chronicle_sync_dismissed is not None: result["chronicle_sync_dismissed"] = from_union([from_bool, from_none], self.chronicle_sync_dismissed) + if self.client_name is not None: + result["client_name"] = from_union([from_str, from_none], self.client_name) if self.created_at is not None: result["created_at"] = from_union([lambda x: x.isoformat(), from_none], self.created_at) if self.cwd is not None: @@ -12158,6 +12162,9 @@ class SessionMetadata: start_time: str """Session creation time as an ISO 8601 timestamp""" + client_name: str | None = None + """Runtime client name that created/last resumed this session""" + context: SessionContext | None = None """Schema for the `SessionContext` type.""" @@ -12165,9 +12172,6 @@ class SessionMetadata: """GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. """ - client_name: str | None = None - """Identifier of the client driving the session.""" - name: str | None = None """Optional human-friendly name set via /rename""" @@ -12181,12 +12185,12 @@ def from_dict(obj: Any) -> 'SessionMetadata': modified_time = from_str(obj.get("modifiedTime")) session_id = from_str(obj.get("sessionId")) start_time = from_str(obj.get("startTime")) + client_name = from_union([from_str, from_none], obj.get("clientName")) context = from_union([SessionContext.from_dict, from_none], obj.get("context")) mc_task_id = from_union([from_str, from_none], obj.get("mcTaskId")) - client_name = from_union([from_str, from_none], obj.get("clientName")) name = from_union([from_str, from_none], obj.get("name")) summary = from_union([from_str, from_none], obj.get("summary")) - return SessionMetadata(is_remote, modified_time, session_id, start_time, context, mc_task_id, client_name, name, summary) + return SessionMetadata(is_remote, modified_time, session_id, start_time, client_name, context, mc_task_id, name, summary) def to_dict(self) -> dict: result: dict = {} @@ -12194,12 +12198,12 @@ def to_dict(self) -> dict: result["modifiedTime"] = from_str(self.modified_time) result["sessionId"] = from_str(self.session_id) result["startTime"] = from_str(self.start_time) + if self.client_name is not None: + result["clientName"] = from_union([from_str, from_none], self.client_name) if self.context is not None: result["context"] = from_union([lambda x: to_class(SessionContext, x), from_none], self.context) if self.mc_task_id is not None: result["mcTaskId"] = from_union([from_str, from_none], self.mc_task_id) - if self.client_name is not None: - result["clientName"] = from_union([from_str, from_none], self.client_name) if self.name is not None: result["name"] = from_union([from_str, from_none], self.name) if self.summary is not None: @@ -13991,6 +13995,9 @@ class SessionMetadataSnapshot: working_directory: str """Absolute path to the session's current working directory""" + client_name: str | None = None + """Runtime client name associated with the session (telemetry identifier).""" + initial_name: str | None = None """User-provided name supplied at session construction (via `--name`), if any. Immutable after construction. @@ -14026,13 +14033,14 @@ def from_dict(obj: Any) -> 'SessionMetadataSnapshot': session_id = from_str(obj.get("sessionId")) start_time = from_datetime(obj.get("startTime")) working_directory = from_str(obj.get("workingDirectory")) + client_name = from_union([from_str, from_none], obj.get("clientName")) initial_name = from_union([from_str, from_none], obj.get("initialName")) remote_metadata = from_union([MetadataSnapshotRemoteMetadata.from_dict, from_none], obj.get("remoteMetadata")) selected_model = from_union([from_str, from_none], obj.get("selectedModel")) summary = from_union([from_str, from_none], obj.get("summary")) workspace = from_union([WorkspaceSummary.from_dict, from_none], obj.get("workspace")) workspace_path = from_union([from_none, from_str], obj.get("workspacePath")) - return SessionMetadataSnapshot(already_in_use, current_mode, is_remote, modified_time, session_id, start_time, working_directory, initial_name, remote_metadata, selected_model, summary, workspace, workspace_path) + return SessionMetadataSnapshot(already_in_use, current_mode, is_remote, modified_time, session_id, start_time, working_directory, client_name, initial_name, remote_metadata, selected_model, summary, workspace, workspace_path) def to_dict(self) -> dict: result: dict = {} @@ -14043,6 +14051,8 @@ def to_dict(self) -> dict: result["sessionId"] = from_str(self.session_id) result["startTime"] = self.start_time.isoformat() result["workingDirectory"] = from_str(self.working_directory) + if self.client_name is not None: + result["clientName"] = from_union([from_str, from_none], self.client_name) if self.initial_name is not None: result["initialName"] = from_union([from_str, from_none], self.initial_name) if self.remote_metadata is not None: diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index 7b86cdadc..0efc8b05b 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -10,7 +10,8 @@ use super::session_events::{ AbortReason, McpServerSource, McpServerStatus, PermissionPromptRequest, PermissionRule, ReasoningSummary, SessionMode, ShutdownType, SkillSource, UserToolSessionApproval, }; -use crate::types::{RequestId, SessionEvent, SessionId}; +use crate::types::SessionEvent; +use crate::types::{RequestId, SessionId}; /// JSON-RPC method name constants. pub mod rpc_methods { @@ -6004,6 +6005,9 @@ pub struct SessionContextInfo { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SessionMetadata { + /// Runtime client name that created/last resumed this session + #[serde(skip_serializing_if = "Option::is_none")] + pub client_name: Option, /// Schema for the `SessionContext` type. #[serde(skip_serializing_if = "Option::is_none")] pub context: Option, @@ -6012,9 +6016,6 @@ pub struct SessionMetadata { /// GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. #[serde(skip_serializing_if = "Option::is_none")] pub mc_task_id: Option, - /// Identifier of the client driving the session. - #[serde(skip_serializing_if = "Option::is_none")] - pub client_name: Option, /// Last-modified time of the session's persisted state, as ISO 8601 pub modified_time: String, /// Optional human-friendly name set via /rename @@ -6651,6 +6652,9 @@ pub struct SessionMetadataSnapshotWorkspace { pub struct SessionMetadataSnapshot { /// True when the session was detected to be in use by another process at construction time. Local consumers may surface a confirmation prompt before fully attaching. Always false for new sessions. pub already_in_use: bool, + /// Runtime client name associated with the session (telemetry identifier). + #[serde(skip_serializing_if = "Option::is_none")] + pub client_name: Option, /// The current agent mode for this session (e.g., 'interactive', 'plan', 'autopilot') pub current_mode: MetadataSnapshotCurrentMode, /// User-provided name supplied at session construction (via `--name`), if any. Immutable after construction. @@ -9049,6 +9053,8 @@ pub struct WorkspacesGetWorkspaceResultWorkspace { skip_serializing_if = "Option::is_none" )] pub chronicle_sync_dismissed: Option, + #[serde(rename = "client_name", skip_serializing_if = "Option::is_none")] + pub client_name: Option, #[serde(rename = "created_at", skip_serializing_if = "Option::is_none")] pub created_at: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -9853,6 +9859,8 @@ pub struct SessionWorkspacesGetWorkspaceResultWorkspace { skip_serializing_if = "Option::is_none" )] pub chronicle_sync_dismissed: Option, + #[serde(rename = "client_name", skip_serializing_if = "Option::is_none")] + pub client_name: Option, #[serde(rename = "created_at", skip_serializing_if = "Option::is_none")] pub created_at: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -11491,6 +11499,9 @@ pub struct SessionMetadataSnapshotResultWorkspace { pub struct SessionMetadataSnapshotResult { /// True when the session was detected to be in use by another process at construction time. Local consumers may surface a confirmation prompt before fully attaching. Always false for new sessions. pub already_in_use: bool, + /// Runtime client name associated with the session (telemetry identifier). + #[serde(skip_serializing_if = "Option::is_none")] + pub client_name: Option, /// The current agent mode for this session (e.g., 'interactive', 'plan', 'autopilot') pub current_mode: MetadataSnapshotCurrentMode, /// User-provided name supplied at session construction (via `--name`), if any. Immutable after construction. From c1c1e2b93e536591132e3d4a5d54e500cc58bf13 Mon Sep 17 00:00:00 2001 From: "David Sterling (VS)" Date: Tue, 26 May 2026 15:30:40 -0700 Subject: [PATCH 05/10] fix: remove unnecessary str() cast for client_name in Python The client_name field should be handled consistently with other optional string fields like summary. Remove the redundant str() cast to match the pattern used elsewhere in the codebase. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- python/copilot/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/copilot/client.py b/python/copilot/client.py index e82a1e8e8..dd56feb50 100644 --- a/python/copilot/client.py +++ b/python/copilot/client.py @@ -805,7 +805,7 @@ def from_dict(obj: Any) -> SessionMetadata: modified_time=_parse_session_timestamp(modified_time), is_remote=bool(is_remote), summary=summary, - client_name=str(client_name) if client_name is not None else None, + client_name=client_name, context=context, ) From 65ad209c10899a6e4a2dd710029890b8bc0d8715 Mon Sep 17 00:00:00 2001 From: "David Sterling (VS)" Date: Tue, 26 May 2026 17:28:54 -0700 Subject: [PATCH 06/10] fix: remove clientName from generated RPC types The runtime schema update adding clientName hasn't been published to the @github/copilot npm package yet. Remove clientName from generated RPC types to match the current published schema. The handwritten public types still include clientName and will work correctly once the runtime update is deployed. This fixes the codegen check failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/src/Generated/Rpc.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index d87d992eb..9d9d6b650 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -2520,10 +2520,6 @@ public sealed class WorkspacesGetWorkspaceResultWorkspace [JsonPropertyName("chronicle_sync_dismissed")] public bool? ChronicleSyncDismissed { get; set; } - /// Gets or sets the client_name value. - [JsonPropertyName("client_name")] - public string? ClientName { get; set; } - /// Gets or sets the created_at value. [JsonPropertyName("created_at")] public DateTimeOffset? CreatedAt { get; set; } @@ -3876,10 +3872,6 @@ internal sealed class McpOauthLoginRequest [JsonPropertyName("callbackSuccessMessage")] public string? CallbackSuccessMessage { get; set; } - /// Optional override for the OAuth client display name shown on the consent screen. Applies to newly registered dynamic clients only — existing registrations keep the name they were created with. When omitted, the runtime applies a neutral fallback; callers driving interactive auth should pass their own surface-specific label so the consent screen matches the product the user sees. - [JsonPropertyName("clientName")] - public string? ClientName { get; set; } - /// When true, clears any cached OAuth token for the server and runs a full new authorization. Use when the user explicitly wants to switch accounts or believes their session is stuck. [JsonPropertyName("forceReauth")] public bool? ForceReauth { get; set; } @@ -4279,10 +4271,6 @@ internal sealed class SessionUpdateOptionsParams [JsonPropertyName("availableTools")] public IList? AvailableTools { get; set; } - /// Identifier of the client driving the session. - [JsonPropertyName("clientName")] - public string? ClientName { get; set; } - /// Whether to include the `Co-authored-by` trailer in commit messages. [JsonPropertyName("coauthorEnabled")] public bool? CoauthorEnabled { get; set; } From d4f6c86dc6f645ccccff26d59d54e75da4f46d6b Mon Sep 17 00:00:00 2001 From: "David Sterling (VS)" Date: Tue, 26 May 2026 21:15:10 -0700 Subject: [PATCH 07/10] fix: regenerate with updated schema including clientName The @github/copilot package has been updated with the runtime schema changes that add clientName. Regenerate all generated RPC types to match the published schema. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/src/Generated/Rpc.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index 9d9d6b650..d87d992eb 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -2520,6 +2520,10 @@ public sealed class WorkspacesGetWorkspaceResultWorkspace [JsonPropertyName("chronicle_sync_dismissed")] public bool? ChronicleSyncDismissed { get; set; } + /// Gets or sets the client_name value. + [JsonPropertyName("client_name")] + public string? ClientName { get; set; } + /// Gets or sets the created_at value. [JsonPropertyName("created_at")] public DateTimeOffset? CreatedAt { get; set; } @@ -3872,6 +3876,10 @@ internal sealed class McpOauthLoginRequest [JsonPropertyName("callbackSuccessMessage")] public string? CallbackSuccessMessage { get; set; } + /// Optional override for the OAuth client display name shown on the consent screen. Applies to newly registered dynamic clients only — existing registrations keep the name they were created with. When omitted, the runtime applies a neutral fallback; callers driving interactive auth should pass their own surface-specific label so the consent screen matches the product the user sees. + [JsonPropertyName("clientName")] + public string? ClientName { get; set; } + /// When true, clears any cached OAuth token for the server and runs a full new authorization. Use when the user explicitly wants to switch accounts or believes their session is stuck. [JsonPropertyName("forceReauth")] public bool? ForceReauth { get; set; } @@ -4271,6 +4279,10 @@ internal sealed class SessionUpdateOptionsParams [JsonPropertyName("availableTools")] public IList? AvailableTools { get; set; } + /// Identifier of the client driving the session. + [JsonPropertyName("clientName")] + public string? ClientName { get; set; } + /// Whether to include the `Co-authored-by` trailer in commit messages. [JsonPropertyName("coauthorEnabled")] public bool? CoauthorEnabled { get; set; } From 3ff42feb69b8ffc22296e32e8f816a83b2194009 Mon Sep 17 00:00:00 2001 From: "David Sterling (VS)" Date: Tue, 26 May 2026 21:16:38 -0700 Subject: [PATCH 08/10] test: add client_name field to Rust test SessionMetadata The generated SessionMetadata type now includes client_name field. Update the test code to provide this field when constructing the struct. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- rust/tests/e2e/rpc_server.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/tests/e2e/rpc_server.rs b/rust/tests/e2e/rpc_server.rs index d89d69458..623b2aed8 100644 --- a/rust/tests/e2e/rpc_server.rs +++ b/rust/tests/e2e/rpc_server.rs @@ -423,6 +423,7 @@ async fn should_enrich_basic_session_metadata() { .expect("create session"); let session_id = session.id().clone(); let metadata = SessionMetadata { + client_name: None, context: Some(SessionContext { branch: None, cwd: ctx.work_dir().display().to_string(), From 0468e7501a35ea8e4d84bc8d7fbcd8332527b072 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Tue, 26 May 2026 21:25:07 -0700 Subject: [PATCH 09/10] build: update @github/copilot to 1.0.55-3 with clientName schema Regenerates all RPC types with the latest schema that includes clientName. Now CI codegen check should pass. --- dotnet/src/Generated/Rpc.cs | 1102 ++++++++++++++++++-- dotnet/src/Generated/SessionEvents.cs | 222 ++++ go/rpc/zrpc.go | 449 +++++++- go/rpc/zrpc_encoding.go | 97 ++ go/rpc/zsession_encoding.go | 18 + go/rpc/zsession_events.go | 236 +++-- go/zsession_events.go | 15 + nodejs/package-lock.json | 84 +- nodejs/package.json | 2 +- nodejs/src/generated/rpc.ts | 428 +++++++- nodejs/src/generated/session-events.ts | 152 +++ python/copilot/generated/rpc.py | 637 ++++++++++- python/copilot/generated/session_events.py | 106 +- rust/src/generated/api_types.rs | 571 +++++++++- rust/src/generated/rpc.rs | 112 +- rust/src/generated/session_events.rs | 86 ++ 16 files changed, 4075 insertions(+), 242 deletions(-) diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index d87d992eb..9d523a182 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -717,6 +717,10 @@ public sealed class SessionMetadata [JsonPropertyName("context")] public SessionContext? Context { get; set; } + /// True for detached maintenance sessions that should be hidden from normal resume lists. + [JsonPropertyName("isDetached")] + public bool? IsDetached { get; set; } + /// True for remote (GitHub) sessions; false for local. [JsonPropertyName("isRemote")] public bool IsRemote { get; set; } @@ -776,7 +780,7 @@ public sealed class SessionListFilter public string? Repository { get; set; } } -/// Optional metadata-load limit and context filter applied to the returned sessions. +/// Optional metadata-load limit and filters applied to the returned sessions. [Experimental(Diagnostics.Experimental)] internal sealed class SessionsListRequest { @@ -784,6 +788,10 @@ internal sealed class SessionsListRequest [JsonPropertyName("filter")] public SessionListFilter? Filter { get; set; } + /// When true, include detached maintenance sessions. Defaults to false for user-facing session lists. + [JsonPropertyName("includeDetached")] + public bool? IncludeDetached { get; set; } + /// When provided, only the first N sessions (sorted by modification time, newest first) load full metadata; remaining sessions return basic info only. Use 0 to return only basic info for every session. [JsonPropertyName("metadataLimit")] public long? MetadataLimit { get; set; } @@ -1122,6 +1130,242 @@ internal sealed class SessionsSetAdditionalPluginsRequest public IList Plugins { get => field ??= []; set; } } +/// Outcome of an agentRegistry.spawn call. +/// Polymorphic base type discriminated by kind. +[Experimental(Diagnostics.Experimental)] +[JsonPolymorphic( + TypeDiscriminatorPropertyName = "kind", + UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] +[JsonDerivedType(typeof(AgentRegistrySpawnResultSpawned), "spawned")] +[JsonDerivedType(typeof(AgentRegistrySpawnResultSpawnError), "spawn-error")] +[JsonDerivedType(typeof(AgentRegistrySpawnResultRegistryTimeout), "registry-timeout")] +[JsonDerivedType(typeof(AgentRegistrySpawnResultValidationError), "validation-error")] +public partial class AgentRegistrySpawnResult +{ + /// The type discriminator. + [JsonPropertyName("kind")] + public virtual string Kind { get; set; } = string.Empty; +} + + +/// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). +[Experimental(Diagnostics.Experimental)] +public sealed class AgentRegistryLiveTargetEntry +{ + /// Kind of attention required when status === "attention". Meaningful only when status === "attention". + [JsonPropertyName("attentionKind")] + public AgentRegistryLiveTargetEntryAttentionKind? AttentionKind { get; set; } + + /// Git branch of the session (when known). + [JsonPropertyName("branch")] + public string? Branch { get; set; } + + /// Copilot CLI version that wrote the entry. + [JsonPropertyName("copilotVersion")] + public string CopilotVersion { get; set; } = string.Empty; + + /// Working directory of the session (when known). + [JsonPropertyName("cwd")] + public string? Cwd { get; set; } + + /// Bind host for the entry's JSON-RPC server. + [JsonPropertyName("host")] + public string Host { get; set; } = string.Empty; + + /// Process kind tag for the registry entry. + [JsonPropertyName("kind")] + public AgentRegistryLiveTargetEntryKind Kind { get; set; } + + /// Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness). + [JsonPropertyName("lastSeenMs")] + public long LastSeenMs { get; set; } + + /// How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done from done_cancelled. + [JsonPropertyName("lastTerminalEvent")] + public AgentRegistryLiveTargetEntryLastTerminalEvent? LastTerminalEvent { get; set; } + + /// Model identifier currently selected for the session. + [JsonPropertyName("model")] + public string? Model { get; set; } + + /// Operating-system pid of the process owning this entry. + [JsonPropertyName("pid")] + public long Pid { get; set; } + + /// TCP port the entry's JSON-RPC server is listening on. + [JsonPropertyName("port")] + public long Port { get; set; } + + /// Registry entry schema version (1 = ui-server, 2 = managed-server). + [JsonPropertyName("schemaVersion")] + public long SchemaVersion { get; set; } + + /// Session ID of the foreground session for this entry. + [JsonPropertyName("sessionId")] + public string? SessionId { get; set; } + + /// Friendly session name (when set). + [JsonPropertyName("sessionName")] + public string? SessionName { get; set; } + + /// ISO 8601 timestamp captured at registration. + [JsonPropertyName("startedAt")] + public string StartedAt { get; set; } = string.Empty; + + /// Coarse lifecycle status of the foreground session. + [JsonPropertyName("status")] + public AgentRegistryLiveTargetEntryStatus? Status { get; set; } + + /// Monotonic per-publisher revision counter incremented on every status update. Lets watchers detect transient flips. + [JsonPropertyName("statusRevision")] + public long? StatusRevision { get; set; } + + /// Connection token (null when the target is unauthenticated). + [JsonInclude] + [JsonPropertyName("token")] + internal string? Token { get; set; } +} + +/// Per-spawn log-capture outcome; populated from spawnLiveTarget. +[Experimental(Diagnostics.Experimental)] +public sealed class AgentRegistryLogCapture +{ + /// Whether per-spawn log capture is on (false when env-disabled or open failed). + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } + + /// Human-readable open failure message (only set when enabled === false AND the env-disable opt-out was NOT used). + [JsonPropertyName("openError")] + public string? OpenError { get; set; } + + /// Categorized reason for log-open failure. + [JsonPropertyName("openErrorReason")] + public AgentRegistryLogCaptureOpenErrorReason? OpenErrorReason { get; set; } + + /// Absolute path to the per-spawn log file (only set when enabled). + [JsonPropertyName("path")] + public string? Path { get; set; } +} + +/// Managed-server child was spawned and registered successfully. +/// The spawned variant of . +[Experimental(Diagnostics.Experimental)] +public partial class AgentRegistrySpawnResultSpawned : AgentRegistrySpawnResult +{ + /// + [JsonIgnore] + public override string Kind => "spawned"; + + /// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). + [JsonPropertyName("entry")] + public required AgentRegistryLiveTargetEntry Entry { get; set; } + + /// If the delegate attempted to send the initial prompt and failed, the categorized error message. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("initialPromptError")] + public string? InitialPromptError { get; set; } + + /// Whether the delegate already sent the initial prompt. Always omitted in the current wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send path. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("initialPromptSent")] + public bool? InitialPromptSent { get; set; } + + /// Per-spawn log-capture outcome; populated from spawnLiveTarget. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("logCapture")] + public AgentRegistryLogCapture? LogCapture { get; set; } +} + +/// `child_process.spawn` itself failed before the child entered the registry. +/// The spawn-error variant of . +[Experimental(Diagnostics.Experimental)] +public partial class AgentRegistrySpawnResultSpawnError : AgentRegistrySpawnResult +{ + /// + [JsonIgnore] + public override string Kind => "spawn-error"; + + /// Underlying errno code (e.g. ENOENT, EACCES) when available. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("code")] + public string? Code { get; set; } + + /// Human-readable error message. + [JsonPropertyName("message")] + public required string Message { get; set; } +} + +/// Spawn succeeded but the child did not publish a matching managed-server entry within the timeout. +/// The registry-timeout variant of . +[Experimental(Diagnostics.Experimental)] +public partial class AgentRegistrySpawnResultRegistryTimeout : AgentRegistrySpawnResult +{ + /// + [JsonIgnore] + public override string Kind => "registry-timeout"; + + /// Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance). + [JsonPropertyName("childPid")] + public required long ChildPid { get; set; } + + /// Per-spawn log-capture outcome; populated from spawnLiveTarget. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("logCapture")] + public AgentRegistryLogCapture? LogCapture { get; set; } +} + +/// Synchronous pre-validation rejected the spawn request. +/// The validation-error variant of . +[Experimental(Diagnostics.Experimental)] +public partial class AgentRegistrySpawnResultValidationError : AgentRegistrySpawnResult +{ + /// + [JsonIgnore] + public override string Kind => "validation-error"; + + /// Which parameter field was invalid. Omitted when the rejection is not field-specific. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("field")] + public AgentRegistrySpawnValidationErrorField? Field { get; set; } + + /// Human-readable explanation; safe to surface in the UI banner. Never logged to unrestricted telemetry. + [JsonPropertyName("message")] + public required string Message { get; set; } + + /// Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by reason without leaking raw paths or agent/model names. + [JsonPropertyName("reason")] + public required AgentRegistrySpawnValidationErrorReason Reason { get; set; } +} + +/// Inputs to spawn a managed-server child via the controller's spawn delegate. +[Experimental(Diagnostics.Experimental)] +internal sealed class AgentRegistrySpawnRequest +{ + /// Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. + [JsonPropertyName("agentName")] + public string? AgentName { get; set; } + + /// Working directory for the spawned child (must be an existing directory). + [JsonPropertyName("cwd")] + public string Cwd { get; set; } = string.Empty; + + /// Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). + [JsonPropertyName("initialPrompt")] + public string? InitialPrompt { get; set; } + + /// Model identifier to apply to the new session. + [JsonPropertyName("model")] + public string? Model { get; set; } + + /// Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. + [JsonPropertyName("name")] + public string? Name { get; set; } + + /// Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. + [JsonPropertyName("permissionMode")] + public AgentRegistrySpawnPermissionMode? PermissionMode { get; set; } +} + /// Identifies the target session. [Experimental(Diagnostics.Experimental)] internal sealed class SessionSuspendRequest @@ -5935,6 +6179,50 @@ internal sealed class PermissionsSetApproveAllRequest public PermissionsSetApproveAllSource? Source { get; set; } } +/// Indicates whether the operation succeeded and reports the post-mutation state. +[Experimental(Diagnostics.Experimental)] +public sealed class AllowAllPermissionSetResult +{ + /// Authoritative allow-all state after the mutation. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } + + /// Whether the operation succeeded. + [JsonPropertyName("success")] + public bool Success { get; set; } +} + +/// Whether to enable full allow-all permissions for the session. +[Experimental(Diagnostics.Experimental)] +internal sealed class PermissionsSetAllowAllRequest +{ + /// Whether to enable full allow-all permissions. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Current full allow-all permission state. +[Experimental(Diagnostics.Experimental)] +public sealed class AllowAllPermissionState +{ + /// Whether full allow-all permissions are currently active. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } +} + +/// No parameters. +[Experimental(Diagnostics.Experimental)] +internal sealed class PermissionsGetAllowAllRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + /// Indicates whether the operation succeeded. [Experimental(Diagnostics.Experimental)] public sealed class PermissionsModifyRulesResult @@ -8354,49 +8642,52 @@ public override void Write(Utf8JsonWriter writer, SessionContextHostType value, } -/// The UI mode the agent was in when this message was sent. Defaults to the session's current mode. +/// Kind of attention required when status === "attention". Meaningful only when status === "attention". [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct SendAgentMode : IEquatable +public readonly struct AgentRegistryLiveTargetEntryAttentionKind : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public SendAgentMode(string value) + public AgentRegistryLiveTargetEntryAttentionKind(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// The agent is responding interactively to the user. - public static SendAgentMode Interactive { get; } = new("interactive"); + /// Session is blocked on an unrecoverable error. + public static AgentRegistryLiveTargetEntryAttentionKind Error { get; } = new("error"); - /// The agent is preparing a plan before making changes. - public static SendAgentMode Plan { get; } = new("plan"); + /// Session is waiting for a tool-permission decision. + public static AgentRegistryLiveTargetEntryAttentionKind Permission { get; } = new("permission"); - /// The agent is working autonomously toward task completion. - public static SendAgentMode Autopilot { get; } = new("autopilot"); + /// Session is waiting for the user to approve or reject a plan. + public static AgentRegistryLiveTargetEntryAttentionKind ExitPlan { get; } = new("exit_plan"); - /// The agent is in shell-focused UI mode. - public static SendAgentMode Shell { get; } = new("shell"); + /// Session is waiting on an elicitation prompt. + public static AgentRegistryLiveTargetEntryAttentionKind Elicitation { get; } = new("elicitation"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(SendAgentMode left, SendAgentMode right) => left.Equals(right); + /// Session is waiting for free-form user input. + public static AgentRegistryLiveTargetEntryAttentionKind UserInput { get; } = new("user_input"); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(SendAgentMode left, SendAgentMode right) => !(left == right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistryLiveTargetEntryAttentionKind left, AgentRegistryLiveTargetEntryAttentionKind right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistryLiveTargetEntryAttentionKind left, AgentRegistryLiveTargetEntryAttentionKind right) => !(left == right); /// - public override bool Equals(object? obj) => obj is SendAgentMode other && Equals(other); + public override bool Equals(object? obj) => obj is AgentRegistryLiveTargetEntryAttentionKind other && Equals(other); /// - public bool Equals(SendAgentMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(AgentRegistryLiveTargetEntryAttentionKind other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -8404,65 +8695,62 @@ public SendAgentMode(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override SendAgentMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override AgentRegistryLiveTargetEntryAttentionKind Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, SendAgentMode value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, AgentRegistryLiveTargetEntryAttentionKind value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SendAgentMode)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistryLiveTargetEntryAttentionKind)); } } } -/// Type of GitHub reference. +/// Process kind tag for the registry entry. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct SendAttachmentGithubReferenceType : IEquatable +public readonly struct AgentRegistryLiveTargetEntryKind : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public SendAttachmentGithubReferenceType(string value) + public AgentRegistryLiveTargetEntryKind(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// GitHub issue reference. - public static SendAttachmentGithubReferenceType Issue { get; } = new("issue"); - - /// GitHub pull request reference. - public static SendAttachmentGithubReferenceType Pr { get; } = new("pr"); + /// Interactive Copilot CLI exposing a UI server (legacy/normal CLI process). + public static AgentRegistryLiveTargetEntryKind UiServer { get; } = new("ui-server"); - /// GitHub discussion reference. - public static SendAttachmentGithubReferenceType Discussion { get; } = new("discussion"); + /// Headless `--server --managed-server` child spawned by a controller. + public static AgentRegistryLiveTargetEntryKind ManagedServer { get; } = new("managed-server"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(SendAttachmentGithubReferenceType left, SendAttachmentGithubReferenceType right) => left.Equals(right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistryLiveTargetEntryKind left, AgentRegistryLiveTargetEntryKind right) => left.Equals(right); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(SendAttachmentGithubReferenceType left, SendAttachmentGithubReferenceType right) => !(left == right); + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistryLiveTargetEntryKind left, AgentRegistryLiveTargetEntryKind right) => !(left == right); /// - public override bool Equals(object? obj) => obj is SendAttachmentGithubReferenceType other && Equals(other); + public override bool Equals(object? obj) => obj is AgentRegistryLiveTargetEntryKind other && Equals(other); /// - public bool Equals(SendAttachmentGithubReferenceType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(AgentRegistryLiveTargetEntryKind other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -8470,62 +8758,62 @@ public SendAttachmentGithubReferenceType(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override SendAttachmentGithubReferenceType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override AgentRegistryLiveTargetEntryKind Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, SendAttachmentGithubReferenceType value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, AgentRegistryLiveTargetEntryKind value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SendAttachmentGithubReferenceType)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistryLiveTargetEntryKind)); } } } -/// How to deliver the message. `enqueue` (default) appends to the message queue. `immediate` interjects during an in-progress turn. +/// How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done from done_cancelled. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct SendMode : IEquatable +public readonly struct AgentRegistryLiveTargetEntryLastTerminalEvent : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public SendMode(string value) + public AgentRegistryLiveTargetEntryLastTerminalEvent(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// Append the message to the normal session queue. - public static SendMode Enqueue { get; } = new("enqueue"); + /// Last turn ended cleanly (model returned a final assistant message). + public static AgentRegistryLiveTargetEntryLastTerminalEvent TurnEnd { get; } = new("turn_end"); - /// Interject the message during the in-progress turn. - public static SendMode Immediate { get; } = new("immediate"); + /// Last turn was aborted (e.g. user interrupted). + public static AgentRegistryLiveTargetEntryLastTerminalEvent Abort { get; } = new("abort"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(SendMode left, SendMode right) => left.Equals(right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistryLiveTargetEntryLastTerminalEvent left, AgentRegistryLiveTargetEntryLastTerminalEvent right) => left.Equals(right); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(SendMode left, SendMode right) => !(left == right); + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistryLiveTargetEntryLastTerminalEvent left, AgentRegistryLiveTargetEntryLastTerminalEvent right) => !(left == right); /// - public override bool Equals(object? obj) => obj is SendMode other && Equals(other); + public override bool Equals(object? obj) => obj is AgentRegistryLiveTargetEntryLastTerminalEvent other && Equals(other); /// - public bool Equals(SendMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(AgentRegistryLiveTargetEntryLastTerminalEvent other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -8533,65 +8821,68 @@ public SendMode(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override SendMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override AgentRegistryLiveTargetEntryLastTerminalEvent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, SendMode value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, AgentRegistryLiveTargetEntryLastTerminalEvent value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SendMode)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistryLiveTargetEntryLastTerminalEvent)); } } } -/// Log severity level. Determines how the message is displayed in the timeline. Defaults to "info". +/// Coarse lifecycle status of the foreground session. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct SessionLogLevel : IEquatable +public readonly struct AgentRegistryLiveTargetEntryStatus : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public SessionLogLevel(string value) + public AgentRegistryLiveTargetEntryStatus(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// Informational message. - public static SessionLogLevel Info { get; } = new("info"); + /// Session is actively processing a turn. + public static AgentRegistryLiveTargetEntryStatus Working { get; } = new("working"); - /// Warning message that may require attention. - public static SessionLogLevel Warning { get; } = new("warning"); + /// Session is idle, waiting for input. + public static AgentRegistryLiveTargetEntryStatus Waiting { get; } = new("waiting"); - /// Error message describing a failure. - public static SessionLogLevel Error { get; } = new("error"); + /// Last turn completed successfully. + public static AgentRegistryLiveTargetEntryStatus Done { get; } = new("done"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(SessionLogLevel left, SessionLogLevel right) => left.Equals(right); + /// Session needs user attention (see attentionKind for the specific reason). + public static AgentRegistryLiveTargetEntryStatus Attention { get; } = new("attention"); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(SessionLogLevel left, SessionLogLevel right) => !(left == right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistryLiveTargetEntryStatus left, AgentRegistryLiveTargetEntryStatus right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistryLiveTargetEntryStatus left, AgentRegistryLiveTargetEntryStatus right) => !(left == right); /// - public override bool Equals(object? obj) => obj is SessionLogLevel other && Equals(other); + public override bool Equals(object? obj) => obj is AgentRegistryLiveTargetEntryStatus other && Equals(other); /// - public bool Equals(SessionLogLevel other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(AgentRegistryLiveTargetEntryStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -8599,35 +8890,575 @@ public SessionLogLevel(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override SessionLogLevel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override AgentRegistryLiveTargetEntryStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, SessionLogLevel value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, AgentRegistryLiveTargetEntryStatus value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SessionLogLevel)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistryLiveTargetEntryStatus)); } } } -/// Authentication type. +/// Categorized reason for log-open failure. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct AuthInfoType : IEquatable +public readonly struct AgentRegistryLogCaptureOpenErrorReason : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public AgentRegistryLogCaptureOpenErrorReason(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Filesystem permission denied opening the log file. + public static AgentRegistryLogCaptureOpenErrorReason Permission { get; } = new("permission"); + + /// No space left on device. + public static AgentRegistryLogCaptureOpenErrorReason DiskFull { get; } = new("disk_full"); + + /// Other / uncategorized open failure. + public static AgentRegistryLogCaptureOpenErrorReason Other { get; } = new("other"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistryLogCaptureOpenErrorReason left, AgentRegistryLogCaptureOpenErrorReason right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistryLogCaptureOpenErrorReason left, AgentRegistryLogCaptureOpenErrorReason right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is AgentRegistryLogCaptureOpenErrorReason other && Equals(other); + + /// + public bool Equals(AgentRegistryLogCaptureOpenErrorReason other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override AgentRegistryLogCaptureOpenErrorReason Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, AgentRegistryLogCaptureOpenErrorReason value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistryLogCaptureOpenErrorReason)); + } + } +} + + +/// Which parameter field was invalid. Omitted when the rejection is not field-specific. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct AgentRegistrySpawnValidationErrorField : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public AgentRegistrySpawnValidationErrorField(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// The cwd parameter. + public static AgentRegistrySpawnValidationErrorField Cwd { get; } = new("cwd"); + + /// The session name parameter. + public static AgentRegistrySpawnValidationErrorField Name { get; } = new("name"); + + /// The agentName parameter. + public static AgentRegistrySpawnValidationErrorField AgentName { get; } = new("agentName"); + + /// The model parameter. + public static AgentRegistrySpawnValidationErrorField Model { get; } = new("model"); + + /// The permissionMode parameter. + public static AgentRegistrySpawnValidationErrorField PermissionMode { get; } = new("permissionMode"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistrySpawnValidationErrorField left, AgentRegistrySpawnValidationErrorField right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistrySpawnValidationErrorField left, AgentRegistrySpawnValidationErrorField right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is AgentRegistrySpawnValidationErrorField other && Equals(other); + + /// + public bool Equals(AgentRegistrySpawnValidationErrorField other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override AgentRegistrySpawnValidationErrorField Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, AgentRegistrySpawnValidationErrorField value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistrySpawnValidationErrorField)); + } + } +} + + +/// Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by reason without leaking raw paths or agent/model names. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct AgentRegistrySpawnValidationErrorReason : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public AgentRegistrySpawnValidationErrorReason(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Provided cwd does not exist on disk. + public static AgentRegistrySpawnValidationErrorReason CwdNotFound { get; } = new("cwd-not-found"); + + /// Provided cwd exists but is not a directory. + public static AgentRegistrySpawnValidationErrorReason CwdNotDirectory { get; } = new("cwd-not-directory"); + + /// Session name failed validateSessionName. + public static AgentRegistrySpawnValidationErrorReason InvalidName { get; } = new("invalid-name"); + + /// Requested agent name was not found in builtin or custom agents. + public static AgentRegistrySpawnValidationErrorReason UnknownAgent { get; } = new("unknown-agent"); + + /// Requested model is not available to this session. + public static AgentRegistrySpawnValidationErrorReason UnknownModel { get; } = new("unknown-model"); + + /// Caller asked for permissionMode='yolo' but the controller is not currently in allow-all mode. + public static AgentRegistrySpawnValidationErrorReason YoloNotAllowed { get; } = new("yolo-not-allowed"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistrySpawnValidationErrorReason left, AgentRegistrySpawnValidationErrorReason right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistrySpawnValidationErrorReason left, AgentRegistrySpawnValidationErrorReason right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is AgentRegistrySpawnValidationErrorReason other && Equals(other); + + /// + public bool Equals(AgentRegistrySpawnValidationErrorReason other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override AgentRegistrySpawnValidationErrorReason Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, AgentRegistrySpawnValidationErrorReason value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistrySpawnValidationErrorReason)); + } + } +} + + +/// Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct AgentRegistrySpawnPermissionMode : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public AgentRegistrySpawnPermissionMode(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Standard permission posture (prompts for each request). + public static AgentRegistrySpawnPermissionMode Default { get; } = new("default"); + + /// Full allow-all (requires the controller-local session to currently be in allow-all mode). + public static AgentRegistrySpawnPermissionMode Yolo { get; } = new("yolo"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentRegistrySpawnPermissionMode left, AgentRegistrySpawnPermissionMode right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentRegistrySpawnPermissionMode left, AgentRegistrySpawnPermissionMode right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is AgentRegistrySpawnPermissionMode other && Equals(other); + + /// + public bool Equals(AgentRegistrySpawnPermissionMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override AgentRegistrySpawnPermissionMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, AgentRegistrySpawnPermissionMode value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentRegistrySpawnPermissionMode)); + } + } +} + + +/// The UI mode the agent was in when this message was sent. Defaults to the session's current mode. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct SendAgentMode : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public SendAgentMode(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// The agent is responding interactively to the user. + public static SendAgentMode Interactive { get; } = new("interactive"); + + /// The agent is preparing a plan before making changes. + public static SendAgentMode Plan { get; } = new("plan"); + + /// The agent is working autonomously toward task completion. + public static SendAgentMode Autopilot { get; } = new("autopilot"); + + /// The agent is in shell-focused UI mode. + public static SendAgentMode Shell { get; } = new("shell"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(SendAgentMode left, SendAgentMode right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(SendAgentMode left, SendAgentMode right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is SendAgentMode other && Equals(other); + + /// + public bool Equals(SendAgentMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override SendAgentMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, SendAgentMode value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SendAgentMode)); + } + } +} + + +/// Type of GitHub reference. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct SendAttachmentGithubReferenceType : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public SendAttachmentGithubReferenceType(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// GitHub issue reference. + public static SendAttachmentGithubReferenceType Issue { get; } = new("issue"); + + /// GitHub pull request reference. + public static SendAttachmentGithubReferenceType Pr { get; } = new("pr"); + + /// GitHub discussion reference. + public static SendAttachmentGithubReferenceType Discussion { get; } = new("discussion"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(SendAttachmentGithubReferenceType left, SendAttachmentGithubReferenceType right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(SendAttachmentGithubReferenceType left, SendAttachmentGithubReferenceType right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is SendAttachmentGithubReferenceType other && Equals(other); + + /// + public bool Equals(SendAttachmentGithubReferenceType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override SendAttachmentGithubReferenceType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, SendAttachmentGithubReferenceType value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SendAttachmentGithubReferenceType)); + } + } +} + + +/// How to deliver the message. `enqueue` (default) appends to the message queue. `immediate` interjects during an in-progress turn. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct SendMode : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public SendMode(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Append the message to the normal session queue. + public static SendMode Enqueue { get; } = new("enqueue"); + + /// Interject the message during the in-progress turn. + public static SendMode Immediate { get; } = new("immediate"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(SendMode left, SendMode right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(SendMode left, SendMode right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is SendMode other && Equals(other); + + /// + public bool Equals(SendMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override SendMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, SendMode value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SendMode)); + } + } +} + + +/// Log severity level. Determines how the message is displayed in the timeline. Defaults to "info". +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct SessionLogLevel : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public SessionLogLevel(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Informational message. + public static SessionLogLevel Info { get; } = new("info"); + + /// Warning message that may require attention. + public static SessionLogLevel Warning { get; } = new("warning"); + + /// Error message describing a failure. + public static SessionLogLevel Error { get; } = new("error"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(SessionLogLevel left, SessionLogLevel right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(SessionLogLevel left, SessionLogLevel right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is SessionLogLevel other && Equals(other); + + /// + public bool Equals(SessionLogLevel other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override SessionLogLevel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, SessionLogLevel value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SessionLogLevel)); + } + } +} + + +/// Authentication type. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct AuthInfoType : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] public AuthInfoType(string value) { @@ -11650,6 +12481,12 @@ internal async Task ConnectAsync(string? token = null, Cancellati field ?? Interlocked.CompareExchange(ref field, new(_rpc), null) ?? field; + + /// AgentRegistry APIs. + public ServerAgentRegistryApi AgentRegistry => + field ?? + Interlocked.CompareExchange(ref field, new(_rpc), null) ?? + field; } /// Provides server-scoped Models APIs. @@ -11960,11 +12797,12 @@ public async Task ConnectAsync(string sessionId, /// Lists persisted sessions, optionally filtered by working-directory context. /// When provided, only the first N sessions (sorted by modification time, newest first) load full metadata; remaining sessions return basic info only. Use 0 to return only basic info for every session. /// Optional filter applied to the returned sessions. + /// When true, include detached maintenance sessions. Defaults to false for user-facing session lists. /// The to monitor for cancellation requests. The default is . /// Persisted sessions matching the filter, ordered most-recently-modified first. - public async Task ListAsync(long? metadataLimit = null, SessionListFilter? filter = null, CancellationToken cancellationToken = default) + public async Task ListAsync(long? metadataLimit = null, SessionListFilter? filter = null, bool? includeDetached = null, CancellationToken cancellationToken = default) { - var request = new SessionsListRequest { MetadataLimit = metadataLimit, Filter = filter }; + var request = new SessionsListRequest { MetadataLimit = metadataLimit, Filter = filter, IncludeDetached = includeDetached }; return await CopilotClient.InvokeRpcAsync(_rpc, "sessions.list", [request], cancellationToken); } @@ -12157,6 +12995,35 @@ public async Task SetAdditionalPluginsAsync( } } +/// Provides server-scoped AgentRegistry APIs. +[Experimental(Diagnostics.Experimental)] +public sealed class ServerAgentRegistryApi +{ + private readonly JsonRpc _rpc; + + internal ServerAgentRegistryApi(JsonRpc rpc) + { + _rpc = rpc; + } + + /// Spawns a managed-server child with the supplied configuration and returns a discriminated-union result. The caller (typically the CLI controller) is responsible for attaching to the spawned child and sending any follow-up prompt. When the controller-local spawn gate is closed the server returns JSON-RPC MethodNotFound. + /// Working directory for the spawned child (must be an existing directory). + /// Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. + /// Model identifier to apply to the new session. + /// Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. + /// Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. + /// Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). + /// The to monitor for cancellation requests. The default is . + /// Outcome of an agentRegistry.spawn call. + public async Task SpawnAsync(string cwd, string? agentName = null, string? model = null, string? name = null, AgentRegistrySpawnPermissionMode? permissionMode = null, string? initialPrompt = null, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(cwd); + + var request = new AgentRegistrySpawnRequest { Cwd = cwd, AgentName = agentName, Model = model, Name = name, PermissionMode = permissionMode, InitialPrompt = initialPrompt }; + return await CopilotClient.InvokeRpcAsync(_rpc, "agentRegistry.spawn", [request], cancellationToken); + } +} + /// Provides typed session-scoped RPC methods. public sealed class SessionRpc { @@ -13942,6 +14809,29 @@ public async Task SetApproveAllAsync(bool enable return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.permissions.setApproveAll", [request], cancellationToken); } + /// Enables or disables full allow-all permissions (tools, paths, and URLs) for the session. Used by attach-mode clients (e.g. LocalRpcSession's `/allow-all` forwarder) to flip the target session's permission state. Unlike `setApproveAll`, this swaps in the unrestricted path and URL managers and emits `session.permissions_changed` on transition. The result returns the authoritative post-mutation state so callers can update their local mirrors without racing the `session.permissions_changed` notification on the same wire. + /// Whether to enable full allow-all permissions. + /// The to monitor for cancellation requests. The default is . + /// Indicates whether the operation succeeded and reports the post-mutation state. + public async Task SetAllowAllAsync(bool enabled, CancellationToken cancellationToken = default) + { + _session.ThrowIfDisposed(); + + var request = new PermissionsSetAllowAllRequest { SessionId = _session.SessionId, Enabled = enabled }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.permissions.setAllowAll", [request], cancellationToken); + } + + /// Returns whether full allow-all permissions are currently active for the session. + /// The to monitor for cancellation requests. The default is . + /// Current full allow-all permission state. + public async Task GetAllowAllAsync(CancellationToken cancellationToken = default) + { + _session.ThrowIfDisposed(); + + var request = new PermissionsGetAllowAllRequest { SessionId = _session.SessionId }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.permissions.getAllowAll", [request], cancellationToken); + } + /// Adds or removes session-scoped or location-scoped permission rules. /// Whether the change applies to ephemeral session-scoped rules (cleared at session end) or to location-scoped rules persisted via the location-permissions config file. /// Rules to add to the scope. Applied before `remove`/`removeAll`. @@ -14859,6 +15749,8 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, FuncAutopilot objective state file operation details indicating what changed. +/// Represents the session.autopilot_objective_changed event. +public sealed partial class SessionAutopilotObjectiveChangedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "session.autopilot_objective_changed"; + + /// The session.autopilot_objective_changed event payload. + [JsonPropertyName("data")] + public required SessionAutopilotObjectiveChangedData Data { get; set; } +} + /// Informational message for timeline display with categorization. /// Represents the session.info event. public sealed partial class SessionInfoEvent : SessionEvent @@ -306,6 +322,19 @@ public sealed partial class SessionModeChangedEvent : SessionEvent public required SessionModeChangedData Data { get; set; } } +/// Permissions change details carrying the aggregate allow-all boolean transition. +/// Represents the session.permissions_changed event. +public sealed partial class SessionPermissionsChangedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "session.permissions_changed"; + + /// The session.permissions_changed event payload. + [JsonPropertyName("data")] + public required SessionPermissionsChangedData Data { get; set; } +} + /// Plan file operation details indicating what changed. /// Represents the session.plan_changed event. public sealed partial class SessionPlanChangedEvent : SessionEvent @@ -800,6 +829,19 @@ public sealed partial class HookEndEvent : SessionEvent public required HookEndData Data { get; set; } } +/// Ephemeral progress update from a running hook process. +/// Represents the hook.progress event. +public sealed partial class HookProgressEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "hook.progress"; + + /// The hook.progress event payload. + [JsonPropertyName("data")] + public required HookProgressData Data { get; set; } +} + /// System/developer instruction content with role and optional template metadata. /// Represents the system.message event. public sealed partial class SystemMessageEvent : SessionEvent @@ -1460,6 +1502,24 @@ public sealed partial class SessionScheduleCancelledData public required long Id { get; set; } } +/// Autopilot objective state file operation details indicating what changed. +public sealed partial class SessionAutopilotObjectiveChangedData +{ + /// Current autopilot objective id, if one exists. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("id")] + public long? Id { get; set; } + + /// The type of operation performed on the autopilot objective state file. + [JsonPropertyName("operation")] + public required AutopilotObjectiveChangedOperation Operation { get; set; } + + /// Current autopilot objective status, if one exists. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("status")] + public AutopilotObjectiveChangedStatus? Status { get; set; } +} + /// Informational message for timeline display with categorization. public sealed partial class SessionInfoData { @@ -1554,6 +1614,18 @@ public sealed partial class SessionModeChangedData public required SessionMode PreviousMode { get; set; } } +/// Permissions change details carrying the aggregate allow-all boolean transition. +public sealed partial class SessionPermissionsChangedData +{ + /// Aggregate allow-all flag after the change. + [JsonPropertyName("allowAllPermissions")] + public required bool AllowAllPermissions { get; set; } + + /// Aggregate allow-all flag before the change. + [JsonPropertyName("previousAllowAllPermissions")] + public required bool PreviousAllowAllPermissions { get; set; } +} + /// Plan file operation details indicating what changed. public sealed partial class SessionPlanChangedData { @@ -2356,6 +2428,11 @@ public sealed partial class ToolExecutionStartData [JsonPropertyName("arguments")] public JsonElement? Arguments { get; set; } + /// When true, the tool output should be displayed expanded (verbatim) in the CLI timeline. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("displayVerbatim")] + public bool? DisplayVerbatim { get; set; } + /// Name of the MCP server hosting this tool, when the tool is an MCP tool. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("mcpServerName")] @@ -2688,6 +2765,14 @@ public sealed partial class HookEndData public required bool Success { get; set; } } +/// Ephemeral progress update from a running hook process. +public sealed partial class HookProgressData +{ + /// Human-readable progress message from the hook process. + [JsonPropertyName("message")] + public required string Message { get; set; } +} + /// System/developer instruction content with role and optional template metadata. public sealed partial class SystemMessageData { @@ -5919,6 +6004,137 @@ public override void Write(Utf8JsonWriter writer, ReasoningSummary value, JsonSe } } +/// The type of operation performed on the autopilot objective state file. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct AutopilotObjectiveChangedOperation : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public AutopilotObjectiveChangedOperation(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Autopilot objective state file was created for a new objective. + public static AutopilotObjectiveChangedOperation Create { get; } = new("create"); + + /// Autopilot objective state file was updated for an existing objective. + public static AutopilotObjectiveChangedOperation Update { get; } = new("update"); + + /// Autopilot objective state file was deleted or cleared. + public static AutopilotObjectiveChangedOperation Delete { get; } = new("delete"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AutopilotObjectiveChangedOperation left, AutopilotObjectiveChangedOperation right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AutopilotObjectiveChangedOperation left, AutopilotObjectiveChangedOperation right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is AutopilotObjectiveChangedOperation other && Equals(other); + + /// + public bool Equals(AutopilotObjectiveChangedOperation other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override AutopilotObjectiveChangedOperation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, AutopilotObjectiveChangedOperation value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AutopilotObjectiveChangedOperation)); + } + } +} + +/// Current autopilot objective status, if one exists. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct AutopilotObjectiveChangedStatus : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public AutopilotObjectiveChangedStatus(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Objective is active and can drive autopilot continuations. + public static AutopilotObjectiveChangedStatus Active { get; } = new("active"); + + /// Objective is paused and will not drive autopilot continuations. + public static AutopilotObjectiveChangedStatus Paused { get; } = new("paused"); + + /// Legacy objective state indicating the previous continuation cap was reached. + public static AutopilotObjectiveChangedStatus CapReached { get; } = new("cap_reached"); + + /// Objective was completed by the agent. + public static AutopilotObjectiveChangedStatus Completed { get; } = new("completed"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AutopilotObjectiveChangedStatus left, AutopilotObjectiveChangedStatus right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AutopilotObjectiveChangedStatus left, AutopilotObjectiveChangedStatus right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is AutopilotObjectiveChangedStatus other && Equals(other); + + /// + public bool Equals(AutopilotObjectiveChangedStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override AutopilotObjectiveChangedStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, AutopilotObjectiveChangedStatus value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AutopilotObjectiveChangedStatus)); + } + } +} + /// Defines the allowed values. [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] @@ -7973,6 +8189,8 @@ public override void Write(Utf8JsonWriter writer, CanvasOpenedAvailability value [JsonSerializable(typeof(HookEndData))] [JsonSerializable(typeof(HookEndError))] [JsonSerializable(typeof(HookEndEvent))] +[JsonSerializable(typeof(HookProgressData))] +[JsonSerializable(typeof(HookProgressEvent))] [JsonSerializable(typeof(HookStartData))] [JsonSerializable(typeof(HookStartEvent))] [JsonSerializable(typeof(McpAppToolCallCompleteData))] @@ -8034,6 +8252,8 @@ public override void Write(Utf8JsonWriter writer, CanvasOpenedAvailability value [JsonSerializable(typeof(SamplingCompletedEvent))] [JsonSerializable(typeof(SamplingRequestedData))] [JsonSerializable(typeof(SamplingRequestedEvent))] +[JsonSerializable(typeof(SessionAutopilotObjectiveChangedData))] +[JsonSerializable(typeof(SessionAutopilotObjectiveChangedEvent))] [JsonSerializable(typeof(SessionBackgroundTasksChangedData))] [JsonSerializable(typeof(SessionBackgroundTasksChangedEvent))] [JsonSerializable(typeof(SessionCanvasOpenedData))] @@ -8069,6 +8289,8 @@ public override void Write(Utf8JsonWriter writer, CanvasOpenedAvailability value [JsonSerializable(typeof(SessionModeChangedEvent))] [JsonSerializable(typeof(SessionModelChangeData))] [JsonSerializable(typeof(SessionModelChangeEvent))] +[JsonSerializable(typeof(SessionPermissionsChangedData))] +[JsonSerializable(typeof(SessionPermissionsChangedEvent))] [JsonSerializable(typeof(SessionPlanChangedData))] [JsonSerializable(typeof(SessionPlanChangedEvent))] [JsonSerializable(typeof(SessionRemoteSteerableChangedData))] diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index 162e5111d..11a56e94f 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -108,6 +108,184 @@ type AgentList struct { Agents []AgentInfo `json:"agents"` } +// Full registry entry for the spawned child. Lets the controller call +// `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a +// TOCTOU window). +// Experimental: AgentRegistryLiveTargetEntry is part of an experimental API and may change +// or be removed. +type AgentRegistryLiveTargetEntry struct { + // Kind of attention required when status === "attention". Meaningful only when status === + // "attention". + AttentionKind *AgentRegistryLiveTargetEntryAttentionKind `json:"attentionKind,omitempty"` + // Git branch of the session (when known) + Branch *string `json:"branch,omitempty"` + // Copilot CLI version that wrote the entry + CopilotVersion string `json:"copilotVersion"` + // Working directory of the session (when known) + Cwd *string `json:"cwd,omitempty"` + // Bind host for the entry's JSON-RPC server + Host string `json:"host"` + // Process kind tag for the registry entry + Kind AgentRegistryLiveTargetEntryKind `json:"kind"` + // Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness) + LastSeenMs int64 `json:"lastSeenMs"` + // How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done + // from done_cancelled. + LastTerminalEvent *AgentRegistryLiveTargetEntryLastTerminalEvent `json:"lastTerminalEvent,omitempty"` + // Model identifier currently selected for the session + Model *string `json:"model,omitempty"` + // Operating-system pid of the process owning this entry + Pid int64 `json:"pid"` + // TCP port the entry's JSON-RPC server is listening on + Port int64 `json:"port"` + // Registry entry schema version (1 = ui-server, 2 = managed-server) + SchemaVersion int64 `json:"schemaVersion"` + // Session ID of the foreground session for this entry + SessionID *string `json:"sessionId,omitempty"` + // Friendly session name (when set) + SessionName *string `json:"sessionName,omitempty"` + // ISO 8601 timestamp captured at registration + StartedAt string `json:"startedAt"` + // Coarse lifecycle status of the foreground session + Status *AgentRegistryLiveTargetEntryStatus `json:"status,omitempty"` + // Monotonic per-publisher revision counter incremented on every status update. Lets + // watchers detect transient flips. + StatusRevision *int64 `json:"statusRevision,omitempty"` + // Connection token (null when the target is unauthenticated) + // Internal: Token is part of the SDK's internal API surface and is not intended for + // external use. + Token *string `json:"token,omitempty"` +} + +// Per-spawn log-capture outcome; populated from spawnLiveTarget. +// Experimental: AgentRegistryLogCapture is part of an experimental API and may change or be +// removed. +type AgentRegistryLogCapture struct { + // Whether per-spawn log capture is on (false when env-disabled or open failed) + Enabled bool `json:"enabled"` + // Human-readable open failure message (only set when enabled === false AND the env-disable + // opt-out was NOT used) + OpenError *string `json:"openError,omitempty"` + // Categorized reason for log-open failure + OpenErrorReason *AgentRegistryLogCaptureOpenErrorReason `json:"openErrorReason,omitempty"` + // Absolute path to the per-spawn log file (only set when enabled) + Path *string `json:"path,omitempty"` +} + +// Inputs to spawn a managed-server child via the controller's spawn delegate. +// Experimental: AgentRegistrySpawnRequest is part of an experimental API and may change or +// be removed. +type AgentRegistrySpawnRequest struct { + // Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own + // default. + AgentName *string `json:"agentName,omitempty"` + // Working directory for the spawned child (must be an existing directory) + Cwd string `json:"cwd"` + // Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it + // post-attach via the standard LocalRpcSession.send path). + InitialPrompt *string `json:"initialPrompt,omitempty"` + // Model identifier to apply to the new session + Model *string `json:"model,omitempty"` + // Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing + // whitespace, <=100 chars, no control chars, no double quotes. + Name *string `json:"name,omitempty"` + // Permission posture for the new session. 'yolo' requires the controller-local session to + // currently be in allow-all mode. + PermissionMode *AgentRegistrySpawnPermissionMode `json:"permissionMode,omitempty"` +} + +// Outcome of an agentRegistry.spawn call. +// Experimental: AgentRegistrySpawnResult is part of an experimental API and may change or +// be removed. +type AgentRegistrySpawnResult interface { + agentRegistrySpawnResult() + Kind() AgentRegistrySpawnResultKind +} + +type RawAgentRegistrySpawnResultData struct { + Discriminator AgentRegistrySpawnResultKind + Raw json.RawMessage +} + +func (RawAgentRegistrySpawnResultData) agentRegistrySpawnResult() {} +func (r RawAgentRegistrySpawnResultData) Kind() AgentRegistrySpawnResultKind { + return r.Discriminator +} + +// `child_process.spawn` itself failed before the child entered the registry. +// Experimental: AgentRegistrySpawnError is part of an experimental API and may change or be +// removed. +type AgentRegistrySpawnError struct { + // Underlying errno code (e.g. ENOENT, EACCES) when available + Code *string `json:"code,omitempty"` + // Human-readable error message + Message string `json:"message"` +} + +func (AgentRegistrySpawnError) agentRegistrySpawnResult() {} +func (AgentRegistrySpawnError) Kind() AgentRegistrySpawnResultKind { + return AgentRegistrySpawnResultKindSpawnError +} + +// Spawn succeeded but the child did not publish a matching managed-server entry within the +// timeout. +// Experimental: AgentRegistrySpawnRegistryTimeout is part of an experimental API and may +// change or be removed. +type AgentRegistrySpawnRegistryTimeout struct { + // Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance) + ChildPid int64 `json:"childPid"` + // Per-spawn log-capture outcome; populated from spawnLiveTarget. + LogCapture *AgentRegistryLogCapture `json:"logCapture,omitempty"` +} + +func (AgentRegistrySpawnRegistryTimeout) agentRegistrySpawnResult() {} +func (AgentRegistrySpawnRegistryTimeout) Kind() AgentRegistrySpawnResultKind { + return AgentRegistrySpawnResultKindRegistryTimeout +} + +// Managed-server child was spawned and registered successfully. +// Experimental: AgentRegistrySpawnSpawned is part of an experimental API and may change or +// be removed. +type AgentRegistrySpawnSpawned struct { + // Full registry entry for the spawned child. Lets the controller call + // `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a + // TOCTOU window). + Entry AgentRegistryLiveTargetEntry `json:"entry"` + // If the delegate attempted to send the initial prompt and failed, the categorized error + // message. + InitialPromptError *string `json:"initialPromptError,omitempty"` + // Whether the delegate already sent the initial prompt. Always omitted in the current + // wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send + // path. + InitialPromptSent *bool `json:"initialPromptSent,omitempty"` + // Per-spawn log-capture outcome; populated from spawnLiveTarget. + LogCapture *AgentRegistryLogCapture `json:"logCapture,omitempty"` +} + +func (AgentRegistrySpawnSpawned) agentRegistrySpawnResult() {} +func (AgentRegistrySpawnSpawned) Kind() AgentRegistrySpawnResultKind { + return AgentRegistrySpawnResultKindSpawned +} + +// Synchronous pre-validation rejected the spawn request. +// Experimental: AgentRegistrySpawnValidationError is part of an experimental API and may +// change or be removed. +type AgentRegistrySpawnValidationError struct { + // Which parameter field was invalid. Omitted when the rejection is not field-specific. + Field *AgentRegistrySpawnValidationErrorField `json:"field,omitempty"` + // Human-readable explanation; safe to surface in the UI banner. Never logged to + // unrestricted telemetry. + Message string `json:"message"` + // Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by + // reason without leaking raw paths or agent/model names. + Reason AgentRegistrySpawnValidationErrorReason `json:"reason"` +} + +func (AgentRegistrySpawnValidationError) agentRegistrySpawnResult() {} +func (AgentRegistrySpawnValidationError) Kind() AgentRegistrySpawnResultKind { + return AgentRegistrySpawnResultKindValidationError +} + // Custom agents available to the session after reloading definitions from disk. // Experimental: AgentReloadResult is part of an experimental API and may change or be // removed. @@ -132,6 +310,24 @@ type AgentSelectResult struct { Agent AgentInfo `json:"agent"` } +// Indicates whether the operation succeeded and reports the post-mutation state. +// Experimental: AllowAllPermissionSetResult is part of an experimental API and may change +// or be removed. +type AllowAllPermissionSetResult struct { + // Authoritative allow-all state after the mutation + Enabled bool `json:"enabled"` + // Whether the operation succeeded + Success bool `json:"success"` +} + +// Current full allow-all permission state. +// Experimental: AllowAllPermissionState is part of an experimental API and may change or be +// removed. +type AllowAllPermissionState struct { + // Whether full allow-all permissions are currently active + Enabled bool `json:"enabled"` +} + // The new auth credentials to install on the session. When omitted or `undefined`, the call // is a no-op and the session's existing credentials are preserved. The runtime stores the // value verbatim and uses it for outbound model/API requests; it does NOT re-validate or @@ -3114,6 +3310,12 @@ type PermissionsFolderTrustAddTrustedResult struct { Success bool `json:"success"` } +// No parameters. +// Experimental: PermissionsGetAllowAllRequest is part of an experimental API and may change +// or be removed. +type PermissionsGetAllowAllRequest struct { +} + // Tool approval to persist and apply // Experimental: PermissionsLocationsAddToolApprovalDetails is part of an experimental API // and may change or be removed. @@ -3336,6 +3538,14 @@ type PermissionsResetSessionApprovalsResult struct { Success bool `json:"success"` } +// Whether to enable full allow-all permissions for the session. +// Experimental: PermissionsSetAllowAllRequest is part of an experimental API and may change +// or be removed. +type PermissionsSetAllowAllRequest struct { + // Whether to enable full allow-all permissions + Enabled bool `json:"enabled"` +} + // Allow-all toggle for tool permission requests, with an optional telemetry source. // Experimental: PermissionsSetApproveAllRequest is part of an experimental API and may // change or be removed. @@ -4394,6 +4604,8 @@ type SessionMetadata struct { ClientName *string `json:"clientName,omitempty"` // Schema for the `SessionContext` type. Context *SessionContext `json:"context,omitempty"` + // True for detached maintenance sessions that should be hidden from normal resume lists. + IsDetached *bool `json:"isDetached,omitempty"` // True for remote (GitHub) sessions; false for local IsRemote bool `json:"isRemote"` // GitHub task ID, when this local session is bound to one. Only present for local sessions @@ -4708,12 +4920,15 @@ type SessionSkillsEnableResult struct { type SessionSkillsEnsureLoadedResult struct { } -// Optional metadata-load limit and context filter applied to the returned sessions. +// Optional metadata-load limit and filters applied to the returned sessions. // Experimental: SessionsListRequest is part of an experimental API and may change or be // removed. type SessionsListRequest struct { // Optional filter applied to the returned sessions Filter *SessionListFilter `json:"filter,omitempty"` + // When true, include detached maintenance sessions. Defaults to false for user-facing + // session lists. + IncludeDetached *bool `json:"includeDetached,omitempty"` // When provided, only the first N sessions (sorted by modification time, newest first) load // full metadata; remaining sessions return basic info only. Use 0 to return only basic info // for every session. @@ -6435,6 +6650,143 @@ const ( AgentInfoSourceUser AgentInfoSource = "user" ) +// Kind of attention required when status === "attention". Meaningful only when status === +// "attention". +// Experimental: AgentRegistryLiveTargetEntryAttentionKind is part of an experimental API +// and may change or be removed. +type AgentRegistryLiveTargetEntryAttentionKind string + +const ( + // Session is waiting on an elicitation prompt + AgentRegistryLiveTargetEntryAttentionKindElicitation AgentRegistryLiveTargetEntryAttentionKind = "elicitation" + // Session is blocked on an unrecoverable error + AgentRegistryLiveTargetEntryAttentionKindError AgentRegistryLiveTargetEntryAttentionKind = "error" + // Session is waiting for the user to approve or reject a plan + AgentRegistryLiveTargetEntryAttentionKindExitPlan AgentRegistryLiveTargetEntryAttentionKind = "exit_plan" + // Session is waiting for a tool-permission decision + AgentRegistryLiveTargetEntryAttentionKindPermission AgentRegistryLiveTargetEntryAttentionKind = "permission" + // Session is waiting for free-form user input + AgentRegistryLiveTargetEntryAttentionKindUserInput AgentRegistryLiveTargetEntryAttentionKind = "user_input" +) + +// Process kind tag for the registry entry +// Experimental: AgentRegistryLiveTargetEntryKind is part of an experimental API and may +// change or be removed. +type AgentRegistryLiveTargetEntryKind string + +const ( + // Headless `--server --managed-server` child spawned by a controller + AgentRegistryLiveTargetEntryKindManagedServer AgentRegistryLiveTargetEntryKind = "managed-server" + // Interactive Copilot CLI exposing a UI server (legacy/normal CLI process) + AgentRegistryLiveTargetEntryKindUIServer AgentRegistryLiveTargetEntryKind = "ui-server" +) + +// How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done +// from done_cancelled. +// Experimental: AgentRegistryLiveTargetEntryLastTerminalEvent is part of an experimental +// API and may change or be removed. +type AgentRegistryLiveTargetEntryLastTerminalEvent string + +const ( + // Last turn was aborted (e.g. user interrupted) + AgentRegistryLiveTargetEntryLastTerminalEventAbort AgentRegistryLiveTargetEntryLastTerminalEvent = "abort" + // Last turn ended cleanly (model returned a final assistant message) + AgentRegistryLiveTargetEntryLastTerminalEventTurnEnd AgentRegistryLiveTargetEntryLastTerminalEvent = "turn_end" +) + +// Coarse lifecycle status of the foreground session +// Experimental: AgentRegistryLiveTargetEntryStatus is part of an experimental API and may +// change or be removed. +type AgentRegistryLiveTargetEntryStatus string + +const ( + // Session needs user attention (see attentionKind for the specific reason) + AgentRegistryLiveTargetEntryStatusAttention AgentRegistryLiveTargetEntryStatus = "attention" + // Last turn completed successfully + AgentRegistryLiveTargetEntryStatusDone AgentRegistryLiveTargetEntryStatus = "done" + // Session is idle, waiting for input + AgentRegistryLiveTargetEntryStatusWaiting AgentRegistryLiveTargetEntryStatus = "waiting" + // Session is actively processing a turn + AgentRegistryLiveTargetEntryStatusWorking AgentRegistryLiveTargetEntryStatus = "working" +) + +// Categorized reason for log-open failure +// Experimental: AgentRegistryLogCaptureOpenErrorReason is part of an experimental API and +// may change or be removed. +type AgentRegistryLogCaptureOpenErrorReason string + +const ( + // No space left on device + AgentRegistryLogCaptureOpenErrorReasonDiskFull AgentRegistryLogCaptureOpenErrorReason = "disk_full" + // Other / uncategorized open failure + AgentRegistryLogCaptureOpenErrorReasonOther AgentRegistryLogCaptureOpenErrorReason = "other" + // Filesystem permission denied opening the log file + AgentRegistryLogCaptureOpenErrorReasonPermission AgentRegistryLogCaptureOpenErrorReason = "permission" +) + +// Permission posture for the new session. 'yolo' requires the controller-local session to +// currently be in allow-all mode. +// Experimental: AgentRegistrySpawnPermissionMode is part of an experimental API and may +// change or be removed. +type AgentRegistrySpawnPermissionMode string + +const ( + // Standard permission posture (prompts for each request) + AgentRegistrySpawnPermissionModeDefault AgentRegistrySpawnPermissionMode = "default" + // Full allow-all (requires the controller-local session to currently be in allow-all mode) + AgentRegistrySpawnPermissionModeYolo AgentRegistrySpawnPermissionMode = "yolo" +) + +// Kind discriminator for AgentRegistrySpawnResult. +type AgentRegistrySpawnResultKind string + +const ( + AgentRegistrySpawnResultKindRegistryTimeout AgentRegistrySpawnResultKind = "registry-timeout" + AgentRegistrySpawnResultKindSpawned AgentRegistrySpawnResultKind = "spawned" + AgentRegistrySpawnResultKindSpawnError AgentRegistrySpawnResultKind = "spawn-error" + AgentRegistrySpawnResultKindValidationError AgentRegistrySpawnResultKind = "validation-error" +) + +// Which parameter field was invalid. Omitted when the rejection is not field-specific. +// Experimental: AgentRegistrySpawnValidationErrorField is part of an experimental API and +// may change or be removed. +type AgentRegistrySpawnValidationErrorField string + +const ( + // The agentName parameter + AgentRegistrySpawnValidationErrorFieldAgentName AgentRegistrySpawnValidationErrorField = "agentName" + // The cwd parameter + AgentRegistrySpawnValidationErrorFieldCwd AgentRegistrySpawnValidationErrorField = "cwd" + // The model parameter + AgentRegistrySpawnValidationErrorFieldModel AgentRegistrySpawnValidationErrorField = "model" + // The session name parameter + AgentRegistrySpawnValidationErrorFieldName AgentRegistrySpawnValidationErrorField = "name" + // The permissionMode parameter + AgentRegistrySpawnValidationErrorFieldPermissionMode AgentRegistrySpawnValidationErrorField = "permissionMode" +) + +// Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by +// reason without leaking raw paths or agent/model names. +// Experimental: AgentRegistrySpawnValidationErrorReason is part of an experimental API and +// may change or be removed. +type AgentRegistrySpawnValidationErrorReason string + +const ( + // Provided cwd exists but is not a directory + AgentRegistrySpawnValidationErrorReasonCwdNotDirectory AgentRegistrySpawnValidationErrorReason = "cwd-not-directory" + // Provided cwd does not exist on disk + AgentRegistrySpawnValidationErrorReasonCwdNotFound AgentRegistrySpawnValidationErrorReason = "cwd-not-found" + // Session name failed validateSessionName + AgentRegistrySpawnValidationErrorReasonInvalidName AgentRegistrySpawnValidationErrorReason = "invalid-name" + // Requested agent name was not found in builtin or custom agents + AgentRegistrySpawnValidationErrorReasonUnknownAgent AgentRegistrySpawnValidationErrorReason = "unknown-agent" + // Requested model is not available to this session + AgentRegistrySpawnValidationErrorReasonUnknownModel AgentRegistrySpawnValidationErrorReason = "unknown-model" + // Caller asked for permissionMode='yolo' but the controller is not currently in allow-all + // mode + AgentRegistrySpawnValidationErrorReasonYoloNotAllowed AgentRegistrySpawnValidationErrorReason = "yolo-not-allowed" +) + // Type discriminator for AuthInfo. // Experimental: AuthInfoType is part of an experimental API and may change or be removed. type AuthInfoType string @@ -7608,6 +7960,32 @@ func (a *ServerAccountApi) GetQuota(ctx context.Context, params *AccountGetQuota return &result, nil } +// Experimental: ServerAgentRegistryApi contains experimental APIs that may change or be +// removed. +type ServerAgentRegistryApi serverApi + +// Spawns a managed-server child with the supplied configuration and returns a +// discriminated-union result. The caller (typically the CLI controller) is responsible for +// attaching to the spawned child and sending any follow-up prompt. When the +// controller-local spawn gate is closed the server returns JSON-RPC MethodNotFound. +// +// RPC method: agentRegistry.spawn. +// +// Parameters: Inputs to spawn a managed-server child via the controller's spawn delegate. +// +// Returns: Outcome of an agentRegistry.spawn call. +func (a *ServerAgentRegistryApi) Spawn(ctx context.Context, params *AgentRegistrySpawnRequest) (AgentRegistrySpawnResult, error) { + raw, err := a.client.Request("agentRegistry.spawn", params) + if err != nil { + return nil, err + } + result, err := unmarshalAgentRegistrySpawnResult(raw) + if err != nil { + return nil, err + } + return result, nil +} + type ServerMcpApi serverApi // Discovers MCP servers from user, workspace, plugin, and builtin sources. @@ -8051,8 +8429,7 @@ func (a *ServerSessionsApi) GetSizes(ctx context.Context) (*SessionSizes, error) // // RPC method: sessions.list. // -// Parameters: Optional metadata-load limit and context filter applied to the returned -// sessions. +// Parameters: Optional metadata-load limit and filters applied to the returned sessions. // // Returns: Persisted sessions matching the filter, ordered most-recently-modified first. func (a *ServerSessionsApi) List(ctx context.Context, params *SessionsListRequest) (*SessionList, error) { @@ -8268,14 +8645,15 @@ type ServerRpc struct { // Reuse a single struct instead of allocating one for each service on the heap. common serverApi - Account *ServerAccountApi - Mcp *ServerMcpApi - Models *ServerModelsApi - Secrets *ServerSecretsApi - SessionFs *ServerSessionFsApi - Sessions *ServerSessionsApi - Skills *ServerSkillsApi - Tools *ServerToolsApi + Account *ServerAccountApi + AgentRegistry *ServerAgentRegistryApi + Mcp *ServerMcpApi + Models *ServerModelsApi + Secrets *ServerSecretsApi + SessionFs *ServerSessionFsApi + Sessions *ServerSessionsApi + Skills *ServerSkillsApi + Tools *ServerToolsApi } // Ping checks server responsiveness and returns protocol information. @@ -8302,6 +8680,7 @@ func NewServerRpc(client *jsonrpc2.Client) *ServerRpc { r := &ServerRpc{} r.common = serverApi{client: client} r.Account = (*ServerAccountApi)(&r.common) + r.AgentRegistry = (*ServerAgentRegistryApi)(&r.common) r.Mcp = (*ServerMcpApi)(&r.common) r.Models = (*ServerModelsApi)(&r.common) r.Secrets = (*ServerSecretsApi)(&r.common) @@ -10053,6 +10432,25 @@ func (a *PermissionsApi) Configure(ctx context.Context, params *PermissionsConfi return &result, nil } +// GetAllowAll returns whether full allow-all permissions are currently active for the +// session. +// +// RPC method: session.permissions.getAllowAll. +// +// Returns: Current full allow-all permission state. +func (a *PermissionsApi) GetAllowAll(ctx context.Context) (*AllowAllPermissionState, error) { + req := map[string]any{"sessionId": a.sessionID} + raw, err := a.client.Request("session.permissions.getAllowAll", req) + if err != nil { + return nil, err + } + var result AllowAllPermissionState + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + // HandlePendingPermissionRequest provides a decision for a pending tool permission request. // // RPC method: session.permissions.handlePendingPermissionRequest. @@ -10174,6 +10572,35 @@ func (a *PermissionsApi) ResetSessionApprovals(ctx context.Context) (*Permission return &result, nil } +// SetAllowAll enables or disables full allow-all permissions (tools, paths, and URLs) for +// the session. Used by attach-mode clients (e.g. LocalRpcSession's `/allow-all` forwarder) +// to flip the target session's permission state. Unlike `setApproveAll`, this swaps in the +// unrestricted path and URL managers and emits `session.permissions_changed` on transition. +// The result returns the authoritative post-mutation state so callers can update their +// local mirrors without racing the `session.permissions_changed` notification on the same +// wire. +// +// RPC method: session.permissions.setAllowAll. +// +// Parameters: Whether to enable full allow-all permissions for the session. +// +// Returns: Indicates whether the operation succeeded and reports the post-mutation state. +func (a *PermissionsApi) SetAllowAll(ctx context.Context, params *PermissionsSetAllowAllRequest) (*AllowAllPermissionSetResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["enabled"] = params.Enabled + } + raw, err := a.client.Request("session.permissions.setAllowAll", req) + if err != nil { + return nil, err + } + var result AllowAllPermissionSetResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + // SetApproveAll enables or disables automatic approval of tool permission requests for the // session. // diff --git a/go/rpc/zrpc_encoding.go b/go/rpc/zrpc_encoding.go index 9224f65cf..a9c758989 100644 --- a/go/rpc/zrpc_encoding.go +++ b/go/rpc/zrpc_encoding.go @@ -8,6 +8,103 @@ import ( "errors" ) +func unmarshalAgentRegistrySpawnResult(data []byte) (AgentRegistrySpawnResult, error) { + if string(data) == "null" { + return nil, nil + } + type rawUnion struct { + Kind AgentRegistrySpawnResultKind `json:"kind"` + } + var raw rawUnion + if err := json.Unmarshal(data, &raw); err != nil { + return nil, err + } + + switch raw.Kind { + case AgentRegistrySpawnResultKindRegistryTimeout: + var d AgentRegistrySpawnRegistryTimeout + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AgentRegistrySpawnResultKindSpawnError: + var d AgentRegistrySpawnError + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AgentRegistrySpawnResultKindSpawned: + var d AgentRegistrySpawnSpawned + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AgentRegistrySpawnResultKindValidationError: + var d AgentRegistrySpawnValidationError + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + default: + return &RawAgentRegistrySpawnResultData{Discriminator: raw.Kind, Raw: data}, nil + } +} + +func (r RawAgentRegistrySpawnResultData) MarshalJSON() ([]byte, error) { + if r.Raw != nil { + return r.Raw, nil + } + return json.Marshal(struct { + Kind AgentRegistrySpawnResultKind `json:"kind"` + }{ + Kind: r.Discriminator, + }) +} + +func (r AgentRegistrySpawnError) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnError + return json.Marshal(struct { + Kind AgentRegistrySpawnResultKind `json:"kind"` + alias + }{ + Kind: r.Kind(), + alias: alias(r), + }) +} + +func (r AgentRegistrySpawnRegistryTimeout) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnRegistryTimeout + return json.Marshal(struct { + Kind AgentRegistrySpawnResultKind `json:"kind"` + alias + }{ + Kind: r.Kind(), + alias: alias(r), + }) +} + +func (r AgentRegistrySpawnSpawned) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnSpawned + return json.Marshal(struct { + Kind AgentRegistrySpawnResultKind `json:"kind"` + alias + }{ + Kind: r.Kind(), + alias: alias(r), + }) +} + +func (r AgentRegistrySpawnValidationError) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnValidationError + return json.Marshal(struct { + Kind AgentRegistrySpawnResultKind `json:"kind"` + alias + }{ + Kind: r.Kind(), + alias: alias(r), + }) +} + func unmarshalAuthInfo(data []byte) (AuthInfo, error) { if string(data) == "null" { return nil, nil diff --git a/go/rpc/zsession_encoding.go b/go/rpc/zsession_encoding.go index cc344851b..f06e3b398 100644 --- a/go/rpc/zsession_encoding.go +++ b/go/rpc/zsession_encoding.go @@ -185,6 +185,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeHookProgress: + var d HookProgressData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeHookStart: var d HookStartData if err := json.Unmarshal(raw.Data, &d); err != nil { @@ -245,6 +251,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeSessionAutopilotObjectiveChanged: + var d SessionAutopilotObjectiveChangedData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeSessionBackgroundTasksChanged: var d SessionBackgroundTasksChangedData if err := json.Unmarshal(raw.Data, &d); err != nil { @@ -347,6 +359,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeSessionPermissionsChanged: + var d SessionPermissionsChangedData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeSessionPlanChanged: var d SessionPlanChangedData if err := json.Unmarshal(raw.Data, &d); err != nil { diff --git a/go/rpc/zsession_events.go b/go/rpc/zsession_events.go index d56371750..1f5561424 100644 --- a/go/rpc/zsession_events.go +++ b/go/rpc/zsession_events.go @@ -53,90 +53,93 @@ func (r RawSessionEventData) Type() SessionEventType { type SessionEventType string const ( - SessionEventTypeAbort SessionEventType = "abort" - SessionEventTypeAssistantIntent SessionEventType = "assistant.intent" - SessionEventTypeAssistantMessage SessionEventType = "assistant.message" - SessionEventTypeAssistantMessageDelta SessionEventType = "assistant.message_delta" - SessionEventTypeAssistantMessageStart SessionEventType = "assistant.message_start" - SessionEventTypeAssistantReasoning SessionEventType = "assistant.reasoning" - SessionEventTypeAssistantReasoningDelta SessionEventType = "assistant.reasoning_delta" - SessionEventTypeAssistantStreamingDelta SessionEventType = "assistant.streaming_delta" - SessionEventTypeAssistantTurnEnd SessionEventType = "assistant.turn_end" - SessionEventTypeAssistantTurnStart SessionEventType = "assistant.turn_start" - SessionEventTypeAssistantUsage SessionEventType = "assistant.usage" - SessionEventTypeAutoModeSwitchCompleted SessionEventType = "auto_mode_switch.completed" - SessionEventTypeAutoModeSwitchRequested SessionEventType = "auto_mode_switch.requested" - SessionEventTypeCapabilitiesChanged SessionEventType = "capabilities.changed" - SessionEventTypeCommandCompleted SessionEventType = "command.completed" - SessionEventTypeCommandExecute SessionEventType = "command.execute" - SessionEventTypeCommandQueued SessionEventType = "command.queued" - SessionEventTypeCommandsChanged SessionEventType = "commands.changed" - SessionEventTypeElicitationCompleted SessionEventType = "elicitation.completed" - SessionEventTypeElicitationRequested SessionEventType = "elicitation.requested" - SessionEventTypeExitPlanModeCompleted SessionEventType = "exit_plan_mode.completed" - SessionEventTypeExitPlanModeRequested SessionEventType = "exit_plan_mode.requested" - SessionEventTypeExternalToolCompleted SessionEventType = "external_tool.completed" - SessionEventTypeExternalToolRequested SessionEventType = "external_tool.requested" - SessionEventTypeHookEnd SessionEventType = "hook.end" - SessionEventTypeHookStart SessionEventType = "hook.start" - SessionEventTypeMcpAppToolCallComplete SessionEventType = "mcp_app.tool_call_complete" - SessionEventTypeMcpOauthCompleted SessionEventType = "mcp.oauth_completed" - SessionEventTypeMcpOauthRequired SessionEventType = "mcp.oauth_required" - SessionEventTypeModelCallFailure SessionEventType = "model.call_failure" - SessionEventTypePendingMessagesModified SessionEventType = "pending_messages.modified" - SessionEventTypePermissionCompleted SessionEventType = "permission.completed" - SessionEventTypePermissionRequested SessionEventType = "permission.requested" - SessionEventTypeSamplingCompleted SessionEventType = "sampling.completed" - SessionEventTypeSamplingRequested SessionEventType = "sampling.requested" - SessionEventTypeSessionBackgroundTasksChanged SessionEventType = "session.background_tasks_changed" - SessionEventTypeSessionCanvasOpened SessionEventType = "session.canvas.opened" - SessionEventTypeSessionCanvasRegistryChanged SessionEventType = "session.canvas.registry_changed" - SessionEventTypeSessionCompactionComplete SessionEventType = "session.compaction_complete" - SessionEventTypeSessionCompactionStart SessionEventType = "session.compaction_start" - SessionEventTypeSessionContextChanged SessionEventType = "session.context_changed" - SessionEventTypeSessionCustomAgentsUpdated SessionEventType = "session.custom_agents_updated" - SessionEventTypeSessionCustomNotification SessionEventType = "session.custom_notification" - SessionEventTypeSessionError SessionEventType = "session.error" - SessionEventTypeSessionExtensionsLoaded SessionEventType = "session.extensions_loaded" - SessionEventTypeSessionHandoff SessionEventType = "session.handoff" - SessionEventTypeSessionIdle SessionEventType = "session.idle" - SessionEventTypeSessionInfo SessionEventType = "session.info" - SessionEventTypeSessionMcpServersLoaded SessionEventType = "session.mcp_servers_loaded" - SessionEventTypeSessionMcpServerStatusChanged SessionEventType = "session.mcp_server_status_changed" - SessionEventTypeSessionModeChanged SessionEventType = "session.mode_changed" - SessionEventTypeSessionModelChange SessionEventType = "session.model_change" - SessionEventTypeSessionPlanChanged SessionEventType = "session.plan_changed" - SessionEventTypeSessionRemoteSteerableChanged SessionEventType = "session.remote_steerable_changed" - SessionEventTypeSessionResume SessionEventType = "session.resume" - SessionEventTypeSessionScheduleCancelled SessionEventType = "session.schedule_cancelled" - SessionEventTypeSessionScheduleCreated SessionEventType = "session.schedule_created" - SessionEventTypeSessionShutdown SessionEventType = "session.shutdown" - SessionEventTypeSessionSkillsLoaded SessionEventType = "session.skills_loaded" - SessionEventTypeSessionSnapshotRewind SessionEventType = "session.snapshot_rewind" - SessionEventTypeSessionStart SessionEventType = "session.start" - SessionEventTypeSessionTaskComplete SessionEventType = "session.task_complete" - SessionEventTypeSessionTitleChanged SessionEventType = "session.title_changed" - SessionEventTypeSessionToolsUpdated SessionEventType = "session.tools_updated" - SessionEventTypeSessionTruncation SessionEventType = "session.truncation" - SessionEventTypeSessionUsageInfo SessionEventType = "session.usage_info" - SessionEventTypeSessionWarning SessionEventType = "session.warning" - SessionEventTypeSessionWorkspaceFileChanged SessionEventType = "session.workspace_file_changed" - SessionEventTypeSkillInvoked SessionEventType = "skill.invoked" - SessionEventTypeSubagentCompleted SessionEventType = "subagent.completed" - SessionEventTypeSubagentDeselected SessionEventType = "subagent.deselected" - SessionEventTypeSubagentFailed SessionEventType = "subagent.failed" - SessionEventTypeSubagentSelected SessionEventType = "subagent.selected" - SessionEventTypeSubagentStarted SessionEventType = "subagent.started" - SessionEventTypeSystemMessage SessionEventType = "system.message" - SessionEventTypeSystemNotification SessionEventType = "system.notification" - SessionEventTypeToolExecutionComplete SessionEventType = "tool.execution_complete" - SessionEventTypeToolExecutionPartialResult SessionEventType = "tool.execution_partial_result" - SessionEventTypeToolExecutionProgress SessionEventType = "tool.execution_progress" - SessionEventTypeToolExecutionStart SessionEventType = "tool.execution_start" - SessionEventTypeToolUserRequested SessionEventType = "tool.user_requested" - SessionEventTypeUserInputCompleted SessionEventType = "user_input.completed" - SessionEventTypeUserInputRequested SessionEventType = "user_input.requested" - SessionEventTypeUserMessage SessionEventType = "user.message" + SessionEventTypeAbort SessionEventType = "abort" + SessionEventTypeAssistantIntent SessionEventType = "assistant.intent" + SessionEventTypeAssistantMessage SessionEventType = "assistant.message" + SessionEventTypeAssistantMessageDelta SessionEventType = "assistant.message_delta" + SessionEventTypeAssistantMessageStart SessionEventType = "assistant.message_start" + SessionEventTypeAssistantReasoning SessionEventType = "assistant.reasoning" + SessionEventTypeAssistantReasoningDelta SessionEventType = "assistant.reasoning_delta" + SessionEventTypeAssistantStreamingDelta SessionEventType = "assistant.streaming_delta" + SessionEventTypeAssistantTurnEnd SessionEventType = "assistant.turn_end" + SessionEventTypeAssistantTurnStart SessionEventType = "assistant.turn_start" + SessionEventTypeAssistantUsage SessionEventType = "assistant.usage" + SessionEventTypeAutoModeSwitchCompleted SessionEventType = "auto_mode_switch.completed" + SessionEventTypeAutoModeSwitchRequested SessionEventType = "auto_mode_switch.requested" + SessionEventTypeCapabilitiesChanged SessionEventType = "capabilities.changed" + SessionEventTypeCommandCompleted SessionEventType = "command.completed" + SessionEventTypeCommandExecute SessionEventType = "command.execute" + SessionEventTypeCommandQueued SessionEventType = "command.queued" + SessionEventTypeCommandsChanged SessionEventType = "commands.changed" + SessionEventTypeElicitationCompleted SessionEventType = "elicitation.completed" + SessionEventTypeElicitationRequested SessionEventType = "elicitation.requested" + SessionEventTypeExitPlanModeCompleted SessionEventType = "exit_plan_mode.completed" + SessionEventTypeExitPlanModeRequested SessionEventType = "exit_plan_mode.requested" + SessionEventTypeExternalToolCompleted SessionEventType = "external_tool.completed" + SessionEventTypeExternalToolRequested SessionEventType = "external_tool.requested" + SessionEventTypeHookEnd SessionEventType = "hook.end" + SessionEventTypeHookProgress SessionEventType = "hook.progress" + SessionEventTypeHookStart SessionEventType = "hook.start" + SessionEventTypeMcpAppToolCallComplete SessionEventType = "mcp_app.tool_call_complete" + SessionEventTypeMcpOauthCompleted SessionEventType = "mcp.oauth_completed" + SessionEventTypeMcpOauthRequired SessionEventType = "mcp.oauth_required" + SessionEventTypeModelCallFailure SessionEventType = "model.call_failure" + SessionEventTypePendingMessagesModified SessionEventType = "pending_messages.modified" + SessionEventTypePermissionCompleted SessionEventType = "permission.completed" + SessionEventTypePermissionRequested SessionEventType = "permission.requested" + SessionEventTypeSamplingCompleted SessionEventType = "sampling.completed" + SessionEventTypeSamplingRequested SessionEventType = "sampling.requested" + SessionEventTypeSessionAutopilotObjectiveChanged SessionEventType = "session.autopilot_objective_changed" + SessionEventTypeSessionBackgroundTasksChanged SessionEventType = "session.background_tasks_changed" + SessionEventTypeSessionCanvasOpened SessionEventType = "session.canvas.opened" + SessionEventTypeSessionCanvasRegistryChanged SessionEventType = "session.canvas.registry_changed" + SessionEventTypeSessionCompactionComplete SessionEventType = "session.compaction_complete" + SessionEventTypeSessionCompactionStart SessionEventType = "session.compaction_start" + SessionEventTypeSessionContextChanged SessionEventType = "session.context_changed" + SessionEventTypeSessionCustomAgentsUpdated SessionEventType = "session.custom_agents_updated" + SessionEventTypeSessionCustomNotification SessionEventType = "session.custom_notification" + SessionEventTypeSessionError SessionEventType = "session.error" + SessionEventTypeSessionExtensionsLoaded SessionEventType = "session.extensions_loaded" + SessionEventTypeSessionHandoff SessionEventType = "session.handoff" + SessionEventTypeSessionIdle SessionEventType = "session.idle" + SessionEventTypeSessionInfo SessionEventType = "session.info" + SessionEventTypeSessionMcpServersLoaded SessionEventType = "session.mcp_servers_loaded" + SessionEventTypeSessionMcpServerStatusChanged SessionEventType = "session.mcp_server_status_changed" + SessionEventTypeSessionModeChanged SessionEventType = "session.mode_changed" + SessionEventTypeSessionModelChange SessionEventType = "session.model_change" + SessionEventTypeSessionPermissionsChanged SessionEventType = "session.permissions_changed" + SessionEventTypeSessionPlanChanged SessionEventType = "session.plan_changed" + SessionEventTypeSessionRemoteSteerableChanged SessionEventType = "session.remote_steerable_changed" + SessionEventTypeSessionResume SessionEventType = "session.resume" + SessionEventTypeSessionScheduleCancelled SessionEventType = "session.schedule_cancelled" + SessionEventTypeSessionScheduleCreated SessionEventType = "session.schedule_created" + SessionEventTypeSessionShutdown SessionEventType = "session.shutdown" + SessionEventTypeSessionSkillsLoaded SessionEventType = "session.skills_loaded" + SessionEventTypeSessionSnapshotRewind SessionEventType = "session.snapshot_rewind" + SessionEventTypeSessionStart SessionEventType = "session.start" + SessionEventTypeSessionTaskComplete SessionEventType = "session.task_complete" + SessionEventTypeSessionTitleChanged SessionEventType = "session.title_changed" + SessionEventTypeSessionToolsUpdated SessionEventType = "session.tools_updated" + SessionEventTypeSessionTruncation SessionEventType = "session.truncation" + SessionEventTypeSessionUsageInfo SessionEventType = "session.usage_info" + SessionEventTypeSessionWarning SessionEventType = "session.warning" + SessionEventTypeSessionWorkspaceFileChanged SessionEventType = "session.workspace_file_changed" + SessionEventTypeSkillInvoked SessionEventType = "skill.invoked" + SessionEventTypeSubagentCompleted SessionEventType = "subagent.completed" + SessionEventTypeSubagentDeselected SessionEventType = "subagent.deselected" + SessionEventTypeSubagentFailed SessionEventType = "subagent.failed" + SessionEventTypeSubagentSelected SessionEventType = "subagent.selected" + SessionEventTypeSubagentStarted SessionEventType = "subagent.started" + SessionEventTypeSystemMessage SessionEventType = "system.message" + SessionEventTypeSystemNotification SessionEventType = "system.notification" + SessionEventTypeToolExecutionComplete SessionEventType = "tool.execution_complete" + SessionEventTypeToolExecutionPartialResult SessionEventType = "tool.execution_partial_result" + SessionEventTypeToolExecutionProgress SessionEventType = "tool.execution_progress" + SessionEventTypeToolExecutionStart SessionEventType = "tool.execution_start" + SessionEventTypeToolUserRequested SessionEventType = "tool.user_requested" + SessionEventTypeUserInputCompleted SessionEventType = "user_input.completed" + SessionEventTypeUserInputRequested SessionEventType = "user_input.requested" + SessionEventTypeUserMessage SessionEventType = "user.message" ) // Agent intent description for current activity or plan @@ -240,6 +243,21 @@ func (*AutoModeSwitchRequestedData) Type() SessionEventType { return SessionEventTypeAutoModeSwitchRequested } +// Autopilot objective state file operation details indicating what changed +type SessionAutopilotObjectiveChangedData struct { + // Current autopilot objective id, if one exists + ID *int64 `json:"id,omitempty"` + // The type of operation performed on the autopilot objective state file + Operation AutopilotObjectiveChangedOperation `json:"operation"` + // Current autopilot objective status, if one exists + Status *AutopilotObjectiveChangedStatus `json:"status,omitempty"` +} + +func (*SessionAutopilotObjectiveChangedData) sessionEventData() {} +func (*SessionAutopilotObjectiveChangedData) Type() SessionEventType { + return SessionEventTypeSessionAutopilotObjectiveChanged +} + // Context window breakdown at the start of LLM-powered conversation compaction type SessionCompactionStartData struct { // Token count from non-system messages (user, assistant, tool) at compaction start @@ -405,6 +423,15 @@ func (*PendingMessagesModifiedData) Type() SessionEventType { return SessionEventTypePendingMessagesModified } +// Ephemeral progress update from a running hook process +type HookProgressData struct { + // Human-readable progress message from the hook process + Message string `json:"message"` +} + +func (*HookProgressData) sessionEventData() {} +func (*HookProgressData) Type() SessionEventType { return SessionEventTypeHookProgress } + // Error details for timeline display including message and optional diagnostic information type SessionErrorData struct { // Only set on `errorType: "rate_limit"`. When `true`, the runtime will follow this error with an `auto_mode_switch.requested` event (or silently switch if `continueOnAutoMode` is enabled). UI clients can use this flag to suppress duplicate rendering of the rate-limit error when they show their own auto-mode-switch prompt. @@ -722,6 +749,19 @@ type PermissionRequestedData struct { func (*PermissionRequestedData) sessionEventData() {} func (*PermissionRequestedData) Type() SessionEventType { return SessionEventTypePermissionRequested } +// Permissions change details carrying the aggregate allow-all boolean transition. +type SessionPermissionsChangedData struct { + // Aggregate allow-all flag after the change + AllowAllPermissions bool `json:"allowAllPermissions"` + // Aggregate allow-all flag before the change + PreviousAllowAllPermissions bool `json:"previousAllowAllPermissions"` +} + +func (*SessionPermissionsChangedData) sessionEventData() {} +func (*SessionPermissionsChangedData) Type() SessionEventType { + return SessionEventTypeSessionPermissionsChanged +} + // Plan approval request with plan content and available user actions type ExitPlanModeRequestedData struct { // Available actions the user can take @@ -1396,6 +1436,8 @@ func (*ToolExecutionProgressData) Type() SessionEventType { type ToolExecutionStartData struct { // Arguments passed to the tool Arguments any `json:"arguments,omitempty"` + // When true, the tool output should be displayed expanded (verbatim) in the CLI timeline + DisplayVerbatim *bool `json:"displayVerbatim,omitempty"` // Name of the MCP server hosting this tool, when the tool is an MCP tool McpServerName *string `json:"mcpServerName,omitempty"` // Original tool name on the MCP server, when the tool is an MCP tool @@ -2983,6 +3025,32 @@ const ( AutoModeSwitchResponseYesAlways AutoModeSwitchResponse = "yes_always" ) +// The type of operation performed on the autopilot objective state file +type AutopilotObjectiveChangedOperation string + +const ( + // Autopilot objective state file was created for a new objective. + AutopilotObjectiveChangedOperationCreate AutopilotObjectiveChangedOperation = "create" + // Autopilot objective state file was deleted or cleared. + AutopilotObjectiveChangedOperationDelete AutopilotObjectiveChangedOperation = "delete" + // Autopilot objective state file was updated for an existing objective. + AutopilotObjectiveChangedOperationUpdate AutopilotObjectiveChangedOperation = "update" +) + +// Current autopilot objective status, if one exists +type AutopilotObjectiveChangedStatus string + +const ( + // Objective is active and can drive autopilot continuations. + AutopilotObjectiveChangedStatusActive AutopilotObjectiveChangedStatus = "active" + // Legacy objective state indicating the previous continuation cap was reached. + AutopilotObjectiveChangedStatusCapReached AutopilotObjectiveChangedStatus = "cap_reached" + // Objective was completed by the agent. + AutopilotObjectiveChangedStatusCompleted AutopilotObjectiveChangedStatus = "completed" + // Objective is paused and will not drive autopilot continuations. + AutopilotObjectiveChangedStatusPaused AutopilotObjectiveChangedStatus = "paused" +) + // Runtime-controlled routing state for the instance. "ready" when the provider connection is live; "stale" when the provider has gone away and the instance is awaiting rebinding. type CanvasOpenedAvailability string diff --git a/go/zsession_events.go b/go/zsession_events.go index 7f99e6eac..9a62d6265 100644 --- a/go/zsession_events.go +++ b/go/zsession_events.go @@ -28,6 +28,8 @@ type ( AutoModeSwitchCompletedData = rpc.AutoModeSwitchCompletedData AutoModeSwitchRequestedData = rpc.AutoModeSwitchRequestedData AutoModeSwitchResponse = rpc.AutoModeSwitchResponse + AutopilotObjectiveChangedOperation = rpc.AutopilotObjectiveChangedOperation + AutopilotObjectiveChangedStatus = rpc.AutopilotObjectiveChangedStatus CanvasOpenedAvailability = rpc.CanvasOpenedAvailability CanvasRegistryChangedCanvas = rpc.CanvasRegistryChangedCanvas CanvasRegistryChangedCanvasAction = rpc.CanvasRegistryChangedCanvasAction @@ -67,6 +69,7 @@ type ( HandoffSourceType = rpc.HandoffSourceType HookEndData = rpc.HookEndData HookEndError = rpc.HookEndError + HookProgressData = rpc.HookProgressData HookStartData = rpc.HookStartData McpAppToolCallCompleteData = rpc.McpAppToolCallCompleteData McpAppToolCallCompleteError = rpc.McpAppToolCallCompleteError @@ -140,6 +143,7 @@ type ( ReasoningSummary = rpc.ReasoningSummary SamplingCompletedData = rpc.SamplingCompletedData SamplingRequestedData = rpc.SamplingRequestedData + SessionAutopilotObjectiveChangedData = rpc.SessionAutopilotObjectiveChangedData SessionBackgroundTasksChangedData = rpc.SessionBackgroundTasksChangedData SessionCanvasOpenedData = rpc.SessionCanvasOpenedData SessionCanvasRegistryChangedData = rpc.SessionCanvasRegistryChangedData @@ -162,6 +166,7 @@ type ( SessionModeChangedData = rpc.SessionModeChangedData SessionModelChangeData = rpc.SessionModelChangeData SessionModelChangeDataContextTier = rpc.SessionModelChangeDataContextTier + SessionPermissionsChangedData = rpc.SessionPermissionsChangedData SessionPlanChangedData = rpc.SessionPlanChangedData SessionRemoteSteerableChangedData = rpc.SessionRemoteSteerableChangedData SessionResumeData = rpc.SessionResumeData @@ -287,6 +292,13 @@ const ( AutoModeSwitchResponseNo = rpc.AutoModeSwitchResponseNo AutoModeSwitchResponseYes = rpc.AutoModeSwitchResponseYes AutoModeSwitchResponseYesAlways = rpc.AutoModeSwitchResponseYesAlways + AutopilotObjectiveChangedOperationCreate = rpc.AutopilotObjectiveChangedOperationCreate + AutopilotObjectiveChangedOperationDelete = rpc.AutopilotObjectiveChangedOperationDelete + AutopilotObjectiveChangedOperationUpdate = rpc.AutopilotObjectiveChangedOperationUpdate + AutopilotObjectiveChangedStatusActive = rpc.AutopilotObjectiveChangedStatusActive + AutopilotObjectiveChangedStatusCapReached = rpc.AutopilotObjectiveChangedStatusCapReached + AutopilotObjectiveChangedStatusCompleted = rpc.AutopilotObjectiveChangedStatusCompleted + AutopilotObjectiveChangedStatusPaused = rpc.AutopilotObjectiveChangedStatusPaused CanvasOpenedAvailabilityReady = rpc.CanvasOpenedAvailabilityReady CanvasOpenedAvailabilityStale = rpc.CanvasOpenedAvailabilityStale ElicitationCompletedActionAccept = rpc.ElicitationCompletedActionAccept @@ -393,6 +405,7 @@ const ( SessionEventTypeExternalToolCompleted = rpc.SessionEventTypeExternalToolCompleted SessionEventTypeExternalToolRequested = rpc.SessionEventTypeExternalToolRequested SessionEventTypeHookEnd = rpc.SessionEventTypeHookEnd + SessionEventTypeHookProgress = rpc.SessionEventTypeHookProgress SessionEventTypeHookStart = rpc.SessionEventTypeHookStart SessionEventTypeMcpAppToolCallComplete = rpc.SessionEventTypeMcpAppToolCallComplete SessionEventTypeMcpOauthCompleted = rpc.SessionEventTypeMcpOauthCompleted @@ -403,6 +416,7 @@ const ( SessionEventTypePermissionRequested = rpc.SessionEventTypePermissionRequested SessionEventTypeSamplingCompleted = rpc.SessionEventTypeSamplingCompleted SessionEventTypeSamplingRequested = rpc.SessionEventTypeSamplingRequested + SessionEventTypeSessionAutopilotObjectiveChanged = rpc.SessionEventTypeSessionAutopilotObjectiveChanged SessionEventTypeSessionBackgroundTasksChanged = rpc.SessionEventTypeSessionBackgroundTasksChanged SessionEventTypeSessionCanvasOpened = rpc.SessionEventTypeSessionCanvasOpened SessionEventTypeSessionCanvasRegistryChanged = rpc.SessionEventTypeSessionCanvasRegistryChanged @@ -420,6 +434,7 @@ const ( SessionEventTypeSessionMcpServerStatusChanged = rpc.SessionEventTypeSessionMcpServerStatusChanged SessionEventTypeSessionModeChanged = rpc.SessionEventTypeSessionModeChanged SessionEventTypeSessionModelChange = rpc.SessionEventTypeSessionModelChange + SessionEventTypeSessionPermissionsChanged = rpc.SessionEventTypeSessionPermissionsChanged SessionEventTypeSessionPlanChanged = rpc.SessionEventTypeSessionPlanChanged SessionEventTypeSessionRemoteSteerableChanged = rpc.SessionEventTypeSessionRemoteSteerableChanged SessionEventTypeSessionResume = rpc.SessionEventTypeSessionResume diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json index 9b81710db..792dc4cdf 100644 --- a/nodejs/package-lock.json +++ b/nodejs/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.8", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.55-1", + "@github/copilot": "^1.0.55-3", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -663,9 +663,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.55-1.tgz", - "integrity": "sha512-P8uFRbbKWyImqPWaHub8dCt2R4f/GWjY/4xyf3uyHs5wZfSPLzh9DvagAA2ryQjuGHsgCZeDscUkJoYW+yn2UA==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.55-3.tgz", + "integrity": "sha512-rtaUFobDVbS6oTvGvQLZBeb6nbsp5lZEaL3bcsuENv7Wv87lL4C6GnAsaGWsm/b/bF3eSqFCOTk9rKsDcyLFmQ==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "detect-libc": "^2.1.2" @@ -674,20 +674,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.55-1", - "@github/copilot-darwin-x64": "1.0.55-1", - "@github/copilot-linux-arm64": "1.0.55-1", - "@github/copilot-linux-x64": "1.0.55-1", - "@github/copilot-linuxmusl-arm64": "1.0.55-1", - "@github/copilot-linuxmusl-x64": "1.0.55-1", - "@github/copilot-win32-arm64": "1.0.55-1", - "@github/copilot-win32-x64": "1.0.55-1" + "@github/copilot-darwin-arm64": "1.0.55-3", + "@github/copilot-darwin-x64": "1.0.55-3", + "@github/copilot-linux-arm64": "1.0.55-3", + "@github/copilot-linux-x64": "1.0.55-3", + "@github/copilot-linuxmusl-arm64": "1.0.55-3", + "@github/copilot-linuxmusl-x64": "1.0.55-3", + "@github/copilot-win32-arm64": "1.0.55-3", + "@github/copilot-win32-x64": "1.0.55-3" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.55-1.tgz", - "integrity": "sha512-0z5P/FZZ7OIJbcs+WWIwkCcY7+sRGxmL80GTvT6x0QiJdJLqLlvwcX/Pfhomp4NxwEYBAK3I51F8I8A3GacjuQ==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.55-3.tgz", + "integrity": "sha512-L1qsdnLtStLc5/1BrKA4m7eumlZbcuwtNc9Q7epafLWfB6nYwXoKmtWdyByhNfyC7Hm9TERvjwKjmxI4fZS2TA==", "cpu": [ "arm64" ], @@ -701,9 +701,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.55-1.tgz", - "integrity": "sha512-334+JCBb0iqg7omB2szc+/Ii2xkq81HKaer+mTaXj+1kHUGtfZacmzejwvutl6CxKTuZ8E9BcozP65KEYLBbwQ==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.55-3.tgz", + "integrity": "sha512-iQLYiKEohJU46IWifwCjBxUp/h1tnnfOeibEM6axB9Rd5noRz5Ka0M+YWJYzh6bhQ/mpuWFXVRINZIHk2muTyQ==", "cpu": [ "x64" ], @@ -717,12 +717,15 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.55-1.tgz", - "integrity": "sha512-UTZuNCWzEaeqjhEyz+BUPNECPy5b6KKnym60q9x9dZw1ufqQSxKdhu02p62x53PA1fd4l6N8FRdhoHOOhKfEkQ==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.55-3.tgz", + "integrity": "sha512-SGRhLxAW7uSzU6TUmGV/ge+b57zq9UAj9oSrVqbjB3kdssCkh5PuzkAN1aX2InVuF+k/Eu0eoeX0FmLtGuQODw==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -733,12 +736,15 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.55-1.tgz", - "integrity": "sha512-IwKgCrSXy7zeQlGgf8tZue8eaM/TcxVxXvpijXUTY0F9KXldzO0xv3WAgh5540ALH+jwkLI85UuPq5aoVCBuCA==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.55-3.tgz", + "integrity": "sha512-ri3r1gk4/FHNQVS7icYIGz+e89pVaa/yiMKee+svkmIedG1c5Ae94gFN7+7zNcnnLmiD/US+WH1QHwCRrp/gbQ==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -749,12 +755,15 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.55-1.tgz", - "integrity": "sha512-3Uu9JOYU9zmr5dcYBQZHwXF1JpzVPZXpBau0khLd6OFZkA6al1D2miNmw4nO/WoT0IfheW6EhYUBN1WuthmXTw==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.55-3.tgz", + "integrity": "sha512-A0bCRkNMEONw2HIcIx+dirI1VLR8onBU7Z9VSZz1uMaNixfWKuYXzc5Rw4G/AVI+cNLntR3HJtvXrdvLlFYn0A==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -765,12 +774,15 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.55-1.tgz", - "integrity": "sha512-0szVr6ejslqi6O+Rbmx5ETRTEMFpGv9A9qiK3E0XuzE4uXSPyPad/wOSSE2yat7YEqUVU8J/HIUKU9TpBpiWbA==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.55-3.tgz", + "integrity": "sha512-i3mji5ZZfiRM1k54qCS49/zGUirxkWVckRFNdZUoVs9Mwb4UQIf75VRjk3MtL5OuKZSsUc27CiKOAgmYIQ5dsg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -781,9 +793,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.55-1.tgz", - "integrity": "sha512-h0LXoTv7cT8J/RVuocWbwd5+VYbxJk5/s7EsMXn+FR6m8ZqYZdBjYMAyDe9v/HcCyAPY0xLYRKt6k3Jb17Upag==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.55-3.tgz", + "integrity": "sha512-uw88Yrfz/2aueonvN+HXHGMK1oeYB4vN0d1/NVMvSJJXr0dMuunjq8aOkIdyoGYfxIUYEZqj97YS7SmgcW5UIg==", "cpu": [ "arm64" ], @@ -797,9 +809,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.55-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.55-1.tgz", - "integrity": "sha512-lxaRdPd5NZaC5YyMOTt2uTV34fQyuClg71JAYoKVZ1w7Dc6E+f7+WMM3L67ZieornfgG80h4QMNtfpVpCVgpAQ==", + "version": "1.0.55-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.55-3.tgz", + "integrity": "sha512-w3vDZr3SbrA8lnV0bdElKsigGEqy/Fzr0p6FNvjlN814VLb67wNcDast5sLC4rpwfcjV/VrI4jTaNruePvbrbQ==", "cpu": [ "x64" ], diff --git a/nodejs/package.json b/nodejs/package.json index f89463195..3905c08d5 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -56,7 +56,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.55-1", + "@github/copilot": "^1.0.55-3", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index df5117f7c..8abc2e280 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -27,6 +27,140 @@ export type AgentInfoSource = | "plugin" /** Agent built into the Copilot runtime. */ | "builtin"; +/** + * Process kind tag for the registry entry + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistryLiveTargetEntryKind". + */ +/** @experimental */ +export type AgentRegistryLiveTargetEntryKind = + /** Interactive Copilot CLI exposing a UI server (legacy/normal CLI process) */ + | "ui-server" + /** Headless `--server --managed-server` child spawned by a controller */ + | "managed-server"; +/** + * Coarse lifecycle status of the foreground session + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistryLiveTargetEntryStatus". + */ +/** @experimental */ +export type AgentRegistryLiveTargetEntryStatus = + /** Session is actively processing a turn */ + | "working" + /** Session is idle, waiting for input */ + | "waiting" + /** Last turn completed successfully */ + | "done" + /** Session needs user attention (see attentionKind for the specific reason) */ + | "attention"; +/** + * Kind of attention required when status === "attention". Meaningful only when status === "attention". + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistryLiveTargetEntryAttentionKind". + */ +/** @experimental */ +export type AgentRegistryLiveTargetEntryAttentionKind = + /** Session is blocked on an unrecoverable error */ + | "error" + /** Session is waiting for a tool-permission decision */ + | "permission" + /** Session is waiting for the user to approve or reject a plan */ + | "exit_plan" + /** Session is waiting on an elicitation prompt */ + | "elicitation" + /** Session is waiting for free-form user input */ + | "user_input"; +/** + * How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done from done_cancelled. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistryLiveTargetEntryLastTerminalEvent". + */ +/** @experimental */ +export type AgentRegistryLiveTargetEntryLastTerminalEvent = + /** Last turn ended cleanly (model returned a final assistant message) */ + | "turn_end" + /** Last turn was aborted (e.g. user interrupted) */ + | "abort"; +/** + * Categorized reason for log-open failure + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistryLogCaptureOpenErrorReason". + */ +/** @experimental */ +export type AgentRegistryLogCaptureOpenErrorReason = + /** Filesystem permission denied opening the log file */ + | "permission" + /** No space left on device */ + | "disk_full" + /** Other / uncategorized open failure */ + | "other"; +/** + * Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnPermissionMode". + */ +/** @experimental */ +export type AgentRegistrySpawnPermissionMode = + /** Standard permission posture (prompts for each request) */ + | "default" + /** Full allow-all (requires the controller-local session to currently be in allow-all mode) */ + | "yolo"; +/** + * Outcome of an agentRegistry.spawn call. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnResult". + */ +/** @experimental */ +export type AgentRegistrySpawnResult = + | AgentRegistrySpawnSpawned + | AgentRegistrySpawnError + | AgentRegistrySpawnRegistryTimeout + | AgentRegistrySpawnValidationError; +/** + * Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by reason without leaking raw paths or agent/model names. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnValidationErrorReason". + */ +/** @experimental */ +export type AgentRegistrySpawnValidationErrorReason = + /** Provided cwd does not exist on disk */ + | "cwd-not-found" + /** Provided cwd exists but is not a directory */ + | "cwd-not-directory" + /** Session name failed validateSessionName */ + | "invalid-name" + /** Requested agent name was not found in builtin or custom agents */ + | "unknown-agent" + /** Requested model is not available to this session */ + | "unknown-model" + /** Caller asked for permissionMode='yolo' but the controller is not currently in allow-all mode */ + | "yolo-not-allowed"; +/** + * Which parameter field was invalid. Omitted when the rejection is not field-specific. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnValidationErrorField". + */ +/** @experimental */ +export type AgentRegistrySpawnValidationErrorField = + /** The cwd parameter */ + | "cwd" + /** The session name parameter */ + | "name" + /** The agentName parameter */ + | "agentName" + /** The model parameter */ + | "model" + /** The permissionMode parameter */ + | "permissionMode"; /** * The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime stores the value verbatim and uses it for outbound model/API requests; it does NOT re-validate or re-fetch the associated Copilot user response. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. * @@ -1394,6 +1528,210 @@ export interface AgentList { */ agents: AgentInfo[]; } +/** + * Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistryLiveTargetEntry". + */ +/** @experimental */ +export interface AgentRegistryLiveTargetEntry { + /** + * Registry entry schema version (1 = ui-server, 2 = managed-server) + */ + schemaVersion: number; + kind: AgentRegistryLiveTargetEntryKind; + /** + * Operating-system pid of the process owning this entry + */ + pid: number; + /** + * Bind host for the entry's JSON-RPC server + */ + host: string; + /** + * TCP port the entry's JSON-RPC server is listening on + */ + port: number; + /** + * Connection token (null when the target is unauthenticated) + * + * @internal + */ + token?: string | null; + /** + * Session ID of the foreground session for this entry + */ + sessionId?: string; + /** + * Friendly session name (when set) + */ + sessionName?: string; + /** + * Working directory of the session (when known) + */ + cwd?: string; + /** + * Git branch of the session (when known) + */ + branch?: string; + /** + * Model identifier currently selected for the session + */ + model?: string; + status?: AgentRegistryLiveTargetEntryStatus; + attentionKind?: AgentRegistryLiveTargetEntryAttentionKind; + /** + * Monotonic per-publisher revision counter incremented on every status update. Lets watchers detect transient flips. + */ + statusRevision?: number; + lastTerminalEvent?: AgentRegistryLiveTargetEntryLastTerminalEvent; + /** + * ISO 8601 timestamp captured at registration + */ + startedAt: string; + /** + * Copilot CLI version that wrote the entry + */ + copilotVersion: string; + /** + * Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness) + */ + lastSeenMs: number; +} +/** + * Per-spawn log-capture outcome; populated from spawnLiveTarget. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistryLogCapture". + */ +/** @experimental */ +export interface AgentRegistryLogCapture { + /** + * Whether per-spawn log capture is on (false when env-disabled or open failed) + */ + enabled: boolean; + /** + * Absolute path to the per-spawn log file (only set when enabled) + */ + path?: string; + /** + * Human-readable open failure message (only set when enabled === false AND the env-disable opt-out was NOT used) + */ + openError?: string; + openErrorReason?: AgentRegistryLogCaptureOpenErrorReason; +} +/** + * `child_process.spawn` itself failed before the child entered the registry. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnError". + */ +/** @experimental */ +export interface AgentRegistrySpawnError { + /** + * Discriminator: child_process.spawn itself failed + */ + kind: "spawn-error"; + /** + * Human-readable error message + */ + message: string; + /** + * Underlying errno code (e.g. ENOENT, EACCES) when available + */ + code?: string; +} +/** + * Spawn succeeded but the child did not publish a matching managed-server entry within the timeout. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnRegistryTimeout". + */ +/** @experimental */ +export interface AgentRegistrySpawnRegistryTimeout { + /** + * Discriminator: spawn succeeded but child never registered + */ + kind: "registry-timeout"; + /** + * Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance) + */ + childPid: number; + logCapture?: AgentRegistryLogCapture; +} +/** + * Inputs to spawn a managed-server child via the controller's spawn delegate. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnRequest". + */ +/** @experimental */ +export interface AgentRegistrySpawnRequest { + /** + * Working directory for the spawned child (must be an existing directory) + */ + cwd: string; + /** + * Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. + */ + agentName?: string; + /** + * Model identifier to apply to the new session + */ + model?: string; + /** + * Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. + */ + name?: string; + permissionMode?: AgentRegistrySpawnPermissionMode; + /** + * Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). + */ + initialPrompt?: string; +} +/** + * Managed-server child was spawned and registered successfully. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnSpawned". + */ +/** @experimental */ +export interface AgentRegistrySpawnSpawned { + /** + * Discriminator: managed-server child spawned successfully + */ + kind: "spawned"; + entry: AgentRegistryLiveTargetEntry; + /** + * Whether the delegate already sent the initial prompt. Always omitted in the current wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send path. + */ + initialPromptSent?: boolean; + /** + * If the delegate attempted to send the initial prompt and failed, the categorized error message. + */ + initialPromptError?: string; + logCapture?: AgentRegistryLogCapture; +} +/** + * Synchronous pre-validation rejected the spawn request. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentRegistrySpawnValidationError". + */ +/** @experimental */ +export interface AgentRegistrySpawnValidationError { + /** + * Discriminator: synchronous pre-validation rejected the request + */ + kind: "validation-error"; + reason: AgentRegistrySpawnValidationErrorReason; + field?: AgentRegistrySpawnValidationErrorField; + /** + * Human-readable explanation; safe to surface in the UI banner. Never logged to unrestricted telemetry. + */ + message: string; +} /** * Custom agents available to the session after reloading definitions from disk. * @@ -1430,6 +1768,36 @@ export interface AgentSelectRequest { export interface AgentSelectResult { agent: AgentInfo; } +/** + * Indicates whether the operation succeeded and reports the post-mutation state. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AllowAllPermissionSetResult". + */ +/** @experimental */ +export interface AllowAllPermissionSetResult { + /** + * Whether the operation succeeded + */ + success: boolean; + /** + * Authoritative allow-all state after the mutation + */ + enabled: boolean; +} +/** + * Current full allow-all permission state. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AllowAllPermissionState". + */ +/** @experimental */ +export interface AllowAllPermissionState { + /** + * Whether full allow-all permissions are currently active + */ + enabled: boolean; +} /** * Schema for the `ApiKeyAuthInfo` type. * @@ -5649,6 +6017,13 @@ export interface PermissionsFolderTrustAddTrustedResult { */ success: boolean; } +/** + * No parameters. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PermissionsGetAllowAllRequest". + */ +export interface PermissionsGetAllowAllRequest {} /** * Indicates whether the operation succeeded. * @@ -5770,6 +6145,19 @@ export interface PermissionsResetSessionApprovalsResult { */ success: boolean; } +/** + * Whether to enable full allow-all permissions for the session. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PermissionsSetAllowAllRequest". + */ +/** @experimental */ +export interface PermissionsSetAllowAllRequest { + /** + * Whether to enable full allow-all permissions + */ + enabled: boolean; +} /** * Allow-all toggle for tool permission requests, with an optional telemetry source. * @@ -6616,6 +7004,10 @@ export interface SessionMetadata { * True for remote (GitHub) sessions; false for local */ isRemote: boolean; + /** + * True for detached maintenance sessions that should be hidden from normal resume lists. + */ + isDetached?: boolean; context?: SessionContext; /** * GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. @@ -7548,7 +7940,7 @@ export interface SessionSizes { }; } /** - * Optional metadata-load limit and context filter applied to the returned sessions. + * Optional metadata-load limit and filters applied to the returned sessions. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema * via the `definition` "SessionsListRequest". @@ -7560,6 +7952,10 @@ export interface SessionsListRequest { */ metadataLimit?: number; filter?: SessionListFilter; + /** + * When true, include detached maintenance sessions. Defaults to false for user-facing session lists. + */ + includeDetached?: boolean; } /** * Active session ID whose deferred repo-level hooks should be loaded. @@ -9850,7 +10246,7 @@ export function createServerRpc(connection: MessageConnection) { /** * Lists persisted sessions, optionally filtered by working-directory context. * - * @param params Optional metadata-load limit and context filter applied to the returned sessions. + * @param params Optional metadata-load limit and filters applied to the returned sessions. * * @returns Persisted sessions matching the filter, ordered most-recently-modified first. */ @@ -9999,6 +10395,18 @@ export function createServerRpc(connection: MessageConnection) { setAdditionalPlugins: async (params: SessionsSetAdditionalPluginsRequest): Promise => connection.sendRequest("sessions.setAdditionalPlugins", params), }, + /** @experimental */ + agentRegistry: { + /** + * Spawns a managed-server child with the supplied configuration and returns a discriminated-union result. The caller (typically the CLI controller) is responsible for attaching to the spawned child and sending any follow-up prompt. When the controller-local spawn gate is closed the server returns JSON-RPC MethodNotFound. + * + * @param params Inputs to spawn a managed-server child via the controller's spawn delegate. + * + * @returns Outcome of an agentRegistry.spawn call. + */ + spawn: async (params: AgentRegistrySpawnRequest): Promise => + connection.sendRequest("agentRegistry.spawn", params), + }, }; } @@ -10862,6 +11270,22 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin */ setApproveAll: async (params: PermissionsSetApproveAllRequest): Promise => connection.sendRequest("session.permissions.setApproveAll", { sessionId, ...params }), + /** + * Enables or disables full allow-all permissions (tools, paths, and URLs) for the session. Used by attach-mode clients (e.g. LocalRpcSession's `/allow-all` forwarder) to flip the target session's permission state. Unlike `setApproveAll`, this swaps in the unrestricted path and URL managers and emits `session.permissions_changed` on transition. The result returns the authoritative post-mutation state so callers can update their local mirrors without racing the `session.permissions_changed` notification on the same wire. + * + * @param params Whether to enable full allow-all permissions for the session. + * + * @returns Indicates whether the operation succeeded and reports the post-mutation state. + */ + setAllowAll: async (params: PermissionsSetAllowAllRequest): Promise => + connection.sendRequest("session.permissions.setAllowAll", { sessionId, ...params }), + /** + * Returns whether full allow-all permissions are currently active for the session. + * + * @returns Current full allow-all permission state. + */ + getAllowAll: async (): Promise => + connection.sendRequest("session.permissions.getAllowAll", { sessionId }), /** * Adds or removes session-scoped or location-scoped permission rules. * diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts index 506ed6ae2..9a89f0746 100644 --- a/nodejs/src/generated/session-events.ts +++ b/nodejs/src/generated/session-events.ts @@ -15,10 +15,12 @@ export type SessionEvent = | TitleChangedEvent | ScheduleCreatedEvent | ScheduleCancelledEvent + | AutopilotObjectiveChangedEvent | InfoEvent | WarningEvent | ModelChangeEvent | ModeChangedEvent + | PermissionsChangedEvent | PlanChangedEvent | WorkspaceFileChangedEvent | HandoffEvent @@ -57,6 +59,7 @@ export type SessionEvent = | SubagentDeselectedEvent | HookStartEvent | HookEndEvent + | HookProgressEvent | SystemMessageEvent | SystemNotificationEvent | PermissionRequestedEvent @@ -109,6 +112,28 @@ export type ReasoningSummary = | "concise" /** Request a detailed summary of the model's reasoning. */ | "detailed"; +/** + * The type of operation performed on the autopilot objective state file + */ +export type AutopilotObjectiveChangedOperation = + /** Autopilot objective state file was created for a new objective. */ + | "create" + /** Autopilot objective state file was updated for an existing objective. */ + | "update" + /** Autopilot objective state file was deleted or cleared. */ + | "delete"; +/** + * Current autopilot objective status, if one exists + */ +export type AutopilotObjectiveChangedStatus = + /** Objective is active and can drive autopilot continuations. */ + | "active" + /** Objective is paused and will not drive autopilot continuations. */ + | "paused" + /** Legacy objective state indicating the previous continuation cap was reached. */ + | "cap_reached" + /** Objective was completed by the agent. */ + | "completed"; /** * The session mode the agent is operating in */ @@ -975,6 +1000,47 @@ export interface ScheduleCancelledData { */ id: number; } +/** + * Session event "session.autopilot_objective_changed". Autopilot objective state file operation details indicating what changed + */ +export interface AutopilotObjectiveChangedEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: AutopilotObjectiveChangedData; + /** + * When true, the event is transient and not persisted to the session event log on disk + */ + ephemeral?: boolean; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "session.autopilot_objective_changed". + */ + type: "session.autopilot_objective_changed"; +} +/** + * Autopilot objective state file operation details indicating what changed + */ +export interface AutopilotObjectiveChangedData { + /** + * Current autopilot objective id, if one exists + */ + id?: number; + operation: AutopilotObjectiveChangedOperation; + status?: AutopilotObjectiveChangedStatus; +} /** * Session event "session.info". Informational message for timeline display with categorization */ @@ -1175,6 +1241,49 @@ export interface ModeChangedData { newMode: SessionMode; previousMode: SessionMode; } +/** + * Session event "session.permissions_changed". Permissions change details carrying the aggregate allow-all boolean transition. + */ +export interface PermissionsChangedEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: PermissionsChangedData; + /** + * When true, the event is transient and not persisted to the session event log on disk + */ + ephemeral?: boolean; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "session.permissions_changed". + */ + type: "session.permissions_changed"; +} +/** + * Permissions change details carrying the aggregate allow-all boolean transition. + */ +export interface PermissionsChangedData { + /** + * Aggregate allow-all flag after the change + */ + allowAllPermissions: boolean; + /** + * Aggregate allow-all flag before the change + */ + previousAllowAllPermissions: boolean; +} /** * Session event "session.plan_changed". Plan file operation details indicating what changed */ @@ -3109,6 +3218,10 @@ export interface ToolExecutionStartData { arguments?: { [k: string]: unknown | undefined; }; + /** + * When true, the tool output should be displayed expanded (verbatim) in the CLI timeline + */ + displayVerbatim?: boolean; /** * Name of the MCP server hosting this tool, when the tool is an MCP tool */ @@ -4058,6 +4171,45 @@ export interface HookEndError { */ stack?: string; } +/** + * Session event "hook.progress". Ephemeral progress update from a running hook process + */ +export interface HookProgressEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: HookProgressData; + /** + * Always true for events that are transient and not persisted to the session event log on disk. + */ + ephemeral: true; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "hook.progress". + */ + type: "hook.progress"; +} +/** + * Ephemeral progress update from a running hook process + */ +export interface HookProgressData { + /** + * Human-readable progress message from the hook process + */ + message: string; +} /** * Session event "system.message". System/developer instruction content with role and optional template metadata */ diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index 4c7db8d77..68aa64209 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -204,6 +204,97 @@ class AgentInfoSource(Enum): REMOTE = "remote" USER = "user" +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistryLiveTargetEntryAttentionKind(Enum): + """Kind of attention required when status === "attention". Meaningful only when status === + "attention". + """ + ELICITATION = "elicitation" + ERROR = "error" + EXIT_PLAN = "exit_plan" + PERMISSION = "permission" + USER_INPUT = "user_input" + +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistryLiveTargetEntryKind(Enum): + """Process kind tag for the registry entry""" + + MANAGED_SERVER = "managed-server" + UI_SERVER = "ui-server" + +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistryLiveTargetEntryLastTerminalEvent(Enum): + """How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done + from done_cancelled. + """ + ABORT = "abort" + TURN_END = "turn_end" + +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistryLiveTargetEntryStatus(Enum): + """Coarse lifecycle status of the foreground session""" + + ATTENTION = "attention" + DONE = "done" + WAITING = "waiting" + WORKING = "working" + +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistryLogCaptureOpenErrorReason(Enum): + """Categorized reason for log-open failure""" + + DISK_FULL = "disk_full" + OTHER = "other" + PERMISSION = "permission" + +class AgentRegistrySpawnErrorKind(Enum): + SPAWN_ERROR = "spawn-error" + +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistrySpawnPermissionMode(Enum): + """Permission posture for the new session. 'yolo' requires the controller-local session to + currently be in allow-all mode. + """ + DEFAULT = "default" + YOLO = "yolo" + +class AgentRegistrySpawnRegistryTimeoutKind(Enum): + REGISTRY_TIMEOUT = "registry-timeout" + +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistrySpawnValidationErrorField(Enum): + """Which parameter field was invalid. Omitted when the rejection is not field-specific.""" + + AGENT_NAME = "agentName" + CWD = "cwd" + MODEL = "model" + NAME = "name" + PERMISSION_MODE = "permissionMode" + +class AgentRegistrySpawnResultKind(Enum): + REGISTRY_TIMEOUT = "registry-timeout" + SPAWNED = "spawned" + SPAWN_ERROR = "spawn-error" + VALIDATION_ERROR = "validation-error" + +# Experimental: this type is part of an experimental API and may change or be removed. +class AgentRegistrySpawnValidationErrorReason(Enum): + """Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by + reason without leaking raw paths or agent/model names. + """ + CWD_NOT_DIRECTORY = "cwd-not-directory" + CWD_NOT_FOUND = "cwd-not-found" + INVALID_NAME = "invalid-name" + UNKNOWN_AGENT = "unknown-agent" + UNKNOWN_MODEL = "unknown-model" + YOLO_NOT_ALLOWED = "yolo-not-allowed" + +class AgentRegistrySpawnSpawnedKind(Enum): + SPAWNED = "spawned" + +class AgentRegistrySpawnValidationErrorKind(Enum): + VALIDATION_ERROR = "validation-error" + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class AgentSelectRequest: @@ -223,6 +314,49 @@ def to_dict(self) -> dict: result["name"] = from_str(self.name) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AllowAllPermissionSetResult: + """Indicates whether the operation succeeded and reports the post-mutation state.""" + + enabled: bool + """Authoritative allow-all state after the mutation""" + + success: bool + """Whether the operation succeeded""" + + @staticmethod + def from_dict(obj: Any) -> 'AllowAllPermissionSetResult': + assert isinstance(obj, dict) + enabled = from_bool(obj.get("enabled")) + success = from_bool(obj.get("success")) + return AllowAllPermissionSetResult(enabled, success) + + def to_dict(self) -> dict: + result: dict = {} + result["enabled"] = from_bool(self.enabled) + result["success"] = from_bool(self.success) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AllowAllPermissionState: + """Current full allow-all permission state.""" + + enabled: bool + """Whether full allow-all permissions are currently active""" + + @staticmethod + def from_dict(obj: Any) -> 'AllowAllPermissionState': + assert isinstance(obj, dict) + enabled = from_bool(obj.get("enabled")) + return AllowAllPermissionState(enabled) + + def to_dict(self) -> dict: + result: dict = {} + result["enabled"] = from_bool(self.enabled) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CopilotUserResponseEndpoints: @@ -3239,6 +3373,19 @@ def to_dict(self) -> dict: result["success"] = from_bool(self.success) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PermissionsGetAllowAllRequest: + """No parameters.""" + @staticmethod + def from_dict(obj: Any) -> 'PermissionsGetAllowAllRequest': + assert isinstance(obj, dict) + return PermissionsGetAllowAllRequest() + + def to_dict(self) -> dict: + result: dict = {} + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class PermissionsLocationsAddToolApprovalResult: @@ -3400,6 +3547,25 @@ def to_dict(self) -> dict: result["success"] = from_bool(self.success) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PermissionsSetAllowAllRequest: + """Whether to enable full allow-all permissions for the session.""" + + enabled: bool + """Whether to enable full allow-all permissions""" + + @staticmethod + def from_dict(obj: Any) -> 'PermissionsSetAllowAllRequest': + assert isinstance(obj, dict) + enabled = from_bool(obj.get("enabled")) + return PermissionsSetAllowAllRequest(enabled) + + def to_dict(self) -> dict: + result: dict = {} + result["enabled"] = from_bool(self.enabled) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class PermissionsSetApproveAllResult: @@ -6754,6 +6920,109 @@ def to_dict(self) -> dict: result["quotaSnapshots"] = from_dict(lambda x: to_class(AccountQuotaSnapshot, x), self.quota_snapshots) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentRegistryLogCapture: + """Per-spawn log-capture outcome; populated from spawnLiveTarget.""" + + enabled: bool + """Whether per-spawn log capture is on (false when env-disabled or open failed)""" + + open_error: str | None = None + """Human-readable open failure message (only set when enabled === false AND the env-disable + opt-out was NOT used) + """ + open_error_reason: AgentRegistryLogCaptureOpenErrorReason | None = None + """Categorized reason for log-open failure""" + + path: str | None = None + """Absolute path to the per-spawn log file (only set when enabled)""" + + @staticmethod + def from_dict(obj: Any) -> 'AgentRegistryLogCapture': + assert isinstance(obj, dict) + enabled = from_bool(obj.get("enabled")) + open_error = from_union([from_str, from_none], obj.get("openError")) + open_error_reason = from_union([AgentRegistryLogCaptureOpenErrorReason, from_none], obj.get("openErrorReason")) + path = from_union([from_str, from_none], obj.get("path")) + return AgentRegistryLogCapture(enabled, open_error, open_error_reason, path) + + def to_dict(self) -> dict: + result: dict = {} + result["enabled"] = from_bool(self.enabled) + if self.open_error is not None: + result["openError"] = from_union([from_str, from_none], self.open_error) + if self.open_error_reason is not None: + result["openErrorReason"] = from_union([lambda x: to_enum(AgentRegistryLogCaptureOpenErrorReason, x), from_none], self.open_error_reason) + if self.path is not None: + result["path"] = from_union([from_str, from_none], self.path) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentRegistrySpawnError: + """`child_process.spawn` itself failed before the child entered the registry.""" + + kind: ClassVar[str] = "spawn-error" + """Discriminator: child_process.spawn itself failed""" + + message: str + """Human-readable error message""" + + code: str | None = None + """Underlying errno code (e.g. ENOENT, EACCES) when available""" + + @staticmethod + def from_dict(obj: Any) -> 'AgentRegistrySpawnError': + assert isinstance(obj, dict) + message = from_str(obj.get("message")) + code = from_union([from_str, from_none], obj.get("code")) + return AgentRegistrySpawnError(message, code) + + def to_dict(self) -> dict: + result: dict = {} + result["kind"] = self.kind + result["message"] = from_str(self.message) + if self.code is not None: + result["code"] = from_union([from_str, from_none], self.code) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentRegistrySpawnValidationError: + """Synchronous pre-validation rejected the spawn request.""" + + kind: ClassVar[str] = "validation-error" + """Discriminator: synchronous pre-validation rejected the request""" + + message: str + """Human-readable explanation; safe to surface in the UI banner. Never logged to + unrestricted telemetry. + """ + reason: AgentRegistrySpawnValidationErrorReason + """Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by + reason without leaking raw paths or agent/model names. + """ + field: AgentRegistrySpawnValidationErrorField | None = None + """Which parameter field was invalid. Omitted when the rejection is not field-specific.""" + + @staticmethod + def from_dict(obj: Any) -> 'AgentRegistrySpawnValidationError': + assert isinstance(obj, dict) + message = from_str(obj.get("message")) + reason = AgentRegistrySpawnValidationErrorReason(obj.get("reason")) + field = from_union([AgentRegistrySpawnValidationErrorField, from_none], obj.get("field")) + return AgentRegistrySpawnValidationError(message, reason, field) + + def to_dict(self) -> dict: + result: dict = {} + result["kind"] = self.kind + result["message"] = from_str(self.message) + result["reason"] = to_enum(AgentRegistrySpawnValidationErrorReason, self.reason) + if self.field is not None: + result["field"] = from_union([lambda x: to_enum(AgentRegistrySpawnValidationErrorField, x), from_none], self.field) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class SessionAuthStatus: @@ -10385,11 +10654,15 @@ def to_dict(self) -> dict: # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class SessionsListRequest: - """Optional metadata-load limit and context filter applied to the returned sessions.""" + """Optional metadata-load limit and filters applied to the returned sessions.""" filter: SessionListFilter | None = None """Optional filter applied to the returned sessions""" + include_detached: bool | None = None + """When true, include detached maintenance sessions. Defaults to false for user-facing + session lists. + """ metadata_limit: int | None = None """When provided, only the first N sessions (sorted by modification time, newest first) load full metadata; remaining sessions return basic info only. Use 0 to return only basic info @@ -10400,13 +10673,16 @@ class SessionsListRequest: def from_dict(obj: Any) -> 'SessionsListRequest': assert isinstance(obj, dict) filter = from_union([SessionListFilter.from_dict, from_none], obj.get("filter")) + include_detached = from_union([from_bool, from_none], obj.get("includeDetached")) metadata_limit = from_union([from_int, from_none], obj.get("metadataLimit")) - return SessionsListRequest(filter, metadata_limit) + return SessionsListRequest(filter, include_detached, metadata_limit) def to_dict(self) -> dict: result: dict = {} if self.filter is not None: result["filter"] = from_union([lambda x: to_class(SessionListFilter, x), from_none], self.filter) + if self.include_detached is not None: + result["includeDetached"] = from_union([from_bool, from_none], self.include_detached) if self.metadata_limit is not None: result["metadataLimit"] = from_union([from_int, from_none], self.metadata_limit) return result @@ -11445,6 +11721,36 @@ def to_dict(self) -> dict: result["saved"] = from_union([lambda x: to_class(Saved, x), from_none], self.saved) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentRegistrySpawnRegistryTimeout: + """Spawn succeeded but the child did not publish a matching managed-server entry within the + timeout. + """ + child_pid: int + """Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance)""" + + kind: ClassVar[str] = "registry-timeout" + """Discriminator: spawn succeeded but child never registered""" + + log_capture: AgentRegistryLogCapture | None = None + """Per-spawn log-capture outcome; populated from spawnLiveTarget.""" + + @staticmethod + def from_dict(obj: Any) -> 'AgentRegistrySpawnRegistryTimeout': + assert isinstance(obj, dict) + child_pid = from_int(obj.get("childPid")) + log_capture = from_union([AgentRegistryLogCapture.from_dict, from_none], obj.get("logCapture")) + return AgentRegistrySpawnRegistryTimeout(child_pid, log_capture) + + def to_dict(self) -> dict: + result: dict = {} + result["childPid"] = from_int(self.child_pid) + result["kind"] = self.kind + if self.log_capture is not None: + result["logCapture"] = from_union([lambda x: to_class(AgentRegistryLogCapture, x), from_none], self.log_capture) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CanvasList: @@ -12168,6 +12474,9 @@ class SessionMetadata: context: SessionContext | None = None """Schema for the `SessionContext` type.""" + is_detached: bool | None = None + """True for detached maintenance sessions that should be hidden from normal resume lists.""" + mc_task_id: str | None = None """GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. @@ -12187,10 +12496,11 @@ def from_dict(obj: Any) -> 'SessionMetadata': start_time = from_str(obj.get("startTime")) client_name = from_union([from_str, from_none], obj.get("clientName")) context = from_union([SessionContext.from_dict, from_none], obj.get("context")) + is_detached = from_union([from_bool, from_none], obj.get("isDetached")) mc_task_id = from_union([from_str, from_none], obj.get("mcTaskId")) name = from_union([from_str, from_none], obj.get("name")) summary = from_union([from_str, from_none], obj.get("summary")) - return SessionMetadata(is_remote, modified_time, session_id, start_time, client_name, context, mc_task_id, name, summary) + return SessionMetadata(is_remote, modified_time, session_id, start_time, client_name, context, is_detached, mc_task_id, name, summary) def to_dict(self) -> dict: result: dict = {} @@ -12202,6 +12512,8 @@ def to_dict(self) -> dict: result["clientName"] = from_union([from_str, from_none], self.client_name) if self.context is not None: result["context"] = from_union([lambda x: to_class(SessionContext, x), from_none], self.context) + if self.is_detached is not None: + result["isDetached"] = from_union([from_bool, from_none], self.is_detached) if self.mc_task_id is not None: result["mcTaskId"] = from_union([from_str, from_none], self.mc_task_id) if self.name is not None: @@ -14462,6 +14774,226 @@ def to_dict(self) -> dict: result["requestedSchema"] = to_class(UIElicitationSchema, self.requested_schema) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentRegistryLiveTargetEntry: + """Full registry entry for the spawned child. Lets the controller call + `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a + TOCTOU window). + """ + copilot_version: str + """Copilot CLI version that wrote the entry""" + + host: str + """Bind host for the entry's JSON-RPC server""" + + kind: AgentRegistryLiveTargetEntryKind + """Process kind tag for the registry entry""" + + last_seen_ms: int + """Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness)""" + + pid: int + """Operating-system pid of the process owning this entry""" + + port: int + """TCP port the entry's JSON-RPC server is listening on""" + + schema_version: int + """Registry entry schema version (1 = ui-server, 2 = managed-server)""" + + started_at: str + """ISO 8601 timestamp captured at registration""" + + attention_kind: AgentRegistryLiveTargetEntryAttentionKind | None = None + """Kind of attention required when status === "attention". Meaningful only when status === + "attention". + """ + branch: str | None = None + """Git branch of the session (when known)""" + + cwd: str | None = None + """Working directory of the session (when known)""" + + last_terminal_event: AgentRegistryLiveTargetEntryLastTerminalEvent | None = None + """How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done + from done_cancelled. + """ + model: str | None = None + """Model identifier currently selected for the session""" + + session_id: str | None = None + """Session ID of the foreground session for this entry""" + + session_name: str | None = None + """Friendly session name (when set)""" + + status: AgentRegistryLiveTargetEntryStatus | None = None + """Coarse lifecycle status of the foreground session""" + + status_revision: int | None = None + """Monotonic per-publisher revision counter incremented on every status update. Lets + watchers detect transient flips. + """ + # Internal: this field is an internal SDK API and is not part of the public surface. + token: str | None = None + """Connection token (null when the target is unauthenticated)""" + + @staticmethod + def from_dict(obj: Any) -> 'AgentRegistryLiveTargetEntry': + assert isinstance(obj, dict) + copilot_version = from_str(obj.get("copilotVersion")) + host = from_str(obj.get("host")) + kind = AgentRegistryLiveTargetEntryKind(obj.get("kind")) + last_seen_ms = from_int(obj.get("lastSeenMs")) + pid = from_int(obj.get("pid")) + port = from_int(obj.get("port")) + schema_version = from_int(obj.get("schemaVersion")) + started_at = from_str(obj.get("startedAt")) + attention_kind = from_union([AgentRegistryLiveTargetEntryAttentionKind, from_none], obj.get("attentionKind")) + branch = from_union([from_str, from_none], obj.get("branch")) + cwd = from_union([from_str, from_none], obj.get("cwd")) + last_terminal_event = from_union([AgentRegistryLiveTargetEntryLastTerminalEvent, from_none], obj.get("lastTerminalEvent")) + model = from_union([from_str, from_none], obj.get("model")) + session_id = from_union([from_str, from_none], obj.get("sessionId")) + session_name = from_union([from_str, from_none], obj.get("sessionName")) + status = from_union([AgentRegistryLiveTargetEntryStatus, from_none], obj.get("status")) + status_revision = from_union([from_int, from_none], obj.get("statusRevision")) + token = from_union([from_none, from_str], obj.get("token")) + return AgentRegistryLiveTargetEntry(copilot_version, host, kind, last_seen_ms, pid, port, schema_version, started_at, attention_kind, branch, cwd, last_terminal_event, model, session_id, session_name, status, status_revision, token) + + def to_dict(self) -> dict: + result: dict = {} + result["copilotVersion"] = from_str(self.copilot_version) + result["host"] = from_str(self.host) + result["kind"] = to_enum(AgentRegistryLiveTargetEntryKind, self.kind) + result["lastSeenMs"] = from_int(self.last_seen_ms) + result["pid"] = from_int(self.pid) + result["port"] = from_int(self.port) + result["schemaVersion"] = from_int(self.schema_version) + result["startedAt"] = from_str(self.started_at) + if self.attention_kind is not None: + result["attentionKind"] = from_union([lambda x: to_enum(AgentRegistryLiveTargetEntryAttentionKind, x), from_none], self.attention_kind) + if self.branch is not None: + result["branch"] = from_union([from_str, from_none], self.branch) + if self.cwd is not None: + result["cwd"] = from_union([from_str, from_none], self.cwd) + if self.last_terminal_event is not None: + result["lastTerminalEvent"] = from_union([lambda x: to_enum(AgentRegistryLiveTargetEntryLastTerminalEvent, x), from_none], self.last_terminal_event) + if self.model is not None: + result["model"] = from_union([from_str, from_none], self.model) + if self.session_id is not None: + result["sessionId"] = from_union([from_str, from_none], self.session_id) + if self.session_name is not None: + result["sessionName"] = from_union([from_str, from_none], self.session_name) + if self.status is not None: + result["status"] = from_union([lambda x: to_enum(AgentRegistryLiveTargetEntryStatus, x), from_none], self.status) + if self.status_revision is not None: + result["statusRevision"] = from_union([from_int, from_none], self.status_revision) + if self.token is not None: + result["token"] = from_union([from_none, from_str], self.token) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentRegistrySpawnRequest: + """Inputs to spawn a managed-server child via the controller's spawn delegate.""" + + cwd: str + """Working directory for the spawned child (must be an existing directory)""" + + agent_name: str | None = None + """Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own + default. + """ + initial_prompt: str | None = None + """Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it + post-attach via the standard LocalRpcSession.send path). + """ + model: str | None = None + """Model identifier to apply to the new session""" + + name: str | None = None + """Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing + whitespace, <=100 chars, no control chars, no double quotes. + """ + permission_mode: AgentRegistrySpawnPermissionMode | None = None + """Permission posture for the new session. 'yolo' requires the controller-local session to + currently be in allow-all mode. + """ + + @staticmethod + def from_dict(obj: Any) -> 'AgentRegistrySpawnRequest': + assert isinstance(obj, dict) + cwd = from_str(obj.get("cwd")) + agent_name = from_union([from_str, from_none], obj.get("agentName")) + initial_prompt = from_union([from_str, from_none], obj.get("initialPrompt")) + model = from_union([from_str, from_none], obj.get("model")) + name = from_union([from_str, from_none], obj.get("name")) + permission_mode = from_union([AgentRegistrySpawnPermissionMode, from_none], obj.get("permissionMode")) + return AgentRegistrySpawnRequest(cwd, agent_name, initial_prompt, model, name, permission_mode) + + def to_dict(self) -> dict: + result: dict = {} + result["cwd"] = from_str(self.cwd) + if self.agent_name is not None: + result["agentName"] = from_union([from_str, from_none], self.agent_name) + if self.initial_prompt is not None: + result["initialPrompt"] = from_union([from_str, from_none], self.initial_prompt) + if self.model is not None: + result["model"] = from_union([from_str, from_none], self.model) + if self.name is not None: + result["name"] = from_union([from_str, from_none], self.name) + if self.permission_mode is not None: + result["permissionMode"] = from_union([lambda x: to_enum(AgentRegistrySpawnPermissionMode, x), from_none], self.permission_mode) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentRegistrySpawnSpawned: + """Managed-server child was spawned and registered successfully.""" + + entry: AgentRegistryLiveTargetEntry + """Full registry entry for the spawned child. Lets the controller call + `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a + TOCTOU window). + """ + kind: ClassVar[str] = "spawned" + """Discriminator: managed-server child spawned successfully""" + + initial_prompt_error: str | None = None + """If the delegate attempted to send the initial prompt and failed, the categorized error + message. + """ + initial_prompt_sent: bool | None = None + """Whether the delegate already sent the initial prompt. Always omitted in the current + wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send + path. + """ + log_capture: AgentRegistryLogCapture | None = None + """Per-spawn log-capture outcome; populated from spawnLiveTarget.""" + + @staticmethod + def from_dict(obj: Any) -> 'AgentRegistrySpawnSpawned': + assert isinstance(obj, dict) + entry = AgentRegistryLiveTargetEntry.from_dict(obj.get("entry")) + initial_prompt_error = from_union([from_str, from_none], obj.get("initialPromptError")) + initial_prompt_sent = from_union([from_bool, from_none], obj.get("initialPromptSent")) + log_capture = from_union([AgentRegistryLogCapture.from_dict, from_none], obj.get("logCapture")) + return AgentRegistrySpawnSpawned(entry, initial_prompt_error, initial_prompt_sent, log_capture) + + def to_dict(self) -> dict: + result: dict = {} + result["entry"] = to_class(AgentRegistryLiveTargetEntry, self.entry) + result["kind"] = self.kind + if self.initial_prompt_error is not None: + result["initialPromptError"] = from_union([from_str, from_none], self.initial_prompt_error) + if self.initial_prompt_sent is not None: + result["initialPromptSent"] = from_union([from_bool, from_none], self.initial_prompt_sent) + if self.log_capture is not None: + result["logCapture"] = from_union([lambda x: to_class(AgentRegistryLogCapture, x), from_none], self.log_capture) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class MCPExecuteSamplingParams: @@ -14867,9 +15399,27 @@ class RPC: agent_info: AgentInfo agent_info_source: AgentInfoSource agent_list: AgentList + agent_registry_live_target_entry: AgentRegistryLiveTargetEntry + agent_registry_live_target_entry_attention_kind: AgentRegistryLiveTargetEntryAttentionKind + agent_registry_live_target_entry_kind: AgentRegistryLiveTargetEntryKind + agent_registry_live_target_entry_last_terminal_event: AgentRegistryLiveTargetEntryLastTerminalEvent + agent_registry_live_target_entry_status: AgentRegistryLiveTargetEntryStatus + agent_registry_log_capture: AgentRegistryLogCapture + agent_registry_log_capture_open_error_reason: AgentRegistryLogCaptureOpenErrorReason + agent_registry_spawn_error: AgentRegistrySpawnError + agent_registry_spawn_permission_mode: AgentRegistrySpawnPermissionMode + agent_registry_spawn_registry_timeout: AgentRegistrySpawnRegistryTimeout + agent_registry_spawn_request: AgentRegistrySpawnRequest + agent_registry_spawn_result: AgentRegistrySpawnResult + agent_registry_spawn_spawned: AgentRegistrySpawnSpawned + agent_registry_spawn_validation_error: AgentRegistrySpawnValidationError + agent_registry_spawn_validation_error_field: AgentRegistrySpawnValidationErrorField + agent_registry_spawn_validation_error_reason: AgentRegistrySpawnValidationErrorReason agent_reload_result: AgentReloadResult agent_select_request: AgentSelectRequest agent_select_result: AgentSelectResult + allow_all_permission_set_result: AllowAllPermissionSetResult + allow_all_permission_state: AllowAllPermissionState api_key_auth_info: APIKeyAuthInfo auth_info: AuthInfo auth_info_type: AuthInfoType @@ -15136,6 +15686,7 @@ class RPC: permissions_configure_params: PermissionsConfigureParams permissions_configure_result: PermissionsConfigureResult permissions_folder_trust_add_trusted_result: PermissionsFolderTrustAddTrustedResult + permissions_get_allow_all_request: PermissionsGetAllowAllRequest permissions_locations_add_tool_approval_details: PermissionsLocationsAddToolApprovalDetails permissions_locations_add_tool_approval_details_commands: PermissionsLocationsAddToolApprovalDetailsCommands permissions_locations_add_tool_approval_details_custom_tool: PermissionsLocationsAddToolApprovalDetailsCustomTool @@ -15157,6 +15708,7 @@ class RPC: permissions_pending_requests_request: PermissionsPendingRequestsRequest permissions_reset_session_approvals_request: PermissionsResetSessionApprovalsRequest permissions_reset_session_approvals_result: PermissionsResetSessionApprovalsResult + permissions_set_allow_all_request: PermissionsSetAllowAllRequest permissions_set_approve_all_request: PermissionsSetApproveAllRequest permissions_set_approve_all_result: PermissionsSetApproveAllResult permissions_set_approve_all_source: PermissionsSetApproveAllSource @@ -15427,9 +15979,27 @@ def from_dict(obj: Any) -> 'RPC': agent_info = AgentInfo.from_dict(obj.get("AgentInfo")) agent_info_source = AgentInfoSource(obj.get("AgentInfoSource")) agent_list = AgentList.from_dict(obj.get("AgentList")) + agent_registry_live_target_entry = AgentRegistryLiveTargetEntry.from_dict(obj.get("AgentRegistryLiveTargetEntry")) + agent_registry_live_target_entry_attention_kind = AgentRegistryLiveTargetEntryAttentionKind(obj.get("AgentRegistryLiveTargetEntryAttentionKind")) + agent_registry_live_target_entry_kind = AgentRegistryLiveTargetEntryKind(obj.get("AgentRegistryLiveTargetEntryKind")) + agent_registry_live_target_entry_last_terminal_event = AgentRegistryLiveTargetEntryLastTerminalEvent(obj.get("AgentRegistryLiveTargetEntryLastTerminalEvent")) + agent_registry_live_target_entry_status = AgentRegistryLiveTargetEntryStatus(obj.get("AgentRegistryLiveTargetEntryStatus")) + agent_registry_log_capture = AgentRegistryLogCapture.from_dict(obj.get("AgentRegistryLogCapture")) + agent_registry_log_capture_open_error_reason = AgentRegistryLogCaptureOpenErrorReason(obj.get("AgentRegistryLogCaptureOpenErrorReason")) + agent_registry_spawn_error = AgentRegistrySpawnError.from_dict(obj.get("AgentRegistrySpawnError")) + agent_registry_spawn_permission_mode = AgentRegistrySpawnPermissionMode(obj.get("AgentRegistrySpawnPermissionMode")) + agent_registry_spawn_registry_timeout = AgentRegistrySpawnRegistryTimeout.from_dict(obj.get("AgentRegistrySpawnRegistryTimeout")) + agent_registry_spawn_request = AgentRegistrySpawnRequest.from_dict(obj.get("AgentRegistrySpawnRequest")) + agent_registry_spawn_result = _load_AgentRegistrySpawnResult(obj.get("AgentRegistrySpawnResult")) + agent_registry_spawn_spawned = AgentRegistrySpawnSpawned.from_dict(obj.get("AgentRegistrySpawnSpawned")) + agent_registry_spawn_validation_error = AgentRegistrySpawnValidationError.from_dict(obj.get("AgentRegistrySpawnValidationError")) + agent_registry_spawn_validation_error_field = AgentRegistrySpawnValidationErrorField(obj.get("AgentRegistrySpawnValidationErrorField")) + agent_registry_spawn_validation_error_reason = AgentRegistrySpawnValidationErrorReason(obj.get("AgentRegistrySpawnValidationErrorReason")) agent_reload_result = AgentReloadResult.from_dict(obj.get("AgentReloadResult")) agent_select_request = AgentSelectRequest.from_dict(obj.get("AgentSelectRequest")) agent_select_result = AgentSelectResult.from_dict(obj.get("AgentSelectResult")) + allow_all_permission_set_result = AllowAllPermissionSetResult.from_dict(obj.get("AllowAllPermissionSetResult")) + allow_all_permission_state = AllowAllPermissionState.from_dict(obj.get("AllowAllPermissionState")) api_key_auth_info = APIKeyAuthInfo.from_dict(obj.get("ApiKeyAuthInfo")) auth_info = _load_AuthInfo(obj.get("AuthInfo")) auth_info_type = AuthInfoType(obj.get("AuthInfoType")) @@ -15696,6 +16266,7 @@ def from_dict(obj: Any) -> 'RPC': permissions_configure_params = PermissionsConfigureParams.from_dict(obj.get("PermissionsConfigureParams")) permissions_configure_result = PermissionsConfigureResult.from_dict(obj.get("PermissionsConfigureResult")) permissions_folder_trust_add_trusted_result = PermissionsFolderTrustAddTrustedResult.from_dict(obj.get("PermissionsFolderTrustAddTrustedResult")) + permissions_get_allow_all_request = PermissionsGetAllowAllRequest.from_dict(obj.get("PermissionsGetAllowAllRequest")) permissions_locations_add_tool_approval_details = _load_PermissionsLocationsAddToolApprovalDetails(obj.get("PermissionsLocationsAddToolApprovalDetails")) permissions_locations_add_tool_approval_details_commands = PermissionsLocationsAddToolApprovalDetailsCommands.from_dict(obj.get("PermissionsLocationsAddToolApprovalDetailsCommands")) permissions_locations_add_tool_approval_details_custom_tool = PermissionsLocationsAddToolApprovalDetailsCustomTool.from_dict(obj.get("PermissionsLocationsAddToolApprovalDetailsCustomTool")) @@ -15717,6 +16288,7 @@ def from_dict(obj: Any) -> 'RPC': permissions_pending_requests_request = PermissionsPendingRequestsRequest.from_dict(obj.get("PermissionsPendingRequestsRequest")) permissions_reset_session_approvals_request = PermissionsResetSessionApprovalsRequest.from_dict(obj.get("PermissionsResetSessionApprovalsRequest")) permissions_reset_session_approvals_result = PermissionsResetSessionApprovalsResult.from_dict(obj.get("PermissionsResetSessionApprovalsResult")) + permissions_set_allow_all_request = PermissionsSetAllowAllRequest.from_dict(obj.get("PermissionsSetAllowAllRequest")) permissions_set_approve_all_request = PermissionsSetApproveAllRequest.from_dict(obj.get("PermissionsSetApproveAllRequest")) permissions_set_approve_all_result = PermissionsSetApproveAllResult.from_dict(obj.get("PermissionsSetApproveAllResult")) permissions_set_approve_all_source = PermissionsSetApproveAllSource(obj.get("PermissionsSetApproveAllSource")) @@ -15974,7 +16546,7 @@ def from_dict(obj: Any) -> 'RPC': session_context_info = from_union([SessionContextInfo.from_dict, from_none], obj.get("SessionContextInfo")) task_progress = from_union([TaskProgress.from_dict, from_none], obj.get("TaskProgress")) workspace_summary = from_union([WorkspaceSummary.from_dict, from_none], obj.get("WorkspaceSummary")) - return RPC(abort_request, abort_result, account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_reload_result, agent_select_request, agent_select_result, api_key_auth_info, auth_info, auth_info_type, canvas_action, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, canvas_instance_availability, canvas_invoke_action_request, canvas_invoke_action_result, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, connected_remote_session_metadata, connected_remote_session_metadata_kind, connected_remote_session_metadata_repository, connect_remote_session_params, connect_request, connect_result, content_filter_mode, copilot_api_token_auth_info, copilot_user_response, copilot_user_response_endpoints, copilot_user_response_quota_snapshots, copilot_user_response_quota_snapshots_chat, copilot_user_response_quota_snapshots_completions, copilot_user_response_quota_snapshots_premium_interactions, current_model, discovered_canvas, discovered_mcp_server, discovered_mcp_server_type, enqueue_command_params, enqueue_command_result, env_auth_info, event_log_read_request, event_log_release_interest_result, event_log_tail_result, event_log_types, events_agent_scope, events_cursor_status, events_read_result, execute_command_params, execute_command_result, extension, extension_list, extensions_disable_request, extensions_enable_request, extension_source, extension_status, external_tool_result, external_tool_text_result_for_llm, external_tool_text_result_for_llm_binary_results_for_llm, external_tool_text_result_for_llm_binary_results_for_llm_type, external_tool_text_result_for_llm_content, external_tool_text_result_for_llm_content_audio, external_tool_text_result_for_llm_content_image, external_tool_text_result_for_llm_content_resource, external_tool_text_result_for_llm_content_resource_details, external_tool_text_result_for_llm_content_resource_link, external_tool_text_result_for_llm_content_resource_link_icon, external_tool_text_result_for_llm_content_resource_link_icon_theme, external_tool_text_result_for_llm_content_terminal, external_tool_text_result_for_llm_content_text, filter_mapping, fleet_start_request, fleet_start_result, folder_trust_add_params, folder_trust_check_params, folder_trust_check_result, gh_cli_auth_info, handle_pending_tool_call_request, handle_pending_tool_call_result, history_abort_manual_compaction_result, history_cancel_background_compaction_result, history_compact_context_window, history_compact_request, history_compact_result, history_summarize_for_handoff_result, history_truncate_request, history_truncate_result, hmac_auth_info, installed_plugin, installed_plugin_source, installed_plugin_source_github, installed_plugin_source_local, installed_plugin_source_url, instructions_get_sources_result, instructions_sources, instructions_sources_location, instructions_sources_type, log_request, log_result, lsp_initialize_request, mcp_apps_call_tool_request, mcp_apps_diagnose_capability, mcp_apps_diagnose_request, mcp_apps_diagnose_result, mcp_apps_diagnose_server, mcp_apps_host_context, mcp_apps_host_context_details, mcp_apps_host_context_details_available_display_mode, mcp_apps_host_context_details_display_mode, mcp_apps_host_context_details_platform, mcp_apps_host_context_details_theme, mcp_apps_list_tools_request, mcp_apps_list_tools_result, mcp_apps_read_resource_request, mcp_apps_read_resource_result, mcp_apps_resource_content, mcp_apps_set_host_context_details, mcp_apps_set_host_context_details_available_display_mode, mcp_apps_set_host_context_details_display_mode, mcp_apps_set_host_context_details_platform, mcp_apps_set_host_context_details_theme, mcp_apps_set_host_context_request, mcp_cancel_sampling_execution_params, mcp_cancel_sampling_execution_result, mcp_config_add_request, mcp_config_disable_request, mcp_config_enable_request, mcp_config_list, mcp_config_remove_request, mcp_config_update_request, mcp_disable_request, mcp_discover_request, mcp_discover_result, mcp_enable_request, mcp_execute_sampling_params, mcp_execute_sampling_request, mcp_execute_sampling_result, mcp_oauth_login_request, mcp_oauth_login_result, mcp_remove_git_hub_result, mcp_sampling_execution_action, mcp_sampling_execution_result, mcp_server, mcp_server_config, mcp_server_config_http, mcp_server_config_http_auth, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_oidc, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_config_stdio_auth, mcp_server_config_stdio_oidc, mcp_server_list, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, metadata_context_info_request, metadata_context_info_result, metadata_is_processing_result, metadata_recompute_context_tokens_request, metadata_recompute_context_tokens_result, metadata_record_context_change_request, metadata_record_context_change_result, metadata_set_working_directory_request, metadata_set_working_directory_result, metadata_snapshot_current_mode, metadata_snapshot_remote_metadata, metadata_snapshot_remote_metadata_repository, metadata_snapshot_remote_metadata_task_type, model, model_billing, model_billing_token_prices, model_billing_token_prices_long_context, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_picker_category, model_picker_price_category, model_policy, model_policy_state, model_set_reasoning_effort_request, model_set_reasoning_effort_result, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_env_value_mode, pending_permission_request, pending_permission_request_list, permission_decision, permission_decision_approved, permission_decision_approved_for_location, permission_decision_approved_for_session, permission_decision_approve_for_location, permission_decision_approve_for_location_approval, permission_decision_approve_for_location_approval_commands, permission_decision_approve_for_location_approval_custom_tool, permission_decision_approve_for_location_approval_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_cancelled, permission_decision_denied_by_content_exclusion_policy, permission_decision_denied_by_permission_request_hook, permission_decision_denied_by_rules, permission_decision_denied_interactively_by_user, permission_decision_denied_no_approval_rule_and_could_not_request_from_user, permission_decision_reject, permission_decision_request, permission_decision_user_not_available, permission_location_add_tool_approval_params, permission_location_apply_params, permission_location_apply_result, permission_location_resolve_params, permission_location_resolve_result, permission_location_type, permission_paths_add_params, permission_paths_allowed_check_params, permission_paths_allowed_check_result, permission_paths_config, permission_paths_list, permission_paths_update_primary_params, permission_paths_workspace_check_params, permission_paths_workspace_check_result, permission_prompt_shown_notification, permission_request_result, permission_rules_set, permissions_configure_additional_content_exclusion_policy, permissions_configure_additional_content_exclusion_policy_rule, permissions_configure_additional_content_exclusion_policy_rule_source, permissions_configure_additional_content_exclusion_policy_scope, permissions_configure_params, permissions_configure_result, permissions_folder_trust_add_trusted_result, permissions_locations_add_tool_approval_details, permissions_locations_add_tool_approval_details_commands, permissions_locations_add_tool_approval_details_custom_tool, permissions_locations_add_tool_approval_details_extension_management, permissions_locations_add_tool_approval_details_extension_permission_access, permissions_locations_add_tool_approval_details_mcp, permissions_locations_add_tool_approval_details_mcp_sampling, permissions_locations_add_tool_approval_details_memory, permissions_locations_add_tool_approval_details_read, permissions_locations_add_tool_approval_details_write, permissions_locations_add_tool_approval_result, permissions_modify_rules_params, permissions_modify_rules_result, permissions_modify_rules_scope, permissions_notify_prompt_shown_result, permissions_paths_add_result, permissions_paths_list_request, permissions_paths_update_primary_result, permissions_pending_requests_request, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_approve_all_request, permissions_set_approve_all_result, permissions_set_approve_all_source, permissions_set_required_request, permissions_set_required_result, permissions_urls_set_unrestricted_mode_result, permission_urls_config, permission_urls_set_unrestricted_mode_params, ping_request, ping_result, plan_read_result, plan_update_request, plugin, plugin_list, queued_command_handled, queued_command_not_handled, queued_command_result, queue_pending_items, queue_pending_items_kind, queue_pending_items_result, queue_remove_most_recent_result, register_event_interest_params, register_event_interest_result, release_event_interest_params, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_mode, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachment, send_attachment_blob, send_attachment_directory, send_attachment_file, send_attachment_file_line_range, send_attachment_github_reference, send_attachment_github_reference_type, send_attachment_selection, send_attachment_selection_details, send_attachment_selection_details_end, send_attachment_selection_details_start, send_mode, send_request, send_result, server_skill, server_skill_list, session_auth_status, session_bulk_delete_result, session_context, session_context_host_type, session_enrich_metadata_result, session_fs_append_file_request, session_fs_error, session_fs_error_code, session_fs_exists_request, session_fs_exists_result, session_fs_mkdir_request, session_fs_readdir_request, session_fs_readdir_result, session_fs_readdir_with_types_entry, session_fs_readdir_with_types_entry_type, session_fs_readdir_with_types_request, session_fs_readdir_with_types_result, session_fs_read_file_request, session_fs_read_file_result, session_fs_rename_request, session_fs_rm_request, session_fs_set_provider_capabilities, session_fs_set_provider_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_sqlite_exists_request, session_fs_sqlite_exists_result, session_fs_sqlite_query_request, session_fs_sqlite_query_result, session_fs_sqlite_query_type, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_installed_plugin, session_installed_plugin_source, session_installed_plugin_source_github, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata, session_metadata_snapshot, session_mode, session_prune_result, sessions_bulk_delete_request, sessions_check_in_use_request, sessions_check_in_use_result, sessions_close_request, sessions_close_result, sessions_enrich_metadata_request, session_set_credentials_params, session_set_credentials_result, sessions_find_by_prefix_request, sessions_find_by_prefix_result, sessions_find_by_task_id_request, sessions_find_by_task_id_result, sessions_fork_request, sessions_fork_result, sessions_get_event_file_path_request, sessions_get_event_file_path_result, sessions_get_last_for_context_request, sessions_get_last_for_context_result, sessions_get_persisted_remote_steerable_request, sessions_get_persisted_remote_steerable_result, session_sizes, sessions_list_request, sessions_load_deferred_repo_hooks_request, sessions_prune_old_request, sessions_release_lock_request, sessions_release_lock_result, sessions_reload_plugin_hooks_request, sessions_reload_plugin_hooks_result, sessions_save_request, sessions_save_result, sessions_set_additional_plugins_request, sessions_set_additional_plugins_result, session_update_options_params, session_update_options_result, session_working_directory_context, session_working_directory_context_host_type, shell_exec_request, shell_exec_result, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_initialize_and_validate_result, tools_list_request, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_exit_plan_mode_action, ui_exit_plan_mode_response, ui_handle_pending_auto_mode_switch_request, ui_handle_pending_elicitation_request, ui_handle_pending_exit_plan_mode_request, ui_handle_pending_result, ui_handle_pending_sampling_request, ui_handle_pending_sampling_response, ui_handle_pending_user_input_request, ui_register_direct_auto_mode_switch_handler_result, ui_unregister_direct_auto_mode_switch_handler_request, ui_unregister_direct_auto_mode_switch_handler_result, ui_user_input_response, usage_get_metrics_result, usage_metrics_code_changes, usage_metrics_model_metric, usage_metrics_model_metric_requests, usage_metrics_model_metric_token_detail, usage_metrics_model_metric_usage, usage_metrics_token_detail, user_auth_info, workspace_diff_file_change, workspace_diff_file_change_type, workspace_diff_mode, workspace_diff_result, workspaces_checkpoints, workspaces_create_file_request, workspaces_diff_request, workspaces_get_workspace_result, workspaces_list_checkpoints_result, workspaces_list_files_result, workspaces_read_checkpoint_request, workspaces_read_checkpoint_result, workspaces_read_file_request, workspaces_read_file_result, workspaces_save_large_paste_request, workspaces_save_large_paste_result, workspace_summary_host_type, workspaces_workspace_details_host_type, session_context_info, task_progress, workspace_summary) + return RPC(abort_request, abort_result, account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_registry_live_target_entry, agent_registry_live_target_entry_attention_kind, agent_registry_live_target_entry_kind, agent_registry_live_target_entry_last_terminal_event, agent_registry_live_target_entry_status, agent_registry_log_capture, agent_registry_log_capture_open_error_reason, agent_registry_spawn_error, agent_registry_spawn_permission_mode, agent_registry_spawn_registry_timeout, agent_registry_spawn_request, agent_registry_spawn_result, agent_registry_spawn_spawned, agent_registry_spawn_validation_error, agent_registry_spawn_validation_error_field, agent_registry_spawn_validation_error_reason, agent_reload_result, agent_select_request, agent_select_result, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, canvas_action, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, canvas_instance_availability, canvas_invoke_action_request, canvas_invoke_action_result, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, connected_remote_session_metadata, connected_remote_session_metadata_kind, connected_remote_session_metadata_repository, connect_remote_session_params, connect_request, connect_result, content_filter_mode, copilot_api_token_auth_info, copilot_user_response, copilot_user_response_endpoints, copilot_user_response_quota_snapshots, copilot_user_response_quota_snapshots_chat, copilot_user_response_quota_snapshots_completions, copilot_user_response_quota_snapshots_premium_interactions, current_model, discovered_canvas, discovered_mcp_server, discovered_mcp_server_type, enqueue_command_params, enqueue_command_result, env_auth_info, event_log_read_request, event_log_release_interest_result, event_log_tail_result, event_log_types, events_agent_scope, events_cursor_status, events_read_result, execute_command_params, execute_command_result, extension, extension_list, extensions_disable_request, extensions_enable_request, extension_source, extension_status, external_tool_result, external_tool_text_result_for_llm, external_tool_text_result_for_llm_binary_results_for_llm, external_tool_text_result_for_llm_binary_results_for_llm_type, external_tool_text_result_for_llm_content, external_tool_text_result_for_llm_content_audio, external_tool_text_result_for_llm_content_image, external_tool_text_result_for_llm_content_resource, external_tool_text_result_for_llm_content_resource_details, external_tool_text_result_for_llm_content_resource_link, external_tool_text_result_for_llm_content_resource_link_icon, external_tool_text_result_for_llm_content_resource_link_icon_theme, external_tool_text_result_for_llm_content_terminal, external_tool_text_result_for_llm_content_text, filter_mapping, fleet_start_request, fleet_start_result, folder_trust_add_params, folder_trust_check_params, folder_trust_check_result, gh_cli_auth_info, handle_pending_tool_call_request, handle_pending_tool_call_result, history_abort_manual_compaction_result, history_cancel_background_compaction_result, history_compact_context_window, history_compact_request, history_compact_result, history_summarize_for_handoff_result, history_truncate_request, history_truncate_result, hmac_auth_info, installed_plugin, installed_plugin_source, installed_plugin_source_github, installed_plugin_source_local, installed_plugin_source_url, instructions_get_sources_result, instructions_sources, instructions_sources_location, instructions_sources_type, log_request, log_result, lsp_initialize_request, mcp_apps_call_tool_request, mcp_apps_diagnose_capability, mcp_apps_diagnose_request, mcp_apps_diagnose_result, mcp_apps_diagnose_server, mcp_apps_host_context, mcp_apps_host_context_details, mcp_apps_host_context_details_available_display_mode, mcp_apps_host_context_details_display_mode, mcp_apps_host_context_details_platform, mcp_apps_host_context_details_theme, mcp_apps_list_tools_request, mcp_apps_list_tools_result, mcp_apps_read_resource_request, mcp_apps_read_resource_result, mcp_apps_resource_content, mcp_apps_set_host_context_details, mcp_apps_set_host_context_details_available_display_mode, mcp_apps_set_host_context_details_display_mode, mcp_apps_set_host_context_details_platform, mcp_apps_set_host_context_details_theme, mcp_apps_set_host_context_request, mcp_cancel_sampling_execution_params, mcp_cancel_sampling_execution_result, mcp_config_add_request, mcp_config_disable_request, mcp_config_enable_request, mcp_config_list, mcp_config_remove_request, mcp_config_update_request, mcp_disable_request, mcp_discover_request, mcp_discover_result, mcp_enable_request, mcp_execute_sampling_params, mcp_execute_sampling_request, mcp_execute_sampling_result, mcp_oauth_login_request, mcp_oauth_login_result, mcp_remove_git_hub_result, mcp_sampling_execution_action, mcp_sampling_execution_result, mcp_server, mcp_server_config, mcp_server_config_http, mcp_server_config_http_auth, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_oidc, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_config_stdio_auth, mcp_server_config_stdio_oidc, mcp_server_list, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, metadata_context_info_request, metadata_context_info_result, metadata_is_processing_result, metadata_recompute_context_tokens_request, metadata_recompute_context_tokens_result, metadata_record_context_change_request, metadata_record_context_change_result, metadata_set_working_directory_request, metadata_set_working_directory_result, metadata_snapshot_current_mode, metadata_snapshot_remote_metadata, metadata_snapshot_remote_metadata_repository, metadata_snapshot_remote_metadata_task_type, model, model_billing, model_billing_token_prices, model_billing_token_prices_long_context, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_picker_category, model_picker_price_category, model_policy, model_policy_state, model_set_reasoning_effort_request, model_set_reasoning_effort_result, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_env_value_mode, pending_permission_request, pending_permission_request_list, permission_decision, permission_decision_approved, permission_decision_approved_for_location, permission_decision_approved_for_session, permission_decision_approve_for_location, permission_decision_approve_for_location_approval, permission_decision_approve_for_location_approval_commands, permission_decision_approve_for_location_approval_custom_tool, permission_decision_approve_for_location_approval_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_cancelled, permission_decision_denied_by_content_exclusion_policy, permission_decision_denied_by_permission_request_hook, permission_decision_denied_by_rules, permission_decision_denied_interactively_by_user, permission_decision_denied_no_approval_rule_and_could_not_request_from_user, permission_decision_reject, permission_decision_request, permission_decision_user_not_available, permission_location_add_tool_approval_params, permission_location_apply_params, permission_location_apply_result, permission_location_resolve_params, permission_location_resolve_result, permission_location_type, permission_paths_add_params, permission_paths_allowed_check_params, permission_paths_allowed_check_result, permission_paths_config, permission_paths_list, permission_paths_update_primary_params, permission_paths_workspace_check_params, permission_paths_workspace_check_result, permission_prompt_shown_notification, permission_request_result, permission_rules_set, permissions_configure_additional_content_exclusion_policy, permissions_configure_additional_content_exclusion_policy_rule, permissions_configure_additional_content_exclusion_policy_rule_source, permissions_configure_additional_content_exclusion_policy_scope, permissions_configure_params, permissions_configure_result, permissions_folder_trust_add_trusted_result, permissions_get_allow_all_request, permissions_locations_add_tool_approval_details, permissions_locations_add_tool_approval_details_commands, permissions_locations_add_tool_approval_details_custom_tool, permissions_locations_add_tool_approval_details_extension_management, permissions_locations_add_tool_approval_details_extension_permission_access, permissions_locations_add_tool_approval_details_mcp, permissions_locations_add_tool_approval_details_mcp_sampling, permissions_locations_add_tool_approval_details_memory, permissions_locations_add_tool_approval_details_read, permissions_locations_add_tool_approval_details_write, permissions_locations_add_tool_approval_result, permissions_modify_rules_params, permissions_modify_rules_result, permissions_modify_rules_scope, permissions_notify_prompt_shown_result, permissions_paths_add_result, permissions_paths_list_request, permissions_paths_update_primary_result, permissions_pending_requests_request, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_allow_all_request, permissions_set_approve_all_request, permissions_set_approve_all_result, permissions_set_approve_all_source, permissions_set_required_request, permissions_set_required_result, permissions_urls_set_unrestricted_mode_result, permission_urls_config, permission_urls_set_unrestricted_mode_params, ping_request, ping_result, plan_read_result, plan_update_request, plugin, plugin_list, queued_command_handled, queued_command_not_handled, queued_command_result, queue_pending_items, queue_pending_items_kind, queue_pending_items_result, queue_remove_most_recent_result, register_event_interest_params, register_event_interest_result, release_event_interest_params, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_mode, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachment, send_attachment_blob, send_attachment_directory, send_attachment_file, send_attachment_file_line_range, send_attachment_github_reference, send_attachment_github_reference_type, send_attachment_selection, send_attachment_selection_details, send_attachment_selection_details_end, send_attachment_selection_details_start, send_mode, send_request, send_result, server_skill, server_skill_list, session_auth_status, session_bulk_delete_result, session_context, session_context_host_type, session_enrich_metadata_result, session_fs_append_file_request, session_fs_error, session_fs_error_code, session_fs_exists_request, session_fs_exists_result, session_fs_mkdir_request, session_fs_readdir_request, session_fs_readdir_result, session_fs_readdir_with_types_entry, session_fs_readdir_with_types_entry_type, session_fs_readdir_with_types_request, session_fs_readdir_with_types_result, session_fs_read_file_request, session_fs_read_file_result, session_fs_rename_request, session_fs_rm_request, session_fs_set_provider_capabilities, session_fs_set_provider_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_sqlite_exists_request, session_fs_sqlite_exists_result, session_fs_sqlite_query_request, session_fs_sqlite_query_result, session_fs_sqlite_query_type, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_installed_plugin, session_installed_plugin_source, session_installed_plugin_source_github, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata, session_metadata_snapshot, session_mode, session_prune_result, sessions_bulk_delete_request, sessions_check_in_use_request, sessions_check_in_use_result, sessions_close_request, sessions_close_result, sessions_enrich_metadata_request, session_set_credentials_params, session_set_credentials_result, sessions_find_by_prefix_request, sessions_find_by_prefix_result, sessions_find_by_task_id_request, sessions_find_by_task_id_result, sessions_fork_request, sessions_fork_result, sessions_get_event_file_path_request, sessions_get_event_file_path_result, sessions_get_last_for_context_request, sessions_get_last_for_context_result, sessions_get_persisted_remote_steerable_request, sessions_get_persisted_remote_steerable_result, session_sizes, sessions_list_request, sessions_load_deferred_repo_hooks_request, sessions_prune_old_request, sessions_release_lock_request, sessions_release_lock_result, sessions_reload_plugin_hooks_request, sessions_reload_plugin_hooks_result, sessions_save_request, sessions_save_result, sessions_set_additional_plugins_request, sessions_set_additional_plugins_result, session_update_options_params, session_update_options_result, session_working_directory_context, session_working_directory_context_host_type, shell_exec_request, shell_exec_result, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_initialize_and_validate_result, tools_list_request, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_exit_plan_mode_action, ui_exit_plan_mode_response, ui_handle_pending_auto_mode_switch_request, ui_handle_pending_elicitation_request, ui_handle_pending_exit_plan_mode_request, ui_handle_pending_result, ui_handle_pending_sampling_request, ui_handle_pending_sampling_response, ui_handle_pending_user_input_request, ui_register_direct_auto_mode_switch_handler_result, ui_unregister_direct_auto_mode_switch_handler_request, ui_unregister_direct_auto_mode_switch_handler_result, ui_user_input_response, usage_get_metrics_result, usage_metrics_code_changes, usage_metrics_model_metric, usage_metrics_model_metric_requests, usage_metrics_model_metric_token_detail, usage_metrics_model_metric_usage, usage_metrics_token_detail, user_auth_info, workspace_diff_file_change, workspace_diff_file_change_type, workspace_diff_mode, workspace_diff_result, workspaces_checkpoints, workspaces_create_file_request, workspaces_diff_request, workspaces_get_workspace_result, workspaces_list_checkpoints_result, workspaces_list_files_result, workspaces_read_checkpoint_request, workspaces_read_checkpoint_result, workspaces_read_file_request, workspaces_read_file_result, workspaces_save_large_paste_request, workspaces_save_large_paste_result, workspace_summary_host_type, workspaces_workspace_details_host_type, session_context_info, task_progress, workspace_summary) def to_dict(self) -> dict: result: dict = {} @@ -15987,9 +16559,27 @@ def to_dict(self) -> dict: result["AgentInfo"] = to_class(AgentInfo, self.agent_info) result["AgentInfoSource"] = to_enum(AgentInfoSource, self.agent_info_source) result["AgentList"] = to_class(AgentList, self.agent_list) + result["AgentRegistryLiveTargetEntry"] = to_class(AgentRegistryLiveTargetEntry, self.agent_registry_live_target_entry) + result["AgentRegistryLiveTargetEntryAttentionKind"] = to_enum(AgentRegistryLiveTargetEntryAttentionKind, self.agent_registry_live_target_entry_attention_kind) + result["AgentRegistryLiveTargetEntryKind"] = to_enum(AgentRegistryLiveTargetEntryKind, self.agent_registry_live_target_entry_kind) + result["AgentRegistryLiveTargetEntryLastTerminalEvent"] = to_enum(AgentRegistryLiveTargetEntryLastTerminalEvent, self.agent_registry_live_target_entry_last_terminal_event) + result["AgentRegistryLiveTargetEntryStatus"] = to_enum(AgentRegistryLiveTargetEntryStatus, self.agent_registry_live_target_entry_status) + result["AgentRegistryLogCapture"] = to_class(AgentRegistryLogCapture, self.agent_registry_log_capture) + result["AgentRegistryLogCaptureOpenErrorReason"] = to_enum(AgentRegistryLogCaptureOpenErrorReason, self.agent_registry_log_capture_open_error_reason) + result["AgentRegistrySpawnError"] = to_class(AgentRegistrySpawnError, self.agent_registry_spawn_error) + result["AgentRegistrySpawnPermissionMode"] = to_enum(AgentRegistrySpawnPermissionMode, self.agent_registry_spawn_permission_mode) + result["AgentRegistrySpawnRegistryTimeout"] = to_class(AgentRegistrySpawnRegistryTimeout, self.agent_registry_spawn_registry_timeout) + result["AgentRegistrySpawnRequest"] = to_class(AgentRegistrySpawnRequest, self.agent_registry_spawn_request) + result["AgentRegistrySpawnResult"] = (self.agent_registry_spawn_result).to_dict() + result["AgentRegistrySpawnSpawned"] = to_class(AgentRegistrySpawnSpawned, self.agent_registry_spawn_spawned) + result["AgentRegistrySpawnValidationError"] = to_class(AgentRegistrySpawnValidationError, self.agent_registry_spawn_validation_error) + result["AgentRegistrySpawnValidationErrorField"] = to_enum(AgentRegistrySpawnValidationErrorField, self.agent_registry_spawn_validation_error_field) + result["AgentRegistrySpawnValidationErrorReason"] = to_enum(AgentRegistrySpawnValidationErrorReason, self.agent_registry_spawn_validation_error_reason) result["AgentReloadResult"] = to_class(AgentReloadResult, self.agent_reload_result) result["AgentSelectRequest"] = to_class(AgentSelectRequest, self.agent_select_request) result["AgentSelectResult"] = to_class(AgentSelectResult, self.agent_select_result) + result["AllowAllPermissionSetResult"] = to_class(AllowAllPermissionSetResult, self.allow_all_permission_set_result) + result["AllowAllPermissionState"] = to_class(AllowAllPermissionState, self.allow_all_permission_state) result["ApiKeyAuthInfo"] = to_class(APIKeyAuthInfo, self.api_key_auth_info) result["AuthInfo"] = (self.auth_info).to_dict() result["AuthInfoType"] = to_enum(AuthInfoType, self.auth_info_type) @@ -16256,6 +16846,7 @@ def to_dict(self) -> dict: result["PermissionsConfigureParams"] = to_class(PermissionsConfigureParams, self.permissions_configure_params) result["PermissionsConfigureResult"] = to_class(PermissionsConfigureResult, self.permissions_configure_result) result["PermissionsFolderTrustAddTrustedResult"] = to_class(PermissionsFolderTrustAddTrustedResult, self.permissions_folder_trust_add_trusted_result) + result["PermissionsGetAllowAllRequest"] = to_class(PermissionsGetAllowAllRequest, self.permissions_get_allow_all_request) result["PermissionsLocationsAddToolApprovalDetails"] = (self.permissions_locations_add_tool_approval_details).to_dict() result["PermissionsLocationsAddToolApprovalDetailsCommands"] = to_class(PermissionsLocationsAddToolApprovalDetailsCommands, self.permissions_locations_add_tool_approval_details_commands) result["PermissionsLocationsAddToolApprovalDetailsCustomTool"] = to_class(PermissionsLocationsAddToolApprovalDetailsCustomTool, self.permissions_locations_add_tool_approval_details_custom_tool) @@ -16277,6 +16868,7 @@ def to_dict(self) -> dict: result["PermissionsPendingRequestsRequest"] = to_class(PermissionsPendingRequestsRequest, self.permissions_pending_requests_request) result["PermissionsResetSessionApprovalsRequest"] = to_class(PermissionsResetSessionApprovalsRequest, self.permissions_reset_session_approvals_request) result["PermissionsResetSessionApprovalsResult"] = to_class(PermissionsResetSessionApprovalsResult, self.permissions_reset_session_approvals_result) + result["PermissionsSetAllowAllRequest"] = to_class(PermissionsSetAllowAllRequest, self.permissions_set_allow_all_request) result["PermissionsSetApproveAllRequest"] = to_class(PermissionsSetApproveAllRequest, self.permissions_set_approve_all_request) result["PermissionsSetApproveAllResult"] = to_class(PermissionsSetApproveAllResult, self.permissions_set_approve_all_result) result["PermissionsSetApproveAllSource"] = to_enum(PermissionsSetApproveAllSource, self.permissions_set_approve_all_source) @@ -16542,6 +17134,19 @@ def rpc_from_dict(s: Any) -> RPC: def rpc_to_dict(x: RPC) -> Any: return to_class(RPC, x) +# Outcome of an agentRegistry.spawn call. +AgentRegistrySpawnResult = AgentRegistrySpawnSpawned | AgentRegistrySpawnError | AgentRegistrySpawnRegistryTimeout | AgentRegistrySpawnValidationError + +def _load_AgentRegistrySpawnResult(obj: Any) -> "AgentRegistrySpawnResult": + assert isinstance(obj, dict) + kind = obj.get("kind") + match kind: + case "spawned": return AgentRegistrySpawnSpawned.from_dict(obj) + case "spawn-error": return AgentRegistrySpawnError.from_dict(obj) + case "registry-timeout": return AgentRegistrySpawnRegistryTimeout.from_dict(obj) + case "validation-error": return AgentRegistrySpawnValidationError.from_dict(obj) + case _: raise ValueError(f"Unknown AgentRegistrySpawnResult kind: {kind!r}") + # The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime stores the value verbatim and uses it for outbound model/API requests; it does NOT re-validate or re-fetch the associated Copilot user response. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. AuthInfo = HMACAuthInfo | EnvAuthInfo | TokenAuthInfo | CopilotAPITokenAuthInfo | UserAuthInfo | GhCLIAuthInfo | APIKeyAuthInfo @@ -16888,7 +17493,7 @@ async def connect(self, params: ConnectRemoteSessionParams, *, timeout: float | return RemoteSessionConnectionResult.from_dict(await self._client.request("sessions.connect", params_dict, **_timeout_kwargs(timeout))) async def list(self, params: SessionsListRequest, *, timeout: float | None = None) -> SessionList: - "Lists persisted sessions, optionally filtered by working-directory context.\n\nArgs:\n params: Optional metadata-load limit and context filter applied to the returned sessions.\n\nReturns:\n Persisted sessions matching the filter, ordered most-recently-modified first." + "Lists persisted sessions, optionally filtered by working-directory context.\n\nArgs:\n params: Optional metadata-load limit and filters applied to the returned sessions.\n\nReturns:\n Persisted sessions matching the filter, ordered most-recently-modified first." params_dict = {k: v for k, v in params.to_dict().items() if v is not None} return SessionList.from_dict(await self._client.request("sessions.list", params_dict, **_timeout_kwargs(timeout))) @@ -16972,6 +17577,17 @@ async def set_additional_plugins(self, params: SessionsSetAdditionalPluginsReque return SessionsSetAdditionalPluginsResult.from_dict(await self._client.request("sessions.setAdditionalPlugins", params_dict, **_timeout_kwargs(timeout))) +# Experimental: this API group is experimental and may change or be removed. +class ServerAgentRegistryApi: + def __init__(self, client: "JsonRpcClient"): + self._client = client + + async def spawn(self, params: AgentRegistrySpawnRequest, *, timeout: float | None = None) -> AgentRegistrySpawnResult: + "Spawns a managed-server child with the supplied configuration and returns a discriminated-union result. The caller (typically the CLI controller) is responsible for attaching to the spawned child and sending any follow-up prompt. When the controller-local spawn gate is closed the server returns JSON-RPC MethodNotFound.\n\nArgs:\n params: Inputs to spawn a managed-server child via the controller's spawn delegate.\n\nReturns:\n Outcome of an agentRegistry.spawn call." + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + return _load_AgentRegistrySpawnResult(await self._client.request("agentRegistry.spawn", params_dict, **_timeout_kwargs(timeout))) + + class ServerRpc: """Typed server-scoped RPC methods.""" def __init__(self, client: "JsonRpcClient"): @@ -16984,6 +17600,7 @@ def __init__(self, client: "JsonRpcClient"): self.skills = ServerSkillsApi(client) self.session_fs = ServerSessionFsApi(client) self.sessions = ServerSessionsApi(client) + self.agent_registry = ServerAgentRegistryApi(client) async def ping(self, params: PingRequest, *, timeout: float | None = None) -> PingResult: "Checks server responsiveness and returns protocol information.\n\nArgs:\n params: Optional message to echo back to the caller.\n\nReturns:\n Server liveness response, including the echoed message, current server timestamp, and protocol version." @@ -17755,6 +18372,16 @@ async def set_approve_all(self, params: PermissionsSetApproveAllRequest, *, time params_dict["sessionId"] = self._session_id return PermissionsSetApproveAllResult.from_dict(await self._client.request("session.permissions.setApproveAll", params_dict, **_timeout_kwargs(timeout))) + async def set_allow_all(self, params: PermissionsSetAllowAllRequest, *, timeout: float | None = None) -> AllowAllPermissionSetResult: + "Enables or disables full allow-all permissions (tools, paths, and URLs) for the session. Used by attach-mode clients (e.g. LocalRpcSession's `/allow-all` forwarder) to flip the target session's permission state. Unlike `setApproveAll`, this swaps in the unrestricted path and URL managers and emits `session.permissions_changed` on transition. The result returns the authoritative post-mutation state so callers can update their local mirrors without racing the `session.permissions_changed` notification on the same wire.\n\nArgs:\n params: Whether to enable full allow-all permissions for the session.\n\nReturns:\n Indicates whether the operation succeeded and reports the post-mutation state." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return AllowAllPermissionSetResult.from_dict(await self._client.request("session.permissions.setAllowAll", params_dict, **_timeout_kwargs(timeout))) + + async def get_allow_all(self, *, timeout: float | None = None) -> AllowAllPermissionState: + "Returns whether full allow-all permissions are currently active for the session.\n\nReturns:\n Current full allow-all permission state." + return AllowAllPermissionState.from_dict(await self._client.request("session.permissions.getAllowAll", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + async def modify_rules(self, params: PermissionsModifyRulesParams, *, timeout: float | None = None) -> PermissionsModifyRulesResult: "Adds or removes session-scoped or location-scoped permission rules.\n\nArgs:\n params: Scope and add/remove instructions for modifying session- or location-scoped permission rules.\n\nReturns:\n Indicates whether the operation succeeded." params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py index 219e6a365..44b717148 100644 --- a/python/copilot/generated/session_events.py +++ b/python/copilot/generated/session_events.py @@ -129,10 +129,12 @@ class SessionEventType(Enum): SESSION_TITLE_CHANGED = "session.title_changed" SESSION_SCHEDULE_CREATED = "session.schedule_created" SESSION_SCHEDULE_CANCELLED = "session.schedule_cancelled" + SESSION_AUTOPILOT_OBJECTIVE_CHANGED = "session.autopilot_objective_changed" SESSION_INFO = "session.info" SESSION_WARNING = "session.warning" SESSION_MODEL_CHANGE = "session.model_change" SESSION_MODE_CHANGED = "session.mode_changed" + SESSION_PERMISSIONS_CHANGED = "session.permissions_changed" SESSION_PLAN_CHANGED = "session.plan_changed" SESSION_WORKSPACE_FILE_CHANGED = "session.workspace_file_changed" SESSION_HANDOFF = "session.handoff" @@ -171,6 +173,7 @@ class SessionEventType(Enum): SUBAGENT_DESELECTED = "subagent.deselected" HOOK_START = "hook.start" HOOK_END = "hook.end" + HOOK_PROGRESS = "hook.progress" SYSTEM_MESSAGE = "system.message" SYSTEM_NOTIFICATION = "system.notification" PERMISSION_REQUESTED = "permission.requested" @@ -1717,6 +1720,25 @@ def to_dict(self) -> dict: return result +@dataclass +class HookProgressData: + "Ephemeral progress update from a running hook process" + message: str + + @staticmethod + def from_dict(obj: Any) -> "HookProgressData": + assert isinstance(obj, dict) + message = from_str(obj.get("message")) + return HookProgressData( + message=message, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["message"] = from_str(self.message) + return result + + @dataclass class HookStartData: "Hook invocation start details including type and input data" @@ -3215,6 +3237,35 @@ def to_dict(self) -> dict: return result +@dataclass +class SessionAutopilotObjectiveChangedData: + "Autopilot objective state file operation details indicating what changed" + operation: AutopilotObjectiveChangedOperation + id: int | None = None + status: AutopilotObjectiveChangedStatus | None = None + + @staticmethod + def from_dict(obj: Any) -> "SessionAutopilotObjectiveChangedData": + assert isinstance(obj, dict) + operation = parse_enum(AutopilotObjectiveChangedOperation, obj.get("operation")) + id = from_union([from_none, from_int], obj.get("id")) + status = from_union([from_none, lambda x: parse_enum(AutopilotObjectiveChangedStatus, x)], obj.get("status")) + return SessionAutopilotObjectiveChangedData( + operation=operation, + id=id, + status=status, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["operation"] = to_enum(AutopilotObjectiveChangedOperation, self.operation) + if self.id is not None: + result["id"] = from_union([from_none, to_int], self.id) + if self.status is not None: + result["status"] = from_union([from_none, lambda x: to_enum(AutopilotObjectiveChangedStatus, x)], self.status) + return result + + @dataclass class SessionBackgroundTasksChangedData: "Schema for the `BackgroundTasksChangedData` type." @@ -3855,6 +3906,29 @@ def to_dict(self) -> dict: return result +@dataclass +class SessionPermissionsChangedData: + "Permissions change details carrying the aggregate allow-all boolean transition." + allow_all_permissions: bool + previous_allow_all_permissions: bool + + @staticmethod + def from_dict(obj: Any) -> "SessionPermissionsChangedData": + assert isinstance(obj, dict) + allow_all_permissions = from_bool(obj.get("allowAllPermissions")) + previous_allow_all_permissions = from_bool(obj.get("previousAllowAllPermissions")) + return SessionPermissionsChangedData( + allow_all_permissions=allow_all_permissions, + previous_allow_all_permissions=previous_allow_all_permissions, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["allowAllPermissions"] = from_bool(self.allow_all_permissions) + result["previousAllowAllPermissions"] = from_bool(self.previous_allow_all_permissions) + return result + + @dataclass class SessionPlanChangedData: "Plan file operation details indicating what changed" @@ -5796,6 +5870,7 @@ class ToolExecutionStartData: tool_call_id: str tool_name: str arguments: Any = None + display_verbatim: bool | None = None mcp_server_name: str | None = None mcp_tool_name: str | None = None # Deprecated: this field is deprecated. @@ -5808,6 +5883,7 @@ def from_dict(obj: Any) -> "ToolExecutionStartData": tool_call_id = from_str(obj.get("toolCallId")) tool_name = from_str(obj.get("toolName")) arguments = obj.get("arguments") + display_verbatim = from_union([from_none, from_bool], obj.get("displayVerbatim")) mcp_server_name = from_union([from_none, from_str], obj.get("mcpServerName")) mcp_tool_name = from_union([from_none, from_str], obj.get("mcpToolName")) parent_tool_call_id = from_union([from_none, from_str], obj.get("parentToolCallId")) @@ -5816,6 +5892,7 @@ def from_dict(obj: Any) -> "ToolExecutionStartData": tool_call_id=tool_call_id, tool_name=tool_name, arguments=arguments, + display_verbatim=display_verbatim, mcp_server_name=mcp_server_name, mcp_tool_name=mcp_tool_name, parent_tool_call_id=parent_tool_call_id, @@ -5828,6 +5905,8 @@ def to_dict(self) -> dict: result["toolName"] = from_str(self.tool_name) if self.arguments is not None: result["arguments"] = self.arguments + if self.display_verbatim is not None: + result["displayVerbatim"] = from_union([from_none, from_bool], self.display_verbatim) if self.mcp_server_name is not None: result["mcpServerName"] = from_union([from_none, from_str], self.mcp_server_name) if self.mcp_tool_name is not None: @@ -6636,6 +6715,28 @@ class AutoModeSwitchResponse(Enum): NO = "no" +class AutopilotObjectiveChangedOperation(Enum): + "The type of operation performed on the autopilot objective state file" + # Autopilot objective state file was created for a new objective. + CREATE = "create" + # Autopilot objective state file was updated for an existing objective. + UPDATE = "update" + # Autopilot objective state file was deleted or cleared. + DELETE = "delete" + + +class AutopilotObjectiveChangedStatus(Enum): + "Current autopilot objective status, if one exists" + # Objective is active and can drive autopilot continuations. + ACTIVE = "active" + # Objective is paused and will not drive autopilot continuations. + PAUSED = "paused" + # Legacy objective state indicating the previous continuation cap was reached. + CAP_REACHED = "cap_reached" + # Objective was completed by the agent. + COMPLETED = "completed" + + class CanvasOpenedAvailability(Enum): "Runtime-controlled routing state for the instance. \"ready\" when the provider connection is live; \"stale\" when the provider has gone away and the instance is awaiting rebinding." # Provider connection is live; actions can be invoked. @@ -6921,7 +7022,7 @@ class WorkspaceFileChangedOperation(Enum): UPDATE = "update" -SessionEventData = SessionStartData | SessionResumeData | SessionRemoteSteerableChangedData | SessionErrorData | SessionIdleData | SessionTitleChangedData | SessionScheduleCreatedData | SessionScheduleCancelledData | SessionInfoData | SessionWarningData | SessionModelChangeData | SessionModeChangedData | SessionPlanChangedData | SessionWorkspaceFileChangedData | SessionHandoffData | SessionTruncationData | SessionSnapshotRewindData | SessionShutdownData | SessionContextChangedData | SessionUsageInfoData | SessionCompactionStartData | SessionCompactionCompleteData | SessionTaskCompleteData | UserMessageData | PendingMessagesModifiedData | AssistantTurnStartData | AssistantIntentData | AssistantReasoningData | AssistantReasoningDeltaData | AssistantStreamingDeltaData | AssistantMessageData | AssistantMessageStartData | AssistantMessageDeltaData | AssistantTurnEndData | AssistantUsageData | ModelCallFailureData | AbortData | ToolUserRequestedData | ToolExecutionStartData | ToolExecutionPartialResultData | ToolExecutionProgressData | ToolExecutionCompleteData | SkillInvokedData | SubagentStartedData | SubagentCompletedData | SubagentFailedData | SubagentSelectedData | SubagentDeselectedData | HookStartData | HookEndData | SystemMessageData | SystemNotificationData | PermissionRequestedData | PermissionCompletedData | UserInputRequestedData | UserInputCompletedData | ElicitationRequestedData | ElicitationCompletedData | SamplingRequestedData | SamplingCompletedData | McpOauthRequiredData | McpOauthCompletedData | SessionCustomNotificationData | ExternalToolRequestedData | ExternalToolCompletedData | CommandQueuedData | CommandExecuteData | CommandCompletedData | AutoModeSwitchRequestedData | AutoModeSwitchCompletedData | CommandsChangedData | CapabilitiesChangedData | ExitPlanModeRequestedData | ExitPlanModeCompletedData | SessionToolsUpdatedData | SessionBackgroundTasksChangedData | SessionSkillsLoadedData | SessionCustomAgentsUpdatedData | SessionMcpServersLoadedData | SessionMcpServerStatusChangedData | SessionExtensionsLoadedData | SessionCanvasOpenedData | SessionCanvasRegistryChangedData | McpAppToolCallCompleteData | RawSessionEventData | Data +SessionEventData = SessionStartData | SessionResumeData | SessionRemoteSteerableChangedData | SessionErrorData | SessionIdleData | SessionTitleChangedData | SessionScheduleCreatedData | SessionScheduleCancelledData | SessionAutopilotObjectiveChangedData | SessionInfoData | SessionWarningData | SessionModelChangeData | SessionModeChangedData | SessionPermissionsChangedData | SessionPlanChangedData | SessionWorkspaceFileChangedData | SessionHandoffData | SessionTruncationData | SessionSnapshotRewindData | SessionShutdownData | SessionContextChangedData | SessionUsageInfoData | SessionCompactionStartData | SessionCompactionCompleteData | SessionTaskCompleteData | UserMessageData | PendingMessagesModifiedData | AssistantTurnStartData | AssistantIntentData | AssistantReasoningData | AssistantReasoningDeltaData | AssistantStreamingDeltaData | AssistantMessageData | AssistantMessageStartData | AssistantMessageDeltaData | AssistantTurnEndData | AssistantUsageData | ModelCallFailureData | AbortData | ToolUserRequestedData | ToolExecutionStartData | ToolExecutionPartialResultData | ToolExecutionProgressData | ToolExecutionCompleteData | SkillInvokedData | SubagentStartedData | SubagentCompletedData | SubagentFailedData | SubagentSelectedData | SubagentDeselectedData | HookStartData | HookEndData | HookProgressData | SystemMessageData | SystemNotificationData | PermissionRequestedData | PermissionCompletedData | UserInputRequestedData | UserInputCompletedData | ElicitationRequestedData | ElicitationCompletedData | SamplingRequestedData | SamplingCompletedData | McpOauthRequiredData | McpOauthCompletedData | SessionCustomNotificationData | ExternalToolRequestedData | ExternalToolCompletedData | CommandQueuedData | CommandExecuteData | CommandCompletedData | AutoModeSwitchRequestedData | AutoModeSwitchCompletedData | CommandsChangedData | CapabilitiesChangedData | ExitPlanModeRequestedData | ExitPlanModeCompletedData | SessionToolsUpdatedData | SessionBackgroundTasksChangedData | SessionSkillsLoadedData | SessionCustomAgentsUpdatedData | SessionMcpServersLoadedData | SessionMcpServerStatusChangedData | SessionExtensionsLoadedData | SessionCanvasOpenedData | SessionCanvasRegistryChangedData | McpAppToolCallCompleteData | RawSessionEventData | Data @dataclass @@ -6955,10 +7056,12 @@ def from_dict(obj: Any) -> "SessionEvent": case SessionEventType.SESSION_TITLE_CHANGED: data = SessionTitleChangedData.from_dict(data_obj) case SessionEventType.SESSION_SCHEDULE_CREATED: data = SessionScheduleCreatedData.from_dict(data_obj) case SessionEventType.SESSION_SCHEDULE_CANCELLED: data = SessionScheduleCancelledData.from_dict(data_obj) + case SessionEventType.SESSION_AUTOPILOT_OBJECTIVE_CHANGED: data = SessionAutopilotObjectiveChangedData.from_dict(data_obj) case SessionEventType.SESSION_INFO: data = SessionInfoData.from_dict(data_obj) case SessionEventType.SESSION_WARNING: data = SessionWarningData.from_dict(data_obj) case SessionEventType.SESSION_MODEL_CHANGE: data = SessionModelChangeData.from_dict(data_obj) case SessionEventType.SESSION_MODE_CHANGED: data = SessionModeChangedData.from_dict(data_obj) + case SessionEventType.SESSION_PERMISSIONS_CHANGED: data = SessionPermissionsChangedData.from_dict(data_obj) case SessionEventType.SESSION_PLAN_CHANGED: data = SessionPlanChangedData.from_dict(data_obj) case SessionEventType.SESSION_WORKSPACE_FILE_CHANGED: data = SessionWorkspaceFileChangedData.from_dict(data_obj) case SessionEventType.SESSION_HANDOFF: data = SessionHandoffData.from_dict(data_obj) @@ -6997,6 +7100,7 @@ def from_dict(obj: Any) -> "SessionEvent": case SessionEventType.SUBAGENT_DESELECTED: data = SubagentDeselectedData.from_dict(data_obj) case SessionEventType.HOOK_START: data = HookStartData.from_dict(data_obj) case SessionEventType.HOOK_END: data = HookEndData.from_dict(data_obj) + case SessionEventType.HOOK_PROGRESS: data = HookProgressData.from_dict(data_obj) case SessionEventType.SYSTEM_MESSAGE: data = SystemMessageData.from_dict(data_obj) case SessionEventType.SYSTEM_NOTIFICATION: data = SystemNotificationData.from_dict(data_obj) case SessionEventType.PERMISSION_REQUESTED: data = PermissionRequestedData.from_dict(data_obj) diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index 0efc8b05b..ad69cb287 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -85,6 +85,8 @@ pub mod rpc_methods { pub const SESSIONS_LOADDEFERREDREPOHOOKS: &str = "sessions.loadDeferredRepoHooks"; /// `sessions.setAdditionalPlugins` pub const SESSIONS_SETADDITIONALPLUGINS: &str = "sessions.setAdditionalPlugins"; + /// `agentRegistry.spawn` + pub const AGENTREGISTRY_SPAWN: &str = "agentRegistry.spawn"; /// `session.suspend` pub const SESSION_SUSPEND: &str = "session.suspend"; /// `session.send` @@ -285,6 +287,10 @@ pub mod rpc_methods { pub const SESSION_PERMISSIONS_PENDINGREQUESTS: &str = "session.permissions.pendingRequests"; /// `session.permissions.setApproveAll` pub const SESSION_PERMISSIONS_SETAPPROVEALL: &str = "session.permissions.setApproveAll"; + /// `session.permissions.setAllowAll` + pub const SESSION_PERMISSIONS_SETALLOWALL: &str = "session.permissions.setAllowAll"; + /// `session.permissions.getAllowAll` + pub const SESSION_PERMISSIONS_GETALLOWALL: &str = "session.permissions.getAllowAll"; /// `session.permissions.modifyRules` pub const SESSION_PERMISSIONS_MODIFYRULES: &str = "session.permissions.modifyRules"; /// `session.permissions.setRequired` @@ -564,6 +570,208 @@ pub struct AgentList { pub agents: Vec, } +/// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AgentRegistryLiveTargetEntry { + /// Kind of attention required when status === "attention". Meaningful only when status === "attention". + #[serde(skip_serializing_if = "Option::is_none")] + pub attention_kind: Option, + /// Git branch of the session (when known) + #[serde(skip_serializing_if = "Option::is_none")] + pub branch: Option, + /// Copilot CLI version that wrote the entry + pub copilot_version: String, + /// Working directory of the session (when known) + #[serde(skip_serializing_if = "Option::is_none")] + pub cwd: Option, + /// Bind host for the entry's JSON-RPC server + pub host: String, + /// Process kind tag for the registry entry + pub kind: AgentRegistryLiveTargetEntryKind, + /// Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness) + pub last_seen_ms: i64, + /// How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done from done_cancelled. + #[serde(skip_serializing_if = "Option::is_none")] + pub last_terminal_event: Option, + /// Model identifier currently selected for the session + #[serde(skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Operating-system pid of the process owning this entry + pub pid: i64, + /// TCP port the entry's JSON-RPC server is listening on + pub port: i64, + /// Registry entry schema version (1 = ui-server, 2 = managed-server) + pub schema_version: i64, + /// Session ID of the foreground session for this entry + #[serde(skip_serializing_if = "Option::is_none")] + pub session_id: Option, + /// Friendly session name (when set) + #[serde(skip_serializing_if = "Option::is_none")] + pub session_name: Option, + /// ISO 8601 timestamp captured at registration + pub started_at: String, + /// Coarse lifecycle status of the foreground session + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, + /// Monotonic per-publisher revision counter incremented on every status update. Lets watchers detect transient flips. + #[serde(skip_serializing_if = "Option::is_none")] + pub status_revision: Option, + /// Connection token (null when the target is unauthenticated) + #[doc(hidden)] + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) token: Option, +} + +/// Per-spawn log-capture outcome; populated from spawnLiveTarget. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AgentRegistryLogCapture { + /// Whether per-spawn log capture is on (false when env-disabled or open failed) + pub enabled: bool, + /// Human-readable open failure message (only set when enabled === false AND the env-disable opt-out was NOT used) + #[serde(skip_serializing_if = "Option::is_none")] + pub open_error: Option, + /// Categorized reason for log-open failure + #[serde(skip_serializing_if = "Option::is_none")] + pub open_error_reason: Option, + /// Absolute path to the per-spawn log file (only set when enabled) + #[serde(skip_serializing_if = "Option::is_none")] + pub path: Option, +} + +/// `child_process.spawn` itself failed before the child entered the registry. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AgentRegistrySpawnError { + /// Underlying errno code (e.g. ENOENT, EACCES) when available + #[serde(skip_serializing_if = "Option::is_none")] + pub code: Option, + /// Discriminator: child_process.spawn itself failed + pub kind: AgentRegistrySpawnErrorKind, + /// Human-readable error message + pub message: String, +} + +/// Spawn succeeded but the child did not publish a matching managed-server entry within the timeout. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AgentRegistrySpawnRegistryTimeout { + /// Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance) + pub child_pid: i64, + /// Discriminator: spawn succeeded but child never registered + pub kind: AgentRegistrySpawnRegistryTimeoutKind, + /// Per-spawn log-capture outcome; populated from spawnLiveTarget. + #[serde(skip_serializing_if = "Option::is_none")] + pub log_capture: Option, +} + +/// Inputs to spawn a managed-server child via the controller's spawn delegate. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AgentRegistrySpawnRequest { + /// Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. + #[serde(skip_serializing_if = "Option::is_none")] + pub agent_name: Option, + /// Working directory for the spawned child (must be an existing directory) + pub cwd: String, + /// Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). + #[serde(skip_serializing_if = "Option::is_none")] + pub initial_prompt: Option, + /// Model identifier to apply to the new session + #[serde(skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. + #[serde(skip_serializing_if = "Option::is_none")] + pub name: Option, + /// Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. + #[serde(skip_serializing_if = "Option::is_none")] + pub permission_mode: Option, +} + +/// Managed-server child was spawned and registered successfully. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AgentRegistrySpawnSpawned { + /// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). + pub entry: AgentRegistryLiveTargetEntry, + /// If the delegate attempted to send the initial prompt and failed, the categorized error message. + #[serde(skip_serializing_if = "Option::is_none")] + pub initial_prompt_error: Option, + /// Whether the delegate already sent the initial prompt. Always omitted in the current wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send path. + #[serde(skip_serializing_if = "Option::is_none")] + pub initial_prompt_sent: Option, + /// Discriminator: managed-server child spawned successfully + pub kind: AgentRegistrySpawnSpawnedKind, + /// Per-spawn log-capture outcome; populated from spawnLiveTarget. + #[serde(skip_serializing_if = "Option::is_none")] + pub log_capture: Option, +} + +/// Synchronous pre-validation rejected the spawn request. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AgentRegistrySpawnValidationError { + /// Which parameter field was invalid. Omitted when the rejection is not field-specific. + #[serde(skip_serializing_if = "Option::is_none")] + pub field: Option, + /// Discriminator: synchronous pre-validation rejected the request + pub kind: AgentRegistrySpawnValidationErrorKind, + /// Human-readable explanation; safe to surface in the UI banner. Never logged to unrestricted telemetry. + pub message: String, + /// Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by reason without leaking raw paths or agent/model names. + pub reason: AgentRegistrySpawnValidationErrorReason, +} + /// Custom agents available to the session after reloading definitions from disk. /// ///
@@ -609,6 +817,38 @@ pub struct AgentSelectResult { pub agent: AgentInfo, } +/// Indicates whether the operation succeeded and reports the post-mutation state. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AllowAllPermissionSetResult { + /// Authoritative allow-all state after the mutation + pub enabled: bool, + /// Whether the operation succeeded + pub success: bool, +} + +/// Current full allow-all permission state. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AllowAllPermissionState { + /// Whether full allow-all permissions are currently active + pub enabled: bool, +} + /// Schema for the `CopilotUserResponseEndpoints` type. /// ///
@@ -4987,6 +5227,18 @@ pub struct PermissionsFolderTrustAddTrustedResult { pub success: bool, } +/// No parameters. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PermissionsGetAllowAllRequest {} + /// Indicates whether the operation succeeded. /// ///
@@ -5137,6 +5389,21 @@ pub struct PermissionsResetSessionApprovalsResult { pub success: bool, } +/// Whether to enable full allow-all permissions for the session. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PermissionsSetAllowAllRequest { + /// Whether to enable full allow-all permissions + pub enabled: bool, +} + /// Allow-all toggle for tool permission requests, with an optional telemetry source. /// ///
@@ -6011,6 +6278,9 @@ pub struct SessionMetadata { /// Schema for the `SessionContext` type. #[serde(skip_serializing_if = "Option::is_none")] pub context: Option, + /// True for detached maintenance sessions that should be hidden from normal resume lists. + #[serde(skip_serializing_if = "Option::is_none")] + pub is_detached: Option, /// True for remote (GitHub) sessions; false for local pub is_remote: bool, /// GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. @@ -7035,7 +7305,7 @@ pub struct SessionSizes { pub sizes: HashMap, } -/// Optional metadata-load limit and context filter applied to the returned sessions. +/// Optional metadata-load limit and filters applied to the returned sessions. /// ///
/// @@ -7049,6 +7319,9 @@ pub struct SessionsListRequest { /// Optional filter applied to the returned sessions #[serde(skip_serializing_if = "Option::is_none")] pub filter: Option, + /// When true, include detached maintenance sessions. Defaults to false for user-facing session lists. + #[serde(skip_serializing_if = "Option::is_none")] + pub include_detached: Option, /// When provided, only the first N sessions (sorted by modification time, newest first) load full metadata; remaining sessions return basic info only. Use 0 to return only basic info for every session. #[serde(skip_serializing_if = "Option::is_none")] pub metadata_limit: Option, @@ -11185,6 +11458,38 @@ pub struct SessionPermissionsSetApproveAllResult { pub success: bool, } +/// Indicates whether the operation succeeded and reports the post-mutation state. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionPermissionsSetAllowAllResult { + /// Authoritative allow-all state after the mutation + pub enabled: bool, + /// Whether the operation succeeded + pub success: bool, +} + +/// Current full allow-all permission state. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionPermissionsGetAllowAllResult { + /// Whether full allow-all permissions are currently active + pub enabled: bool, +} + /// Indicates whether the operation succeeded. /// ///
@@ -12210,6 +12515,270 @@ pub enum AgentInfoSource { Unknown, } +/// Kind of attention required when status === "attention". Meaningful only when status === "attention". +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistryLiveTargetEntryAttentionKind { + /// Session is blocked on an unrecoverable error + #[serde(rename = "error")] + Error, + /// Session is waiting for a tool-permission decision + #[serde(rename = "permission")] + Permission, + /// Session is waiting for the user to approve or reject a plan + #[serde(rename = "exit_plan")] + ExitPlan, + /// Session is waiting on an elicitation prompt + #[serde(rename = "elicitation")] + Elicitation, + /// Session is waiting for free-form user input + #[serde(rename = "user_input")] + UserInput, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Process kind tag for the registry entry +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistryLiveTargetEntryKind { + /// Interactive Copilot CLI exposing a UI server (legacy/normal CLI process) + #[serde(rename = "ui-server")] + UiServer, + /// Headless `--server --managed-server` child spawned by a controller + #[serde(rename = "managed-server")] + ManagedServer, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done from done_cancelled. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistryLiveTargetEntryLastTerminalEvent { + /// Last turn ended cleanly (model returned a final assistant message) + #[serde(rename = "turn_end")] + TurnEnd, + /// Last turn was aborted (e.g. user interrupted) + #[serde(rename = "abort")] + Abort, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Coarse lifecycle status of the foreground session +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistryLiveTargetEntryStatus { + /// Session is actively processing a turn + #[serde(rename = "working")] + Working, + /// Session is idle, waiting for input + #[serde(rename = "waiting")] + Waiting, + /// Last turn completed successfully + #[serde(rename = "done")] + Done, + /// Session needs user attention (see attentionKind for the specific reason) + #[serde(rename = "attention")] + Attention, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Categorized reason for log-open failure +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistryLogCaptureOpenErrorReason { + /// Filesystem permission denied opening the log file + #[serde(rename = "permission")] + Permission, + /// No space left on device + #[serde(rename = "disk_full")] + DiskFull, + /// Other / uncategorized open failure + #[serde(rename = "other")] + Other, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Discriminator: child_process.spawn itself failed +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistrySpawnErrorKind { + #[serde(rename = "spawn-error")] + #[default] + SpawnError, +} + +/// Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistrySpawnPermissionMode { + /// Standard permission posture (prompts for each request) + #[serde(rename = "default")] + Default, + /// Full allow-all (requires the controller-local session to currently be in allow-all mode) + #[serde(rename = "yolo")] + Yolo, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Discriminator: spawn succeeded but child never registered +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistrySpawnRegistryTimeoutKind { + #[serde(rename = "registry-timeout")] + #[default] + RegistryTimeout, +} + +/// Discriminator: managed-server child spawned successfully +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistrySpawnSpawnedKind { + #[serde(rename = "spawned")] + #[default] + Spawned, +} + +/// Which parameter field was invalid. Omitted when the rejection is not field-specific. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistrySpawnValidationErrorField { + /// The cwd parameter + #[serde(rename = "cwd")] + Cwd, + /// The session name parameter + #[serde(rename = "name")] + Name, + /// The agentName parameter + #[serde(rename = "agentName")] + AgentName, + /// The model parameter + #[serde(rename = "model")] + Model, + /// The permissionMode parameter + #[serde(rename = "permissionMode")] + PermissionMode, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Discriminator: synchronous pre-validation rejected the request +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistrySpawnValidationErrorKind { + #[serde(rename = "validation-error")] + #[default] + ValidationError, +} + +/// Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by reason without leaking raw paths or agent/model names. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgentRegistrySpawnValidationErrorReason { + /// Provided cwd does not exist on disk + #[serde(rename = "cwd-not-found")] + CwdNotFound, + /// Provided cwd exists but is not a directory + #[serde(rename = "cwd-not-directory")] + CwdNotDirectory, + /// Session name failed validateSessionName + #[serde(rename = "invalid-name")] + InvalidName, + /// Requested agent name was not found in builtin or custom agents + #[serde(rename = "unknown-agent")] + UnknownAgent, + /// Requested model is not available to this session + #[serde(rename = "unknown-model")] + UnknownModel, + /// Caller asked for permissionMode='yolo' but the controller is not currently in allow-all mode + #[serde(rename = "yolo-not-allowed")] + YoloNotAllowed, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Outcome of an agentRegistry.spawn call. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum AgentRegistrySpawnResult { + Spawned(AgentRegistrySpawnSpawned), + SpawnError(AgentRegistrySpawnError), + RegistryTimeout(AgentRegistrySpawnRegistryTimeout), + ValidationError(AgentRegistrySpawnValidationError), +} + /// API-key authentication for non-GitHub LLM providers (e.g. when running BYOM-style). #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum ApiKeyAuthInfoType { diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs index c0c793fe0..e89722ff9 100644 --- a/rust/src/generated/rpc.rs +++ b/rust/src/generated/rpc.rs @@ -27,6 +27,13 @@ impl<'a> ClientRpc<'a> { } } + /// `agentRegistry.*` sub-namespace. + pub fn agent_registry(&self) -> ClientRpcAgentRegistry<'a> { + ClientRpcAgentRegistry { + client: self.client, + } + } + /// `mcp.*` sub-namespace. pub fn mcp(&self) -> ClientRpcMcp<'a> { ClientRpcMcp { @@ -164,6 +171,45 @@ impl<'a> ClientRpcAccount<'a> { } } +/// `agentRegistry.*` RPCs. +#[derive(Clone, Copy)] +pub struct ClientRpcAgentRegistry<'a> { + pub(crate) client: &'a Client, +} + +impl<'a> ClientRpcAgentRegistry<'a> { + /// Spawns a managed-server child with the supplied configuration and returns a discriminated-union result. The caller (typically the CLI controller) is responsible for attaching to the spawned child and sending any follow-up prompt. When the controller-local spawn gate is closed the server returns JSON-RPC MethodNotFound. + /// + /// Wire method: `agentRegistry.spawn`. + /// + /// # Parameters + /// + /// * `params` - Inputs to spawn a managed-server child via the controller's spawn delegate. + /// + /// # Returns + /// + /// Outcome of an agentRegistry.spawn call. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn spawn( + &self, + params: AgentRegistrySpawnRequest, + ) -> Result { + let wire_params = serde_json::to_value(params)?; + let _value = self + .client + .call(rpc_methods::AGENTREGISTRY_SPAWN, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } +} + /// `mcp.*` RPCs. #[derive(Clone, Copy)] pub struct ClientRpcMcp<'a> { @@ -505,7 +551,7 @@ impl<'a> ClientRpcSessions<'a> { /// /// # Parameters /// - /// * `params` - Optional metadata-load limit and context filter applied to the returned sessions. + /// * `params` - Optional metadata-load limit and filters applied to the returned sessions. /// /// # Returns /// @@ -3743,6 +3789,70 @@ impl<'a> SessionRpcPermissions<'a> { Ok(serde_json::from_value(_value)?) } + /// Enables or disables full allow-all permissions (tools, paths, and URLs) for the session. Used by attach-mode clients (e.g. LocalRpcSession's `/allow-all` forwarder) to flip the target session's permission state. Unlike `setApproveAll`, this swaps in the unrestricted path and URL managers and emits `session.permissions_changed` on transition. The result returns the authoritative post-mutation state so callers can update their local mirrors without racing the `session.permissions_changed` notification on the same wire. + /// + /// Wire method: `session.permissions.setAllowAll`. + /// + /// # Parameters + /// + /// * `params` - Whether to enable full allow-all permissions for the session. + /// + /// # Returns + /// + /// Indicates whether the operation succeeded and reports the post-mutation state. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn set_allow_all( + &self, + params: PermissionsSetAllowAllRequest, + ) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call( + rpc_methods::SESSION_PERMISSIONS_SETALLOWALL, + Some(wire_params), + ) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Returns whether full allow-all permissions are currently active for the session. + /// + /// Wire method: `session.permissions.getAllowAll`. + /// + /// # Returns + /// + /// Current full allow-all permission state. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn get_allow_all(&self) -> Result { + let wire_params = serde_json::json!({ "sessionId": self.session.id() }); + let _value = self + .session + .client() + .call( + rpc_methods::SESSION_PERMISSIONS_GETALLOWALL, + Some(wire_params), + ) + .await?; + Ok(serde_json::from_value(_value)?) + } + /// Adds or removes session-scoped or location-scoped permission rules. /// /// Wire method: `session.permissions.modifyRules`. diff --git a/rust/src/generated/session_events.rs b/rust/src/generated/session_events.rs index 6605ecbde..45b61a6c0 100644 --- a/rust/src/generated/session_events.rs +++ b/rust/src/generated/session_events.rs @@ -25,6 +25,8 @@ pub enum SessionEventType { SessionScheduleCreated, #[serde(rename = "session.schedule_cancelled")] SessionScheduleCancelled, + #[serde(rename = "session.autopilot_objective_changed")] + SessionAutopilotObjectiveChanged, #[serde(rename = "session.info")] SessionInfo, #[serde(rename = "session.warning")] @@ -33,6 +35,8 @@ pub enum SessionEventType { SessionModelChange, #[serde(rename = "session.mode_changed")] SessionModeChanged, + #[serde(rename = "session.permissions_changed")] + SessionPermissionsChanged, #[serde(rename = "session.plan_changed")] SessionPlanChanged, #[serde(rename = "session.workspace_file_changed")] @@ -109,6 +113,8 @@ pub enum SessionEventType { HookStart, #[serde(rename = "hook.end")] HookEnd, + #[serde(rename = "hook.progress")] + HookProgress, #[serde(rename = "system.message")] SystemMessage, #[serde(rename = "system.notification")] @@ -205,6 +211,8 @@ pub enum SessionEventData { SessionScheduleCreated(SessionScheduleCreatedData), #[serde(rename = "session.schedule_cancelled")] SessionScheduleCancelled(SessionScheduleCancelledData), + #[serde(rename = "session.autopilot_objective_changed")] + SessionAutopilotObjectiveChanged(SessionAutopilotObjectiveChangedData), #[serde(rename = "session.info")] SessionInfo(SessionInfoData), #[serde(rename = "session.warning")] @@ -213,6 +221,8 @@ pub enum SessionEventData { SessionModelChange(SessionModelChangeData), #[serde(rename = "session.mode_changed")] SessionModeChanged(SessionModeChangedData), + #[serde(rename = "session.permissions_changed")] + SessionPermissionsChanged(SessionPermissionsChangedData), #[serde(rename = "session.plan_changed")] SessionPlanChanged(SessionPlanChangedData), #[serde(rename = "session.workspace_file_changed")] @@ -289,6 +299,8 @@ pub enum SessionEventData { HookStart(HookStartData), #[serde(rename = "hook.end")] HookEnd(HookEndData), + #[serde(rename = "hook.progress")] + HookProgress(HookProgressData), #[serde(rename = "system.message")] SystemMessage(SystemMessageData), #[serde(rename = "system.notification")] @@ -568,6 +580,20 @@ pub struct SessionScheduleCancelledData { pub id: i64, } +/// Session event "session.autopilot_objective_changed". Autopilot objective state file operation details indicating what changed +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionAutopilotObjectiveChangedData { + /// Current autopilot objective id, if one exists + #[serde(skip_serializing_if = "Option::is_none")] + pub id: Option, + /// The type of operation performed on the autopilot objective state file + pub operation: AutopilotObjectiveChangedOperation, + /// Current autopilot objective status, if one exists + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, +} + /// Session event "session.info". Informational message for timeline display with categorization #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -636,6 +662,16 @@ pub struct SessionModeChangedData { pub previous_mode: SessionMode, } +/// Session event "session.permissions_changed". Permissions change details carrying the aggregate allow-all boolean transition. +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionPermissionsChangedData { + /// Aggregate allow-all flag after the change + pub allow_all_permissions: bool, + /// Aggregate allow-all flag before the change + pub previous_allow_all_permissions: bool, +} + /// Session event "session.plan_changed". Plan file operation details indicating what changed #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -1462,6 +1498,9 @@ pub struct ToolExecutionStartData { /// Arguments passed to the tool #[serde(skip_serializing_if = "Option::is_none")] pub arguments: Option, + /// When true, the tool output should be displayed expanded (verbatim) in the CLI timeline + #[serde(skip_serializing_if = "Option::is_none")] + pub display_verbatim: Option, /// Name of the MCP server hosting this tool, when the tool is an MCP tool #[serde(skip_serializing_if = "Option::is_none")] pub mcp_server_name: Option, @@ -1989,6 +2028,14 @@ pub struct HookEndData { pub success: bool, } +/// Session event "hook.progress". Ephemeral progress update from a running hook process +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct HookProgressData { + /// Human-readable progress message from the hook process + pub message: String, +} + /// Metadata about the prompt template and its construction #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -3296,6 +3343,45 @@ pub enum ReasoningSummary { Unknown, } +/// The type of operation performed on the autopilot objective state file +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AutopilotObjectiveChangedOperation { + /// Autopilot objective state file was created for a new objective. + #[serde(rename = "create")] + Create, + /// Autopilot objective state file was updated for an existing objective. + #[serde(rename = "update")] + Update, + /// Autopilot objective state file was deleted or cleared. + #[serde(rename = "delete")] + Delete, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Current autopilot objective status, if one exists +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AutopilotObjectiveChangedStatus { + /// Objective is active and can drive autopilot continuations. + #[serde(rename = "active")] + Active, + /// Objective is paused and will not drive autopilot continuations. + #[serde(rename = "paused")] + Paused, + /// Legacy objective state indicating the previous continuation cap was reached. + #[serde(rename = "cap_reached")] + CapReached, + /// Objective was completed by the agent. + #[serde(rename = "completed")] + Completed, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum SessionModelChangeDataContextTier { /// Default context tier with standard context window size. From 9204d0b7a32e480e750eda936a5cb66faed973ce Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Wed, 27 May 2026 08:53:00 -0700 Subject: [PATCH 10/10] fix: format Rust imports in generated api_types.rs --- rust/src/generated/api_types.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index 2c1a31bac..fcef87982 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -10,8 +10,7 @@ use super::session_events::{ AbortReason, McpServerSource, McpServerStatus, PermissionPromptRequest, PermissionRule, ReasoningSummary, SessionMode, ShutdownType, SkillSource, UserToolSessionApproval, }; -use crate::types::SessionEvent; -use crate::types::{RequestId, SessionId}; +use crate::types::{RequestId, SessionEvent, SessionId}; /// JSON-RPC method name constants. pub mod rpc_methods {