From 1fd7b5111428c7aeb48e2f695b2b59926f28cff2 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 30 Apr 2026 14:47:29 +0000
Subject: [PATCH 1/6] Update @github/copilot to 1.0.40-1
- Updated nodejs and test harness dependencies
- Re-ran code generators
- Formatted generated code
---
dotnet/src/Generated/Rpc.cs | 77 +-
dotnet/src/Generated/SessionEvents.cs | 360 ++++++++-
go/generated_session_events.go | 120 ++-
go/rpc/generated_rpc.go | 793 +++++++++++++-------
nodejs/package-lock.json | 56 +-
nodejs/package.json | 2 +-
nodejs/samples/package-lock.json | 2 +-
nodejs/src/generated/rpc.ts | 363 ++++++++--
nodejs/src/generated/session-events.ts | 270 ++++++-
python/copilot/generated/rpc.py | 802 ++++++++++++++++++---
python/copilot/generated/session_events.py | 266 ++++++-
test/harness/package-lock.json | 56 +-
test/harness/package.json | 2 +-
13 files changed, 2596 insertions(+), 573 deletions(-)
diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs
index f90d836c9..9d1a76558 100644
--- a/dotnet/src/Generated/Rpc.cs
+++ b/dotnet/src/Generated/Rpc.cs
@@ -1676,16 +1676,16 @@ internal sealed class SessionExtensionsReloadRequest
public string SessionId { get; set; } = string.Empty;
}
-/// RPC data type for HandleToolCall operations.
-public sealed class HandleToolCallResult
+/// RPC data type for HandlePendingToolCall operations.
+public sealed class HandlePendingToolCallResult
{
/// Whether the tool call result was handled successfully.
[JsonPropertyName("success")]
public bool Success { get; set; }
}
-/// RPC data type for ToolsHandlePendingToolCall operations.
-internal sealed class ToolsHandlePendingToolCallRequest
+/// RPC data type for HandlePendingToolCall operations.
+internal sealed class HandlePendingToolCallRequest
{
/// Error message if the tool call failed.
[JsonPropertyName("error")]
@@ -1811,6 +1811,7 @@ public sealed class PermissionRequestResult
[JsonDerivedType(typeof(PermissionDecisionApproveOnce), "approve-once")]
[JsonDerivedType(typeof(PermissionDecisionApproveForSession), "approve-for-session")]
[JsonDerivedType(typeof(PermissionDecisionApproveForLocation), "approve-for-location")]
+[JsonDerivedType(typeof(PermissionDecisionApprovePermanently), "approve-permanently")]
[JsonDerivedType(typeof(PermissionDecisionReject), "reject")]
[JsonDerivedType(typeof(PermissionDecisionUserNotAvailable), "user-not-available")]
public partial class PermissionDecision
@@ -1933,8 +1934,14 @@ public partial class PermissionDecisionApproveForSession : PermissionDecision
public override string Kind => "approve-for-session";
/// The approval to add as a session-scoped rule.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("approval")]
- public required PermissionDecisionApproveForSessionApproval Approval { get; set; }
+ public PermissionDecisionApproveForSessionApproval? Approval { get; set; }
+
+ /// The URL domain to approve for this session.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("domain")]
+ public string? Domain { get; set; }
}
/// The approval to persist for this location.
@@ -2049,6 +2056,18 @@ public partial class PermissionDecisionApproveForLocation : PermissionDecision
public required string LocationKey { get; set; }
}
+/// The approve-permanently variant of .
+public partial class PermissionDecisionApprovePermanently : PermissionDecision
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "approve-permanently";
+
+ /// The URL domain to approve permanently.
+ [JsonPropertyName("domain")]
+ public required string Domain { get; set; }
+}
+
/// The reject variant of .
public partial class PermissionDecisionReject : PermissionDecision
{
@@ -2293,6 +2312,15 @@ public sealed class UsageMetricsModelMetricRequests
public long Count { get; set; }
}
+/// RPC data type for UsageMetricsModelMetricTokenDetail operations.
+public sealed class UsageMetricsModelMetricTokenDetail
+{
+ /// Accumulated token count for this token type.
+ [Range((double)0, (double)long.MaxValue)]
+ [JsonPropertyName("tokenCount")]
+ public long TokenCount { get; set; }
+}
+
/// Token usage metrics for this model.
public sealed class UsageMetricsModelMetricUsage
{
@@ -2329,11 +2357,29 @@ public sealed class UsageMetricsModelMetric
[JsonPropertyName("requests")]
public UsageMetricsModelMetricRequests Requests { get => field ??= new(); set; }
+ /// Token count details per type.
+ [JsonPropertyName("tokenDetails")]
+ public IDictionary? TokenDetails { get; set; }
+
+ /// Accumulated nano-AI units cost for this model.
+ [Range((double)0, (double)long.MaxValue)]
+ [JsonPropertyName("totalNanoAiu")]
+ public long? TotalNanoAiu { get; set; }
+
/// Token usage metrics for this model.
[JsonPropertyName("usage")]
public UsageMetricsModelMetricUsage Usage { get => field ??= new(); set; }
}
+/// RPC data type for UsageMetricsTokenDetail operations.
+public sealed class UsageMetricsTokenDetail
+{
+ /// Accumulated token count for this token type.
+ [Range((double)0, (double)long.MaxValue)]
+ [JsonPropertyName("tokenCount")]
+ public long TokenCount { get; set; }
+}
+
/// RPC data type for UsageGetMetrics operations.
[Experimental(Diagnostics.Experimental)]
public sealed class UsageGetMetricsResult
@@ -2364,12 +2410,21 @@ public sealed class UsageGetMetricsResult
[JsonPropertyName("sessionStartTime")]
public long SessionStartTime { get; set; }
+ /// Session-wide per-token-type accumulated token counts.
+ [JsonPropertyName("tokenDetails")]
+ public IDictionary? TokenDetails { get; set; }
+
/// Total time spent in model API calls (milliseconds).
[Range(0, double.MaxValue)]
[JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonPropertyName("totalApiDurationMs")]
public TimeSpan TotalApiDurationMs { get; set; }
+ /// Session-wide accumulated nano-AI units cost.
+ [Range((double)0, (double)long.MaxValue)]
+ [JsonPropertyName("totalNanoAiu")]
+ public long? TotalNanoAiu { get; set; }
+
/// Total user-initiated premium request cost across all models (may be fractional due to multipliers).
[JsonPropertyName("totalPremiumRequestCost")]
public double TotalPremiumRequestCost { get; set; }
@@ -3898,10 +3953,10 @@ internal ToolsApi(JsonRpc rpc, string sessionId)
}
/// Calls "session.tools.handlePendingToolCall".
- public async Task HandlePendingToolCallAsync(string requestId, object? result = null, string? error = null, CancellationToken cancellationToken = default)
+ public async Task HandlePendingToolCallAsync(string requestId, object? result = null, string? error = null, CancellationToken cancellationToken = default)
{
- var request = new ToolsHandlePendingToolCallRequest { SessionId = _sessionId, RequestId = requestId, Result = result, Error = error };
- return await CopilotClient.InvokeRpcAsync(_rpc, "session.tools.handlePendingToolCall", [request], cancellationToken);
+ var request = new HandlePendingToolCallRequest { SessionId = _sessionId, RequestId = requestId, Result = result, Error = error };
+ return await CopilotClient.InvokeRpcAsync(_rpc, "session.tools.handlePendingToolCall", [request], cancellationToken);
}
}
@@ -4190,7 +4245,8 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, FuncWhen true, tool calls and permission requests left in flight by the previous session lifetime remain pending after resume and the agentic loop awaits their results. User sends are queued behind the pending work until all such requests reach a terminal state. When false (the default), any such tool calls and permission requests are immediately marked as interrupted on resume.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("continuePendingWork")]
+ public bool? ContinuePendingWork { get; set; }
+
/// Total number of persisted events in the session at the time of resume.
[JsonPropertyName("eventCount")]
public required double EventCount { get; set; }
@@ -1214,6 +1219,11 @@ public partial class SessionResumeData
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("selectedModel")]
public string? SelectedModel { get; set; }
+
+ /// True when this resume attached to a session that the runtime already had running in-memory (for example, an extension joining a session another client was actively driving). False (or omitted) for cold resumes — the runtime had to reconstitute the session from its persisted event log.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sessionWasActive")]
+ public bool? SessionWasActive { get; set; }
}
/// Notifies Mission Control that the session's remote steering capability has changed.
@@ -1517,6 +1527,11 @@ public partial class SessionShutdownData
[JsonPropertyName("systemTokens")]
public double? SystemTokens { get; set; }
+ /// Session-wide per-token-type accumulated token counts.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("tokenDetails")]
+ public IDictionary? TokenDetails { get; set; }
+
/// Tool definitions token count at shutdown.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("toolDefinitionsTokens")]
@@ -1526,6 +1541,11 @@ public partial class SessionShutdownData
[JsonPropertyName("totalApiDurationMs")]
public required double TotalApiDurationMs { get; set; }
+ /// Session-wide accumulated nano-AI units cost.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("totalNanoAiu")]
+ public double? TotalNanoAiu { get; set; }
+
/// Total number of premium API requests used during the session.
[JsonPropertyName("totalPremiumRequests")]
public required double TotalPremiumRequests { get; set; }
@@ -1748,6 +1768,11 @@ public partial class UserMessageData
[JsonPropertyName("nativeDocumentPathFallbackPaths")]
public string[]? NativeDocumentPathFallbackPaths { get; set; }
+ /// Parent agent task ID for background telemetry correlated to this user turn.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("parentAgentTaskId")]
+ public string? ParentAgentTaskId { get; set; }
+
/// Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user).
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("source")]
@@ -1878,6 +1903,11 @@ public partial class AssistantMessageData
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("toolRequests")]
public AssistantMessageToolRequest[]? ToolRequests { get; set; }
+
+ /// Identifier for the agent loop turn that produced this message, matching the corresponding assistant.turn_start event.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("turnId")]
+ public string? TurnId { get; set; }
}
/// Streaming assistant message delta for incremental response updates.
@@ -2094,6 +2124,11 @@ public partial class ToolExecutionStartData
/// Name of the tool being executed.
[JsonPropertyName("toolName")]
public required string ToolName { get; set; }
+
+ /// Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("turnId")]
+ public string? TurnId { get; set; }
}
/// Streaming tool execution output for incremental result display.
@@ -2166,6 +2201,11 @@ public partial class ToolExecutionCompleteData
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("toolTelemetry")]
public IDictionary? ToolTelemetry { get; set; }
+
+ /// Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("turnId")]
+ public string? TurnId { get; set; }
}
/// Skill invocation details including content, allowed tools, and plugin metadata.
@@ -2429,7 +2469,7 @@ public partial class PermissionCompletedData
/// The result of the permission request.
[JsonPropertyName("result")]
- public required PermissionCompletedResult Result { get; set; }
+ public required PermissionResult Result { get; set; }
/// Optional tool call ID associated with this permission prompt; clients may use it to correlate UI created from tool-scoped prompts.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -2929,6 +2969,14 @@ public partial class ShutdownModelMetricRequests
public required double Count { get; set; }
}
+/// Nested data type for ShutdownModelMetricTokenDetail.
+public partial class ShutdownModelMetricTokenDetail
+{
+ /// Accumulated token count for this token type.
+ [JsonPropertyName("tokenCount")]
+ public required double TokenCount { get; set; }
+}
+
/// Token usage breakdown.
/// Nested data type for ShutdownModelMetricUsage.
public partial class ShutdownModelMetricUsage
@@ -2962,11 +3010,29 @@ public partial class ShutdownModelMetric
[JsonPropertyName("requests")]
public required ShutdownModelMetricRequests Requests { get; set; }
+ /// Token count details per type.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("tokenDetails")]
+ public IDictionary? TokenDetails { get; set; }
+
+ /// Accumulated nano-AI units cost for this model.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("totalNanoAiu")]
+ public double? TotalNanoAiu { get; set; }
+
/// Token usage breakdown.
[JsonPropertyName("usage")]
public required ShutdownModelMetricUsage Usage { get; set; }
}
+/// Nested data type for ShutdownTokenDetail.
+public partial class ShutdownTokenDetail
+{
+ /// Accumulated token count for this token type.
+ [JsonPropertyName("tokenCount")]
+ public required double TokenCount { get; set; }
+}
+
/// Token usage detail for a single billing category.
/// Nested data type for CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail.
public partial class CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail
@@ -2996,7 +3062,7 @@ public partial class CompactionCompleteCompactionTokensUsedCopilotUsage
[JsonPropertyName("tokenDetails")]
public required CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail[] TokenDetails { get; set; }
- /// Total cost in nano-AIU (AI Units) for this request.
+ /// Total cost in nano-AI units for this request.
[JsonPropertyName("totalNanoAiu")]
public required double TotalNanoAiu { get; set; }
}
@@ -3294,7 +3360,7 @@ public partial class AssistantUsageCopilotUsage
[JsonPropertyName("tokenDetails")]
public required AssistantUsageCopilotUsageTokenDetail[] TokenDetails { get; set; }
- /// Total cost in nano-AIU (AI Units) for this request.
+ /// Total cost in nano-AI units for this request.
[JsonPropertyName("totalNanoAiu")]
public required double TotalNanoAiu { get; set; }
}
@@ -4313,15 +4379,244 @@ public partial class PermissionPromptRequest
}
+/// The approved variant of .
+public partial class PermissionResultApproved : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "approved";
+}
+
+/// The commands variant of .
+public partial class UserToolSessionApprovalCommands : UserToolSessionApproval
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "commands";
+
+ /// Command identifiers approved by the user.
+ [JsonPropertyName("commandIdentifiers")]
+ public required string[] CommandIdentifiers { get; set; }
+}
+
+/// The read variant of .
+public partial class UserToolSessionApprovalRead : UserToolSessionApproval
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "read";
+}
+
+/// The write variant of .
+public partial class UserToolSessionApprovalWrite : UserToolSessionApproval
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "write";
+}
+
+/// The mcp variant of .
+public partial class UserToolSessionApprovalMcp : UserToolSessionApproval
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "mcp";
+
+ /// MCP server name.
+ [JsonPropertyName("serverName")]
+ public required string ServerName { get; set; }
+
+ /// Optional MCP tool name, or null for all tools on the server.
+ [JsonPropertyName("toolName")]
+ public string? ToolName { get; set; }
+}
+
+/// The memory variant of .
+public partial class UserToolSessionApprovalMemory : UserToolSessionApproval
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "memory";
+}
+
+/// The custom-tool variant of .
+public partial class UserToolSessionApprovalCustomTool : UserToolSessionApproval
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "custom-tool";
+
+ /// Custom tool name.
+ [JsonPropertyName("toolName")]
+ public required string ToolName { get; set; }
+}
+
+/// The approval to add as a session-scoped rule.
+/// Polymorphic base type discriminated by kind.
+[JsonPolymorphic(
+ TypeDiscriminatorPropertyName = "kind",
+ UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
+[JsonDerivedType(typeof(UserToolSessionApprovalCommands), "commands")]
+[JsonDerivedType(typeof(UserToolSessionApprovalRead), "read")]
+[JsonDerivedType(typeof(UserToolSessionApprovalWrite), "write")]
+[JsonDerivedType(typeof(UserToolSessionApprovalMcp), "mcp")]
+[JsonDerivedType(typeof(UserToolSessionApprovalMemory), "memory")]
+[JsonDerivedType(typeof(UserToolSessionApprovalCustomTool), "custom-tool")]
+public partial class UserToolSessionApproval
+{
+ /// The type discriminator.
+ [JsonPropertyName("kind")]
+ public virtual string Kind { get; set; } = string.Empty;
+}
+
+
+/// The approved-for-session variant of .
+public partial class PermissionResultApprovedForSession : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "approved-for-session";
+
+ /// The approval to add as a session-scoped rule.
+ [JsonPropertyName("approval")]
+ public required UserToolSessionApproval Approval { get; set; }
+}
+
+/// The approved-for-location variant of .
+public partial class PermissionResultApprovedForLocation : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "approved-for-location";
+
+ /// The approval to persist for this location.
+ [JsonPropertyName("approval")]
+ public required UserToolSessionApproval Approval { get; set; }
+
+ /// The location key (git root or cwd) to persist the approval to.
+ [JsonPropertyName("locationKey")]
+ public required string LocationKey { get; set; }
+}
+
+/// The cancelled variant of .
+public partial class PermissionResultCancelled : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "cancelled";
+
+ /// Optional explanation of why the request was cancelled.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("reason")]
+ public string? Reason { get; set; }
+}
+
+/// Nested data type for PermissionRule.
+public partial class PermissionRule
+{
+ /// Optional rule argument matched against the request.
+ [JsonPropertyName("argument")]
+ public string? Argument { get; set; }
+
+ /// The rule kind, such as Shell or GitHubMCP.
+ [JsonPropertyName("kind")]
+ public required string Kind { get; set; }
+}
+
+/// The denied-by-rules variant of .
+public partial class PermissionResultDeniedByRules : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "denied-by-rules";
+
+ /// Rules that denied the request.
+ [JsonPropertyName("rules")]
+ public required PermissionRule[] Rules { get; set; }
+}
+
+/// The denied-no-approval-rule-and-could-not-request-from-user variant of .
+public partial class PermissionResultDeniedNoApprovalRuleAndCouldNotRequestFromUser : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "denied-no-approval-rule-and-could-not-request-from-user";
+}
+
+/// The denied-interactively-by-user variant of .
+public partial class PermissionResultDeniedInteractivelyByUser : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "denied-interactively-by-user";
+
+ /// Optional feedback from the user explaining the denial.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("feedback")]
+ public string? Feedback { get; set; }
+
+ /// Whether to force-reject the current agent turn.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("forceReject")]
+ public bool? ForceReject { get; set; }
+}
+
+/// The denied-by-content-exclusion-policy variant of .
+public partial class PermissionResultDeniedByContentExclusionPolicy : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "denied-by-content-exclusion-policy";
+
+ /// Human-readable explanation of why the path was excluded.
+ [JsonPropertyName("message")]
+ public required string Message { get; set; }
+
+ /// File path that triggered the exclusion.
+ [JsonPropertyName("path")]
+ public required string Path { get; set; }
+}
+
+/// The denied-by-permission-request-hook variant of .
+public partial class PermissionResultDeniedByPermissionRequestHook : PermissionResult
+{
+ ///
+ [JsonIgnore]
+ public override string Kind => "denied-by-permission-request-hook";
+
+ /// Whether to interrupt the current agent turn.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("interrupt")]
+ public bool? Interrupt { get; set; }
+
+ /// Optional message from the hook explaining the denial.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("message")]
+ public string? Message { get; set; }
+}
+
/// The result of the permission request.
-/// Nested data type for PermissionCompletedResult.
-public partial class PermissionCompletedResult
+/// Polymorphic base type discriminated by kind.
+[JsonPolymorphic(
+ TypeDiscriminatorPropertyName = "kind",
+ UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
+[JsonDerivedType(typeof(PermissionResultApproved), "approved")]
+[JsonDerivedType(typeof(PermissionResultApprovedForSession), "approved-for-session")]
+[JsonDerivedType(typeof(PermissionResultApprovedForLocation), "approved-for-location")]
+[JsonDerivedType(typeof(PermissionResultCancelled), "cancelled")]
+[JsonDerivedType(typeof(PermissionResultDeniedByRules), "denied-by-rules")]
+[JsonDerivedType(typeof(PermissionResultDeniedNoApprovalRuleAndCouldNotRequestFromUser), "denied-no-approval-rule-and-could-not-request-from-user")]
+[JsonDerivedType(typeof(PermissionResultDeniedInteractivelyByUser), "denied-interactively-by-user")]
+[JsonDerivedType(typeof(PermissionResultDeniedByContentExclusionPolicy), "denied-by-content-exclusion-policy")]
+[JsonDerivedType(typeof(PermissionResultDeniedByPermissionRequestHook), "denied-by-permission-request-hook")]
+public partial class PermissionResult
{
- /// The outcome of the permission request.
+ /// The type discriminator.
[JsonPropertyName("kind")]
- public required PermissionCompletedKind Kind { get; set; }
+ public virtual string Kind { get; set; } = string.Empty;
}
+
/// JSON Schema describing the form fields to present to the user (form mode only).
/// Nested data type for ElicitationRequestedSchema.
public partial class ElicitationRequestedSchema
@@ -4707,36 +5002,6 @@ public enum PermissionPromptRequestPathAccessKind
Write,
}
-/// The outcome of the permission request.
-[JsonConverter(typeof(JsonStringEnumConverter))]
-public enum PermissionCompletedKind
-{
- /// The approved variant.
- [JsonStringEnumMemberName("approved")]
- Approved,
- /// The approved-for-session variant.
- [JsonStringEnumMemberName("approved-for-session")]
- ApprovedForSession,
- /// The approved-for-location variant.
- [JsonStringEnumMemberName("approved-for-location")]
- ApprovedForLocation,
- /// The denied-by-rules variant.
- [JsonStringEnumMemberName("denied-by-rules")]
- DeniedByRules,
- /// The denied-no-approval-rule-and-could-not-request-from-user variant.
- [JsonStringEnumMemberName("denied-no-approval-rule-and-could-not-request-from-user")]
- DeniedNoApprovalRuleAndCouldNotRequestFromUser,
- /// The denied-interactively-by-user variant.
- [JsonStringEnumMemberName("denied-interactively-by-user")]
- DeniedInteractivelyByUser,
- /// The denied-by-content-exclusion-policy variant.
- [JsonStringEnumMemberName("denied-by-content-exclusion-policy")]
- DeniedByContentExclusionPolicy,
- /// The denied-by-permission-request-hook variant.
- [JsonStringEnumMemberName("denied-by-permission-request-hook")]
- DeniedByPermissionRequestHook,
-}
-
/// Elicitation mode; "form" for structured input, "url" for browser-based. Defaults to "form" when absent.
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ElicitationRequestedMode
@@ -4923,7 +5188,6 @@ public enum ExtensionsLoadedExtensionStatus
[JsonSerializable(typeof(PendingMessagesModifiedEvent))]
[JsonSerializable(typeof(PermissionCompletedData))]
[JsonSerializable(typeof(PermissionCompletedEvent))]
-[JsonSerializable(typeof(PermissionCompletedResult))]
[JsonSerializable(typeof(PermissionPromptRequest))]
[JsonSerializable(typeof(PermissionPromptRequestCommands))]
[JsonSerializable(typeof(PermissionPromptRequestCustomTool))]
@@ -4947,6 +5211,17 @@ public enum ExtensionsLoadedExtensionStatus
[JsonSerializable(typeof(PermissionRequestWrite))]
[JsonSerializable(typeof(PermissionRequestedData))]
[JsonSerializable(typeof(PermissionRequestedEvent))]
+[JsonSerializable(typeof(PermissionResult))]
+[JsonSerializable(typeof(PermissionResultApproved))]
+[JsonSerializable(typeof(PermissionResultApprovedForLocation))]
+[JsonSerializable(typeof(PermissionResultApprovedForSession))]
+[JsonSerializable(typeof(PermissionResultCancelled))]
+[JsonSerializable(typeof(PermissionResultDeniedByContentExclusionPolicy))]
+[JsonSerializable(typeof(PermissionResultDeniedByPermissionRequestHook))]
+[JsonSerializable(typeof(PermissionResultDeniedByRules))]
+[JsonSerializable(typeof(PermissionResultDeniedInteractivelyByUser))]
+[JsonSerializable(typeof(PermissionResultDeniedNoApprovalRuleAndCouldNotRequestFromUser))]
+[JsonSerializable(typeof(PermissionRule))]
[JsonSerializable(typeof(SamplingCompletedData))]
[JsonSerializable(typeof(SamplingCompletedEvent))]
[JsonSerializable(typeof(SamplingRequestedData))]
@@ -5011,7 +5286,9 @@ public enum ExtensionsLoadedExtensionStatus
[JsonSerializable(typeof(ShutdownCodeChanges))]
[JsonSerializable(typeof(ShutdownModelMetric))]
[JsonSerializable(typeof(ShutdownModelMetricRequests))]
+[JsonSerializable(typeof(ShutdownModelMetricTokenDetail))]
[JsonSerializable(typeof(ShutdownModelMetricUsage))]
+[JsonSerializable(typeof(ShutdownTokenDetail))]
[JsonSerializable(typeof(SkillInvokedData))]
[JsonSerializable(typeof(SkillInvokedEvent))]
[JsonSerializable(typeof(SkillsLoadedSkill))]
@@ -5073,6 +5350,13 @@ public enum ExtensionsLoadedExtensionStatus
[JsonSerializable(typeof(UserMessageAttachmentSelectionDetailsStart))]
[JsonSerializable(typeof(UserMessageData))]
[JsonSerializable(typeof(UserMessageEvent))]
+[JsonSerializable(typeof(UserToolSessionApproval))]
+[JsonSerializable(typeof(UserToolSessionApprovalCommands))]
+[JsonSerializable(typeof(UserToolSessionApprovalCustomTool))]
+[JsonSerializable(typeof(UserToolSessionApprovalMcp))]
+[JsonSerializable(typeof(UserToolSessionApprovalMemory))]
+[JsonSerializable(typeof(UserToolSessionApprovalRead))]
+[JsonSerializable(typeof(UserToolSessionApprovalWrite))]
[JsonSerializable(typeof(WorkingDirectoryContext))]
[JsonSerializable(typeof(JsonElement))]
internal partial class SessionEventsJsonContext : JsonSerializerContext;
\ No newline at end of file
diff --git a/go/generated_session_events.go b/go/generated_session_events.go
index c9fb889a2..5fd844aae 100644
--- a/go/generated_session_events.go
+++ b/go/generated_session_events.go
@@ -694,6 +694,8 @@ type AssistantMessageData struct {
RequestID *string `json:"requestId,omitempty"`
// Tool invocations requested by the assistant in this message
ToolRequests []AssistantMessageToolRequest `json:"toolRequests,omitempty"`
+ // Identifier for the agent loop turn that produced this message, matching the corresponding assistant.turn_start event
+ TurnID *string `json:"turnId,omitempty"`
}
func (*AssistantMessageData) sessionEventData() {}
@@ -1080,7 +1082,7 @@ type PermissionCompletedData struct {
// Request ID of the resolved permission request; clients should dismiss any UI for this request
RequestID string `json:"requestId"`
// The result of the permission request
- Result PermissionCompletedResult `json:"result"`
+ Result PermissionResult `json:"result"`
// Optional tool call ID associated with this permission prompt; clients may use it to correlate UI created from tool-scoped prompts
ToolCallID *string `json:"toolCallId,omitempty"`
}
@@ -1261,6 +1263,8 @@ type SessionResumeData struct {
AlreadyInUse *bool `json:"alreadyInUse,omitempty"`
// Updated working directory and git context at resume time
Context *WorkingDirectoryContext `json:"context,omitempty"`
+ // When true, tool calls and permission requests left in flight by the previous session lifetime remain pending after resume and the agentic loop awaits their results. User sends are queued behind the pending work until all such requests reach a terminal state. When false (the default), any such tool calls and permission requests are immediately marked as interrupted on resume.
+ ContinuePendingWork *bool `json:"continuePendingWork,omitempty"`
// Total number of persisted events in the session at the time of resume
EventCount float64 `json:"eventCount"`
// Reasoning effort level used for model calls, if applicable (e.g. "low", "medium", "high", "xhigh")
@@ -1271,6 +1275,8 @@ type SessionResumeData struct {
ResumeTime time.Time `json:"resumeTime"`
// Model currently selected at resume time
SelectedModel *string `json:"selectedModel,omitempty"`
+ // True when this resume attached to a session that the runtime already had running in-memory (for example, an extension joining a session another client was actively driving). False (or omitted) for cold resumes — the runtime had to reconstitute the session from its persisted event log.
+ SessionWasActive *bool `json:"sessionWasActive,omitempty"`
}
func (*SessionResumeData) sessionEventData() {}
@@ -1305,10 +1311,14 @@ type SessionShutdownData struct {
ShutdownType ShutdownType `json:"shutdownType"`
// System message token count at shutdown
SystemTokens *float64 `json:"systemTokens,omitempty"`
+ // Session-wide per-token-type accumulated token counts
+ TokenDetails map[string]ShutdownTokenDetail `json:"tokenDetails,omitempty"`
// Tool definitions token count at shutdown
ToolDefinitionsTokens *float64 `json:"toolDefinitionsTokens,omitempty"`
// Cumulative time spent in API calls during the session, in milliseconds
TotalAPIDurationMs float64 `json:"totalApiDurationMs"`
+ // Session-wide accumulated nano-AI units cost
+ TotalNanoAiu *float64 `json:"totalNanoAiu,omitempty"`
// Total number of premium API requests used during the session
TotalPremiumRequests float64 `json:"totalPremiumRequests"`
}
@@ -1554,6 +1564,8 @@ type ToolExecutionCompleteData struct {
ToolCallID string `json:"toolCallId"`
// Tool-specific telemetry data (e.g., CodeQL check counts, grep match counts)
ToolTelemetry map[string]any `json:"toolTelemetry,omitempty"`
+ // Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event
+ TurnID *string `json:"turnId,omitempty"`
}
func (*ToolExecutionCompleteData) sessionEventData() {}
@@ -1583,6 +1595,8 @@ type ToolExecutionStartData struct {
ToolCallID string `json:"toolCallId"`
// Name of the tool being executed
ToolName string `json:"toolName"`
+ // Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event
+ TurnID *string `json:"turnId,omitempty"`
}
func (*ToolExecutionStartData) sessionEventData() {}
@@ -1665,6 +1679,8 @@ type UserMessageData struct {
InteractionID *string `json:"interactionId,omitempty"`
// Path-backed native document attachments that stayed on the tagged_files path flow because native upload would exceed the request size limit
NativeDocumentPathFallbackPaths []string `json:"nativeDocumentPathFallbackPaths,omitempty"`
+ // Parent agent task ID for background telemetry correlated to this user turn
+ ParentAgentTaskID *string `json:"parentAgentTaskId,omitempty"`
// Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user)
Source *string `json:"source,omitempty"`
// Normalized document MIME types that were sent natively instead of through tagged_files XML
@@ -1995,7 +2011,7 @@ type UserMessageAttachmentFileLineRange struct {
type AssistantUsageCopilotUsage struct {
// Itemized token usage breakdown
TokenDetails []AssistantUsageCopilotUsageTokenDetail `json:"tokenDetails"`
- // Total cost in nano-AIU (AI Units) for this request
+ // Total cost in nano-AI units for this request
TotalNanoAiu float64 `json:"totalNanoAiu"`
}
@@ -2003,7 +2019,7 @@ type AssistantUsageCopilotUsage struct {
type CompactionCompleteCompactionTokensUsedCopilotUsage struct {
// Itemized token usage breakdown
TokenDetails []CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail `json:"tokenDetails"`
- // Total cost in nano-AIU (AI Units) for this request
+ // Total cost in nano-AI units for this request
TotalNanoAiu float64 `json:"totalNanoAiu"`
}
@@ -2083,10 +2099,40 @@ type SystemNotification struct {
TriggerTool *string `json:"triggerTool,omitempty"`
}
+// The approval to add as a session-scoped rule
+type UserToolSessionApproval struct {
+ // Kind discriminator
+ Kind UserToolSessionApprovalKind `json:"kind"`
+ // Command identifiers approved by the user
+ CommandIdentifiers []string `json:"commandIdentifiers,omitempty"`
+ // MCP server name
+ ServerName *string `json:"serverName,omitempty"`
+ // Optional MCP tool name, or null for all tools on the server
+ ToolName *string `json:"toolName,omitempty"`
+}
+
// The result of the permission request
-type PermissionCompletedResult struct {
- // The outcome of the permission request
- Kind PermissionCompletedKind `json:"kind"`
+type PermissionResult struct {
+ // Kind discriminator
+ Kind PermissionResultKind `json:"kind"`
+ // The approval to add as a session-scoped rule
+ Approval *UserToolSessionApproval `json:"approval,omitempty"`
+ // Optional feedback from the user explaining the denial
+ Feedback *string `json:"feedback,omitempty"`
+ // Whether to force-reject the current agent turn
+ ForceReject *bool `json:"forceReject,omitempty"`
+ // Whether to interrupt the current agent turn
+ Interrupt *bool `json:"interrupt,omitempty"`
+ // The location key (git root or cwd) to persist the approval to
+ LocationKey *string `json:"locationKey,omitempty"`
+ // Human-readable explanation of why the path was excluded
+ Message *string `json:"message,omitempty"`
+ // File path that triggered the exclusion
+ Path *string `json:"path,omitempty"`
+ // Optional explanation of why the request was cancelled
+ Reason *string `json:"reason,omitempty"`
+ // Rules that denied the request
+ Rules []PermissionRule `json:"rules,omitempty"`
}
// Token usage breakdown
@@ -2258,13 +2304,34 @@ type PermissionRequestShellPossibleURL struct {
URL string `json:"url"`
}
+type PermissionRule struct {
+ // Optional rule argument matched against the request
+ Argument *string `json:"argument"`
+ // The rule kind, such as Shell or GitHubMCP
+ Kind string `json:"kind"`
+}
+
type ShutdownModelMetric struct {
// Request count and cost metrics
Requests ShutdownModelMetricRequests `json:"requests"`
+ // Token count details per type
+ TokenDetails map[string]ShutdownModelMetricTokenDetail `json:"tokenDetails,omitempty"`
+ // Accumulated nano-AI units cost for this model
+ TotalNanoAiu *float64 `json:"totalNanoAiu,omitempty"`
// Token usage breakdown
Usage ShutdownModelMetricUsage `json:"usage"`
}
+type ShutdownModelMetricTokenDetail struct {
+ // Accumulated token count for this token type
+ TokenCount float64 `json:"tokenCount"`
+}
+
+type ShutdownTokenDetail struct {
+ // Accumulated token count for this token type
+ TokenCount float64 `json:"tokenCount"`
+}
+
type SkillsLoadedSkill struct {
// Description of what the skill does
Description string `json:"description"`
@@ -2355,6 +2422,33 @@ const (
PermissionRequestKindHook PermissionRequestKind = "hook"
)
+// Kind discriminator for PermissionResult.
+type PermissionResultKind string
+
+const (
+ PermissionResultKindApproved PermissionResultKind = "approved"
+ PermissionResultKindApprovedForSession PermissionResultKind = "approved-for-session"
+ PermissionResultKindApprovedForLocation PermissionResultKind = "approved-for-location"
+ PermissionResultKindCancelled PermissionResultKind = "cancelled"
+ PermissionResultKindDeniedByRules PermissionResultKind = "denied-by-rules"
+ PermissionResultKindDeniedNoApprovalRuleAndCouldNotRequestFromUser PermissionResultKind = "denied-no-approval-rule-and-could-not-request-from-user"
+ PermissionResultKindDeniedInteractivelyByUser PermissionResultKind = "denied-interactively-by-user"
+ PermissionResultKindDeniedByContentExclusionPolicy PermissionResultKind = "denied-by-content-exclusion-policy"
+ PermissionResultKindDeniedByPermissionRequestHook PermissionResultKind = "denied-by-permission-request-hook"
+)
+
+// Kind discriminator for UserToolSessionApproval.
+type UserToolSessionApprovalKind string
+
+const (
+ UserToolSessionApprovalKindCommands UserToolSessionApprovalKind = "commands"
+ UserToolSessionApprovalKindRead UserToolSessionApprovalKind = "read"
+ UserToolSessionApprovalKindWrite UserToolSessionApprovalKind = "write"
+ UserToolSessionApprovalKindMcp UserToolSessionApprovalKind = "mcp"
+ UserToolSessionApprovalKindMemory UserToolSessionApprovalKind = "memory"
+ UserToolSessionApprovalKindCustomTool UserToolSessionApprovalKind = "custom-tool"
+)
+
// Message role: "system" for system prompts, "developer" for developer-injected instructions
type SystemMessageRole string
@@ -2393,20 +2487,6 @@ const (
UserMessageAgentModeShell UserMessageAgentMode = "shell"
)
-// The outcome of the permission request
-type PermissionCompletedKind string
-
-const (
- PermissionCompletedKindApproved PermissionCompletedKind = "approved"
- PermissionCompletedKindApprovedForSession PermissionCompletedKind = "approved-for-session"
- PermissionCompletedKindApprovedForLocation PermissionCompletedKind = "approved-for-location"
- PermissionCompletedKindDeniedByRules PermissionCompletedKind = "denied-by-rules"
- PermissionCompletedKindDeniedNoApprovalRuleAndCouldNotRequestFromUser PermissionCompletedKind = "denied-no-approval-rule-and-could-not-request-from-user"
- PermissionCompletedKindDeniedInteractivelyByUser PermissionCompletedKind = "denied-interactively-by-user"
- PermissionCompletedKindDeniedByContentExclusionPolicy PermissionCompletedKind = "denied-by-content-exclusion-policy"
- PermissionCompletedKindDeniedByPermissionRequestHook PermissionCompletedKind = "denied-by-permission-request-hook"
-)
-
// The type of operation performed on the plan file
type PlanChangedOperation string
diff --git a/go/rpc/generated_rpc.go b/go/rpc/generated_rpc.go
index 311081247..c56418a24 100644
--- a/go/rpc/generated_rpc.go
+++ b/go/rpc/generated_rpc.go
@@ -13,233 +13,248 @@ import (
)
type RPCTypes struct {
- AccountGetQuotaRequest AccountGetQuotaRequest `json:"AccountGetQuotaRequest"`
- AccountGetQuotaResult AccountGetQuotaResult `json:"AccountGetQuotaResult"`
- AccountQuotaSnapshot AccountQuotaSnapshot `json:"AccountQuotaSnapshot"`
- AgentDeselectResult AgentDeselectResult `json:"AgentDeselectResult"`
- AgentGetCurrentResult AgentGetCurrentResult `json:"AgentGetCurrentResult"`
- AgentInfo AgentInfo `json:"AgentInfo"`
- AgentList AgentList `json:"AgentList"`
- AgentReloadResult AgentReloadResult `json:"AgentReloadResult"`
- AgentSelectRequest AgentSelectRequest `json:"AgentSelectRequest"`
- AgentSelectResult AgentSelectResult `json:"AgentSelectResult"`
- AuthInfoType AuthInfoType `json:"AuthInfoType"`
- CommandsHandlePendingCommandRequest CommandsHandlePendingCommandRequest `json:"CommandsHandlePendingCommandRequest"`
- CommandsHandlePendingCommandResult CommandsHandlePendingCommandResult `json:"CommandsHandlePendingCommandResult"`
- CurrentModel CurrentModel `json:"CurrentModel"`
- DiscoveredMCPServer DiscoveredMCPServer `json:"DiscoveredMcpServer"`
- DiscoveredMCPServerSource MCPServerSource `json:"DiscoveredMcpServerSource"`
- DiscoveredMCPServerType DiscoveredMCPServerType `json:"DiscoveredMcpServerType"`
- Extension Extension `json:"Extension"`
- ExtensionList ExtensionList `json:"ExtensionList"`
- ExtensionsDisableRequest ExtensionsDisableRequest `json:"ExtensionsDisableRequest"`
- ExtensionsDisableResult ExtensionsDisableResult `json:"ExtensionsDisableResult"`
- ExtensionsEnableRequest ExtensionsEnableRequest `json:"ExtensionsEnableRequest"`
- ExtensionsEnableResult ExtensionsEnableResult `json:"ExtensionsEnableResult"`
- ExtensionSource ExtensionSource `json:"ExtensionSource"`
- ExtensionsReloadResult ExtensionsReloadResult `json:"ExtensionsReloadResult"`
- ExtensionStatus ExtensionStatus `json:"ExtensionStatus"`
- FilterMapping *FilterMapping `json:"FilterMapping"`
- FilterMappingString FilterMappingString `json:"FilterMappingString"`
- FilterMappingValue FilterMappingString `json:"FilterMappingValue"`
- FleetStartRequest FleetStartRequest `json:"FleetStartRequest"`
- FleetStartResult FleetStartResult `json:"FleetStartResult"`
- HandleToolCallResult HandleToolCallResult `json:"HandleToolCallResult"`
- HistoryCompactContextWindow HistoryCompactContextWindow `json:"HistoryCompactContextWindow"`
- HistoryCompactResult HistoryCompactResult `json:"HistoryCompactResult"`
- HistoryTruncateRequest HistoryTruncateRequest `json:"HistoryTruncateRequest"`
- HistoryTruncateResult HistoryTruncateResult `json:"HistoryTruncateResult"`
- InstructionsGetSourcesResult InstructionsGetSourcesResult `json:"InstructionsGetSourcesResult"`
- InstructionsSources InstructionsSources `json:"InstructionsSources"`
- InstructionsSourcesLocation InstructionsSourcesLocation `json:"InstructionsSourcesLocation"`
- InstructionsSourcesType InstructionsSourcesType `json:"InstructionsSourcesType"`
- LogRequest LogRequest `json:"LogRequest"`
- LogResult LogResult `json:"LogResult"`
- MCPConfigAddRequest MCPConfigAddRequest `json:"McpConfigAddRequest"`
- MCPConfigAddResult MCPConfigAddResult `json:"McpConfigAddResult"`
- MCPConfigDisableRequest MCPConfigDisableRequest `json:"McpConfigDisableRequest"`
- MCPConfigDisableResult MCPConfigDisableResult `json:"McpConfigDisableResult"`
- MCPConfigEnableRequest MCPConfigEnableRequest `json:"McpConfigEnableRequest"`
- MCPConfigEnableResult MCPConfigEnableResult `json:"McpConfigEnableResult"`
- MCPConfigList MCPConfigList `json:"McpConfigList"`
- MCPConfigRemoveRequest MCPConfigRemoveRequest `json:"McpConfigRemoveRequest"`
- MCPConfigRemoveResult MCPConfigRemoveResult `json:"McpConfigRemoveResult"`
- MCPConfigUpdateRequest MCPConfigUpdateRequest `json:"McpConfigUpdateRequest"`
- MCPConfigUpdateResult MCPConfigUpdateResult `json:"McpConfigUpdateResult"`
- MCPDisableRequest MCPDisableRequest `json:"McpDisableRequest"`
- MCPDisableResult MCPDisableResult `json:"McpDisableResult"`
- MCPDiscoverRequest MCPDiscoverRequest `json:"McpDiscoverRequest"`
- MCPDiscoverResult MCPDiscoverResult `json:"McpDiscoverResult"`
- MCPEnableRequest MCPEnableRequest `json:"McpEnableRequest"`
- MCPEnableResult MCPEnableResult `json:"McpEnableResult"`
- MCPOauthLoginRequest MCPOauthLoginRequest `json:"McpOauthLoginRequest"`
- MCPOauthLoginResult MCPOauthLoginResult `json:"McpOauthLoginResult"`
- MCPReloadResult MCPReloadResult `json:"McpReloadResult"`
- MCPServer MCPServer `json:"McpServer"`
- MCPServerConfig MCPServerConfig `json:"McpServerConfig"`
- MCPServerConfigHTTP MCPServerConfigHTTP `json:"McpServerConfigHttp"`
- MCPServerConfigHTTPType MCPServerConfigHTTPType `json:"McpServerConfigHttpType"`
- MCPServerConfigLocal MCPServerConfigLocal `json:"McpServerConfigLocal"`
- MCPServerConfigLocalType MCPServerConfigLocalType `json:"McpServerConfigLocalType"`
- MCPServerList MCPServerList `json:"McpServerList"`
- MCPServerSource MCPServerSource `json:"McpServerSource"`
- MCPServerStatus MCPServerStatus `json:"McpServerStatus"`
- Model ModelElement `json:"Model"`
- ModelBilling ModelBilling `json:"ModelBilling"`
- ModelCapabilities ModelCapabilities `json:"ModelCapabilities"`
- ModelCapabilitiesLimits ModelCapabilitiesLimits `json:"ModelCapabilitiesLimits"`
- ModelCapabilitiesLimitsVision ModelCapabilitiesLimitsVision `json:"ModelCapabilitiesLimitsVision"`
- ModelCapabilitiesOverride ModelCapabilitiesOverride `json:"ModelCapabilitiesOverride"`
- ModelCapabilitiesOverrideLimits ModelCapabilitiesOverrideLimits `json:"ModelCapabilitiesOverrideLimits"`
- ModelCapabilitiesOverrideLimitsVision ModelCapabilitiesOverrideLimitsVision `json:"ModelCapabilitiesOverrideLimitsVision"`
- ModelCapabilitiesOverrideSupports ModelCapabilitiesOverrideSupports `json:"ModelCapabilitiesOverrideSupports"`
- ModelCapabilitiesSupports ModelCapabilitiesSupports `json:"ModelCapabilitiesSupports"`
- ModelList ModelList `json:"ModelList"`
- ModelPolicy ModelPolicy `json:"ModelPolicy"`
- ModelsListRequest ModelsListRequest `json:"ModelsListRequest"`
- ModelSwitchToRequest ModelSwitchToRequest `json:"ModelSwitchToRequest"`
- ModelSwitchToResult ModelSwitchToResult `json:"ModelSwitchToResult"`
- ModeSetRequest ModeSetRequest `json:"ModeSetRequest"`
- ModeSetResult ModeSetResult `json:"ModeSetResult"`
- NameGetResult NameGetResult `json:"NameGetResult"`
- NameSetRequest NameSetRequest `json:"NameSetRequest"`
- NameSetResult NameSetResult `json:"NameSetResult"`
- PermissionDecision PermissionDecision `json:"PermissionDecision"`
- PermissionDecisionApproveForLocation PermissionDecisionApproveForLocation `json:"PermissionDecisionApproveForLocation"`
- PermissionDecisionApproveForLocationApproval PermissionDecisionApproveForLocationApproval `json:"PermissionDecisionApproveForLocationApproval"`
- PermissionDecisionApproveForLocationApprovalCommands PermissionDecisionApproveForLocationApprovalCommands `json:"PermissionDecisionApproveForLocationApprovalCommands"`
- PermissionDecisionApproveForLocationApprovalCustomTool PermissionDecisionApproveForLocationApprovalCustomTool `json:"PermissionDecisionApproveForLocationApprovalCustomTool"`
- PermissionDecisionApproveForLocationApprovalMCP PermissionDecisionApproveForLocationApprovalMCP `json:"PermissionDecisionApproveForLocationApprovalMcp"`
- PermissionDecisionApproveForLocationApprovalMCPSampling PermissionDecisionApproveForLocationApprovalMCPSampling `json:"PermissionDecisionApproveForLocationApprovalMcpSampling"`
- PermissionDecisionApproveForLocationApprovalMemory PermissionDecisionApproveForLocationApprovalMemory `json:"PermissionDecisionApproveForLocationApprovalMemory"`
- PermissionDecisionApproveForLocationApprovalRead PermissionDecisionApproveForLocationApprovalRead `json:"PermissionDecisionApproveForLocationApprovalRead"`
- PermissionDecisionApproveForLocationApprovalWrite PermissionDecisionApproveForLocationApprovalWrite `json:"PermissionDecisionApproveForLocationApprovalWrite"`
- PermissionDecisionApproveForSession PermissionDecisionApproveForSession `json:"PermissionDecisionApproveForSession"`
- PermissionDecisionApproveForSessionApproval PermissionDecisionApproveForSessionApproval `json:"PermissionDecisionApproveForSessionApproval"`
- PermissionDecisionApproveForSessionApprovalCommands PermissionDecisionApproveForSessionApprovalCommands `json:"PermissionDecisionApproveForSessionApprovalCommands"`
- PermissionDecisionApproveForSessionApprovalCustomTool PermissionDecisionApproveForSessionApprovalCustomTool `json:"PermissionDecisionApproveForSessionApprovalCustomTool"`
- PermissionDecisionApproveForSessionApprovalMCP PermissionDecisionApproveForSessionApprovalMCP `json:"PermissionDecisionApproveForSessionApprovalMcp"`
- PermissionDecisionApproveForSessionApprovalMCPSampling PermissionDecisionApproveForSessionApprovalMCPSampling `json:"PermissionDecisionApproveForSessionApprovalMcpSampling"`
- PermissionDecisionApproveForSessionApprovalMemory PermissionDecisionApproveForSessionApprovalMemory `json:"PermissionDecisionApproveForSessionApprovalMemory"`
- PermissionDecisionApproveForSessionApprovalRead PermissionDecisionApproveForSessionApprovalRead `json:"PermissionDecisionApproveForSessionApprovalRead"`
- PermissionDecisionApproveForSessionApprovalWrite PermissionDecisionApproveForSessionApprovalWrite `json:"PermissionDecisionApproveForSessionApprovalWrite"`
- PermissionDecisionApproveOnce PermissionDecisionApproveOnce `json:"PermissionDecisionApproveOnce"`
- PermissionDecisionReject PermissionDecisionReject `json:"PermissionDecisionReject"`
- PermissionDecisionRequest PermissionDecisionRequest `json:"PermissionDecisionRequest"`
- PermissionDecisionUserNotAvailable PermissionDecisionUserNotAvailable `json:"PermissionDecisionUserNotAvailable"`
- PermissionRequestResult PermissionRequestResult `json:"PermissionRequestResult"`
- PermissionsResetSessionApprovalsRequest PermissionsResetSessionApprovalsRequest `json:"PermissionsResetSessionApprovalsRequest"`
- PermissionsResetSessionApprovalsResult PermissionsResetSessionApprovalsResult `json:"PermissionsResetSessionApprovalsResult"`
- PermissionsSetApproveAllRequest PermissionsSetApproveAllRequest `json:"PermissionsSetApproveAllRequest"`
- PermissionsSetApproveAllResult PermissionsSetApproveAllResult `json:"PermissionsSetApproveAllResult"`
- PingRequest PingRequest `json:"PingRequest"`
- PingResult PingResult `json:"PingResult"`
- PlanDeleteResult PlanDeleteResult `json:"PlanDeleteResult"`
- PlanReadResult PlanReadResult `json:"PlanReadResult"`
- PlanUpdateRequest PlanUpdateRequest `json:"PlanUpdateRequest"`
- PlanUpdateResult PlanUpdateResult `json:"PlanUpdateResult"`
- Plugin PluginElement `json:"Plugin"`
- PluginList PluginList `json:"PluginList"`
- ServerSkill ServerSkill `json:"ServerSkill"`
- ServerSkillList ServerSkillList `json:"ServerSkillList"`
- SessionAuthStatus SessionAuthStatus `json:"SessionAuthStatus"`
- SessionFSAppendFileRequest SessionFSAppendFileRequest `json:"SessionFsAppendFileRequest"`
- SessionFSError SessionFSError `json:"SessionFsError"`
- SessionFSErrorCode SessionFSErrorCode `json:"SessionFsErrorCode"`
- SessionFSExistsRequest SessionFSExistsRequest `json:"SessionFsExistsRequest"`
- SessionFSExistsResult SessionFSExistsResult `json:"SessionFsExistsResult"`
- SessionFSMkdirRequest SessionFSMkdirRequest `json:"SessionFsMkdirRequest"`
- SessionFSReaddirRequest SessionFSReaddirRequest `json:"SessionFsReaddirRequest"`
- SessionFSReaddirResult SessionFSReaddirResult `json:"SessionFsReaddirResult"`
- SessionFSReaddirWithTypesEntry SessionFSReaddirWithTypesEntry `json:"SessionFsReaddirWithTypesEntry"`
- SessionFSReaddirWithTypesEntryType SessionFSReaddirWithTypesEntryType `json:"SessionFsReaddirWithTypesEntryType"`
- SessionFSReaddirWithTypesRequest SessionFSReaddirWithTypesRequest `json:"SessionFsReaddirWithTypesRequest"`
- SessionFSReaddirWithTypesResult SessionFSReaddirWithTypesResult `json:"SessionFsReaddirWithTypesResult"`
- SessionFSReadFileRequest SessionFSReadFileRequest `json:"SessionFsReadFileRequest"`
- SessionFSReadFileResult SessionFSReadFileResult `json:"SessionFsReadFileResult"`
- SessionFSRenameRequest SessionFSRenameRequest `json:"SessionFsRenameRequest"`
- SessionFSRmRequest SessionFSRmRequest `json:"SessionFsRmRequest"`
- SessionFSSetProviderConventions SessionFSSetProviderConventions `json:"SessionFsSetProviderConventions"`
- SessionFSSetProviderRequest SessionFSSetProviderRequest `json:"SessionFsSetProviderRequest"`
- SessionFSSetProviderResult SessionFSSetProviderResult `json:"SessionFsSetProviderResult"`
- SessionFSStatRequest SessionFSStatRequest `json:"SessionFsStatRequest"`
- SessionFSStatResult SessionFSStatResult `json:"SessionFsStatResult"`
- SessionFSWriteFileRequest SessionFSWriteFileRequest `json:"SessionFsWriteFileRequest"`
- SessionLogLevel SessionLogLevel `json:"SessionLogLevel"`
- SessionMode SessionMode `json:"SessionMode"`
- SessionsForkRequest SessionsForkRequest `json:"SessionsForkRequest"`
- SessionsForkResult SessionsForkResult `json:"SessionsForkResult"`
- ShellExecRequest ShellExecRequest `json:"ShellExecRequest"`
- ShellExecResult ShellExecResult `json:"ShellExecResult"`
- ShellKillRequest ShellKillRequest `json:"ShellKillRequest"`
- ShellKillResult ShellKillResult `json:"ShellKillResult"`
- ShellKillSignal ShellKillSignal `json:"ShellKillSignal"`
- Skill Skill `json:"Skill"`
- SkillList SkillList `json:"SkillList"`
- SkillsConfigSetDisabledSkillsRequest SkillsConfigSetDisabledSkillsRequest `json:"SkillsConfigSetDisabledSkillsRequest"`
- SkillsConfigSetDisabledSkillsResult SkillsConfigSetDisabledSkillsResult `json:"SkillsConfigSetDisabledSkillsResult"`
- SkillsDisableRequest SkillsDisableRequest `json:"SkillsDisableRequest"`
- SkillsDisableResult SkillsDisableResult `json:"SkillsDisableResult"`
- SkillsDiscoverRequest SkillsDiscoverRequest `json:"SkillsDiscoverRequest"`
- SkillsEnableRequest SkillsEnableRequest `json:"SkillsEnableRequest"`
- SkillsEnableResult SkillsEnableResult `json:"SkillsEnableResult"`
- SkillsReloadResult SkillsReloadResult `json:"SkillsReloadResult"`
- TaskAgentInfo TaskAgentInfo `json:"TaskAgentInfo"`
- TaskAgentInfoExecutionMode TaskInfoExecutionMode `json:"TaskAgentInfoExecutionMode"`
- TaskAgentInfoStatus TaskInfoStatus `json:"TaskAgentInfoStatus"`
- TaskInfo TaskInfo `json:"TaskInfo"`
- TaskList TaskList `json:"TaskList"`
- TasksCancelRequest TasksCancelRequest `json:"TasksCancelRequest"`
- TasksCancelResult TasksCancelResult `json:"TasksCancelResult"`
- TaskShellInfo TaskShellInfo `json:"TaskShellInfo"`
- TaskShellInfoAttachmentMode TaskShellInfoAttachmentMode `json:"TaskShellInfoAttachmentMode"`
- TaskShellInfoExecutionMode TaskInfoExecutionMode `json:"TaskShellInfoExecutionMode"`
- TaskShellInfoStatus TaskInfoStatus `json:"TaskShellInfoStatus"`
- TasksPromoteToBackgroundRequest TasksPromoteToBackgroundRequest `json:"TasksPromoteToBackgroundRequest"`
- TasksPromoteToBackgroundResult TasksPromoteToBackgroundResult `json:"TasksPromoteToBackgroundResult"`
- TasksRemoveRequest TasksRemoveRequest `json:"TasksRemoveRequest"`
- TasksRemoveResult TasksRemoveResult `json:"TasksRemoveResult"`
- TasksStartAgentRequest TasksStartAgentRequest `json:"TasksStartAgentRequest"`
- TasksStartAgentResult TasksStartAgentResult `json:"TasksStartAgentResult"`
- Tool Tool `json:"Tool"`
- ToolCallResult ToolCallResult `json:"ToolCallResult"`
- ToolList ToolList `json:"ToolList"`
- ToolsHandlePendingToolCall *ToolsHandlePendingToolCall `json:"ToolsHandlePendingToolCall"`
- ToolsHandlePendingToolCallRequest ToolsHandlePendingToolCallRequest `json:"ToolsHandlePendingToolCallRequest"`
- ToolsListRequest ToolsListRequest `json:"ToolsListRequest"`
- UIElicitationArrayAnyOfField UIElicitationArrayAnyOfField `json:"UIElicitationArrayAnyOfField"`
- UIElicitationArrayAnyOfFieldItems UIElicitationArrayAnyOfFieldItems `json:"UIElicitationArrayAnyOfFieldItems"`
- UIElicitationArrayAnyOfFieldItemsAnyOf UIElicitationArrayAnyOfFieldItemsAnyOf `json:"UIElicitationArrayAnyOfFieldItemsAnyOf"`
- UIElicitationArrayEnumField UIElicitationArrayEnumField `json:"UIElicitationArrayEnumField"`
- UIElicitationArrayEnumFieldItems UIElicitationArrayEnumFieldItems `json:"UIElicitationArrayEnumFieldItems"`
- UIElicitationFieldValue *UIElicitationFieldValue `json:"UIElicitationFieldValue"`
- UIElicitationRequest UIElicitationRequest `json:"UIElicitationRequest"`
- UIElicitationResponse UIElicitationResponse `json:"UIElicitationResponse"`
- UIElicitationResponseAction UIElicitationResponseAction `json:"UIElicitationResponseAction"`
- UIElicitationResponseContent map[string]*UIElicitationFieldValue `json:"UIElicitationResponseContent"`
- UIElicitationResult UIElicitationResult `json:"UIElicitationResult"`
- UIElicitationSchema UIElicitationSchema `json:"UIElicitationSchema"`
- UIElicitationSchemaProperty UIElicitationSchemaProperty `json:"UIElicitationSchemaProperty"`
- UIElicitationSchemaPropertyBoolean UIElicitationSchemaPropertyBoolean `json:"UIElicitationSchemaPropertyBoolean"`
- UIElicitationSchemaPropertyNumber UIElicitationSchemaPropertyNumber `json:"UIElicitationSchemaPropertyNumber"`
- UIElicitationSchemaPropertyNumberType UIElicitationSchemaPropertyNumberTypeEnum `json:"UIElicitationSchemaPropertyNumberType"`
- UIElicitationSchemaPropertyString UIElicitationSchemaPropertyString `json:"UIElicitationSchemaPropertyString"`
- UIElicitationSchemaPropertyStringFormat UIElicitationSchemaPropertyStringFormat `json:"UIElicitationSchemaPropertyStringFormat"`
- UIElicitationStringEnumField UIElicitationStringEnumField `json:"UIElicitationStringEnumField"`
- UIElicitationStringOneOfField UIElicitationStringOneOfField `json:"UIElicitationStringOneOfField"`
- UIElicitationStringOneOfFieldOneOf UIElicitationStringOneOfFieldOneOf `json:"UIElicitationStringOneOfFieldOneOf"`
- UIHandlePendingElicitationRequest UIHandlePendingElicitationRequest `json:"UIHandlePendingElicitationRequest"`
- UsageGetMetricsResult UsageGetMetricsResult `json:"UsageGetMetricsResult"`
- UsageMetricsCodeChanges UsageMetricsCodeChanges `json:"UsageMetricsCodeChanges"`
- UsageMetricsModelMetric UsageMetricsModelMetric `json:"UsageMetricsModelMetric"`
- UsageMetricsModelMetricRequests UsageMetricsModelMetricRequests `json:"UsageMetricsModelMetricRequests"`
- UsageMetricsModelMetricUsage UsageMetricsModelMetricUsage `json:"UsageMetricsModelMetricUsage"`
- WorkspacesCreateFileRequest WorkspacesCreateFileRequest `json:"WorkspacesCreateFileRequest"`
- WorkspacesCreateFileResult WorkspacesCreateFileResult `json:"WorkspacesCreateFileResult"`
- WorkspacesGetWorkspaceResult WorkspacesGetWorkspaceResult `json:"WorkspacesGetWorkspaceResult"`
- WorkspacesListFilesResult WorkspacesListFilesResult `json:"WorkspacesListFilesResult"`
- WorkspacesReadFileRequest WorkspacesReadFileRequest `json:"WorkspacesReadFileRequest"`
- WorkspacesReadFileResult WorkspacesReadFileResult `json:"WorkspacesReadFileResult"`
+ AccountGetQuotaRequest AccountGetQuotaRequest `json:"AccountGetQuotaRequest"`
+ AccountGetQuotaResult AccountGetQuotaResult `json:"AccountGetQuotaResult"`
+ AccountQuotaSnapshot AccountQuotaSnapshot `json:"AccountQuotaSnapshot"`
+ AgentDeselectResult AgentDeselectResult `json:"AgentDeselectResult"`
+ AgentGetCurrentResult AgentGetCurrentResult `json:"AgentGetCurrentResult"`
+ AgentInfo AgentInfo `json:"AgentInfo"`
+ AgentList AgentList `json:"AgentList"`
+ AgentReloadResult AgentReloadResult `json:"AgentReloadResult"`
+ AgentSelectRequest AgentSelectRequest `json:"AgentSelectRequest"`
+ AgentSelectResult AgentSelectResult `json:"AgentSelectResult"`
+ AuthInfoType AuthInfoType `json:"AuthInfoType"`
+ CommandsHandlePendingCommandRequest CommandsHandlePendingCommandRequest `json:"CommandsHandlePendingCommandRequest"`
+ CommandsHandlePendingCommandResult CommandsHandlePendingCommandResult `json:"CommandsHandlePendingCommandResult"`
+ CurrentModel CurrentModel `json:"CurrentModel"`
+ DiscoveredMCPServer DiscoveredMCPServer `json:"DiscoveredMcpServer"`
+ DiscoveredMCPServerSource MCPServerSource `json:"DiscoveredMcpServerSource"`
+ DiscoveredMCPServerType DiscoveredMCPServerType `json:"DiscoveredMcpServerType"`
+ EmbeddedBlobResourceContents EmbeddedBlobResourceContents `json:"EmbeddedBlobResourceContents"`
+ EmbeddedTextResourceContents EmbeddedTextResourceContents `json:"EmbeddedTextResourceContents"`
+ Extension Extension `json:"Extension"`
+ ExtensionList ExtensionList `json:"ExtensionList"`
+ ExtensionsDisableRequest ExtensionsDisableRequest `json:"ExtensionsDisableRequest"`
+ ExtensionsDisableResult ExtensionsDisableResult `json:"ExtensionsDisableResult"`
+ ExtensionsEnableRequest ExtensionsEnableRequest `json:"ExtensionsEnableRequest"`
+ ExtensionsEnableResult ExtensionsEnableResult `json:"ExtensionsEnableResult"`
+ ExtensionSource ExtensionSource `json:"ExtensionSource"`
+ ExtensionsReloadResult ExtensionsReloadResult `json:"ExtensionsReloadResult"`
+ ExtensionStatus ExtensionStatus `json:"ExtensionStatus"`
+ ExternalToolResult *ExternalToolResult `json:"ExternalToolResult"`
+ ExternalToolTextResultForLlm ExternalToolTextResultForLlm `json:"ExternalToolTextResultForLlm"`
+ ExternalToolTextResultForLlmContent ExternalToolTextResultForLlmContent `json:"ExternalToolTextResultForLlmContent"`
+ ExternalToolTextResultForLlmContentAudio ExternalToolTextResultForLlmContentAudio `json:"ExternalToolTextResultForLlmContentAudio"`
+ ExternalToolTextResultForLlmContentImage ExternalToolTextResultForLlmContentImage `json:"ExternalToolTextResultForLlmContentImage"`
+ ExternalToolTextResultForLlmContentResource ExternalToolTextResultForLlmContentResource `json:"ExternalToolTextResultForLlmContentResource"`
+ ExternalToolTextResultForLlmContentResourceDetails ExternalToolTextResultForLlmContentResourceDetails `json:"ExternalToolTextResultForLlmContentResourceDetails"`
+ ExternalToolTextResultForLlmContentResourceLink ExternalToolTextResultForLlmContentResourceLink `json:"ExternalToolTextResultForLlmContentResourceLink"`
+ ExternalToolTextResultForLlmContentResourceLinkIcon ExternalToolTextResultForLlmContentResourceLinkIcon `json:"ExternalToolTextResultForLlmContentResourceLinkIcon"`
+ ExternalToolTextResultForLlmContentResourceLinkIconTheme ExternalToolTextResultForLlmContentResourceLinkIconTheme `json:"ExternalToolTextResultForLlmContentResourceLinkIconTheme"`
+ ExternalToolTextResultForLlmContentTerminal ExternalToolTextResultForLlmContentTerminal `json:"ExternalToolTextResultForLlmContentTerminal"`
+ ExternalToolTextResultForLlmContentText ExternalToolTextResultForLlmContentText `json:"ExternalToolTextResultForLlmContentText"`
+ FilterMapping *FilterMapping `json:"FilterMapping"`
+ FilterMappingString FilterMappingString `json:"FilterMappingString"`
+ FilterMappingValue FilterMappingString `json:"FilterMappingValue"`
+ FleetStartRequest FleetStartRequest `json:"FleetStartRequest"`
+ FleetStartResult FleetStartResult `json:"FleetStartResult"`
+ HandlePendingToolCallRequest HandlePendingToolCallRequest `json:"HandlePendingToolCallRequest"`
+ HandlePendingToolCallResult HandlePendingToolCallResult `json:"HandlePendingToolCallResult"`
+ HistoryCompactContextWindow HistoryCompactContextWindow `json:"HistoryCompactContextWindow"`
+ HistoryCompactResult HistoryCompactResult `json:"HistoryCompactResult"`
+ HistoryTruncateRequest HistoryTruncateRequest `json:"HistoryTruncateRequest"`
+ HistoryTruncateResult HistoryTruncateResult `json:"HistoryTruncateResult"`
+ InstructionsGetSourcesResult InstructionsGetSourcesResult `json:"InstructionsGetSourcesResult"`
+ InstructionsSources InstructionsSources `json:"InstructionsSources"`
+ InstructionsSourcesLocation InstructionsSourcesLocation `json:"InstructionsSourcesLocation"`
+ InstructionsSourcesType InstructionsSourcesType `json:"InstructionsSourcesType"`
+ LogRequest LogRequest `json:"LogRequest"`
+ LogResult LogResult `json:"LogResult"`
+ MCPConfigAddRequest MCPConfigAddRequest `json:"McpConfigAddRequest"`
+ MCPConfigAddResult MCPConfigAddResult `json:"McpConfigAddResult"`
+ MCPConfigDisableRequest MCPConfigDisableRequest `json:"McpConfigDisableRequest"`
+ MCPConfigDisableResult MCPConfigDisableResult `json:"McpConfigDisableResult"`
+ MCPConfigEnableRequest MCPConfigEnableRequest `json:"McpConfigEnableRequest"`
+ MCPConfigEnableResult MCPConfigEnableResult `json:"McpConfigEnableResult"`
+ MCPConfigList MCPConfigList `json:"McpConfigList"`
+ MCPConfigRemoveRequest MCPConfigRemoveRequest `json:"McpConfigRemoveRequest"`
+ MCPConfigRemoveResult MCPConfigRemoveResult `json:"McpConfigRemoveResult"`
+ MCPConfigUpdateRequest MCPConfigUpdateRequest `json:"McpConfigUpdateRequest"`
+ MCPConfigUpdateResult MCPConfigUpdateResult `json:"McpConfigUpdateResult"`
+ MCPDisableRequest MCPDisableRequest `json:"McpDisableRequest"`
+ MCPDisableResult MCPDisableResult `json:"McpDisableResult"`
+ MCPDiscoverRequest MCPDiscoverRequest `json:"McpDiscoverRequest"`
+ MCPDiscoverResult MCPDiscoverResult `json:"McpDiscoverResult"`
+ MCPEnableRequest MCPEnableRequest `json:"McpEnableRequest"`
+ MCPEnableResult MCPEnableResult `json:"McpEnableResult"`
+ MCPOauthLoginRequest MCPOauthLoginRequest `json:"McpOauthLoginRequest"`
+ MCPOauthLoginResult MCPOauthLoginResult `json:"McpOauthLoginResult"`
+ MCPReloadResult MCPReloadResult `json:"McpReloadResult"`
+ MCPServer MCPServer `json:"McpServer"`
+ MCPServerConfig MCPServerConfig `json:"McpServerConfig"`
+ MCPServerConfigHTTP MCPServerConfigHTTP `json:"McpServerConfigHttp"`
+ MCPServerConfigHTTPType MCPServerConfigHTTPType `json:"McpServerConfigHttpType"`
+ MCPServerConfigLocal MCPServerConfigLocal `json:"McpServerConfigLocal"`
+ MCPServerConfigLocalType MCPServerConfigLocalType `json:"McpServerConfigLocalType"`
+ MCPServerList MCPServerList `json:"McpServerList"`
+ MCPServerSource MCPServerSource `json:"McpServerSource"`
+ MCPServerStatus MCPServerStatus `json:"McpServerStatus"`
+ Model ModelElement `json:"Model"`
+ ModelBilling ModelBilling `json:"ModelBilling"`
+ ModelCapabilities ModelCapabilities `json:"ModelCapabilities"`
+ ModelCapabilitiesLimits ModelCapabilitiesLimits `json:"ModelCapabilitiesLimits"`
+ ModelCapabilitiesLimitsVision ModelCapabilitiesLimitsVision `json:"ModelCapabilitiesLimitsVision"`
+ ModelCapabilitiesOverride ModelCapabilitiesOverride `json:"ModelCapabilitiesOverride"`
+ ModelCapabilitiesOverrideLimits ModelCapabilitiesOverrideLimits `json:"ModelCapabilitiesOverrideLimits"`
+ ModelCapabilitiesOverrideLimitsVision ModelCapabilitiesOverrideLimitsVision `json:"ModelCapabilitiesOverrideLimitsVision"`
+ ModelCapabilitiesOverrideSupports ModelCapabilitiesOverrideSupports `json:"ModelCapabilitiesOverrideSupports"`
+ ModelCapabilitiesSupports ModelCapabilitiesSupports `json:"ModelCapabilitiesSupports"`
+ ModelList ModelList `json:"ModelList"`
+ ModelPolicy ModelPolicy `json:"ModelPolicy"`
+ ModelsListRequest ModelsListRequest `json:"ModelsListRequest"`
+ ModelSwitchToRequest ModelSwitchToRequest `json:"ModelSwitchToRequest"`
+ ModelSwitchToResult ModelSwitchToResult `json:"ModelSwitchToResult"`
+ ModeSetRequest ModeSetRequest `json:"ModeSetRequest"`
+ ModeSetResult ModeSetResult `json:"ModeSetResult"`
+ NameGetResult NameGetResult `json:"NameGetResult"`
+ NameSetRequest NameSetRequest `json:"NameSetRequest"`
+ NameSetResult NameSetResult `json:"NameSetResult"`
+ PermissionDecision PermissionDecision `json:"PermissionDecision"`
+ PermissionDecisionApproveForLocation PermissionDecisionApproveForLocation `json:"PermissionDecisionApproveForLocation"`
+ PermissionDecisionApproveForLocationApproval PermissionDecisionApproveForLocationApproval `json:"PermissionDecisionApproveForLocationApproval"`
+ PermissionDecisionApproveForLocationApprovalCommands PermissionDecisionApproveForLocationApprovalCommands `json:"PermissionDecisionApproveForLocationApprovalCommands"`
+ PermissionDecisionApproveForLocationApprovalCustomTool PermissionDecisionApproveForLocationApprovalCustomTool `json:"PermissionDecisionApproveForLocationApprovalCustomTool"`
+ PermissionDecisionApproveForLocationApprovalMCP PermissionDecisionApproveForLocationApprovalMCP `json:"PermissionDecisionApproveForLocationApprovalMcp"`
+ PermissionDecisionApproveForLocationApprovalMCPSampling PermissionDecisionApproveForLocationApprovalMCPSampling `json:"PermissionDecisionApproveForLocationApprovalMcpSampling"`
+ PermissionDecisionApproveForLocationApprovalMemory PermissionDecisionApproveForLocationApprovalMemory `json:"PermissionDecisionApproveForLocationApprovalMemory"`
+ PermissionDecisionApproveForLocationApprovalRead PermissionDecisionApproveForLocationApprovalRead `json:"PermissionDecisionApproveForLocationApprovalRead"`
+ PermissionDecisionApproveForLocationApprovalWrite PermissionDecisionApproveForLocationApprovalWrite `json:"PermissionDecisionApproveForLocationApprovalWrite"`
+ PermissionDecisionApproveForSession PermissionDecisionApproveForSession `json:"PermissionDecisionApproveForSession"`
+ PermissionDecisionApproveForSessionApproval PermissionDecisionApproveForSessionApproval `json:"PermissionDecisionApproveForSessionApproval"`
+ PermissionDecisionApproveForSessionApprovalCommands PermissionDecisionApproveForSessionApprovalCommands `json:"PermissionDecisionApproveForSessionApprovalCommands"`
+ PermissionDecisionApproveForSessionApprovalCustomTool PermissionDecisionApproveForSessionApprovalCustomTool `json:"PermissionDecisionApproveForSessionApprovalCustomTool"`
+ PermissionDecisionApproveForSessionApprovalMCP PermissionDecisionApproveForSessionApprovalMCP `json:"PermissionDecisionApproveForSessionApprovalMcp"`
+ PermissionDecisionApproveForSessionApprovalMCPSampling PermissionDecisionApproveForSessionApprovalMCPSampling `json:"PermissionDecisionApproveForSessionApprovalMcpSampling"`
+ PermissionDecisionApproveForSessionApprovalMemory PermissionDecisionApproveForSessionApprovalMemory `json:"PermissionDecisionApproveForSessionApprovalMemory"`
+ PermissionDecisionApproveForSessionApprovalRead PermissionDecisionApproveForSessionApprovalRead `json:"PermissionDecisionApproveForSessionApprovalRead"`
+ PermissionDecisionApproveForSessionApprovalWrite PermissionDecisionApproveForSessionApprovalWrite `json:"PermissionDecisionApproveForSessionApprovalWrite"`
+ PermissionDecisionApproveOnce PermissionDecisionApproveOnce `json:"PermissionDecisionApproveOnce"`
+ PermissionDecisionApprovePermanently PermissionDecisionApprovePermanently `json:"PermissionDecisionApprovePermanently"`
+ PermissionDecisionReject PermissionDecisionReject `json:"PermissionDecisionReject"`
+ PermissionDecisionRequest PermissionDecisionRequest `json:"PermissionDecisionRequest"`
+ PermissionDecisionUserNotAvailable PermissionDecisionUserNotAvailable `json:"PermissionDecisionUserNotAvailable"`
+ PermissionRequestResult PermissionRequestResult `json:"PermissionRequestResult"`
+ PermissionsResetSessionApprovalsRequest PermissionsResetSessionApprovalsRequest `json:"PermissionsResetSessionApprovalsRequest"`
+ PermissionsResetSessionApprovalsResult PermissionsResetSessionApprovalsResult `json:"PermissionsResetSessionApprovalsResult"`
+ PermissionsSetApproveAllRequest PermissionsSetApproveAllRequest `json:"PermissionsSetApproveAllRequest"`
+ PermissionsSetApproveAllResult PermissionsSetApproveAllResult `json:"PermissionsSetApproveAllResult"`
+ PingRequest PingRequest `json:"PingRequest"`
+ PingResult PingResult `json:"PingResult"`
+ PlanDeleteResult PlanDeleteResult `json:"PlanDeleteResult"`
+ PlanReadResult PlanReadResult `json:"PlanReadResult"`
+ PlanUpdateRequest PlanUpdateRequest `json:"PlanUpdateRequest"`
+ PlanUpdateResult PlanUpdateResult `json:"PlanUpdateResult"`
+ Plugin PluginElement `json:"Plugin"`
+ PluginList PluginList `json:"PluginList"`
+ ServerSkill ServerSkill `json:"ServerSkill"`
+ ServerSkillList ServerSkillList `json:"ServerSkillList"`
+ SessionAuthStatus SessionAuthStatus `json:"SessionAuthStatus"`
+ SessionFSAppendFileRequest SessionFSAppendFileRequest `json:"SessionFsAppendFileRequest"`
+ SessionFSError SessionFSError `json:"SessionFsError"`
+ SessionFSErrorCode SessionFSErrorCode `json:"SessionFsErrorCode"`
+ SessionFSExistsRequest SessionFSExistsRequest `json:"SessionFsExistsRequest"`
+ SessionFSExistsResult SessionFSExistsResult `json:"SessionFsExistsResult"`
+ SessionFSMkdirRequest SessionFSMkdirRequest `json:"SessionFsMkdirRequest"`
+ SessionFSReaddirRequest SessionFSReaddirRequest `json:"SessionFsReaddirRequest"`
+ SessionFSReaddirResult SessionFSReaddirResult `json:"SessionFsReaddirResult"`
+ SessionFSReaddirWithTypesEntry SessionFSReaddirWithTypesEntry `json:"SessionFsReaddirWithTypesEntry"`
+ SessionFSReaddirWithTypesEntryType SessionFSReaddirWithTypesEntryType `json:"SessionFsReaddirWithTypesEntryType"`
+ SessionFSReaddirWithTypesRequest SessionFSReaddirWithTypesRequest `json:"SessionFsReaddirWithTypesRequest"`
+ SessionFSReaddirWithTypesResult SessionFSReaddirWithTypesResult `json:"SessionFsReaddirWithTypesResult"`
+ SessionFSReadFileRequest SessionFSReadFileRequest `json:"SessionFsReadFileRequest"`
+ SessionFSReadFileResult SessionFSReadFileResult `json:"SessionFsReadFileResult"`
+ SessionFSRenameRequest SessionFSRenameRequest `json:"SessionFsRenameRequest"`
+ SessionFSRmRequest SessionFSRmRequest `json:"SessionFsRmRequest"`
+ SessionFSSetProviderConventions SessionFSSetProviderConventions `json:"SessionFsSetProviderConventions"`
+ SessionFSSetProviderRequest SessionFSSetProviderRequest `json:"SessionFsSetProviderRequest"`
+ SessionFSSetProviderResult SessionFSSetProviderResult `json:"SessionFsSetProviderResult"`
+ SessionFSStatRequest SessionFSStatRequest `json:"SessionFsStatRequest"`
+ SessionFSStatResult SessionFSStatResult `json:"SessionFsStatResult"`
+ SessionFSWriteFileRequest SessionFSWriteFileRequest `json:"SessionFsWriteFileRequest"`
+ SessionLogLevel SessionLogLevel `json:"SessionLogLevel"`
+ SessionMode SessionMode `json:"SessionMode"`
+ SessionsForkRequest SessionsForkRequest `json:"SessionsForkRequest"`
+ SessionsForkResult SessionsForkResult `json:"SessionsForkResult"`
+ ShellExecRequest ShellExecRequest `json:"ShellExecRequest"`
+ ShellExecResult ShellExecResult `json:"ShellExecResult"`
+ ShellKillRequest ShellKillRequest `json:"ShellKillRequest"`
+ ShellKillResult ShellKillResult `json:"ShellKillResult"`
+ ShellKillSignal ShellKillSignal `json:"ShellKillSignal"`
+ Skill Skill `json:"Skill"`
+ SkillList SkillList `json:"SkillList"`
+ SkillsConfigSetDisabledSkillsRequest SkillsConfigSetDisabledSkillsRequest `json:"SkillsConfigSetDisabledSkillsRequest"`
+ SkillsConfigSetDisabledSkillsResult SkillsConfigSetDisabledSkillsResult `json:"SkillsConfigSetDisabledSkillsResult"`
+ SkillsDisableRequest SkillsDisableRequest `json:"SkillsDisableRequest"`
+ SkillsDisableResult SkillsDisableResult `json:"SkillsDisableResult"`
+ SkillsDiscoverRequest SkillsDiscoverRequest `json:"SkillsDiscoverRequest"`
+ SkillsEnableRequest SkillsEnableRequest `json:"SkillsEnableRequest"`
+ SkillsEnableResult SkillsEnableResult `json:"SkillsEnableResult"`
+ SkillsReloadResult SkillsReloadResult `json:"SkillsReloadResult"`
+ TaskAgentInfo TaskAgentInfo `json:"TaskAgentInfo"`
+ TaskAgentInfoExecutionMode TaskInfoExecutionMode `json:"TaskAgentInfoExecutionMode"`
+ TaskAgentInfoStatus TaskInfoStatus `json:"TaskAgentInfoStatus"`
+ TaskInfo TaskInfo `json:"TaskInfo"`
+ TaskList TaskList `json:"TaskList"`
+ TasksCancelRequest TasksCancelRequest `json:"TasksCancelRequest"`
+ TasksCancelResult TasksCancelResult `json:"TasksCancelResult"`
+ TaskShellInfo TaskShellInfo `json:"TaskShellInfo"`
+ TaskShellInfoAttachmentMode TaskShellInfoAttachmentMode `json:"TaskShellInfoAttachmentMode"`
+ TaskShellInfoExecutionMode TaskInfoExecutionMode `json:"TaskShellInfoExecutionMode"`
+ TaskShellInfoStatus TaskInfoStatus `json:"TaskShellInfoStatus"`
+ TasksPromoteToBackgroundRequest TasksPromoteToBackgroundRequest `json:"TasksPromoteToBackgroundRequest"`
+ TasksPromoteToBackgroundResult TasksPromoteToBackgroundResult `json:"TasksPromoteToBackgroundResult"`
+ TasksRemoveRequest TasksRemoveRequest `json:"TasksRemoveRequest"`
+ TasksRemoveResult TasksRemoveResult `json:"TasksRemoveResult"`
+ TasksStartAgentRequest TasksStartAgentRequest `json:"TasksStartAgentRequest"`
+ TasksStartAgentResult TasksStartAgentResult `json:"TasksStartAgentResult"`
+ Tool Tool `json:"Tool"`
+ ToolList ToolList `json:"ToolList"`
+ ToolsListRequest ToolsListRequest `json:"ToolsListRequest"`
+ UIElicitationArrayAnyOfField UIElicitationArrayAnyOfField `json:"UIElicitationArrayAnyOfField"`
+ UIElicitationArrayAnyOfFieldItems UIElicitationArrayAnyOfFieldItems `json:"UIElicitationArrayAnyOfFieldItems"`
+ UIElicitationArrayAnyOfFieldItemsAnyOf UIElicitationArrayAnyOfFieldItemsAnyOf `json:"UIElicitationArrayAnyOfFieldItemsAnyOf"`
+ UIElicitationArrayEnumField UIElicitationArrayEnumField `json:"UIElicitationArrayEnumField"`
+ UIElicitationArrayEnumFieldItems UIElicitationArrayEnumFieldItems `json:"UIElicitationArrayEnumFieldItems"`
+ UIElicitationFieldValue *UIElicitationFieldValue `json:"UIElicitationFieldValue"`
+ UIElicitationRequest UIElicitationRequest `json:"UIElicitationRequest"`
+ UIElicitationResponse UIElicitationResponse `json:"UIElicitationResponse"`
+ UIElicitationResponseAction UIElicitationResponseAction `json:"UIElicitationResponseAction"`
+ UIElicitationResponseContent map[string]*UIElicitationFieldValue `json:"UIElicitationResponseContent"`
+ UIElicitationResult UIElicitationResult `json:"UIElicitationResult"`
+ UIElicitationSchema UIElicitationSchema `json:"UIElicitationSchema"`
+ UIElicitationSchemaProperty UIElicitationSchemaProperty `json:"UIElicitationSchemaProperty"`
+ UIElicitationSchemaPropertyBoolean UIElicitationSchemaPropertyBoolean `json:"UIElicitationSchemaPropertyBoolean"`
+ UIElicitationSchemaPropertyNumber UIElicitationSchemaPropertyNumber `json:"UIElicitationSchemaPropertyNumber"`
+ UIElicitationSchemaPropertyNumberType UIElicitationSchemaPropertyNumberTypeEnum `json:"UIElicitationSchemaPropertyNumberType"`
+ UIElicitationSchemaPropertyString UIElicitationSchemaPropertyString `json:"UIElicitationSchemaPropertyString"`
+ UIElicitationSchemaPropertyStringFormat UIElicitationSchemaPropertyStringFormat `json:"UIElicitationSchemaPropertyStringFormat"`
+ UIElicitationStringEnumField UIElicitationStringEnumField `json:"UIElicitationStringEnumField"`
+ UIElicitationStringOneOfField UIElicitationStringOneOfField `json:"UIElicitationStringOneOfField"`
+ UIElicitationStringOneOfFieldOneOf UIElicitationStringOneOfFieldOneOf `json:"UIElicitationStringOneOfFieldOneOf"`
+ UIHandlePendingElicitationRequest UIHandlePendingElicitationRequest `json:"UIHandlePendingElicitationRequest"`
+ UsageGetMetricsResult UsageGetMetricsResult `json:"UsageGetMetricsResult"`
+ UsageMetricsCodeChanges UsageMetricsCodeChanges `json:"UsageMetricsCodeChanges"`
+ UsageMetricsModelMetric UsageMetricsModelMetric `json:"UsageMetricsModelMetric"`
+ UsageMetricsModelMetricRequests UsageMetricsModelMetricRequests `json:"UsageMetricsModelMetricRequests"`
+ UsageMetricsModelMetricTokenDetail UsageMetricsModelMetricTokenDetail `json:"UsageMetricsModelMetricTokenDetail"`
+ UsageMetricsModelMetricUsage UsageMetricsModelMetricUsage `json:"UsageMetricsModelMetricUsage"`
+ UsageMetricsTokenDetail UsageMetricsTokenDetail `json:"UsageMetricsTokenDetail"`
+ WorkspacesCreateFileRequest WorkspacesCreateFileRequest `json:"WorkspacesCreateFileRequest"`
+ WorkspacesCreateFileResult WorkspacesCreateFileResult `json:"WorkspacesCreateFileResult"`
+ WorkspacesGetWorkspaceResult WorkspacesGetWorkspaceResult `json:"WorkspacesGetWorkspaceResult"`
+ WorkspacesListFilesResult WorkspacesListFilesResult `json:"WorkspacesListFilesResult"`
+ WorkspacesReadFileRequest WorkspacesReadFileRequest `json:"WorkspacesReadFileRequest"`
+ WorkspacesReadFileResult WorkspacesReadFileResult `json:"WorkspacesReadFileResult"`
}
type AccountGetQuotaRequest struct {
@@ -347,6 +362,24 @@ type DiscoveredMCPServer struct {
Type *DiscoveredMCPServerType `json:"type,omitempty"`
}
+type EmbeddedBlobResourceContents struct {
+ // Base64-encoded binary content of the resource
+ Blob string `json:"blob"`
+ // MIME type of the blob content
+ MIMEType *string `json:"mimeType,omitempty"`
+ // URI identifying the resource
+ URI string `json:"uri"`
+}
+
+type EmbeddedTextResourceContents struct {
+ // MIME type of the text content
+ MIMEType *string `json:"mimeType,omitempty"`
+ // Text content of the resource
+ Text string `json:"text"`
+ // URI identifying the resource
+ URI string `json:"uri"`
+}
+
type Extension struct {
// Source-qualified ID (e.g., 'project:my-ext', 'user:auth-helper')
ID string `json:"id"`
@@ -390,6 +423,168 @@ type ExtensionsEnableResult struct {
type ExtensionsReloadResult struct {
}
+// Expanded external tool result payload
+type ExternalToolTextResultForLlm struct {
+ // Structured content blocks from the tool
+ Contents []ExternalToolTextResultForLlmContent `json:"contents,omitempty"`
+ // Optional error message for failed executions
+ Error *string `json:"error,omitempty"`
+ // Execution outcome classification. Optional for back-compat; normalized to 'success' (or
+ // 'failure' when error is present) when missing or unrecognized.
+ ResultType *string `json:"resultType,omitempty"`
+ // Detailed log content for timeline display
+ SessionLog *string `json:"sessionLog,omitempty"`
+ // Text result returned to the model
+ TextResultForLlm string `json:"textResultForLlm"`
+ // Optional tool-specific telemetry
+ ToolTelemetry map[string]any `json:"toolTelemetry,omitempty"`
+}
+
+// A content block within a tool result, which may be text, terminal output, image, audio,
+// or a resource
+//
+// # Plain text content block
+//
+// Terminal/shell output content block with optional exit code and working directory
+//
+// # Image content block with base64-encoded data
+//
+// # Audio content block with base64-encoded data
+//
+// # Resource link content block referencing an external resource
+//
+// Embedded resource content block with inline text or binary data
+type ExternalToolTextResultForLlmContent struct {
+ // The text content
+ //
+ // Terminal/shell output text
+ Text *string `json:"text,omitempty"`
+ // Content block type discriminator
+ Type ExternalToolTextResultForLlmContentType `json:"type"`
+ // Working directory where the command was executed
+ Cwd *string `json:"cwd,omitempty"`
+ // Process exit code, if the command has completed
+ ExitCode *float64 `json:"exitCode,omitempty"`
+ // Base64-encoded image data
+ //
+ // Base64-encoded audio data
+ Data *string `json:"data,omitempty"`
+ // MIME type of the image (e.g., image/png, image/jpeg)
+ //
+ // MIME type of the audio (e.g., audio/wav, audio/mpeg)
+ //
+ // MIME type of the resource content
+ MIMEType *string `json:"mimeType,omitempty"`
+ // Human-readable description of the resource
+ Description *string `json:"description,omitempty"`
+ // Icons associated with this resource
+ Icons []ExternalToolTextResultForLlmContentResourceLinkIcon `json:"icons,omitempty"`
+ // Resource name identifier
+ Name *string `json:"name,omitempty"`
+ // Size of the resource in bytes
+ Size *float64 `json:"size,omitempty"`
+ // Human-readable display title for the resource
+ Title *string `json:"title,omitempty"`
+ // URI identifying the resource
+ URI *string `json:"uri,omitempty"`
+ // The embedded resource contents, either text or base64-encoded binary
+ Resource *ExternalToolTextResultForLlmContentResourceDetails `json:"resource,omitempty"`
+}
+
+// Icon image for a resource
+type ExternalToolTextResultForLlmContentResourceLinkIcon struct {
+ // MIME type of the icon image
+ MIMEType *string `json:"mimeType,omitempty"`
+ // Available icon sizes (e.g., ['16x16', '32x32'])
+ Sizes []string `json:"sizes,omitempty"`
+ // URL or path to the icon image
+ Src string `json:"src"`
+ // Theme variant this icon is intended for
+ Theme *ExternalToolTextResultForLlmContentResourceLinkIconTheme `json:"theme,omitempty"`
+}
+
+// The embedded resource contents, either text or base64-encoded binary
+type ExternalToolTextResultForLlmContentResourceDetails struct {
+ // MIME type of the text content
+ //
+ // MIME type of the blob content
+ MIMEType *string `json:"mimeType,omitempty"`
+ // Text content of the resource
+ Text *string `json:"text,omitempty"`
+ // URI identifying the resource
+ URI string `json:"uri"`
+ // Base64-encoded binary content of the resource
+ Blob *string `json:"blob,omitempty"`
+}
+
+// Audio content block with base64-encoded data
+type ExternalToolTextResultForLlmContentAudio struct {
+ // Base64-encoded audio data
+ Data string `json:"data"`
+ // MIME type of the audio (e.g., audio/wav, audio/mpeg)
+ MIMEType string `json:"mimeType"`
+ // Content block type discriminator
+ Type ExternalToolTextResultForLlmContentAudioType `json:"type"`
+}
+
+// Image content block with base64-encoded data
+type ExternalToolTextResultForLlmContentImage struct {
+ // Base64-encoded image data
+ Data string `json:"data"`
+ // MIME type of the image (e.g., image/png, image/jpeg)
+ MIMEType string `json:"mimeType"`
+ // Content block type discriminator
+ Type ExternalToolTextResultForLlmContentImageType `json:"type"`
+}
+
+// Embedded resource content block with inline text or binary data
+type ExternalToolTextResultForLlmContentResource struct {
+ // The embedded resource contents, either text or base64-encoded binary
+ Resource ExternalToolTextResultForLlmContentResourceDetails `json:"resource"`
+ // Content block type discriminator
+ Type ExternalToolTextResultForLlmContentResourceType `json:"type"`
+}
+
+// Resource link content block referencing an external resource
+type ExternalToolTextResultForLlmContentResourceLink struct {
+ // Human-readable description of the resource
+ Description *string `json:"description,omitempty"`
+ // Icons associated with this resource
+ Icons []ExternalToolTextResultForLlmContentResourceLinkIcon `json:"icons,omitempty"`
+ // MIME type of the resource content
+ MIMEType *string `json:"mimeType,omitempty"`
+ // Resource name identifier
+ Name string `json:"name"`
+ // Size of the resource in bytes
+ Size *float64 `json:"size,omitempty"`
+ // Human-readable display title for the resource
+ Title *string `json:"title,omitempty"`
+ // Content block type discriminator
+ Type ExternalToolTextResultForLlmContentResourceLinkType `json:"type"`
+ // URI identifying the resource
+ URI string `json:"uri"`
+}
+
+// Terminal/shell output content block with optional exit code and working directory
+type ExternalToolTextResultForLlmContentTerminal struct {
+ // Working directory where the command was executed
+ Cwd *string `json:"cwd,omitempty"`
+ // Process exit code, if the command has completed
+ ExitCode *float64 `json:"exitCode,omitempty"`
+ // Terminal/shell output text
+ Text string `json:"text"`
+ // Content block type discriminator
+ Type ExternalToolTextResultForLlmContentTerminalType `json:"type"`
+}
+
+// Plain text content block
+type ExternalToolTextResultForLlmContentText struct {
+ // The text content
+ Text string `json:"text"`
+ // Content block type discriminator
+ Type ExternalToolTextResultForLlmContentTextType `json:"type"`
+}
+
// Experimental: FleetStartRequest is part of an experimental API and may change or be removed.
type FleetStartRequest struct {
// Optional user prompt to combine with fleet instructions
@@ -402,7 +597,16 @@ type FleetStartResult struct {
Started bool `json:"started"`
}
-type HandleToolCallResult struct {
+type HandlePendingToolCallRequest struct {
+ // Error message if the tool call failed
+ Error *string `json:"error,omitempty"`
+ // Request ID of the pending tool call
+ RequestID string `json:"requestId"`
+ // Tool call result (string or expanded result object)
+ Result *ExternalToolResult `json:"result"`
+}
+
+type HandlePendingToolCallResult struct {
// Whether the tool call result was handled successfully
Success bool `json:"success"`
}
@@ -816,6 +1020,8 @@ type PermissionDecision struct {
//
// Approved and persisted for this project location
//
+ // Approved and persisted across sessions
+ //
// Denied by the user during an interactive prompt
//
// Denied because user confirmation was unavailable
@@ -824,6 +1030,10 @@ type PermissionDecision struct {
//
// The approval to persist for this location
Approval *PermissionDecisionApproveForLocationApproval `json:"approval,omitempty"`
+ // The URL domain to approve for this session
+ //
+ // The URL domain to approve permanently
+ Domain *string `json:"domain,omitempty"`
// The location key (git root or cwd) to persist the approval to
LocationKey *string `json:"locationKey,omitempty"`
// Optional feedback from the user explaining the denial
@@ -882,7 +1092,9 @@ type PermissionDecisionApproveForLocationApprovalWrite struct {
type PermissionDecisionApproveForSession struct {
// The approval to add as a session-scoped rule
- Approval PermissionDecisionApproveForSessionApproval `json:"approval"`
+ Approval *PermissionDecisionApproveForSessionApproval `json:"approval,omitempty"`
+ // The URL domain to approve for this session
+ Domain *string `json:"domain,omitempty"`
// Approved and remembered for the rest of the session
Kind PermissionDecisionApproveForSessionKind `json:"kind"`
}
@@ -933,6 +1145,13 @@ type PermissionDecisionApproveOnce struct {
Kind PermissionDecisionApproveOnceKind `json:"kind"`
}
+type PermissionDecisionApprovePermanently struct {
+ // The URL domain to approve permanently
+ Domain string `json:"domain"`
+ // Approved and persisted across sessions
+ Kind PermissionDecisionApprovePermanentlyKind `json:"kind"`
+}
+
type PermissionDecisionReject struct {
// Optional feedback from the user explaining the denial
Feedback *string `json:"feedback,omitempty"`
@@ -1521,31 +1740,11 @@ type Tool struct {
Parameters map[string]any `json:"parameters,omitempty"`
}
-type ToolCallResult struct {
- // Error message if the tool call failed
- Error *string `json:"error,omitempty"`
- // Type of the tool result
- ResultType *string `json:"resultType,omitempty"`
- // Text result to send back to the LLM
- TextResultForLlm string `json:"textResultForLlm"`
- // Telemetry data from tool execution
- ToolTelemetry map[string]any `json:"toolTelemetry,omitempty"`
-}
-
type ToolList struct {
// List of available built-in tools with metadata
Tools []Tool `json:"tools"`
}
-type ToolsHandlePendingToolCallRequest struct {
- // Error message if the tool call failed
- Error *string `json:"error,omitempty"`
- // Request ID of the pending tool call
- RequestID string `json:"requestId"`
- // Tool call result (string or expanded result object)
- Result *ToolsHandlePendingToolCall `json:"result"`
-}
-
type ToolsListRequest struct {
// Optional model ID — when provided, the returned tool list reflects model-specific
// overrides
@@ -1710,8 +1909,12 @@ type UsageGetMetricsResult struct {
ModelMetrics map[string]UsageMetricsModelMetric `json:"modelMetrics"`
// Session start timestamp (epoch milliseconds)
SessionStartTime int64 `json:"sessionStartTime"`
+ // Session-wide per-token-type accumulated token counts
+ TokenDetails map[string]UsageMetricsTokenDetail `json:"tokenDetails,omitempty"`
// Total time spent in model API calls (milliseconds)
TotalAPIDurationMS float64 `json:"totalApiDurationMs"`
+ // Session-wide accumulated nano-AI units cost
+ TotalNanoAiu *int64 `json:"totalNanoAiu,omitempty"`
// Total user-initiated premium request cost across all models (may be fractional due to
// multipliers)
TotalPremiumRequestCost float64 `json:"totalPremiumRequestCost"`
@@ -1732,6 +1935,10 @@ type UsageMetricsCodeChanges struct {
type UsageMetricsModelMetric struct {
// Request count and cost metrics for this model
Requests UsageMetricsModelMetricRequests `json:"requests"`
+ // Token count details per type
+ TokenDetails map[string]UsageMetricsModelMetricTokenDetail `json:"tokenDetails,omitempty"`
+ // Accumulated nano-AI units cost for this model
+ TotalNanoAiu *int64 `json:"totalNanoAiu,omitempty"`
// Token usage metrics for this model
Usage UsageMetricsModelMetricUsage `json:"usage"`
}
@@ -1744,6 +1951,11 @@ type UsageMetricsModelMetricRequests struct {
Count int64 `json:"count"`
}
+type UsageMetricsModelMetricTokenDetail struct {
+ // Accumulated token count for this token type
+ TokenCount int64 `json:"tokenCount"`
+}
+
// Token usage metrics for this model
type UsageMetricsModelMetricUsage struct {
// Total tokens read from prompt cache
@@ -1758,6 +1970,11 @@ type UsageMetricsModelMetricUsage struct {
ReasoningTokens *int64 `json:"reasoningTokens,omitempty"`
}
+type UsageMetricsTokenDetail struct {
+ // Accumulated token count for this token type
+ TokenCount int64 `json:"tokenCount"`
+}
+
type WorkspacesCreateFileRequest struct {
// File content to write as a UTF-8 string
Content string `json:"content"`
@@ -1862,6 +2079,61 @@ const (
ExtensionStatusStarting ExtensionStatus = "starting"
)
+// Theme variant this icon is intended for
+type ExternalToolTextResultForLlmContentResourceLinkIconTheme string
+
+const (
+ ExternalToolTextResultForLlmContentResourceLinkIconThemeDark ExternalToolTextResultForLlmContentResourceLinkIconTheme = "dark"
+ ExternalToolTextResultForLlmContentResourceLinkIconThemeLight ExternalToolTextResultForLlmContentResourceLinkIconTheme = "light"
+)
+
+type ExternalToolTextResultForLlmContentType string
+
+const (
+ ExternalToolTextResultForLlmContentTypeAudio ExternalToolTextResultForLlmContentType = "audio"
+ ExternalToolTextResultForLlmContentTypeImage ExternalToolTextResultForLlmContentType = "image"
+ ExternalToolTextResultForLlmContentTypeResource ExternalToolTextResultForLlmContentType = "resource"
+ ExternalToolTextResultForLlmContentTypeResourceLink ExternalToolTextResultForLlmContentType = "resource_link"
+ ExternalToolTextResultForLlmContentTypeTerminal ExternalToolTextResultForLlmContentType = "terminal"
+ ExternalToolTextResultForLlmContentTypeText ExternalToolTextResultForLlmContentType = "text"
+)
+
+type ExternalToolTextResultForLlmContentAudioType string
+
+const (
+ ExternalToolTextResultForLlmContentAudioTypeAudio ExternalToolTextResultForLlmContentAudioType = "audio"
+)
+
+type ExternalToolTextResultForLlmContentImageType string
+
+const (
+ ExternalToolTextResultForLlmContentImageTypeImage ExternalToolTextResultForLlmContentImageType = "image"
+)
+
+type ExternalToolTextResultForLlmContentResourceType string
+
+const (
+ ExternalToolTextResultForLlmContentResourceTypeResource ExternalToolTextResultForLlmContentResourceType = "resource"
+)
+
+type ExternalToolTextResultForLlmContentResourceLinkType string
+
+const (
+ ExternalToolTextResultForLlmContentResourceLinkTypeResourceLink ExternalToolTextResultForLlmContentResourceLinkType = "resource_link"
+)
+
+type ExternalToolTextResultForLlmContentTerminalType string
+
+const (
+ ExternalToolTextResultForLlmContentTerminalTypeTerminal ExternalToolTextResultForLlmContentTerminalType = "terminal"
+)
+
+type ExternalToolTextResultForLlmContentTextType string
+
+const (
+ ExternalToolTextResultForLlmContentTextTypeText ExternalToolTextResultForLlmContentTextType = "text"
+)
+
type FilterMappingString string
const (
@@ -1965,6 +2237,7 @@ const (
PermissionDecisionKindApproveForLocation PermissionDecisionKind = "approve-for-location"
PermissionDecisionKindApproveForSession PermissionDecisionKind = "approve-for-session"
PermissionDecisionKindApproveOnce PermissionDecisionKind = "approve-once"
+ PermissionDecisionKindApprovePermanently PermissionDecisionKind = "approve-permanently"
PermissionDecisionKindReject PermissionDecisionKind = "reject"
PermissionDecisionKindUserNotAvailable PermissionDecisionKind = "user-not-available"
)
@@ -2029,6 +2302,12 @@ const (
PermissionDecisionApproveOnceKindApproveOnce PermissionDecisionApproveOnceKind = "approve-once"
)
+type PermissionDecisionApprovePermanentlyKind string
+
+const (
+ PermissionDecisionApprovePermanentlyKindApprovePermanently PermissionDecisionApprovePermanentlyKind = "approve-permanently"
+)
+
type PermissionDecisionRejectKind string
const (
@@ -2197,17 +2476,17 @@ const (
SessionSyncLevelUser SessionSyncLevel = "user"
)
+// Tool call result (string or expanded result object)
+type ExternalToolResult struct {
+ ExternalToolTextResultForLlm *ExternalToolTextResultForLlm
+ String *string
+}
+
type FilterMapping struct {
Enum *FilterMappingString
EnumMap map[string]FilterMappingString
}
-// Tool call result (string or expanded result object)
-type ToolsHandlePendingToolCall struct {
- String *string
- ToolCallResult *ToolCallResult
-}
-
type UIElicitationFieldValue struct {
Bool *bool
Double *float64
@@ -3105,7 +3384,7 @@ func (a *ExtensionsApi) Reload(ctx context.Context) (*ExtensionsReloadResult, er
type ToolsApi sessionApi
-func (a *ToolsApi) HandlePendingToolCall(ctx context.Context, params *ToolsHandlePendingToolCallRequest) (*HandleToolCallResult, error) {
+func (a *ToolsApi) HandlePendingToolCall(ctx context.Context, params *HandlePendingToolCallRequest) (*HandlePendingToolCallResult, error) {
req := map[string]any{"sessionId": a.sessionID}
if params != nil {
req["requestId"] = params.RequestID
@@ -3120,7 +3399,7 @@ func (a *ToolsApi) HandlePendingToolCall(ctx context.Context, params *ToolsHandl
if err != nil {
return nil, err
}
- var result HandleToolCallResult
+ var result HandlePendingToolCallResult
if err := json.Unmarshal(raw, &result); err != nil {
return nil, err
}
diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json
index 0988fe241..8f8f12a00 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.40-0",
+ "@github/copilot": "^1.0.40-1",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
@@ -663,26 +663,26 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.40-0.tgz",
- "integrity": "sha512-KIrRqPOCGPcYUq09wvi66qUi5YMFTH5z9fOEzo1BuyLFVQqUen0TtRk0mpbhG6TxArLPqosBY8nDXOdc+NqKKw==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.40-1.tgz",
+ "integrity": "sha512-jdohe7CcjlmbNR0bnL/uAbaYDtmqZnHcHo3t/ZspVb9vo7+yk7AdTc4AF4TpV7M/tCKc+ynoqgQNCalWAmXYWQ==",
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.40-0",
- "@github/copilot-darwin-x64": "1.0.40-0",
- "@github/copilot-linux-arm64": "1.0.40-0",
- "@github/copilot-linux-x64": "1.0.40-0",
- "@github/copilot-win32-arm64": "1.0.40-0",
- "@github/copilot-win32-x64": "1.0.40-0"
+ "@github/copilot-darwin-arm64": "1.0.40-1",
+ "@github/copilot-darwin-x64": "1.0.40-1",
+ "@github/copilot-linux-arm64": "1.0.40-1",
+ "@github/copilot-linux-x64": "1.0.40-1",
+ "@github/copilot-win32-arm64": "1.0.40-1",
+ "@github/copilot-win32-x64": "1.0.40-1"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.40-0.tgz",
- "integrity": "sha512-l905DiMvOB7Jn5MAkS+iEQcM99hmJHQ5yrKaGJ9OteVWBCcxPEO5ctnRYFdeq4NHL+9OnAzJzNc0kwScOAUCzg==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.40-1.tgz",
+ "integrity": "sha512-DSArBmv1A6BstJs23QgXzes7B8Hu+sz4Ccqh1NhY/4NPfxck1rD2v61ZWz8kdwpgTdjP6lWSZ5nLWdi9Go+PhA==",
"cpu": [
"arm64"
],
@@ -696,9 +696,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.40-0.tgz",
- "integrity": "sha512-e/Dtc1CjZ5SpNLdtY7vHxzH3hhNKfiMJdyp/2UY/6rzXsSPfbw9xZL01nUBbZt0aYj2FbPBDMTyfqoh5weUSww==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.40-1.tgz",
+ "integrity": "sha512-fTOL2XChDSsPc/q//mIFlq47ABNgyUKqz1+ix5oxloE9RlT1YpD7v3O+dqU/tmdxXwMTfQqgZsYglRY/nna3yw==",
"cpu": [
"x64"
],
@@ -712,9 +712,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.40-0.tgz",
- "integrity": "sha512-fR/gVUXFpjwojNf3Pg5lH2vrb8q0Gghv6RK6xx1QS6pEBdPTMGeoPxQVqSSB6dZCR/X3dkK1tIZ5IGnuABDHbA==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.40-1.tgz",
+ "integrity": "sha512-+aon/9kAxgGlxLZrxzwUrNO1G/eUIhhEB6W4u1sMs2GwXjANrDr6WIsp056dOnU2TY9oEnn8vWTJQSIwyFlGHQ==",
"cpu": [
"arm64"
],
@@ -728,9 +728,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.40-0.tgz",
- "integrity": "sha512-vDfE5Cxgg+BealbxBjqa0MUrLGJF+zT+XygMFgWXi/4ESVpRvvAet8rUoLeL+7Lgg6QRlS+UMPWfWL6ZAoSp5w==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.40-1.tgz",
+ "integrity": "sha512-p44TeuI01EpizsJmQX0W21f7pPXyTvrXYkv/5W1GgCiNEP4HKLG9rdgdIEtqaIMnXFKssxpGF45+hJuz0iep5g==",
"cpu": [
"x64"
],
@@ -744,9 +744,9 @@
}
},
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.40-0.tgz",
- "integrity": "sha512-7aEo1CZ5476lWRtfcym0TX1DhH5l9+PKENHPOr8vfziHKeNlWYkXHVTo7OGIUnCAwIetbCQRyf92nnaFhG/8Jw==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.40-1.tgz",
+ "integrity": "sha512-nrbMh1qc8VWL1KU2N+VdQ2M+4jiGlugApIFNUbfywnUITktWEpQ62Jqf2YQlrMr51f1F1fjSE/YBuDW6InzzYg==",
"cpu": [
"arm64"
],
@@ -760,9 +760,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.40-0.tgz",
- "integrity": "sha512-egnoilEO6TS0qSexe+A26GUSyfeinaqXJRTYL4Qr6eVgAfFhCEpCJtK/gHIZmlDXnq2ex3jGrVvz9+ZIp+JSoA==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.40-1.tgz",
+ "integrity": "sha512-n5qmzAn4OKbdHJeOmdt4eUA7XWSUOmNSJUtRswKVqgCxrmMOR/0FXCPzVS0gAJn+UEj9ApHulC6G09HR5Nhp7Q==",
"cpu": [
"x64"
],
diff --git a/nodejs/package.json b/nodejs/package.json
index 6e53791b9..b04d19511 100644
--- a/nodejs/package.json
+++ b/nodejs/package.json
@@ -56,7 +56,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
- "@github/copilot": "^1.0.40-0",
+ "@github/copilot": "^1.0.40-1",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json
index 4d9076e84..dfc68c929 100644
--- a/nodejs/samples/package-lock.json
+++ b/nodejs/samples/package-lock.json
@@ -18,7 +18,7 @@
"version": "0.1.8",
"license": "MIT",
"dependencies": {
- "@github/copilot": "^1.0.40-0",
+ "@github/copilot": "^1.0.40-1",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts
index d792e2aca..349201951 100644
--- a/nodejs/src/generated/rpc.ts
+++ b/nodejs/src/generated/rpc.ts
@@ -40,6 +40,42 @@ export type ExtensionSource = "project" | "user";
* via the `definition` "ExtensionStatus".
*/
export type ExtensionStatus = "running" | "disabled" | "failed" | "starting";
+/**
+ * Tool call result (string or expanded result object)
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolResult".
+ */
+export type ExternalToolResult = string | ExternalToolTextResultForLlm;
+/**
+ * A content block within a tool result, which may be text, terminal output, image, audio, or a resource
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContent".
+ */
+export type ExternalToolTextResultForLlmContent =
+ | ExternalToolTextResultForLlmContentText
+ | ExternalToolTextResultForLlmContentTerminal
+ | ExternalToolTextResultForLlmContentImage
+ | ExternalToolTextResultForLlmContentAudio
+ | ExternalToolTextResultForLlmContentResourceLink
+ | ExternalToolTextResultForLlmContentResource;
+/**
+ * Theme variant this icon is intended for
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentResourceLinkIconTheme".
+ */
+export type ExternalToolTextResultForLlmContentResourceLinkIconTheme = "light" | "dark";
+/**
+ * The embedded resource contents, either text or base64-encoded binary
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentResourceDetails".
+ */
+export type ExternalToolTextResultForLlmContentResourceDetails =
+ | EmbeddedTextResourceContents
+ | EmbeddedBlobResourceContents;
export type FilterMapping =
| {
@@ -113,6 +149,7 @@ export type PermissionDecision =
| PermissionDecisionApproveOnce
| PermissionDecisionApproveForSession
| PermissionDecisionApproveForLocation
+ | PermissionDecisionApprovePermanently
| PermissionDecisionReject
| PermissionDecisionUserNotAvailable;
/**
@@ -208,13 +245,6 @@ export type TaskShellInfoAttachmentMode = "attached" | "detached";
* via the `definition` "TaskShellInfoExecutionMode".
*/
export type TaskShellInfoExecutionMode = "sync" | "background";
-/**
- * Tool call result (string or expanded result object)
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "ToolsHandlePendingToolCall".
- */
-export type ToolsHandlePendingToolCall = string | ToolCallResult;
export type UIElicitationFieldValue = string | number | boolean | string[];
@@ -383,6 +413,36 @@ export interface DiscoveredMcpServer {
enabled: boolean;
}
+export interface EmbeddedBlobResourceContents {
+ /**
+ * URI identifying the resource
+ */
+ uri: string;
+ /**
+ * MIME type of the blob content
+ */
+ mimeType?: string;
+ /**
+ * Base64-encoded binary content of the resource
+ */
+ blob: string;
+}
+
+export interface EmbeddedTextResourceContents {
+ /**
+ * URI identifying the resource
+ */
+ uri: string;
+ /**
+ * MIME type of the text content
+ */
+ mimeType?: string;
+ /**
+ * Text content of the resource
+ */
+ text: string;
+}
+
export interface Extension {
/**
* Source-qualified ID (e.g., 'project:my-ext', 'user:auth-helper')
@@ -423,6 +483,195 @@ export interface ExtensionsEnableRequest {
*/
id: string;
}
+/**
+ * Expanded external tool result payload
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlm".
+ */
+export interface ExternalToolTextResultForLlm {
+ /**
+ * Text result returned to the model
+ */
+ textResultForLlm: string;
+ /**
+ * Execution outcome classification. Optional for back-compat; normalized to 'success' (or 'failure' when error is present) when missing or unrecognized.
+ */
+ resultType?: string;
+ /**
+ * Optional error message for failed executions
+ */
+ error?: string;
+ /**
+ * Detailed log content for timeline display
+ */
+ sessionLog?: string;
+ /**
+ * Optional tool-specific telemetry
+ */
+ toolTelemetry?: {
+ [k: string]: unknown;
+ };
+ /**
+ * Structured content blocks from the tool
+ */
+ contents?: ExternalToolTextResultForLlmContent[];
+ [k: string]: unknown;
+}
+/**
+ * Plain text content block
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentText".
+ */
+export interface ExternalToolTextResultForLlmContentText {
+ /**
+ * Content block type discriminator
+ */
+ type: "text";
+ /**
+ * The text content
+ */
+ text: string;
+}
+/**
+ * Terminal/shell output content block with optional exit code and working directory
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentTerminal".
+ */
+export interface ExternalToolTextResultForLlmContentTerminal {
+ /**
+ * Content block type discriminator
+ */
+ type: "terminal";
+ /**
+ * Terminal/shell output text
+ */
+ text: string;
+ /**
+ * Process exit code, if the command has completed
+ */
+ exitCode?: number;
+ /**
+ * Working directory where the command was executed
+ */
+ cwd?: string;
+}
+/**
+ * Image content block with base64-encoded data
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentImage".
+ */
+export interface ExternalToolTextResultForLlmContentImage {
+ /**
+ * Content block type discriminator
+ */
+ type: "image";
+ /**
+ * Base64-encoded image data
+ */
+ data: string;
+ /**
+ * MIME type of the image (e.g., image/png, image/jpeg)
+ */
+ mimeType: string;
+}
+/**
+ * Audio content block with base64-encoded data
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentAudio".
+ */
+export interface ExternalToolTextResultForLlmContentAudio {
+ /**
+ * Content block type discriminator
+ */
+ type: "audio";
+ /**
+ * Base64-encoded audio data
+ */
+ data: string;
+ /**
+ * MIME type of the audio (e.g., audio/wav, audio/mpeg)
+ */
+ mimeType: string;
+}
+/**
+ * Resource link content block referencing an external resource
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentResourceLink".
+ */
+export interface ExternalToolTextResultForLlmContentResourceLink {
+ /**
+ * Icons associated with this resource
+ */
+ icons?: ExternalToolTextResultForLlmContentResourceLinkIcon[];
+ /**
+ * Resource name identifier
+ */
+ name: string;
+ /**
+ * Human-readable display title for the resource
+ */
+ title?: string;
+ /**
+ * URI identifying the resource
+ */
+ uri: string;
+ /**
+ * Human-readable description of the resource
+ */
+ description?: string;
+ /**
+ * MIME type of the resource content
+ */
+ mimeType?: string;
+ /**
+ * Size of the resource in bytes
+ */
+ size?: number;
+ /**
+ * Content block type discriminator
+ */
+ type: "resource_link";
+}
+/**
+ * Icon image for a resource
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentResourceLinkIcon".
+ */
+export interface ExternalToolTextResultForLlmContentResourceLinkIcon {
+ /**
+ * URL or path to the icon image
+ */
+ src: string;
+ /**
+ * MIME type of the icon image
+ */
+ mimeType?: string;
+ /**
+ * Available icon sizes (e.g., ['16x16', '32x32'])
+ */
+ sizes?: string[];
+ theme?: ExternalToolTextResultForLlmContentResourceLinkIconTheme;
+}
+/**
+ * Embedded resource content block with inline text or binary data
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmContentResource".
+ */
+export interface ExternalToolTextResultForLlmContentResource {
+ /**
+ * Content block type discriminator
+ */
+ type: "resource";
+ resource: ExternalToolTextResultForLlmContentResourceDetails;
+}
/** @experimental */
export interface FleetStartRequest {
@@ -440,7 +689,19 @@ export interface FleetStartResult {
started: boolean;
}
-export interface HandleToolCallResult {
+export interface HandlePendingToolCallRequest {
+ /**
+ * Request ID of the pending tool call
+ */
+ requestId: string;
+ result?: ExternalToolResult;
+ /**
+ * Error message if the tool call failed
+ */
+ error?: string;
+}
+
+export interface HandlePendingToolCallResult {
/**
* Whether the tool call result was handled successfully
*/
@@ -966,7 +1227,11 @@ export interface PermissionDecisionApproveForSession {
* Approved and remembered for the rest of the session
*/
kind: "approve-for-session";
- approval: PermissionDecisionApproveForSessionApproval;
+ approval?: PermissionDecisionApproveForSessionApproval;
+ /**
+ * The URL domain to approve for this session
+ */
+ domain?: string;
}
export interface PermissionDecisionApproveForSessionApprovalCommands {
@@ -1047,6 +1312,17 @@ export interface PermissionDecisionApproveForLocationApprovalCustomTool {
toolName: string;
}
+export interface PermissionDecisionApprovePermanently {
+ /**
+ * Approved and persisted across sessions
+ */
+ kind: "approve-permanently";
+ /**
+ * The URL domain to approve permanently
+ */
+ domain: string;
+}
+
export interface PermissionDecisionReject {
/**
* Denied by the user during an interactive prompt
@@ -1827,27 +2103,6 @@ export interface Tool {
instructions?: string;
}
-export interface ToolCallResult {
- /**
- * Text result to send back to the LLM
- */
- textResultForLlm: string;
- /**
- * Type of the tool result
- */
- resultType?: string;
- /**
- * Error message if the tool call failed
- */
- error?: string;
- /**
- * Telemetry data from tool execution
- */
- toolTelemetry?: {
- [k: string]: unknown;
- };
-}
-
export interface ToolList {
/**
* List of available built-in tools with metadata
@@ -1855,18 +2110,6 @@ export interface ToolList {
tools: Tool[];
}
-export interface ToolsHandlePendingToolCallRequest {
- /**
- * Request ID of the pending tool call
- */
- requestId: string;
- result?: ToolsHandlePendingToolCall;
- /**
- * Error message if the tool call failed
- */
- error?: string;
-}
-
export interface ToolsListRequest {
/**
* Optional model ID — when provided, the returned tool list reflects model-specific overrides
@@ -2030,6 +2273,16 @@ export interface UsageGetMetricsResult {
* Raw count of user-initiated API requests
*/
totalUserRequests: number;
+ /**
+ * Session-wide accumulated nano-AI units cost
+ */
+ totalNanoAiu?: number;
+ /**
+ * Session-wide per-token-type accumulated token counts
+ */
+ tokenDetails?: {
+ [k: string]: UsageMetricsTokenDetail;
+ };
/**
* Total time spent in model API calls (milliseconds)
*/
@@ -2058,6 +2311,13 @@ export interface UsageGetMetricsResult {
*/
lastCallOutputTokens: number;
}
+
+export interface UsageMetricsTokenDetail {
+ /**
+ * Accumulated token count for this token type
+ */
+ tokenCount: number;
+}
/**
* Aggregated code change metrics
*
@@ -2082,6 +2342,16 @@ export interface UsageMetricsCodeChanges {
export interface UsageMetricsModelMetric {
requests: UsageMetricsModelMetricRequests;
usage: UsageMetricsModelMetricUsage;
+ /**
+ * Accumulated nano-AI units cost for this model
+ */
+ totalNanoAiu?: number;
+ /**
+ * Token count details per type
+ */
+ tokenDetails?: {
+ [k: string]: UsageMetricsModelMetricTokenDetail;
+ };
}
/**
* Request count and cost metrics for this model
@@ -2128,6 +2398,13 @@ export interface UsageMetricsModelMetricUsage {
reasoningTokens?: number;
}
+export interface UsageMetricsModelMetricTokenDetail {
+ /**
+ * Accumulated token count for this token type
+ */
+ tokenCount: number;
+}
+
export interface WorkspacesCreateFileRequest {
/**
* Relative path within the workspace files directory
@@ -2363,7 +2640,7 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin
connection.sendRequest("session.extensions.reload", { sessionId }),
},
tools: {
- handlePendingToolCall: async (params: ToolsHandlePendingToolCallRequest): Promise =>
+ handlePendingToolCall: async (params: HandlePendingToolCallRequest): Promise =>
connection.sendRequest("session.tools.handlePendingToolCall", { sessionId, ...params }),
},
commands: {
diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts
index dc919cb46..23c61710f 100644
--- a/nodejs/src/generated/session-events.ts
+++ b/nodejs/src/generated/session-events.ts
@@ -208,17 +208,28 @@ export type PermissionPromptRequestMemoryDirection = "upvote" | "downvote";
*/
export type PermissionPromptRequestPathAccessKind = "read" | "shell" | "write";
/**
- * The outcome of the permission request
- */
-export type PermissionCompletedKind =
- | "approved"
- | "approved-for-session"
- | "approved-for-location"
- | "denied-by-rules"
- | "denied-no-approval-rule-and-could-not-request-from-user"
- | "denied-interactively-by-user"
- | "denied-by-content-exclusion-policy"
- | "denied-by-permission-request-hook";
+ * The result of the permission request
+ */
+export type PermissionResult =
+ | PermissionApproved
+ | PermissionApprovedForSession
+ | PermissionApprovedForLocation
+ | PermissionCancelled
+ | PermissionDeniedByRules
+ | PermissionDeniedNoApprovalRuleAndCouldNotRequestFromUser
+ | PermissionDeniedInteractivelyByUser
+ | PermissionDeniedByContentExclusionPolicy
+ | PermissionDeniedByPermissionRequestHook;
+/**
+ * The approval to add as a session-scoped rule
+ */
+export type UserToolSessionApproval =
+ | UserToolSessionApprovalCommands
+ | UserToolSessionApprovalRead
+ | UserToolSessionApprovalWrite
+ | UserToolSessionApprovalMcp
+ | UserToolSessionApprovalMemory
+ | UserToolSessionApprovalCustomTool;
/**
* Elicitation mode; "form" for structured input, "url" for browser-based. Defaults to "form" when absent.
*/
@@ -390,6 +401,10 @@ export interface ResumeData {
*/
alreadyInUse?: boolean;
context?: WorkingDirectoryContext;
+ /**
+ * When true, tool calls and permission requests left in flight by the previous session lifetime remain pending after resume and the agentic loop awaits their results. User sends are queued behind the pending work until all such requests reach a terminal state. When false (the default), any such tool calls and permission requests are immediately marked as interrupted on resume.
+ */
+ continuePendingWork?: boolean;
/**
* Total number of persisted events in the session at the time of resume
*/
@@ -410,6 +425,10 @@ export interface ResumeData {
* Model currently selected at resume time
*/
selectedModel?: string;
+ /**
+ * True when this resume attached to a session that the runtime already had running in-memory (for example, an extension joining a session another client was actively driving). False (or omitted) for cold resumes — the runtime had to reconstitute the session from its persisted event log.
+ */
+ sessionWasActive?: boolean;
}
export interface RemoteSteerableChangedEvent {
/**
@@ -1024,6 +1043,12 @@ export interface ShutdownData {
* System message token count at shutdown
*/
systemTokens?: number;
+ /**
+ * Session-wide per-token-type accumulated token counts
+ */
+ tokenDetails?: {
+ [k: string]: ShutdownTokenDetail;
+ };
/**
* Tool definitions token count at shutdown
*/
@@ -1032,6 +1057,10 @@ export interface ShutdownData {
* Cumulative time spent in API calls during the session, in milliseconds
*/
totalApiDurationMs: number;
+ /**
+ * Session-wide accumulated nano-AI units cost
+ */
+ totalNanoAiu?: number;
/**
* Total number of premium API requests used during the session
*/
@@ -1056,6 +1085,16 @@ export interface ShutdownCodeChanges {
}
export interface ShutdownModelMetric {
requests: ShutdownModelMetricRequests;
+ /**
+ * Token count details per type
+ */
+ tokenDetails?: {
+ [k: string]: ShutdownModelMetricTokenDetail;
+ };
+ /**
+ * Accumulated nano-AI units cost for this model
+ */
+ totalNanoAiu?: number;
usage: ShutdownModelMetricUsage;
}
/**
@@ -1071,6 +1110,12 @@ export interface ShutdownModelMetricRequests {
*/
count: number;
}
+export interface ShutdownModelMetricTokenDetail {
+ /**
+ * Accumulated token count for this token type
+ */
+ tokenCount: number;
+}
/**
* Token usage breakdown
*/
@@ -1096,6 +1141,12 @@ export interface ShutdownModelMetricUsage {
*/
reasoningTokens?: number;
}
+export interface ShutdownTokenDetail {
+ /**
+ * Accumulated token count for this token type
+ */
+ tokenCount: number;
+}
export interface ContextChangedEvent {
/**
* Sub-agent instance identifier. Absent for events from the root/main agent and session-level events.
@@ -1340,7 +1391,7 @@ export interface CompactionCompleteCompactionTokensUsedCopilotUsage {
*/
tokenDetails: CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail[];
/**
- * Total cost in nano-AIU (AI Units) for this request
+ * Total cost in nano-AI units for this request
*/
totalNanoAiu: number;
}
@@ -1444,6 +1495,10 @@ export interface UserMessageData {
* Path-backed native document attachments that stayed on the tagged_files path flow because native upload would exceed the request size limit
*/
nativeDocumentPathFallbackPaths?: string[];
+ /**
+ * Parent agent task ID for background telemetry correlated to this user turn
+ */
+ parentAgentTaskId?: string;
/**
* Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user)
*/
@@ -1873,6 +1928,10 @@ export interface AssistantMessageData {
* Tool invocations requested by the assistant in this message
*/
toolRequests?: AssistantMessageToolRequest[];
+ /**
+ * Identifier for the agent loop turn that produced this message, matching the corresponding assistant.turn_start event
+ */
+ turnId?: string;
}
/**
* A tool invocation request from the assistant
@@ -2081,7 +2140,7 @@ export interface AssistantUsageCopilotUsage {
*/
tokenDetails: AssistantUsageCopilotUsageTokenDetail[];
/**
- * Total cost in nano-AIU (AI Units) for this request
+ * Total cost in nano-AI units for this request
*/
totalNanoAiu: number;
}
@@ -2326,6 +2385,10 @@ export interface ToolExecutionStartData {
* Name of the tool being executed
*/
toolName: string;
+ /**
+ * Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event
+ */
+ turnId?: string;
}
export interface ToolExecutionPartialResultEvent {
/**
@@ -2456,6 +2519,10 @@ export interface ToolExecutionCompleteData {
toolTelemetry?: {
[k: string]: unknown;
};
+ /**
+ * Identifier for the agent loop turn this tool was invoked in, matching the corresponding assistant.turn_start event
+ */
+ turnId?: string;
}
/**
* Error details when the tool execution failed
@@ -3234,7 +3301,10 @@ export interface PermissionRequestedEvent {
*/
agentId?: string;
data: PermissionRequestedData;
- ephemeral: true;
+ /**
+ * 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
*/
@@ -3763,7 +3833,10 @@ export interface PermissionCompletedEvent {
*/
agentId?: string;
data: PermissionCompletedData;
- ephemeral: true;
+ /**
+ * 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
*/
@@ -3786,17 +3859,165 @@ export interface PermissionCompletedData {
* Request ID of the resolved permission request; clients should dismiss any UI for this request
*/
requestId: string;
- result: PermissionCompletedResult;
+ result: PermissionResult;
/**
* Optional tool call ID associated with this permission prompt; clients may use it to correlate UI created from tool-scoped prompts
*/
toolCallId?: string;
}
-/**
- * The result of the permission request
- */
-export interface PermissionCompletedResult {
- kind: PermissionCompletedKind;
+export interface PermissionApproved {
+ /**
+ * The permission request was approved
+ */
+ kind: "approved";
+}
+export interface PermissionApprovedForSession {
+ approval: UserToolSessionApproval;
+ /**
+ * Approved and remembered for the rest of the session
+ */
+ kind: "approved-for-session";
+}
+export interface UserToolSessionApprovalCommands {
+ /**
+ * Command identifiers approved by the user
+ */
+ commandIdentifiers: string[];
+ /**
+ * Command approval kind
+ */
+ kind: "commands";
+}
+export interface UserToolSessionApprovalRead {
+ /**
+ * Read approval kind
+ */
+ kind: "read";
+}
+export interface UserToolSessionApprovalWrite {
+ /**
+ * Write approval kind
+ */
+ kind: "write";
+}
+export interface UserToolSessionApprovalMcp {
+ /**
+ * MCP tool approval kind
+ */
+ kind: "mcp";
+ /**
+ * MCP server name
+ */
+ serverName: string;
+ /**
+ * Optional MCP tool name, or null for all tools on the server
+ */
+ toolName: string | null;
+}
+export interface UserToolSessionApprovalMemory {
+ /**
+ * Memory approval kind
+ */
+ kind: "memory";
+}
+export interface UserToolSessionApprovalCustomTool {
+ /**
+ * Custom tool approval kind
+ */
+ kind: "custom-tool";
+ /**
+ * Custom tool name
+ */
+ toolName: string;
+}
+export interface PermissionApprovedForLocation {
+ approval: UserToolSessionApproval;
+ /**
+ * Approved and persisted for this project location
+ */
+ kind: "approved-for-location";
+ /**
+ * The location key (git root or cwd) to persist the approval to
+ */
+ locationKey: string;
+}
+export interface PermissionCancelled {
+ /**
+ * The permission request was cancelled before a response was used
+ */
+ kind: "cancelled";
+ /**
+ * Optional explanation of why the request was cancelled
+ */
+ reason?: string;
+}
+export interface PermissionDeniedByRules {
+ /**
+ * Denied because approval rules explicitly blocked it
+ */
+ kind: "denied-by-rules";
+ /**
+ * Rules that denied the request
+ */
+ rules: PermissionRule[];
+}
+export interface PermissionRule {
+ /**
+ * Optional rule argument matched against the request
+ */
+ argument: string | null;
+ /**
+ * The rule kind, such as Shell or GitHubMCP
+ */
+ kind: string;
+}
+export interface PermissionDeniedNoApprovalRuleAndCouldNotRequestFromUser {
+ /**
+ * Denied because no approval rule matched and user confirmation was unavailable
+ */
+ kind: "denied-no-approval-rule-and-could-not-request-from-user";
+}
+export interface PermissionDeniedInteractivelyByUser {
+ /**
+ * Optional feedback from the user explaining the denial
+ */
+ feedback?: string;
+ /**
+ * Whether to force-reject the current agent turn
+ */
+ forceReject?: boolean;
+ /**
+ * Denied by the user during an interactive prompt
+ */
+ kind: "denied-interactively-by-user";
+}
+export interface PermissionDeniedByContentExclusionPolicy {
+ /**
+ * Denied by the organization's content exclusion policy
+ */
+ kind: "denied-by-content-exclusion-policy";
+ /**
+ * Human-readable explanation of why the path was excluded
+ */
+ message: string;
+ /**
+ * File path that triggered the exclusion
+ */
+ path: string;
+}
+export interface PermissionDeniedByPermissionRequestHook {
+ /**
+ * Whether to interrupt the current agent turn
+ */
+ interrupt?: boolean;
+ /**
+ * Denied by a permission request hook registered by an extension or plugin
+ */
+ kind: "denied-by-permission-request-hook";
+ /**
+ * Optional message from the hook explaining the denial
+ */
+ message?: string;
}
export interface UserInputRequestedEvent {
/**
@@ -4144,7 +4365,10 @@ export interface ExternalToolRequestedEvent {
*/
agentId?: string;
data: ExternalToolRequestedData;
- ephemeral: true;
+ /**
+ * 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
*/
@@ -4200,7 +4424,7 @@ export interface ExternalToolCompletedEvent {
*/
agentId?: string;
data: ExternalToolCompletedData;
- ephemeral: true;
+ ephemeral?: true;
/**
* Unique event identifier (UUID v4), generated when the event is emitted
*/
diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py
index 397e3166a..560ea29a0 100644
--- a/python/copilot/generated/rpc.py
+++ b/python/copilot/generated/rpc.py
@@ -280,6 +280,60 @@ class DiscoveredMCPServerType(Enum):
SSE = "sse"
STDIO = "stdio"
+@dataclass
+class EmbeddedBlobResourceContents:
+ blob: str
+ """Base64-encoded binary content of the resource"""
+
+ uri: str
+ """URI identifying the resource"""
+
+ mime_type: str | None = None
+ """MIME type of the blob content"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'EmbeddedBlobResourceContents':
+ assert isinstance(obj, dict)
+ blob = from_str(obj.get("blob"))
+ uri = from_str(obj.get("uri"))
+ mime_type = from_union([from_str, from_none], obj.get("mimeType"))
+ return EmbeddedBlobResourceContents(blob, uri, mime_type)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["blob"] = from_str(self.blob)
+ result["uri"] = from_str(self.uri)
+ if self.mime_type is not None:
+ result["mimeType"] = from_union([from_str, from_none], self.mime_type)
+ return result
+
+@dataclass
+class EmbeddedTextResourceContents:
+ text: str
+ """Text content of the resource"""
+
+ uri: str
+ """URI identifying the resource"""
+
+ mime_type: str | None = None
+ """MIME type of the text content"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'EmbeddedTextResourceContents':
+ assert isinstance(obj, dict)
+ text = from_str(obj.get("text"))
+ uri = from_str(obj.get("uri"))
+ mime_type = from_union([from_str, from_none], obj.get("mimeType"))
+ return EmbeddedTextResourceContents(text, uri, mime_type)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["text"] = from_str(self.text)
+ result["uri"] = from_str(self.uri)
+ if self.mime_type is not None:
+ result["mimeType"] = from_union([from_str, from_none], self.mime_type)
+ return result
+
class ExtensionSource(Enum):
"""Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/)"""
@@ -328,6 +382,76 @@ def to_dict(self) -> dict:
result["id"] = from_str(self.id)
return result
+class ExternalToolTextResultForLlmContentResourceLinkIconTheme(Enum):
+ """Theme variant this icon is intended for"""
+
+ DARK = "dark"
+ LIGHT = "light"
+
+@dataclass
+class ExternalToolTextResultForLlmContentResourceDetails:
+ """The embedded resource contents, either text or base64-encoded binary"""
+
+ uri: str
+ """URI identifying the resource"""
+
+ mime_type: str | None = None
+ """MIME type of the text content
+
+ MIME type of the blob content
+ """
+ text: str | None = None
+ """Text content of the resource"""
+
+ blob: str | None = None
+ """Base64-encoded binary content of the resource"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentResourceDetails':
+ assert isinstance(obj, dict)
+ uri = from_str(obj.get("uri"))
+ mime_type = from_union([from_str, from_none], obj.get("mimeType"))
+ text = from_union([from_str, from_none], obj.get("text"))
+ blob = from_union([from_str, from_none], obj.get("blob"))
+ return ExternalToolTextResultForLlmContentResourceDetails(uri, mime_type, text, blob)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["uri"] = from_str(self.uri)
+ if self.mime_type is not None:
+ result["mimeType"] = from_union([from_str, from_none], self.mime_type)
+ if self.text is not None:
+ result["text"] = from_union([from_str, from_none], self.text)
+ if self.blob is not None:
+ result["blob"] = from_union([from_str, from_none], self.blob)
+ return result
+
+class ExternalToolTextResultForLlmContentType(Enum):
+ AUDIO = "audio"
+ IMAGE = "image"
+ RESOURCE = "resource"
+ RESOURCE_LINK = "resource_link"
+ TERMINAL = "terminal"
+ TEXT = "text"
+
+class ExternalToolTextResultForLlmContentAudioType(Enum):
+ AUDIO = "audio"
+
+class ExternalToolTextResultForLlmContentImageType(Enum):
+ IMAGE = "image"
+
+class ExternalToolTextResultForLlmContentResourceType(Enum):
+ RESOURCE = "resource"
+
+class ExternalToolTextResultForLlmContentResourceLinkType(Enum):
+ RESOURCE_LINK = "resource_link"
+
+class ExternalToolTextResultForLlmContentTerminalType(Enum):
+ TERMINAL = "terminal"
+
+class ExternalToolTextResultForLlmContentTextType(Enum):
+ TEXT = "text"
+
class FilterMappingString(Enum):
HIDDEN_CHARACTERS = "hidden_characters"
MARKDOWN = "markdown"
@@ -369,15 +493,15 @@ def to_dict(self) -> dict:
return result
@dataclass
-class HandleToolCallResult:
+class HandlePendingToolCallResult:
success: bool
"""Whether the tool call result was handled successfully"""
@staticmethod
- def from_dict(obj: Any) -> 'HandleToolCallResult':
+ def from_dict(obj: Any) -> 'HandlePendingToolCallResult':
assert isinstance(obj, dict)
success = from_bool(obj.get("success"))
- return HandleToolCallResult(success)
+ return HandlePendingToolCallResult(success)
def to_dict(self) -> dict:
result: dict = {}
@@ -934,6 +1058,7 @@ class PermissionDecisionKind(Enum):
APPROVE_FOR_LOCATION = "approve-for-location"
APPROVE_FOR_SESSION = "approve-for-session"
APPROVE_ONCE = "approve-once"
+ APPROVE_PERMANENTLY = "approve-permanently"
REJECT = "reject"
USER_NOT_AVAILABLE = "user-not-available"
@@ -967,6 +1092,9 @@ class PermissionDecisionApproveForSessionKind(Enum):
class PermissionDecisionApproveOnceKind(Enum):
APPROVE_ONCE = "approve-once"
+class PermissionDecisionApprovePermanentlyKind(Enum):
+ APPROVE_PERMANENTLY = "approve-permanently"
+
class PermissionDecisionRejectKind(Enum):
REJECT = "reject"
@@ -1982,40 +2110,6 @@ def to_dict(self) -> dict:
result["parameters"] = from_union([lambda x: from_dict(lambda x: x, x), from_none], self.parameters)
return result
-@dataclass
-class ToolCallResult:
- text_result_for_llm: str
- """Text result to send back to the LLM"""
-
- error: str | None = None
- """Error message if the tool call failed"""
-
- result_type: str | None = None
- """Type of the tool result"""
-
- tool_telemetry: dict[str, Any] | None = None
- """Telemetry data from tool execution"""
-
- @staticmethod
- def from_dict(obj: Any) -> 'ToolCallResult':
- assert isinstance(obj, dict)
- text_result_for_llm = from_str(obj.get("textResultForLlm"))
- error = from_union([from_str, from_none], obj.get("error"))
- result_type = from_union([from_str, from_none], obj.get("resultType"))
- tool_telemetry = from_union([lambda x: from_dict(lambda x: x, x), from_none], obj.get("toolTelemetry"))
- return ToolCallResult(text_result_for_llm, error, result_type, tool_telemetry)
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["textResultForLlm"] = from_str(self.text_result_for_llm)
- if self.error is not None:
- result["error"] = from_union([from_str, from_none], self.error)
- if self.result_type is not None:
- result["resultType"] = from_union([from_str, from_none], self.result_type)
- if self.tool_telemetry is not None:
- result["toolTelemetry"] = from_union([lambda x: from_dict(lambda x: x, x), from_none], self.tool_telemetry)
- return result
-
@dataclass
class ToolsListRequest:
model: str | None = None
@@ -2176,6 +2270,22 @@ def to_dict(self) -> dict:
result["count"] = from_int(self.count)
return result
+@dataclass
+class UsageMetricsModelMetricTokenDetail:
+ token_count: int
+ """Accumulated token count for this token type"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'UsageMetricsModelMetricTokenDetail':
+ assert isinstance(obj, dict)
+ token_count = from_int(obj.get("tokenCount"))
+ return UsageMetricsModelMetricTokenDetail(token_count)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["tokenCount"] = from_int(self.token_count)
+ return result
+
@dataclass
class UsageMetricsModelMetricUsage:
"""Token usage metrics for this model"""
@@ -2215,6 +2325,22 @@ def to_dict(self) -> dict:
result["reasoningTokens"] = from_union([from_int, from_none], self.reasoning_tokens)
return result
+@dataclass
+class UsageMetricsTokenDetail:
+ token_count: int
+ """Accumulated token count for this token type"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'UsageMetricsTokenDetail':
+ assert isinstance(obj, dict)
+ token_count = from_int(obj.get("tokenCount"))
+ return UsageMetricsTokenDetail(token_count)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["tokenCount"] = from_int(self.token_count)
+ return result
+
@dataclass
class WorkspacesCreateFileRequest:
content: str
@@ -2493,6 +2619,179 @@ def to_dict(self) -> dict:
result["pid"] = from_union([from_int, from_none], self.pid)
return result
+@dataclass
+class ExternalToolTextResultForLlmContentResourceLinkIcon:
+ """Icon image for a resource"""
+
+ src: str
+ """URL or path to the icon image"""
+
+ mime_type: str | None = None
+ """MIME type of the icon image"""
+
+ sizes: list[str] | None = None
+ """Available icon sizes (e.g., ['16x16', '32x32'])"""
+
+ theme: ExternalToolTextResultForLlmContentResourceLinkIconTheme | None = None
+ """Theme variant this icon is intended for"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentResourceLinkIcon':
+ assert isinstance(obj, dict)
+ src = from_str(obj.get("src"))
+ mime_type = from_union([from_str, from_none], obj.get("mimeType"))
+ sizes = from_union([lambda x: from_list(from_str, x), from_none], obj.get("sizes"))
+ theme = from_union([ExternalToolTextResultForLlmContentResourceLinkIconTheme, from_none], obj.get("theme"))
+ return ExternalToolTextResultForLlmContentResourceLinkIcon(src, mime_type, sizes, theme)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["src"] = from_str(self.src)
+ if self.mime_type is not None:
+ result["mimeType"] = from_union([from_str, from_none], self.mime_type)
+ if self.sizes is not None:
+ result["sizes"] = from_union([lambda x: from_list(from_str, x), from_none], self.sizes)
+ if self.theme is not None:
+ result["theme"] = from_union([lambda x: to_enum(ExternalToolTextResultForLlmContentResourceLinkIconTheme, x), from_none], self.theme)
+ return result
+
+@dataclass
+class ExternalToolTextResultForLlmContentAudio:
+ """Audio content block with base64-encoded data"""
+
+ data: str
+ """Base64-encoded audio data"""
+
+ mime_type: str
+ """MIME type of the audio (e.g., audio/wav, audio/mpeg)"""
+
+ type: ExternalToolTextResultForLlmContentAudioType
+ """Content block type discriminator"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentAudio':
+ assert isinstance(obj, dict)
+ data = from_str(obj.get("data"))
+ mime_type = from_str(obj.get("mimeType"))
+ type = ExternalToolTextResultForLlmContentAudioType(obj.get("type"))
+ return ExternalToolTextResultForLlmContentAudio(data, mime_type, type)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["data"] = from_str(self.data)
+ result["mimeType"] = from_str(self.mime_type)
+ result["type"] = to_enum(ExternalToolTextResultForLlmContentAudioType, self.type)
+ return result
+
+@dataclass
+class ExternalToolTextResultForLlmContentImage:
+ """Image content block with base64-encoded data"""
+
+ data: str
+ """Base64-encoded image data"""
+
+ mime_type: str
+ """MIME type of the image (e.g., image/png, image/jpeg)"""
+
+ type: ExternalToolTextResultForLlmContentImageType
+ """Content block type discriminator"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentImage':
+ assert isinstance(obj, dict)
+ data = from_str(obj.get("data"))
+ mime_type = from_str(obj.get("mimeType"))
+ type = ExternalToolTextResultForLlmContentImageType(obj.get("type"))
+ return ExternalToolTextResultForLlmContentImage(data, mime_type, type)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["data"] = from_str(self.data)
+ result["mimeType"] = from_str(self.mime_type)
+ result["type"] = to_enum(ExternalToolTextResultForLlmContentImageType, self.type)
+ return result
+
+@dataclass
+class ExternalToolTextResultForLlmContentResource:
+ """Embedded resource content block with inline text or binary data"""
+
+ resource: ExternalToolTextResultForLlmContentResourceDetails
+ """The embedded resource contents, either text or base64-encoded binary"""
+
+ type: ExternalToolTextResultForLlmContentResourceType
+ """Content block type discriminator"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentResource':
+ assert isinstance(obj, dict)
+ resource = ExternalToolTextResultForLlmContentResourceDetails.from_dict(obj.get("resource"))
+ type = ExternalToolTextResultForLlmContentResourceType(obj.get("type"))
+ return ExternalToolTextResultForLlmContentResource(resource, type)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["resource"] = to_class(ExternalToolTextResultForLlmContentResourceDetails, self.resource)
+ result["type"] = to_enum(ExternalToolTextResultForLlmContentResourceType, self.type)
+ return result
+
+@dataclass
+class ExternalToolTextResultForLlmContentTerminal:
+ """Terminal/shell output content block with optional exit code and working directory"""
+
+ text: str
+ """Terminal/shell output text"""
+
+ type: ExternalToolTextResultForLlmContentTerminalType
+ """Content block type discriminator"""
+
+ cwd: str | None = None
+ """Working directory where the command was executed"""
+
+ exit_code: float | None = None
+ """Process exit code, if the command has completed"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentTerminal':
+ assert isinstance(obj, dict)
+ text = from_str(obj.get("text"))
+ type = ExternalToolTextResultForLlmContentTerminalType(obj.get("type"))
+ cwd = from_union([from_str, from_none], obj.get("cwd"))
+ exit_code = from_union([from_float, from_none], obj.get("exitCode"))
+ return ExternalToolTextResultForLlmContentTerminal(text, type, cwd, exit_code)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["text"] = from_str(self.text)
+ result["type"] = to_enum(ExternalToolTextResultForLlmContentTerminalType, self.type)
+ if self.cwd is not None:
+ result["cwd"] = from_union([from_str, from_none], self.cwd)
+ if self.exit_code is not None:
+ result["exitCode"] = from_union([to_float, from_none], self.exit_code)
+ return result
+
+@dataclass
+class ExternalToolTextResultForLlmContentText:
+ """Plain text content block"""
+
+ text: str
+ """The text content"""
+
+ type: ExternalToolTextResultForLlmContentTextType
+ """Content block type discriminator"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentText':
+ assert isinstance(obj, dict)
+ text = from_str(obj.get("text"))
+ type = ExternalToolTextResultForLlmContentTextType(obj.get("type"))
+ return ExternalToolTextResultForLlmContentText(text, type)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["text"] = from_str(self.text)
+ result["type"] = to_enum(ExternalToolTextResultForLlmContentTextType, self.type)
+ return result
+
# Experimental: this type is part of an experimental API and may change or be removed.
@dataclass
class HistoryCompactResult:
@@ -3251,6 +3550,27 @@ def to_dict(self) -> dict:
result["kind"] = to_enum(PermissionDecisionApproveOnceKind, self.kind)
return result
+@dataclass
+class PermissionDecisionApprovePermanently:
+ domain: str
+ """The URL domain to approve permanently"""
+
+ kind: PermissionDecisionApprovePermanentlyKind
+ """Approved and persisted across sessions"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'PermissionDecisionApprovePermanently':
+ assert isinstance(obj, dict)
+ domain = from_str(obj.get("domain"))
+ kind = PermissionDecisionApprovePermanentlyKind(obj.get("kind"))
+ return PermissionDecisionApprovePermanently(domain, kind)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["domain"] = from_str(self.domain)
+ result["kind"] = to_enum(PermissionDecisionApprovePermanentlyKind, self.kind)
+ return result
+
@dataclass
class PermissionDecisionReject:
kind: PermissionDecisionRejectKind
@@ -3525,34 +3845,6 @@ def to_dict(self) -> dict:
result["tools"] = from_list(lambda x: to_class(Tool, x), self.tools)
return result
-@dataclass
-class ToolsHandlePendingToolCallRequest:
- request_id: str
- """Request ID of the pending tool call"""
-
- error: str | None = None
- """Error message if the tool call failed"""
-
- result: ToolCallResult | str | None = None
- """Tool call result (string or expanded result object)"""
-
- @staticmethod
- def from_dict(obj: Any) -> 'ToolsHandlePendingToolCallRequest':
- assert isinstance(obj, dict)
- request_id = from_str(obj.get("requestId"))
- error = from_union([from_str, from_none], obj.get("error"))
- result = from_union([ToolCallResult.from_dict, from_str, from_none], obj.get("result"))
- return ToolsHandlePendingToolCallRequest(request_id, error, result)
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["requestId"] = from_str(self.request_id)
- if self.error is not None:
- result["error"] = from_union([from_str, from_none], self.error)
- if self.result is not None:
- result["result"] = from_union([lambda x: to_class(ToolCallResult, x), from_str, from_none], self.result)
- return result
-
@dataclass
class UIElicitationArrayAnyOfFieldItems:
any_of: list[UIElicitationArrayAnyOfFieldItemsAnyOf]
@@ -3807,17 +4099,29 @@ class UsageMetricsModelMetric:
usage: UsageMetricsModelMetricUsage
"""Token usage metrics for this model"""
+ token_details: dict[str, UsageMetricsModelMetricTokenDetail] | None = None
+ """Token count details per type"""
+
+ total_nano_aiu: int | None = None
+ """Accumulated nano-AI units cost for this model"""
+
@staticmethod
def from_dict(obj: Any) -> 'UsageMetricsModelMetric':
assert isinstance(obj, dict)
requests = UsageMetricsModelMetricRequests.from_dict(obj.get("requests"))
usage = UsageMetricsModelMetricUsage.from_dict(obj.get("usage"))
- return UsageMetricsModelMetric(requests, usage)
+ token_details = from_union([lambda x: from_dict(UsageMetricsModelMetricTokenDetail.from_dict, x), from_none], obj.get("tokenDetails"))
+ total_nano_aiu = from_union([from_int, from_none], obj.get("totalNanoAiu"))
+ return UsageMetricsModelMetric(requests, usage, token_details, total_nano_aiu)
def to_dict(self) -> dict:
result: dict = {}
result["requests"] = to_class(UsageMetricsModelMetricRequests, self.requests)
result["usage"] = to_class(UsageMetricsModelMetricUsage, self.usage)
+ if self.token_details is not None:
+ result["tokenDetails"] = from_union([lambda x: from_dict(lambda x: to_class(UsageMetricsModelMetricTokenDetail, x), x), from_none], self.token_details)
+ if self.total_nano_aiu is not None:
+ result["totalNanoAiu"] = from_union([from_int, from_none], self.total_nano_aiu)
return result
@dataclass
@@ -3936,6 +4240,175 @@ def to_dict(self) -> dict:
result["extensions"] = from_list(lambda x: to_class(Extension, x), self.extensions)
return result
+@dataclass
+class ExternalToolTextResultForLlmContent:
+ """A content block within a tool result, which may be text, terminal output, image, audio,
+ or a resource
+
+ Plain text content block
+
+ Terminal/shell output content block with optional exit code and working directory
+
+ Image content block with base64-encoded data
+
+ Audio content block with base64-encoded data
+
+ Resource link content block referencing an external resource
+
+ Embedded resource content block with inline text or binary data
+ """
+ type: ExternalToolTextResultForLlmContentType
+ """Content block type discriminator"""
+
+ text: str | None = None
+ """The text content
+
+ Terminal/shell output text
+ """
+ cwd: str | None = None
+ """Working directory where the command was executed"""
+
+ exit_code: float | None = None
+ """Process exit code, if the command has completed"""
+
+ data: str | None = None
+ """Base64-encoded image data
+
+ Base64-encoded audio data
+ """
+ mime_type: str | None = None
+ """MIME type of the image (e.g., image/png, image/jpeg)
+
+ MIME type of the audio (e.g., audio/wav, audio/mpeg)
+
+ MIME type of the resource content
+ """
+ description: str | None = None
+ """Human-readable description of the resource"""
+
+ icons: list[ExternalToolTextResultForLlmContentResourceLinkIcon] | None = None
+ """Icons associated with this resource"""
+
+ name: str | None = None
+ """Resource name identifier"""
+
+ size: float | None = None
+ """Size of the resource in bytes"""
+
+ title: str | None = None
+ """Human-readable display title for the resource"""
+
+ uri: str | None = None
+ """URI identifying the resource"""
+
+ resource: ExternalToolTextResultForLlmContentResourceDetails | None = None
+ """The embedded resource contents, either text or base64-encoded binary"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContent':
+ assert isinstance(obj, dict)
+ type = ExternalToolTextResultForLlmContentType(obj.get("type"))
+ text = from_union([from_str, from_none], obj.get("text"))
+ cwd = from_union([from_str, from_none], obj.get("cwd"))
+ exit_code = from_union([from_float, from_none], obj.get("exitCode"))
+ data = from_union([from_str, from_none], obj.get("data"))
+ mime_type = from_union([from_str, from_none], obj.get("mimeType"))
+ description = from_union([from_str, from_none], obj.get("description"))
+ icons = from_union([lambda x: from_list(ExternalToolTextResultForLlmContentResourceLinkIcon.from_dict, x), from_none], obj.get("icons"))
+ name = from_union([from_str, from_none], obj.get("name"))
+ size = from_union([from_float, from_none], obj.get("size"))
+ title = from_union([from_str, from_none], obj.get("title"))
+ uri = from_union([from_str, from_none], obj.get("uri"))
+ resource = from_union([ExternalToolTextResultForLlmContentResourceDetails.from_dict, from_none], obj.get("resource"))
+ return ExternalToolTextResultForLlmContent(type, text, cwd, exit_code, data, mime_type, description, icons, name, size, title, uri, resource)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["type"] = to_enum(ExternalToolTextResultForLlmContentType, self.type)
+ if self.text is not None:
+ result["text"] = from_union([from_str, from_none], self.text)
+ if self.cwd is not None:
+ result["cwd"] = from_union([from_str, from_none], self.cwd)
+ if self.exit_code is not None:
+ result["exitCode"] = from_union([to_float, from_none], self.exit_code)
+ if self.data is not None:
+ result["data"] = from_union([from_str, from_none], self.data)
+ if self.mime_type is not None:
+ result["mimeType"] = from_union([from_str, from_none], self.mime_type)
+ if self.description is not None:
+ result["description"] = from_union([from_str, from_none], self.description)
+ if self.icons is not None:
+ result["icons"] = from_union([lambda x: from_list(lambda x: to_class(ExternalToolTextResultForLlmContentResourceLinkIcon, x), x), from_none], self.icons)
+ if self.name is not None:
+ result["name"] = from_union([from_str, from_none], self.name)
+ if self.size is not None:
+ result["size"] = from_union([to_float, from_none], self.size)
+ if self.title is not None:
+ result["title"] = from_union([from_str, from_none], self.title)
+ if self.uri is not None:
+ result["uri"] = from_union([from_str, from_none], self.uri)
+ if self.resource is not None:
+ result["resource"] = from_union([lambda x: to_class(ExternalToolTextResultForLlmContentResourceDetails, x), from_none], self.resource)
+ return result
+
+@dataclass
+class ExternalToolTextResultForLlmContentResourceLink:
+ """Resource link content block referencing an external resource"""
+
+ name: str
+ """Resource name identifier"""
+
+ type: ExternalToolTextResultForLlmContentResourceLinkType
+ """Content block type discriminator"""
+
+ uri: str
+ """URI identifying the resource"""
+
+ description: str | None = None
+ """Human-readable description of the resource"""
+
+ icons: list[ExternalToolTextResultForLlmContentResourceLinkIcon] | None = None
+ """Icons associated with this resource"""
+
+ mime_type: str | None = None
+ """MIME type of the resource content"""
+
+ size: float | None = None
+ """Size of the resource in bytes"""
+
+ title: str | None = None
+ """Human-readable display title for the resource"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmContentResourceLink':
+ assert isinstance(obj, dict)
+ name = from_str(obj.get("name"))
+ type = ExternalToolTextResultForLlmContentResourceLinkType(obj.get("type"))
+ uri = from_str(obj.get("uri"))
+ description = from_union([from_str, from_none], obj.get("description"))
+ icons = from_union([lambda x: from_list(ExternalToolTextResultForLlmContentResourceLinkIcon.from_dict, x), from_none], obj.get("icons"))
+ mime_type = from_union([from_str, from_none], obj.get("mimeType"))
+ size = from_union([from_float, from_none], obj.get("size"))
+ title = from_union([from_str, from_none], obj.get("title"))
+ return ExternalToolTextResultForLlmContentResourceLink(name, type, uri, description, icons, mime_type, size, title)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["name"] = from_str(self.name)
+ result["type"] = to_enum(ExternalToolTextResultForLlmContentResourceLinkType, self.type)
+ result["uri"] = from_str(self.uri)
+ if self.description is not None:
+ result["description"] = from_union([from_str, from_none], self.description)
+ if self.icons is not None:
+ result["icons"] = from_union([lambda x: from_list(lambda x: to_class(ExternalToolTextResultForLlmContentResourceLinkIcon, x), x), from_none], self.icons)
+ if self.mime_type is not None:
+ result["mimeType"] = from_union([from_str, from_none], self.mime_type)
+ if self.size is not None:
+ result["size"] = from_union([to_float, from_none], self.size)
+ if self.title is not None:
+ result["title"] = from_union([from_str, from_none], self.title)
+ return result
+
@dataclass
class InstructionsGetSourcesResult:
sources: list[InstructionsSources]
@@ -4060,6 +4533,8 @@ class PermissionDecision:
Approved and persisted for this project location
+ Approved and persisted across sessions
+
Denied by the user during an interactive prompt
Denied because user confirmation was unavailable
@@ -4069,6 +4544,11 @@ class PermissionDecision:
The approval to persist for this location
"""
+ domain: str | None = None
+ """The URL domain to approve for this session
+
+ The URL domain to approve permanently
+ """
location_key: str | None = None
"""The location key (git root or cwd) to persist the approval to"""
@@ -4080,15 +4560,18 @@ def from_dict(obj: Any) -> 'PermissionDecision':
assert isinstance(obj, dict)
kind = PermissionDecisionKind(obj.get("kind"))
approval = from_union([PermissionDecisionApproveForIonApproval.from_dict, from_none], obj.get("approval"))
+ domain = from_union([from_str, from_none], obj.get("domain"))
location_key = from_union([from_str, from_none], obj.get("locationKey"))
feedback = from_union([from_str, from_none], obj.get("feedback"))
- return PermissionDecision(kind, approval, location_key, feedback)
+ return PermissionDecision(kind, approval, domain, location_key, feedback)
def to_dict(self) -> dict:
result: dict = {}
result["kind"] = to_enum(PermissionDecisionKind, self.kind)
if self.approval is not None:
result["approval"] = from_union([lambda x: to_class(PermissionDecisionApproveForIonApproval, x), from_none], self.approval)
+ if self.domain is not None:
+ result["domain"] = from_union([from_str, from_none], self.domain)
if self.location_key is not None:
result["locationKey"] = from_union([from_str, from_none], self.location_key)
if self.feedback is not None:
@@ -4123,23 +4606,30 @@ def to_dict(self) -> dict:
@dataclass
class PermissionDecisionApproveForSession:
- approval: PermissionDecisionApproveForSessionApproval
- """The approval to add as a session-scoped rule"""
-
kind: PermissionDecisionApproveForSessionKind
"""Approved and remembered for the rest of the session"""
+ approval: PermissionDecisionApproveForSessionApproval | None = None
+ """The approval to add as a session-scoped rule"""
+
+ domain: str | None = None
+ """The URL domain to approve for this session"""
+
@staticmethod
def from_dict(obj: Any) -> 'PermissionDecisionApproveForSession':
assert isinstance(obj, dict)
- approval = PermissionDecisionApproveForSessionApproval.from_dict(obj.get("approval"))
kind = PermissionDecisionApproveForSessionKind(obj.get("kind"))
- return PermissionDecisionApproveForSession(approval, kind)
+ approval = from_union([PermissionDecisionApproveForSessionApproval.from_dict, from_none], obj.get("approval"))
+ domain = from_union([from_str, from_none], obj.get("domain"))
+ return PermissionDecisionApproveForSession(kind, approval, domain)
def to_dict(self) -> dict:
result: dict = {}
- result["approval"] = to_class(PermissionDecisionApproveForSessionApproval, self.approval)
result["kind"] = to_enum(PermissionDecisionApproveForSessionKind, self.kind)
+ if self.approval is not None:
+ result["approval"] = from_union([lambda x: to_class(PermissionDecisionApproveForSessionApproval, x), from_none], self.approval)
+ if self.domain is not None:
+ result["domain"] = from_union([from_str, from_none], self.domain)
return result
@dataclass
@@ -4449,6 +4939,12 @@ class UsageGetMetricsResult:
current_model: str | None = None
"""Currently active model identifier"""
+ token_details: dict[str, UsageMetricsTokenDetail] | None = None
+ """Session-wide per-token-type accumulated token counts"""
+
+ total_nano_aiu: int | None = None
+ """Session-wide accumulated nano-AI units cost"""
+
@staticmethod
def from_dict(obj: Any) -> 'UsageGetMetricsResult':
assert isinstance(obj, dict)
@@ -4461,7 +4957,9 @@ def from_dict(obj: Any) -> 'UsageGetMetricsResult':
total_premium_request_cost = from_float(obj.get("totalPremiumRequestCost"))
total_user_requests = from_int(obj.get("totalUserRequests"))
current_model = from_union([from_str, from_none], obj.get("currentModel"))
- return UsageGetMetricsResult(code_changes, last_call_input_tokens, last_call_output_tokens, model_metrics, session_start_time, total_api_duration_ms, total_premium_request_cost, total_user_requests, current_model)
+ token_details = from_union([lambda x: from_dict(UsageMetricsTokenDetail.from_dict, x), from_none], obj.get("tokenDetails"))
+ total_nano_aiu = from_union([from_int, from_none], obj.get("totalNanoAiu"))
+ return UsageGetMetricsResult(code_changes, last_call_input_tokens, last_call_output_tokens, model_metrics, session_start_time, total_api_duration_ms, total_premium_request_cost, total_user_requests, current_model, token_details, total_nano_aiu)
def to_dict(self) -> dict:
result: dict = {}
@@ -4475,6 +4973,10 @@ def to_dict(self) -> dict:
result["totalUserRequests"] = from_int(self.total_user_requests)
if self.current_model is not None:
result["currentModel"] = from_union([from_str, from_none], self.current_model)
+ if self.token_details is not None:
+ result["tokenDetails"] = from_union([lambda x: from_dict(lambda x: to_class(UsageMetricsTokenDetail, x), x), from_none], self.token_details)
+ if self.total_nano_aiu is not None:
+ result["totalNanoAiu"] = from_union([from_int, from_none], self.total_nano_aiu)
return result
@dataclass
@@ -4493,6 +4995,55 @@ def to_dict(self) -> dict:
result["workspace"] = from_union([lambda x: to_class(Workspace, x), from_none], self.workspace)
return result
+@dataclass
+class ExternalToolTextResultForLlm:
+ """Expanded external tool result payload"""
+
+ text_result_for_llm: str
+ """Text result returned to the model"""
+
+ contents: list[ExternalToolTextResultForLlmContent] | None = None
+ """Structured content blocks from the tool"""
+
+ error: str | None = None
+ """Optional error message for failed executions"""
+
+ result_type: str | None = None
+ """Execution outcome classification. Optional for back-compat; normalized to 'success' (or
+ 'failure' when error is present) when missing or unrecognized.
+ """
+ session_log: str | None = None
+ """Detailed log content for timeline display"""
+
+ tool_telemetry: dict[str, Any] | None = None
+ """Optional tool-specific telemetry"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlm':
+ assert isinstance(obj, dict)
+ text_result_for_llm = from_str(obj.get("textResultForLlm"))
+ contents = from_union([lambda x: from_list(ExternalToolTextResultForLlmContent.from_dict, x), from_none], obj.get("contents"))
+ error = from_union([from_str, from_none], obj.get("error"))
+ result_type = from_union([from_str, from_none], obj.get("resultType"))
+ session_log = from_union([from_str, from_none], obj.get("sessionLog"))
+ tool_telemetry = from_union([lambda x: from_dict(lambda x: x, x), from_none], obj.get("toolTelemetry"))
+ return ExternalToolTextResultForLlm(text_result_for_llm, contents, error, result_type, session_log, tool_telemetry)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["textResultForLlm"] = from_str(self.text_result_for_llm)
+ if self.contents is not None:
+ result["contents"] = from_union([lambda x: from_list(lambda x: to_class(ExternalToolTextResultForLlmContent, x), x), from_none], self.contents)
+ if self.error is not None:
+ result["error"] = from_union([from_str, from_none], self.error)
+ if self.result_type is not None:
+ result["resultType"] = from_union([from_str, from_none], self.result_type)
+ if self.session_log is not None:
+ result["sessionLog"] = from_union([from_str, from_none], self.session_log)
+ if self.tool_telemetry is not None:
+ result["toolTelemetry"] = from_union([lambda x: from_dict(lambda x: x, x), from_none], self.tool_telemetry)
+ return result
+
@dataclass
class PermissionDecisionRequest:
request_id: str
@@ -4542,6 +5093,34 @@ def to_dict(self) -> dict:
result["required"] = from_union([lambda x: from_list(from_str, x), from_none], self.required)
return result
+@dataclass
+class HandlePendingToolCallRequest:
+ request_id: str
+ """Request ID of the pending tool call"""
+
+ error: str | None = None
+ """Error message if the tool call failed"""
+
+ result: ExternalToolTextResultForLlm | str | None = None
+ """Tool call result (string or expanded result object)"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'HandlePendingToolCallRequest':
+ assert isinstance(obj, dict)
+ request_id = from_str(obj.get("requestId"))
+ error = from_union([from_str, from_none], obj.get("error"))
+ result = from_union([ExternalToolTextResultForLlm.from_dict, from_str, from_none], obj.get("result"))
+ return HandlePendingToolCallRequest(request_id, error, result)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["requestId"] = from_str(self.request_id)
+ if self.error is not None:
+ result["error"] = from_union([from_str, from_none], self.error)
+ if self.result is not None:
+ result["result"] = from_union([lambda x: to_class(ExternalToolTextResultForLlm, x), from_str, from_none], self.result)
+ return result
+
@dataclass
class UIElicitationRequest:
message: str
@@ -4975,18 +5554,33 @@ class RPC:
discovered_mcp_server: DiscoveredMCPServer
discovered_mcp_server_source: MCPServerSource
discovered_mcp_server_type: DiscoveredMCPServerType
+ embedded_blob_resource_contents: EmbeddedBlobResourceContents
+ embedded_text_resource_contents: EmbeddedTextResourceContents
extension: Extension
extension_list: ExtensionList
extensions_disable_request: ExtensionsDisableRequest
extensions_enable_request: ExtensionsEnableRequest
extension_source: ExtensionSource
extension_status: ExtensionStatus
+ external_tool_result: ExternalToolTextResultForLlm | str
+ external_tool_text_result_for_llm: ExternalToolTextResultForLlm
+ external_tool_text_result_for_llm_content: ExternalToolTextResultForLlmContent
+ external_tool_text_result_for_llm_content_audio: ExternalToolTextResultForLlmContentAudio
+ external_tool_text_result_for_llm_content_image: ExternalToolTextResultForLlmContentImage
+ external_tool_text_result_for_llm_content_resource: ExternalToolTextResultForLlmContentResource
+ external_tool_text_result_for_llm_content_resource_details: ExternalToolTextResultForLlmContentResourceDetails
+ external_tool_text_result_for_llm_content_resource_link: ExternalToolTextResultForLlmContentResourceLink
+ external_tool_text_result_for_llm_content_resource_link_icon: ExternalToolTextResultForLlmContentResourceLinkIcon
+ external_tool_text_result_for_llm_content_resource_link_icon_theme: ExternalToolTextResultForLlmContentResourceLinkIconTheme
+ external_tool_text_result_for_llm_content_terminal: ExternalToolTextResultForLlmContentTerminal
+ external_tool_text_result_for_llm_content_text: ExternalToolTextResultForLlmContentText
filter_mapping: dict[str, FilterMappingString] | FilterMappingString
filter_mapping_string: FilterMappingString
filter_mapping_value: FilterMappingString
fleet_start_request: FleetStartRequest
fleet_start_result: FleetStartResult
- handle_tool_call_result: HandleToolCallResult
+ handle_pending_tool_call_request: HandlePendingToolCallRequest
+ handle_pending_tool_call_result: HandlePendingToolCallResult
history_compact_context_window: HistoryCompactContextWindow
history_compact_result: HistoryCompactResult
history_truncate_request: HistoryTruncateRequest
@@ -5056,6 +5650,7 @@ class RPC:
permission_decision_approve_for_session_approval_read: PermissionDecisionApproveForSessionApprovalRead
permission_decision_approve_for_session_approval_write: PermissionDecisionApproveForSessionApprovalWrite
permission_decision_approve_once: PermissionDecisionApproveOnce
+ permission_decision_approve_permanently: PermissionDecisionApprovePermanently
permission_decision_reject: PermissionDecisionReject
permission_decision_request: PermissionDecisionRequest
permission_decision_user_not_available: PermissionDecisionUserNotAvailable
@@ -5128,10 +5723,7 @@ class RPC:
tasks_start_agent_request: TasksStartAgentRequest
tasks_start_agent_result: TasksStartAgentResult
tool: Tool
- tool_call_result: ToolCallResult
tool_list: ToolList
- tools_handle_pending_tool_call: ToolCallResult | str
- tools_handle_pending_tool_call_request: ToolsHandlePendingToolCallRequest
tools_list_request: ToolsListRequest
ui_elicitation_array_any_of_field: UIElicitationArrayAnyOfField
ui_elicitation_array_any_of_field_items: UIElicitationArrayAnyOfFieldItems
@@ -5159,7 +5751,9 @@ class RPC:
usage_metrics_code_changes: UsageMetricsCodeChanges
usage_metrics_model_metric: UsageMetricsModelMetric
usage_metrics_model_metric_requests: UsageMetricsModelMetricRequests
+ usage_metrics_model_metric_token_detail: UsageMetricsModelMetricTokenDetail
usage_metrics_model_metric_usage: UsageMetricsModelMetricUsage
+ usage_metrics_token_detail: UsageMetricsTokenDetail
workspaces_create_file_request: WorkspacesCreateFileRequest
workspaces_get_workspace_result: WorkspacesGetWorkspaceResult
workspaces_list_files_result: WorkspacesListFilesResult
@@ -5185,18 +5779,33 @@ def from_dict(obj: Any) -> 'RPC':
discovered_mcp_server = DiscoveredMCPServer.from_dict(obj.get("DiscoveredMcpServer"))
discovered_mcp_server_source = MCPServerSource(obj.get("DiscoveredMcpServerSource"))
discovered_mcp_server_type = DiscoveredMCPServerType(obj.get("DiscoveredMcpServerType"))
+ embedded_blob_resource_contents = EmbeddedBlobResourceContents.from_dict(obj.get("EmbeddedBlobResourceContents"))
+ embedded_text_resource_contents = EmbeddedTextResourceContents.from_dict(obj.get("EmbeddedTextResourceContents"))
extension = Extension.from_dict(obj.get("Extension"))
extension_list = ExtensionList.from_dict(obj.get("ExtensionList"))
extensions_disable_request = ExtensionsDisableRequest.from_dict(obj.get("ExtensionsDisableRequest"))
extensions_enable_request = ExtensionsEnableRequest.from_dict(obj.get("ExtensionsEnableRequest"))
extension_source = ExtensionSource(obj.get("ExtensionSource"))
extension_status = ExtensionStatus(obj.get("ExtensionStatus"))
+ external_tool_result = from_union([ExternalToolTextResultForLlm.from_dict, from_str], obj.get("ExternalToolResult"))
+ external_tool_text_result_for_llm = ExternalToolTextResultForLlm.from_dict(obj.get("ExternalToolTextResultForLlm"))
+ external_tool_text_result_for_llm_content = ExternalToolTextResultForLlmContent.from_dict(obj.get("ExternalToolTextResultForLlmContent"))
+ external_tool_text_result_for_llm_content_audio = ExternalToolTextResultForLlmContentAudio.from_dict(obj.get("ExternalToolTextResultForLlmContentAudio"))
+ external_tool_text_result_for_llm_content_image = ExternalToolTextResultForLlmContentImage.from_dict(obj.get("ExternalToolTextResultForLlmContentImage"))
+ external_tool_text_result_for_llm_content_resource = ExternalToolTextResultForLlmContentResource.from_dict(obj.get("ExternalToolTextResultForLlmContentResource"))
+ external_tool_text_result_for_llm_content_resource_details = ExternalToolTextResultForLlmContentResourceDetails.from_dict(obj.get("ExternalToolTextResultForLlmContentResourceDetails"))
+ external_tool_text_result_for_llm_content_resource_link = ExternalToolTextResultForLlmContentResourceLink.from_dict(obj.get("ExternalToolTextResultForLlmContentResourceLink"))
+ external_tool_text_result_for_llm_content_resource_link_icon = ExternalToolTextResultForLlmContentResourceLinkIcon.from_dict(obj.get("ExternalToolTextResultForLlmContentResourceLinkIcon"))
+ external_tool_text_result_for_llm_content_resource_link_icon_theme = ExternalToolTextResultForLlmContentResourceLinkIconTheme(obj.get("ExternalToolTextResultForLlmContentResourceLinkIconTheme"))
+ external_tool_text_result_for_llm_content_terminal = ExternalToolTextResultForLlmContentTerminal.from_dict(obj.get("ExternalToolTextResultForLlmContentTerminal"))
+ external_tool_text_result_for_llm_content_text = ExternalToolTextResultForLlmContentText.from_dict(obj.get("ExternalToolTextResultForLlmContentText"))
filter_mapping = from_union([lambda x: from_dict(FilterMappingString, x), FilterMappingString], obj.get("FilterMapping"))
filter_mapping_string = FilterMappingString(obj.get("FilterMappingString"))
filter_mapping_value = FilterMappingString(obj.get("FilterMappingValue"))
fleet_start_request = FleetStartRequest.from_dict(obj.get("FleetStartRequest"))
fleet_start_result = FleetStartResult.from_dict(obj.get("FleetStartResult"))
- handle_tool_call_result = HandleToolCallResult.from_dict(obj.get("HandleToolCallResult"))
+ handle_pending_tool_call_request = HandlePendingToolCallRequest.from_dict(obj.get("HandlePendingToolCallRequest"))
+ handle_pending_tool_call_result = HandlePendingToolCallResult.from_dict(obj.get("HandlePendingToolCallResult"))
history_compact_context_window = HistoryCompactContextWindow.from_dict(obj.get("HistoryCompactContextWindow"))
history_compact_result = HistoryCompactResult.from_dict(obj.get("HistoryCompactResult"))
history_truncate_request = HistoryTruncateRequest.from_dict(obj.get("HistoryTruncateRequest"))
@@ -5266,6 +5875,7 @@ def from_dict(obj: Any) -> 'RPC':
permission_decision_approve_for_session_approval_read = PermissionDecisionApproveForSessionApprovalRead.from_dict(obj.get("PermissionDecisionApproveForSessionApprovalRead"))
permission_decision_approve_for_session_approval_write = PermissionDecisionApproveForSessionApprovalWrite.from_dict(obj.get("PermissionDecisionApproveForSessionApprovalWrite"))
permission_decision_approve_once = PermissionDecisionApproveOnce.from_dict(obj.get("PermissionDecisionApproveOnce"))
+ permission_decision_approve_permanently = PermissionDecisionApprovePermanently.from_dict(obj.get("PermissionDecisionApprovePermanently"))
permission_decision_reject = PermissionDecisionReject.from_dict(obj.get("PermissionDecisionReject"))
permission_decision_request = PermissionDecisionRequest.from_dict(obj.get("PermissionDecisionRequest"))
permission_decision_user_not_available = PermissionDecisionUserNotAvailable.from_dict(obj.get("PermissionDecisionUserNotAvailable"))
@@ -5338,10 +5948,7 @@ def from_dict(obj: Any) -> 'RPC':
tasks_start_agent_request = TasksStartAgentRequest.from_dict(obj.get("TasksStartAgentRequest"))
tasks_start_agent_result = TasksStartAgentResult.from_dict(obj.get("TasksStartAgentResult"))
tool = Tool.from_dict(obj.get("Tool"))
- tool_call_result = ToolCallResult.from_dict(obj.get("ToolCallResult"))
tool_list = ToolList.from_dict(obj.get("ToolList"))
- tools_handle_pending_tool_call = from_union([ToolCallResult.from_dict, from_str], obj.get("ToolsHandlePendingToolCall"))
- tools_handle_pending_tool_call_request = ToolsHandlePendingToolCallRequest.from_dict(obj.get("ToolsHandlePendingToolCallRequest"))
tools_list_request = ToolsListRequest.from_dict(obj.get("ToolsListRequest"))
ui_elicitation_array_any_of_field = UIElicitationArrayAnyOfField.from_dict(obj.get("UIElicitationArrayAnyOfField"))
ui_elicitation_array_any_of_field_items = UIElicitationArrayAnyOfFieldItems.from_dict(obj.get("UIElicitationArrayAnyOfFieldItems"))
@@ -5369,13 +5976,15 @@ def from_dict(obj: Any) -> 'RPC':
usage_metrics_code_changes = UsageMetricsCodeChanges.from_dict(obj.get("UsageMetricsCodeChanges"))
usage_metrics_model_metric = UsageMetricsModelMetric.from_dict(obj.get("UsageMetricsModelMetric"))
usage_metrics_model_metric_requests = UsageMetricsModelMetricRequests.from_dict(obj.get("UsageMetricsModelMetricRequests"))
+ usage_metrics_model_metric_token_detail = UsageMetricsModelMetricTokenDetail.from_dict(obj.get("UsageMetricsModelMetricTokenDetail"))
usage_metrics_model_metric_usage = UsageMetricsModelMetricUsage.from_dict(obj.get("UsageMetricsModelMetricUsage"))
+ usage_metrics_token_detail = UsageMetricsTokenDetail.from_dict(obj.get("UsageMetricsTokenDetail"))
workspaces_create_file_request = WorkspacesCreateFileRequest.from_dict(obj.get("WorkspacesCreateFileRequest"))
workspaces_get_workspace_result = WorkspacesGetWorkspaceResult.from_dict(obj.get("WorkspacesGetWorkspaceResult"))
workspaces_list_files_result = WorkspacesListFilesResult.from_dict(obj.get("WorkspacesListFilesResult"))
workspaces_read_file_request = WorkspacesReadFileRequest.from_dict(obj.get("WorkspacesReadFileRequest"))
workspaces_read_file_result = WorkspacesReadFileResult.from_dict(obj.get("WorkspacesReadFileResult"))
- return RPC(account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_list, agent_reload_result, agent_select_request, agent_select_result, auth_info_type, commands_handle_pending_command_request, commands_handle_pending_command_result, current_model, discovered_mcp_server, discovered_mcp_server_source, discovered_mcp_server_type, extension, extension_list, extensions_disable_request, extensions_enable_request, extension_source, extension_status, filter_mapping, filter_mapping_string, filter_mapping_value, fleet_start_request, fleet_start_result, handle_tool_call_result, history_compact_context_window, history_compact_result, history_truncate_request, history_truncate_result, instructions_get_sources_result, instructions_sources, instructions_sources_location, instructions_sources_type, log_request, log_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_oauth_login_request, mcp_oauth_login_result, mcp_server, mcp_server_config, mcp_server_config_http, mcp_server_config_http_type, mcp_server_config_local, mcp_server_config_local_type, mcp_server_list, mcp_server_source, mcp_server_status, model, model_billing, 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_policy, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, name_get_result, name_set_request, permission_decision, 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_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_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_reject, permission_decision_request, permission_decision_user_not_available, permission_request_result, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_approve_all_request, permissions_set_approve_all_result, ping_request, ping_result, plan_read_result, plan_update_request, plugin, plugin_list, server_skill, server_skill_list, session_auth_status, 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_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_log_level, session_mode, sessions_fork_request, sessions_fork_result, shell_exec_request, shell_exec_result, shell_kill_request, shell_kill_result, shell_kill_signal, skill, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, task_agent_info, task_agent_info_execution_mode, task_agent_info_status, task_info, task_list, tasks_cancel_request, tasks_cancel_result, task_shell_info, task_shell_info_attachment_mode, task_shell_info_execution_mode, task_shell_info_status, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_remove_request, tasks_remove_result, tasks_start_agent_request, tasks_start_agent_result, tool, tool_call_result, tool_list, tools_handle_pending_tool_call, tools_handle_pending_tool_call_request, tools_list_request, 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_handle_pending_elicitation_request, usage_get_metrics_result, usage_metrics_code_changes, usage_metrics_model_metric, usage_metrics_model_metric_requests, usage_metrics_model_metric_usage, workspaces_create_file_request, workspaces_get_workspace_result, workspaces_list_files_result, workspaces_read_file_request, workspaces_read_file_result)
+ return RPC(account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_list, agent_reload_result, agent_select_request, agent_select_result, auth_info_type, commands_handle_pending_command_request, commands_handle_pending_command_result, current_model, discovered_mcp_server, discovered_mcp_server_source, discovered_mcp_server_type, embedded_blob_resource_contents, embedded_text_resource_contents, 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_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, filter_mapping_string, filter_mapping_value, fleet_start_request, fleet_start_result, handle_pending_tool_call_request, handle_pending_tool_call_result, history_compact_context_window, history_compact_result, history_truncate_request, history_truncate_result, instructions_get_sources_result, instructions_sources, instructions_sources_location, instructions_sources_type, log_request, log_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_oauth_login_request, mcp_oauth_login_result, mcp_server, mcp_server_config, mcp_server_config_http, mcp_server_config_http_type, mcp_server_config_local, mcp_server_config_local_type, mcp_server_list, mcp_server_source, mcp_server_status, model, model_billing, 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_policy, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, name_get_result, name_set_request, permission_decision, 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_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_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_reject, permission_decision_request, permission_decision_user_not_available, permission_request_result, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_approve_all_request, permissions_set_approve_all_result, ping_request, ping_result, plan_read_result, plan_update_request, plugin, plugin_list, server_skill, server_skill_list, session_auth_status, 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_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_log_level, session_mode, sessions_fork_request, sessions_fork_result, shell_exec_request, shell_exec_result, shell_kill_request, shell_kill_result, shell_kill_signal, skill, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, task_agent_info, task_agent_info_execution_mode, task_agent_info_status, task_info, task_list, tasks_cancel_request, tasks_cancel_result, task_shell_info, task_shell_info_attachment_mode, task_shell_info_execution_mode, task_shell_info_status, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_remove_request, tasks_remove_result, tasks_start_agent_request, tasks_start_agent_result, tool, tool_list, tools_list_request, 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_handle_pending_elicitation_request, 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, workspaces_create_file_request, workspaces_get_workspace_result, workspaces_list_files_result, workspaces_read_file_request, workspaces_read_file_result)
def to_dict(self) -> dict:
result: dict = {}
@@ -5395,18 +6004,33 @@ def to_dict(self) -> dict:
result["DiscoveredMcpServer"] = to_class(DiscoveredMCPServer, self.discovered_mcp_server)
result["DiscoveredMcpServerSource"] = to_enum(MCPServerSource, self.discovered_mcp_server_source)
result["DiscoveredMcpServerType"] = to_enum(DiscoveredMCPServerType, self.discovered_mcp_server_type)
+ result["EmbeddedBlobResourceContents"] = to_class(EmbeddedBlobResourceContents, self.embedded_blob_resource_contents)
+ result["EmbeddedTextResourceContents"] = to_class(EmbeddedTextResourceContents, self.embedded_text_resource_contents)
result["Extension"] = to_class(Extension, self.extension)
result["ExtensionList"] = to_class(ExtensionList, self.extension_list)
result["ExtensionsDisableRequest"] = to_class(ExtensionsDisableRequest, self.extensions_disable_request)
result["ExtensionsEnableRequest"] = to_class(ExtensionsEnableRequest, self.extensions_enable_request)
result["ExtensionSource"] = to_enum(ExtensionSource, self.extension_source)
result["ExtensionStatus"] = to_enum(ExtensionStatus, self.extension_status)
+ result["ExternalToolResult"] = from_union([lambda x: to_class(ExternalToolTextResultForLlm, x), from_str], self.external_tool_result)
+ result["ExternalToolTextResultForLlm"] = to_class(ExternalToolTextResultForLlm, self.external_tool_text_result_for_llm)
+ result["ExternalToolTextResultForLlmContent"] = to_class(ExternalToolTextResultForLlmContent, self.external_tool_text_result_for_llm_content)
+ result["ExternalToolTextResultForLlmContentAudio"] = to_class(ExternalToolTextResultForLlmContentAudio, self.external_tool_text_result_for_llm_content_audio)
+ result["ExternalToolTextResultForLlmContentImage"] = to_class(ExternalToolTextResultForLlmContentImage, self.external_tool_text_result_for_llm_content_image)
+ result["ExternalToolTextResultForLlmContentResource"] = to_class(ExternalToolTextResultForLlmContentResource, self.external_tool_text_result_for_llm_content_resource)
+ result["ExternalToolTextResultForLlmContentResourceDetails"] = to_class(ExternalToolTextResultForLlmContentResourceDetails, self.external_tool_text_result_for_llm_content_resource_details)
+ result["ExternalToolTextResultForLlmContentResourceLink"] = to_class(ExternalToolTextResultForLlmContentResourceLink, self.external_tool_text_result_for_llm_content_resource_link)
+ result["ExternalToolTextResultForLlmContentResourceLinkIcon"] = to_class(ExternalToolTextResultForLlmContentResourceLinkIcon, self.external_tool_text_result_for_llm_content_resource_link_icon)
+ result["ExternalToolTextResultForLlmContentResourceLinkIconTheme"] = to_enum(ExternalToolTextResultForLlmContentResourceLinkIconTheme, self.external_tool_text_result_for_llm_content_resource_link_icon_theme)
+ result["ExternalToolTextResultForLlmContentTerminal"] = to_class(ExternalToolTextResultForLlmContentTerminal, self.external_tool_text_result_for_llm_content_terminal)
+ result["ExternalToolTextResultForLlmContentText"] = to_class(ExternalToolTextResultForLlmContentText, self.external_tool_text_result_for_llm_content_text)
result["FilterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(FilterMappingString, x), x), lambda x: to_enum(FilterMappingString, x)], self.filter_mapping)
result["FilterMappingString"] = to_enum(FilterMappingString, self.filter_mapping_string)
result["FilterMappingValue"] = to_enum(FilterMappingString, self.filter_mapping_value)
result["FleetStartRequest"] = to_class(FleetStartRequest, self.fleet_start_request)
result["FleetStartResult"] = to_class(FleetStartResult, self.fleet_start_result)
- result["HandleToolCallResult"] = to_class(HandleToolCallResult, self.handle_tool_call_result)
+ result["HandlePendingToolCallRequest"] = to_class(HandlePendingToolCallRequest, self.handle_pending_tool_call_request)
+ result["HandlePendingToolCallResult"] = to_class(HandlePendingToolCallResult, self.handle_pending_tool_call_result)
result["HistoryCompactContextWindow"] = to_class(HistoryCompactContextWindow, self.history_compact_context_window)
result["HistoryCompactResult"] = to_class(HistoryCompactResult, self.history_compact_result)
result["HistoryTruncateRequest"] = to_class(HistoryTruncateRequest, self.history_truncate_request)
@@ -5476,6 +6100,7 @@ def to_dict(self) -> dict:
result["PermissionDecisionApproveForSessionApprovalRead"] = to_class(PermissionDecisionApproveForSessionApprovalRead, self.permission_decision_approve_for_session_approval_read)
result["PermissionDecisionApproveForSessionApprovalWrite"] = to_class(PermissionDecisionApproveForSessionApprovalWrite, self.permission_decision_approve_for_session_approval_write)
result["PermissionDecisionApproveOnce"] = to_class(PermissionDecisionApproveOnce, self.permission_decision_approve_once)
+ result["PermissionDecisionApprovePermanently"] = to_class(PermissionDecisionApprovePermanently, self.permission_decision_approve_permanently)
result["PermissionDecisionReject"] = to_class(PermissionDecisionReject, self.permission_decision_reject)
result["PermissionDecisionRequest"] = to_class(PermissionDecisionRequest, self.permission_decision_request)
result["PermissionDecisionUserNotAvailable"] = to_class(PermissionDecisionUserNotAvailable, self.permission_decision_user_not_available)
@@ -5548,10 +6173,7 @@ def to_dict(self) -> dict:
result["TasksStartAgentRequest"] = to_class(TasksStartAgentRequest, self.tasks_start_agent_request)
result["TasksStartAgentResult"] = to_class(TasksStartAgentResult, self.tasks_start_agent_result)
result["Tool"] = to_class(Tool, self.tool)
- result["ToolCallResult"] = to_class(ToolCallResult, self.tool_call_result)
result["ToolList"] = to_class(ToolList, self.tool_list)
- result["ToolsHandlePendingToolCall"] = from_union([lambda x: to_class(ToolCallResult, x), from_str], self.tools_handle_pending_tool_call)
- result["ToolsHandlePendingToolCallRequest"] = to_class(ToolsHandlePendingToolCallRequest, self.tools_handle_pending_tool_call_request)
result["ToolsListRequest"] = to_class(ToolsListRequest, self.tools_list_request)
result["UIElicitationArrayAnyOfField"] = to_class(UIElicitationArrayAnyOfField, self.ui_elicitation_array_any_of_field)
result["UIElicitationArrayAnyOfFieldItems"] = to_class(UIElicitationArrayAnyOfFieldItems, self.ui_elicitation_array_any_of_field_items)
@@ -5579,7 +6201,9 @@ def to_dict(self) -> dict:
result["UsageMetricsCodeChanges"] = to_class(UsageMetricsCodeChanges, self.usage_metrics_code_changes)
result["UsageMetricsModelMetric"] = to_class(UsageMetricsModelMetric, self.usage_metrics_model_metric)
result["UsageMetricsModelMetricRequests"] = to_class(UsageMetricsModelMetricRequests, self.usage_metrics_model_metric_requests)
+ result["UsageMetricsModelMetricTokenDetail"] = to_class(UsageMetricsModelMetricTokenDetail, self.usage_metrics_model_metric_token_detail)
result["UsageMetricsModelMetricUsage"] = to_class(UsageMetricsModelMetricUsage, self.usage_metrics_model_metric_usage)
+ result["UsageMetricsTokenDetail"] = to_class(UsageMetricsTokenDetail, self.usage_metrics_token_detail)
result["WorkspacesCreateFileRequest"] = to_class(WorkspacesCreateFileRequest, self.workspaces_create_file_request)
result["WorkspacesGetWorkspaceResult"] = to_class(WorkspacesGetWorkspaceResult, self.workspaces_get_workspace_result)
result["WorkspacesListFilesResult"] = to_class(WorkspacesListFilesResult, self.workspaces_list_files_result)
@@ -6004,10 +6628,10 @@ def __init__(self, client: "JsonRpcClient", session_id: str):
self._client = client
self._session_id = session_id
- async def handle_pending_tool_call(self, params: ToolsHandlePendingToolCallRequest, *, timeout: float | None = None) -> HandleToolCallResult:
+ async def handle_pending_tool_call(self, params: HandlePendingToolCallRequest, *, timeout: float | None = None) -> HandlePendingToolCallResult:
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 HandleToolCallResult.from_dict(await self._client.request("session.tools.handlePendingToolCall", params_dict, **_timeout_kwargs(timeout)))
+ return HandlePendingToolCallResult.from_dict(await self._client.request("session.tools.handlePendingToolCall", params_dict, **_timeout_kwargs(timeout)))
class CommandsApi:
diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py
index 9c0655c71..0cdd5eab0 100644
--- a/python/copilot/generated/session_events.py
+++ b/python/copilot/generated/session_events.py
@@ -307,6 +307,7 @@ class AssistantMessageData:
reasoning_text: str | None = None
request_id: str | None = None
tool_requests: list[AssistantMessageToolRequest] | None = None
+ turn_id: str | None = None
@staticmethod
def from_dict(obj: Any) -> "AssistantMessageData":
@@ -322,6 +323,7 @@ def from_dict(obj: Any) -> "AssistantMessageData":
reasoning_text = from_union([from_none, from_str], obj.get("reasoningText"))
request_id = from_union([from_none, from_str], obj.get("requestId"))
tool_requests = from_union([from_none, lambda x: from_list(AssistantMessageToolRequest.from_dict, x)], obj.get("toolRequests"))
+ turn_id = from_union([from_none, from_str], obj.get("turnId"))
return AssistantMessageData(
content=content,
message_id=message_id,
@@ -334,6 +336,7 @@ def from_dict(obj: Any) -> "AssistantMessageData":
reasoning_text=reasoning_text,
request_id=request_id,
tool_requests=tool_requests,
+ turn_id=turn_id,
)
def to_dict(self) -> dict:
@@ -358,6 +361,8 @@ def to_dict(self) -> dict:
result["requestId"] = from_union([from_none, from_str], self.request_id)
if self.tool_requests is not None:
result["toolRequests"] = from_union([from_none, lambda x: from_list(lambda x: to_class(AssistantMessageToolRequest, x), x)], self.tool_requests)
+ if self.turn_id is not None:
+ result["turnId"] = from_union([from_none, from_str], self.turn_id)
return result
@@ -1673,14 +1678,14 @@ def to_dict(self) -> dict:
class PermissionCompletedData:
"Permission request completion notification signaling UI dismissal"
request_id: str
- result: PermissionCompletedResult
+ result: PermissionResult
tool_call_id: str | None = None
@staticmethod
def from_dict(obj: Any) -> "PermissionCompletedData":
assert isinstance(obj, dict)
request_id = from_str(obj.get("requestId"))
- result = PermissionCompletedResult.from_dict(obj.get("result"))
+ result = PermissionResult.from_dict(obj.get("result"))
tool_call_id = from_union([from_none, from_str], obj.get("toolCallId"))
return PermissionCompletedData(
request_id=request_id,
@@ -1691,31 +1696,12 @@ def from_dict(obj: Any) -> "PermissionCompletedData":
def to_dict(self) -> dict:
result: dict = {}
result["requestId"] = from_str(self.request_id)
- result["result"] = to_class(PermissionCompletedResult, self.result)
+ result["result"] = to_class(PermissionResult, self.result)
if self.tool_call_id is not None:
result["toolCallId"] = from_union([from_none, from_str], self.tool_call_id)
return result
-@dataclass
-class PermissionCompletedResult:
- "The result of the permission request"
- kind: PermissionCompletedKind
-
- @staticmethod
- def from_dict(obj: Any) -> "PermissionCompletedResult":
- assert isinstance(obj, dict)
- kind = parse_enum(PermissionCompletedKind, obj.get("kind"))
- return PermissionCompletedResult(
- kind=kind,
- )
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["kind"] = to_enum(PermissionCompletedKind, self.kind)
- return result
-
-
@dataclass
class PermissionPromptRequest:
"Derived user-facing permission prompt details for UI consumers"
@@ -2097,6 +2083,92 @@ def to_dict(self) -> dict:
return result
+@dataclass
+class PermissionResult:
+ "The result of the permission request"
+ kind: PermissionResultKind
+ approval: UserToolSessionApproval | None = None
+ feedback: str | None = None
+ force_reject: bool | None = None
+ interrupt: bool | None = None
+ location_key: str | None = None
+ message: str | None = None
+ path: str | None = None
+ reason: str | None = None
+ rules: list[PermissionRule] | None = None
+
+ @staticmethod
+ def from_dict(obj: Any) -> "PermissionResult":
+ assert isinstance(obj, dict)
+ kind = parse_enum(PermissionResultKind, obj.get("kind"))
+ approval = from_union([from_none, UserToolSessionApproval.from_dict], obj.get("approval"))
+ feedback = from_union([from_none, from_str], obj.get("feedback"))
+ force_reject = from_union([from_none, from_bool], obj.get("forceReject"))
+ interrupt = from_union([from_none, from_bool], obj.get("interrupt"))
+ location_key = from_union([from_none, from_str], obj.get("locationKey"))
+ message = from_union([from_none, from_str], obj.get("message"))
+ path = from_union([from_none, from_str], obj.get("path"))
+ reason = from_union([from_none, from_str], obj.get("reason"))
+ rules = from_union([from_none, lambda x: from_list(PermissionRule.from_dict, x)], obj.get("rules"))
+ return PermissionResult(
+ kind=kind,
+ approval=approval,
+ feedback=feedback,
+ force_reject=force_reject,
+ interrupt=interrupt,
+ location_key=location_key,
+ message=message,
+ path=path,
+ reason=reason,
+ rules=rules,
+ )
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["kind"] = to_enum(PermissionResultKind, self.kind)
+ if self.approval is not None:
+ result["approval"] = from_union([from_none, lambda x: to_class(UserToolSessionApproval, x)], self.approval)
+ if self.feedback is not None:
+ result["feedback"] = from_union([from_none, from_str], self.feedback)
+ if self.force_reject is not None:
+ result["forceReject"] = from_union([from_none, from_bool], self.force_reject)
+ if self.interrupt is not None:
+ result["interrupt"] = from_union([from_none, from_bool], self.interrupt)
+ if self.location_key is not None:
+ result["locationKey"] = from_union([from_none, from_str], self.location_key)
+ if self.message is not None:
+ result["message"] = from_union([from_none, from_str], self.message)
+ if self.path is not None:
+ result["path"] = from_union([from_none, from_str], self.path)
+ if self.reason is not None:
+ result["reason"] = from_union([from_none, from_str], self.reason)
+ if self.rules is not None:
+ result["rules"] = from_union([from_none, lambda x: from_list(lambda x: to_class(PermissionRule, x), x)], self.rules)
+ return result
+
+
+@dataclass
+class PermissionRule:
+ argument: str | None
+ kind: str
+
+ @staticmethod
+ def from_dict(obj: Any) -> "PermissionRule":
+ assert isinstance(obj, dict)
+ argument = from_union([from_none, from_str], obj.get("argument"))
+ kind = from_str(obj.get("kind"))
+ return PermissionRule(
+ argument=argument,
+ kind=kind,
+ )
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["argument"] = from_union([from_none, from_str], self.argument)
+ result["kind"] = from_str(self.kind)
+ return result
+
+
@dataclass
class SamplingCompletedData:
"Sampling request completion notification signaling UI dismissal"
@@ -2672,9 +2744,11 @@ class SessionResumeData:
resume_time: datetime
already_in_use: bool | None = None
context: WorkingDirectoryContext | None = None
+ continue_pending_work: bool | None = None
reasoning_effort: str | None = None
remote_steerable: bool | None = None
selected_model: str | None = None
+ session_was_active: bool | None = None
@staticmethod
def from_dict(obj: Any) -> "SessionResumeData":
@@ -2683,17 +2757,21 @@ def from_dict(obj: Any) -> "SessionResumeData":
resume_time = from_datetime(obj.get("resumeTime"))
already_in_use = from_union([from_none, from_bool], obj.get("alreadyInUse"))
context = from_union([from_none, WorkingDirectoryContext.from_dict], obj.get("context"))
+ continue_pending_work = from_union([from_none, from_bool], obj.get("continuePendingWork"))
reasoning_effort = from_union([from_none, from_str], obj.get("reasoningEffort"))
remote_steerable = from_union([from_none, from_bool], obj.get("remoteSteerable"))
selected_model = from_union([from_none, from_str], obj.get("selectedModel"))
+ session_was_active = from_union([from_none, from_bool], obj.get("sessionWasActive"))
return SessionResumeData(
event_count=event_count,
resume_time=resume_time,
already_in_use=already_in_use,
context=context,
+ continue_pending_work=continue_pending_work,
reasoning_effort=reasoning_effort,
remote_steerable=remote_steerable,
selected_model=selected_model,
+ session_was_active=session_was_active,
)
def to_dict(self) -> dict:
@@ -2704,12 +2782,16 @@ def to_dict(self) -> dict:
result["alreadyInUse"] = from_union([from_none, from_bool], self.already_in_use)
if self.context is not None:
result["context"] = from_union([from_none, lambda x: to_class(WorkingDirectoryContext, x)], self.context)
+ if self.continue_pending_work is not None:
+ result["continuePendingWork"] = from_union([from_none, from_bool], self.continue_pending_work)
if self.reasoning_effort is not None:
result["reasoningEffort"] = from_union([from_none, from_str], self.reasoning_effort)
if self.remote_steerable is not None:
result["remoteSteerable"] = from_union([from_none, from_bool], self.remote_steerable)
if self.selected_model is not None:
result["selectedModel"] = from_union([from_none, from_str], self.selected_model)
+ if self.session_was_active is not None:
+ result["sessionWasActive"] = from_union([from_none, from_bool], self.session_was_active)
return result
@@ -2727,7 +2809,9 @@ class SessionShutdownData:
current_tokens: float | None = None
error_reason: str | None = None
system_tokens: float | None = None
+ token_details: dict[str, ShutdownTokenDetail] | None = None
tool_definitions_tokens: float | None = None
+ total_nano_aiu: float | None = None
@staticmethod
def from_dict(obj: Any) -> "SessionShutdownData":
@@ -2743,7 +2827,9 @@ def from_dict(obj: Any) -> "SessionShutdownData":
current_tokens = from_union([from_none, from_float], obj.get("currentTokens"))
error_reason = from_union([from_none, from_str], obj.get("errorReason"))
system_tokens = from_union([from_none, from_float], obj.get("systemTokens"))
+ token_details = from_union([from_none, lambda x: from_dict(ShutdownTokenDetail.from_dict, x)], obj.get("tokenDetails"))
tool_definitions_tokens = from_union([from_none, from_float], obj.get("toolDefinitionsTokens"))
+ total_nano_aiu = from_union([from_none, from_float], obj.get("totalNanoAiu"))
return SessionShutdownData(
code_changes=code_changes,
model_metrics=model_metrics,
@@ -2756,7 +2842,9 @@ def from_dict(obj: Any) -> "SessionShutdownData":
current_tokens=current_tokens,
error_reason=error_reason,
system_tokens=system_tokens,
+ token_details=token_details,
tool_definitions_tokens=tool_definitions_tokens,
+ total_nano_aiu=total_nano_aiu,
)
def to_dict(self) -> dict:
@@ -2777,8 +2865,12 @@ def to_dict(self) -> dict:
result["errorReason"] = from_union([from_none, from_str], self.error_reason)
if self.system_tokens is not None:
result["systemTokens"] = from_union([from_none, to_float], self.system_tokens)
+ if self.token_details is not None:
+ result["tokenDetails"] = from_union([from_none, lambda x: from_dict(lambda x: to_class(ShutdownTokenDetail, x), x)], self.token_details)
if self.tool_definitions_tokens is not None:
result["toolDefinitionsTokens"] = from_union([from_none, to_float], self.tool_definitions_tokens)
+ if self.total_nano_aiu is not None:
+ result["totalNanoAiu"] = from_union([from_none, to_float], self.total_nano_aiu)
return result
@@ -3121,21 +3213,31 @@ def to_dict(self) -> dict:
class ShutdownModelMetric:
requests: ShutdownModelMetricRequests
usage: ShutdownModelMetricUsage
+ token_details: dict[str, ShutdownModelMetricTokenDetail] | None = None
+ total_nano_aiu: float | None = None
@staticmethod
def from_dict(obj: Any) -> "ShutdownModelMetric":
assert isinstance(obj, dict)
requests = ShutdownModelMetricRequests.from_dict(obj.get("requests"))
usage = ShutdownModelMetricUsage.from_dict(obj.get("usage"))
+ token_details = from_union([from_none, lambda x: from_dict(ShutdownModelMetricTokenDetail.from_dict, x)], obj.get("tokenDetails"))
+ total_nano_aiu = from_union([from_none, from_float], obj.get("totalNanoAiu"))
return ShutdownModelMetric(
requests=requests,
usage=usage,
+ token_details=token_details,
+ total_nano_aiu=total_nano_aiu,
)
def to_dict(self) -> dict:
result: dict = {}
result["requests"] = to_class(ShutdownModelMetricRequests, self.requests)
result["usage"] = to_class(ShutdownModelMetricUsage, self.usage)
+ if self.token_details is not None:
+ result["tokenDetails"] = from_union([from_none, lambda x: from_dict(lambda x: to_class(ShutdownModelMetricTokenDetail, x), x)], self.token_details)
+ if self.total_nano_aiu is not None:
+ result["totalNanoAiu"] = from_union([from_none, to_float], self.total_nano_aiu)
return result
@@ -3162,6 +3264,24 @@ def to_dict(self) -> dict:
return result
+@dataclass
+class ShutdownModelMetricTokenDetail:
+ token_count: float
+
+ @staticmethod
+ def from_dict(obj: Any) -> "ShutdownModelMetricTokenDetail":
+ assert isinstance(obj, dict)
+ token_count = from_float(obj.get("tokenCount"))
+ return ShutdownModelMetricTokenDetail(
+ token_count=token_count,
+ )
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["tokenCount"] = to_float(self.token_count)
+ return result
+
+
@dataclass
class ShutdownModelMetricUsage:
"Token usage breakdown"
@@ -3198,6 +3318,24 @@ def to_dict(self) -> dict:
return result
+@dataclass
+class ShutdownTokenDetail:
+ token_count: float
+
+ @staticmethod
+ def from_dict(obj: Any) -> "ShutdownTokenDetail":
+ assert isinstance(obj, dict)
+ token_count = from_float(obj.get("tokenCount"))
+ return ShutdownTokenDetail(
+ token_count=token_count,
+ )
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["tokenCount"] = to_float(self.token_count)
+ return result
+
+
@dataclass
class SkillInvokedData:
"Skill invocation details including content, allowed tools, and plugin metadata"
@@ -3748,6 +3886,7 @@ class ToolExecutionCompleteData:
parent_tool_call_id: str | None = None
result: ToolExecutionCompleteResult | None = None
tool_telemetry: dict[str, Any] | None = None
+ turn_id: str | None = None
@staticmethod
def from_dict(obj: Any) -> "ToolExecutionCompleteData":
@@ -3761,6 +3900,7 @@ def from_dict(obj: Any) -> "ToolExecutionCompleteData":
parent_tool_call_id = from_union([from_none, from_str], obj.get("parentToolCallId"))
result = from_union([from_none, ToolExecutionCompleteResult.from_dict], obj.get("result"))
tool_telemetry = from_union([from_none, lambda x: from_dict(lambda x: x, x)], obj.get("toolTelemetry"))
+ turn_id = from_union([from_none, from_str], obj.get("turnId"))
return ToolExecutionCompleteData(
success=success,
tool_call_id=tool_call_id,
@@ -3771,6 +3911,7 @@ def from_dict(obj: Any) -> "ToolExecutionCompleteData":
parent_tool_call_id=parent_tool_call_id,
result=result,
tool_telemetry=tool_telemetry,
+ turn_id=turn_id,
)
def to_dict(self) -> dict:
@@ -3791,6 +3932,8 @@ def to_dict(self) -> dict:
result["result"] = from_union([from_none, lambda x: to_class(ToolExecutionCompleteResult, x)], self.result)
if self.tool_telemetry is not None:
result["toolTelemetry"] = from_union([from_none, lambda x: from_dict(lambda x: x, x)], self.tool_telemetry)
+ if self.turn_id is not None:
+ result["turnId"] = from_union([from_none, from_str], self.turn_id)
return result
@@ -3903,6 +4046,7 @@ class ToolExecutionStartData:
mcp_tool_name: str | None = None
# Deprecated: this field is deprecated.
parent_tool_call_id: str | None = None
+ turn_id: str | None = None
@staticmethod
def from_dict(obj: Any) -> "ToolExecutionStartData":
@@ -3913,6 +4057,7 @@ def from_dict(obj: Any) -> "ToolExecutionStartData":
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"))
+ turn_id = from_union([from_none, from_str], obj.get("turnId"))
return ToolExecutionStartData(
tool_call_id=tool_call_id,
tool_name=tool_name,
@@ -3920,6 +4065,7 @@ def from_dict(obj: Any) -> "ToolExecutionStartData":
mcp_server_name=mcp_server_name,
mcp_tool_name=mcp_tool_name,
parent_tool_call_id=parent_tool_call_id,
+ turn_id=turn_id,
)
def to_dict(self) -> dict:
@@ -3934,6 +4080,8 @@ def to_dict(self) -> dict:
result["mcpToolName"] = from_union([from_none, from_str], self.mcp_tool_name)
if self.parent_tool_call_id is not None:
result["parentToolCallId"] = from_union([from_none, from_str], self.parent_tool_call_id)
+ if self.turn_id is not None:
+ result["turnId"] = from_union([from_none, from_str], self.turn_id)
return result
@@ -4215,6 +4363,7 @@ class UserMessageData:
attachments: list[UserMessageAttachment] | None = None
interaction_id: str | None = None
native_document_path_fallback_paths: list[str] | None = None
+ parent_agent_task_id: str | None = None
source: str | None = None
supported_native_document_mime_types: list[str] | None = None
transformed_content: str | None = None
@@ -4227,6 +4376,7 @@ def from_dict(obj: Any) -> "UserMessageData":
attachments = from_union([from_none, lambda x: from_list(UserMessageAttachment.from_dict, x)], obj.get("attachments"))
interaction_id = from_union([from_none, from_str], obj.get("interactionId"))
native_document_path_fallback_paths = from_union([from_none, lambda x: from_list(from_str, x)], obj.get("nativeDocumentPathFallbackPaths"))
+ parent_agent_task_id = from_union([from_none, from_str], obj.get("parentAgentTaskId"))
source = from_union([from_none, from_str], obj.get("source"))
supported_native_document_mime_types = from_union([from_none, lambda x: from_list(from_str, x)], obj.get("supportedNativeDocumentMimeTypes"))
transformed_content = from_union([from_none, from_str], obj.get("transformedContent"))
@@ -4236,6 +4386,7 @@ def from_dict(obj: Any) -> "UserMessageData":
attachments=attachments,
interaction_id=interaction_id,
native_document_path_fallback_paths=native_document_path_fallback_paths,
+ parent_agent_task_id=parent_agent_task_id,
source=source,
supported_native_document_mime_types=supported_native_document_mime_types,
transformed_content=transformed_content,
@@ -4252,6 +4403,8 @@ def to_dict(self) -> dict:
result["interactionId"] = from_union([from_none, from_str], self.interaction_id)
if self.native_document_path_fallback_paths is not None:
result["nativeDocumentPathFallbackPaths"] = from_union([from_none, lambda x: from_list(from_str, x)], self.native_document_path_fallback_paths)
+ if self.parent_agent_task_id is not None:
+ result["parentAgentTaskId"] = from_union([from_none, from_str], self.parent_agent_task_id)
if self.source is not None:
result["source"] = from_union([from_none, from_str], self.source)
if self.supported_native_document_mime_types is not None:
@@ -4261,6 +4414,40 @@ def to_dict(self) -> dict:
return result
+@dataclass
+class UserToolSessionApproval:
+ "The approval to add as a session-scoped rule"
+ kind: UserToolSessionApprovalKind
+ command_identifiers: list[str] | None = None
+ server_name: str | None = None
+ tool_name: str | None = None
+
+ @staticmethod
+ def from_dict(obj: Any) -> "UserToolSessionApproval":
+ assert isinstance(obj, dict)
+ kind = parse_enum(UserToolSessionApprovalKind, obj.get("kind"))
+ command_identifiers = from_union([from_none, lambda x: from_list(from_str, x)], obj.get("commandIdentifiers"))
+ server_name = from_union([from_none, from_str], obj.get("serverName"))
+ tool_name = from_union([from_none, from_str], obj.get("toolName"))
+ return UserToolSessionApproval(
+ kind=kind,
+ command_identifiers=command_identifiers,
+ server_name=server_name,
+ tool_name=tool_name,
+ )
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["kind"] = to_enum(UserToolSessionApprovalKind, self.kind)
+ if self.command_identifiers is not None:
+ result["commandIdentifiers"] = from_union([from_none, lambda x: from_list(from_str, x)], self.command_identifiers)
+ if self.server_name is not None:
+ result["serverName"] = from_union([from_none, from_str], self.server_name)
+ if self.tool_name is not None:
+ result["toolName"] = from_union([from_none, from_str], self.tool_name)
+ return result
+
+
@dataclass
class WorkingDirectoryContext:
"Working directory and git context at session start"
@@ -4381,18 +4568,6 @@ class ModelCallFailureSource(Enum):
MCP_SAMPLING = "mcp_sampling"
-class PermissionCompletedKind(Enum):
- "The outcome of the permission request"
- APPROVED = "approved"
- APPROVED_FOR_SESSION = "approved-for-session"
- APPROVED_FOR_LOCATION = "approved-for-location"
- DENIED_BY_RULES = "denied-by-rules"
- DENIED_NO_APPROVAL_RULE_AND_COULD_NOT_REQUEST_FROM_USER = "denied-no-approval-rule-and-could-not-request-from-user"
- DENIED_INTERACTIVELY_BY_USER = "denied-interactively-by-user"
- DENIED_BY_CONTENT_EXCLUSION_POLICY = "denied-by-content-exclusion-policy"
- DENIED_BY_PERMISSION_REQUEST_HOOK = "denied-by-permission-request-hook"
-
-
class PermissionPromptRequestKind(Enum):
"Derived user-facing permission prompt details for UI consumers discriminator"
COMMANDS = "commands"
@@ -4449,6 +4624,19 @@ class PermissionRequestMemoryDirection(Enum):
DOWNVOTE = "downvote"
+class PermissionResultKind(Enum):
+ "The result of the permission request discriminator"
+ APPROVED = "approved"
+ APPROVED_FOR_SESSION = "approved-for-session"
+ APPROVED_FOR_LOCATION = "approved-for-location"
+ CANCELLED = "cancelled"
+ DENIED_BY_RULES = "denied-by-rules"
+ DENIED_NO_APPROVAL_RULE_AND_COULD_NOT_REQUEST_FROM_USER = "denied-no-approval-rule-and-could-not-request-from-user"
+ DENIED_INTERACTIVELY_BY_USER = "denied-interactively-by-user"
+ DENIED_BY_CONTENT_EXCLUSION_POLICY = "denied-by-content-exclusion-policy"
+ DENIED_BY_PERMISSION_REQUEST_HOOK = "denied-by-permission-request-hook"
+
+
class PlanChangedOperation(Enum):
"The type of operation performed on the plan file"
CREATE = "create"
@@ -4524,6 +4712,16 @@ class UserMessageAttachmentType(Enum):
BLOB = "blob"
+class UserToolSessionApprovalKind(Enum):
+ "The approval to add as a session-scoped rule discriminator"
+ COMMANDS = "commands"
+ READ = "read"
+ WRITE = "write"
+ MCP = "mcp"
+ MEMORY = "memory"
+ CUSTOM_TOOL = "custom-tool"
+
+
class WorkingDirectoryContextHostType(Enum):
"Hosting platform type of the repository (github or ado)"
GITHUB = "github"
diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json
index 8b8db1111..d4f646085 100644
--- a/test/harness/package-lock.json
+++ b/test/harness/package-lock.json
@@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
- "@github/copilot": "^1.0.40-0",
+ "@github/copilot": "^1.0.40-1",
"@modelcontextprotocol/sdk": "^1.26.0",
"@types/node": "^25.3.3",
"openai": "^6.17.0",
@@ -462,27 +462,27 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.40-0.tgz",
- "integrity": "sha512-KIrRqPOCGPcYUq09wvi66qUi5YMFTH5z9fOEzo1BuyLFVQqUen0TtRk0mpbhG6TxArLPqosBY8nDXOdc+NqKKw==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.40-1.tgz",
+ "integrity": "sha512-jdohe7CcjlmbNR0bnL/uAbaYDtmqZnHcHo3t/ZspVb9vo7+yk7AdTc4AF4TpV7M/tCKc+ynoqgQNCalWAmXYWQ==",
"dev": true,
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.40-0",
- "@github/copilot-darwin-x64": "1.0.40-0",
- "@github/copilot-linux-arm64": "1.0.40-0",
- "@github/copilot-linux-x64": "1.0.40-0",
- "@github/copilot-win32-arm64": "1.0.40-0",
- "@github/copilot-win32-x64": "1.0.40-0"
+ "@github/copilot-darwin-arm64": "1.0.40-1",
+ "@github/copilot-darwin-x64": "1.0.40-1",
+ "@github/copilot-linux-arm64": "1.0.40-1",
+ "@github/copilot-linux-x64": "1.0.40-1",
+ "@github/copilot-win32-arm64": "1.0.40-1",
+ "@github/copilot-win32-x64": "1.0.40-1"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.40-0.tgz",
- "integrity": "sha512-l905DiMvOB7Jn5MAkS+iEQcM99hmJHQ5yrKaGJ9OteVWBCcxPEO5ctnRYFdeq4NHL+9OnAzJzNc0kwScOAUCzg==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.40-1.tgz",
+ "integrity": "sha512-DSArBmv1A6BstJs23QgXzes7B8Hu+sz4Ccqh1NhY/4NPfxck1rD2v61ZWz8kdwpgTdjP6lWSZ5nLWdi9Go+PhA==",
"cpu": [
"arm64"
],
@@ -497,9 +497,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.40-0.tgz",
- "integrity": "sha512-e/Dtc1CjZ5SpNLdtY7vHxzH3hhNKfiMJdyp/2UY/6rzXsSPfbw9xZL01nUBbZt0aYj2FbPBDMTyfqoh5weUSww==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.40-1.tgz",
+ "integrity": "sha512-fTOL2XChDSsPc/q//mIFlq47ABNgyUKqz1+ix5oxloE9RlT1YpD7v3O+dqU/tmdxXwMTfQqgZsYglRY/nna3yw==",
"cpu": [
"x64"
],
@@ -514,9 +514,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.40-0.tgz",
- "integrity": "sha512-fR/gVUXFpjwojNf3Pg5lH2vrb8q0Gghv6RK6xx1QS6pEBdPTMGeoPxQVqSSB6dZCR/X3dkK1tIZ5IGnuABDHbA==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.40-1.tgz",
+ "integrity": "sha512-+aon/9kAxgGlxLZrxzwUrNO1G/eUIhhEB6W4u1sMs2GwXjANrDr6WIsp056dOnU2TY9oEnn8vWTJQSIwyFlGHQ==",
"cpu": [
"arm64"
],
@@ -531,9 +531,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.40-0.tgz",
- "integrity": "sha512-vDfE5Cxgg+BealbxBjqa0MUrLGJF+zT+XygMFgWXi/4ESVpRvvAet8rUoLeL+7Lgg6QRlS+UMPWfWL6ZAoSp5w==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.40-1.tgz",
+ "integrity": "sha512-p44TeuI01EpizsJmQX0W21f7pPXyTvrXYkv/5W1GgCiNEP4HKLG9rdgdIEtqaIMnXFKssxpGF45+hJuz0iep5g==",
"cpu": [
"x64"
],
@@ -548,9 +548,9 @@
}
},
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.40-0.tgz",
- "integrity": "sha512-7aEo1CZ5476lWRtfcym0TX1DhH5l9+PKENHPOr8vfziHKeNlWYkXHVTo7OGIUnCAwIetbCQRyf92nnaFhG/8Jw==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.40-1.tgz",
+ "integrity": "sha512-nrbMh1qc8VWL1KU2N+VdQ2M+4jiGlugApIFNUbfywnUITktWEpQ62Jqf2YQlrMr51f1F1fjSE/YBuDW6InzzYg==",
"cpu": [
"arm64"
],
@@ -565,9 +565,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.40-0",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.40-0.tgz",
- "integrity": "sha512-egnoilEO6TS0qSexe+A26GUSyfeinaqXJRTYL4Qr6eVgAfFhCEpCJtK/gHIZmlDXnq2ex3jGrVvz9+ZIp+JSoA==",
+ "version": "1.0.40-1",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.40-1.tgz",
+ "integrity": "sha512-n5qmzAn4OKbdHJeOmdt4eUA7XWSUOmNSJUtRswKVqgCxrmMOR/0FXCPzVS0gAJn+UEj9ApHulC6G09HR5Nhp7Q==",
"cpu": [
"x64"
],
diff --git a/test/harness/package.json b/test/harness/package.json
index 15b1aa940..7bca45eaa 100644
--- a/test/harness/package.json
+++ b/test/harness/package.json
@@ -11,7 +11,7 @@
"test": "vitest run"
},
"devDependencies": {
- "@github/copilot": "^1.0.40-0",
+ "@github/copilot": "^1.0.40-1",
"@modelcontextprotocol/sdk": "^1.26.0",
"@types/node": "^25.3.3",
"openai": "^6.17.0",
From 24b9ac334542c1e1e8fd7caddaab7ed87eaa0338 Mon Sep 17 00:00:00 2001
From: Stephen Toub
Date: Thu, 30 Apr 2026 12:25:07 -0400
Subject: [PATCH 2/6] Adapt hand-authored code to renamed schema in
@github/copilot 1.0.40-1
The 1.0.40-1 schema renames several types that are referenced from
hand-authored code:
- ToolsHandlePendingToolCallRequest -> HandlePendingToolCallRequest
- ToolsHandlePendingToolCall (union) -> ExternalToolResult (union)
- ToolCallResult -> ExternalToolTextResultForLlm
- PermissionCompletedKind enum -> PermissionResult polymorphism
(PermissionResultApproved,
PermissionResultDeniedInteractivelyByUser,
...)
Update the corresponding hand-authored files so the SDKs build again:
- go/rpc/result_union.go: rename receiver and union field references
on the custom (Un)MarshalJSON methods.
- go/session.go: use the new request/result type and union field names
when sending tool call results back via RPC.
- python/copilot/session.py: import the renamed RPC types and use them
when constructing handle_pending_tool_call requests.
- dotnet/test/MultiClientTests.cs: switch from a removed Kind enum
comparison to Assert.IsType against the new
polymorphic PermissionResult derived types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
dotnet/test/MultiClientTests.cs | 4 ++--
go/rpc/result_union.go | 22 +++++++++++-----------
go/session.go | 12 ++++++------
python/copilot/session.py | 12 ++++++------
4 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/dotnet/test/MultiClientTests.cs b/dotnet/test/MultiClientTests.cs
index f3b4186fc..2a262466e 100644
--- a/dotnet/test/MultiClientTests.cs
+++ b/dotnet/test/MultiClientTests.cs
@@ -194,7 +194,7 @@ public async Task One_Client_Approves_Permission_And_Both_See_The_Result()
foreach (var evt in client1Events.OfType()
.Concat(client2Events.OfType()))
{
- Assert.Equal(PermissionCompletedKind.Approved, evt.Data.Result.Kind);
+ Assert.IsType(evt.Data.Result);
}
await session2.DisposeAsync();
@@ -246,7 +246,7 @@ await session1.SendAndWaitAsync(new MessageOptions
foreach (var evt in client1Events.OfType()
.Concat(client2Events.OfType()))
{
- Assert.Equal(PermissionCompletedKind.DeniedInteractivelyByUser, evt.Data.Result.Kind);
+ Assert.IsType(evt.Data.Result);
}
await session2.DisposeAsync();
diff --git a/go/rpc/result_union.go b/go/rpc/result_union.go
index aabfe6553..3387dce1b 100644
--- a/go/rpc/result_union.go
+++ b/go/rpc/result_union.go
@@ -2,33 +2,33 @@ package rpc
import "encoding/json"
-// MarshalJSON serializes ToolsHandlePendingToolCall as the appropriate JSON variant:
-// a plain string when String is set, or the ToolCallResult object otherwise.
+// MarshalJSON serializes ExternalToolResult as the appropriate JSON variant:
+// a plain string when String is set, or the ExternalToolTextResultForLlm object otherwise.
// The generated struct has no custom marshaler, so without this the Go
-// struct fields would serialize as {"ToolCallResult":...,"String":...}
+// struct fields would serialize as {"ExternalToolTextResultForLlm":...,"String":...}
// instead of the union the server expects.
-func (r ToolsHandlePendingToolCall) MarshalJSON() ([]byte, error) {
+func (r ExternalToolResult) MarshalJSON() ([]byte, error) {
if r.String != nil {
return json.Marshal(*r.String)
}
- if r.ToolCallResult != nil {
- return json.Marshal(*r.ToolCallResult)
+ if r.ExternalToolTextResultForLlm != nil {
+ return json.Marshal(*r.ExternalToolTextResultForLlm)
}
return []byte("null"), nil
}
-// UnmarshalJSON deserializes a JSON value into the appropriate ToolsHandlePendingToolCall variant.
-func (r *ToolsHandlePendingToolCall) UnmarshalJSON(data []byte) error {
+// UnmarshalJSON deserializes a JSON value into the appropriate ExternalToolResult variant.
+func (r *ExternalToolResult) UnmarshalJSON(data []byte) error {
// Try string first
var s string
if err := json.Unmarshal(data, &s); err == nil {
r.String = &s
return nil
}
- // Try ToolCallResult object
- var rr ToolCallResult
+ // Try ExternalToolTextResultForLlm object
+ var rr ExternalToolTextResultForLlm
if err := json.Unmarshal(data, &rr); err == nil {
- r.ToolCallResult = &rr
+ r.ExternalToolTextResultForLlm = &rr
return nil
}
return nil
diff --git a/go/session.go b/go/session.go
index 8bcdf57c8..b58972c15 100644
--- a/go/session.go
+++ b/go/session.go
@@ -966,7 +966,7 @@ func (s *Session) executeToolAndRespond(requestID, toolName, toolCallID string,
defer func() {
if r := recover(); r != nil {
errMsg := fmt.Sprintf("tool panic: %v", r)
- s.RPC.Tools.HandlePendingToolCall(ctx, &rpc.ToolsHandlePendingToolCallRequest{
+ s.RPC.Tools.HandlePendingToolCall(ctx, &rpc.HandlePendingToolCallRequest{
RequestID: requestID,
Error: &errMsg,
})
@@ -984,7 +984,7 @@ func (s *Session) executeToolAndRespond(requestID, toolName, toolCallID string,
result, err := handler(invocation)
if err != nil {
errMsg := err.Error()
- s.RPC.Tools.HandlePendingToolCall(ctx, &rpc.ToolsHandlePendingToolCallRequest{
+ s.RPC.Tools.HandlePendingToolCall(ctx, &rpc.HandlePendingToolCallRequest{
RequestID: requestID,
Error: &errMsg,
})
@@ -1006,17 +1006,17 @@ func (s *Session) executeToolAndRespond(requestID, toolName, toolCallID string,
}
}
- rpcResult := rpc.ToolsHandlePendingToolCall{
- ToolCallResult: &rpc.ToolCallResult{
+ rpcResult := rpc.ExternalToolResult{
+ ExternalToolTextResultForLlm: &rpc.ExternalToolTextResultForLlm{
TextResultForLlm: textResultForLLM,
ToolTelemetry: result.ToolTelemetry,
ResultType: &effectiveResultType,
},
}
if result.Error != "" {
- rpcResult.ToolCallResult.Error = &result.Error
+ rpcResult.ExternalToolTextResultForLlm.Error = &result.Error
}
- s.RPC.Tools.HandlePendingToolCall(ctx, &rpc.ToolsHandlePendingToolCallRequest{
+ s.RPC.Tools.HandlePendingToolCall(ctx, &rpc.HandlePendingToolCallRequest{
RequestID: requestID,
Result: &rpcResult,
})
diff --git a/python/copilot/session.py b/python/copilot/session.py
index 3e1d40931..dffd8a570 100644
--- a/python/copilot/session.py
+++ b/python/copilot/session.py
@@ -24,6 +24,8 @@
from .generated.rpc import (
ClientSessionApiHandlers,
CommandsHandlePendingCommandRequest,
+ ExternalToolTextResultForLlm,
+ HandlePendingToolCallRequest,
LogRequest,
ModelSwitchToRequest,
PermissionDecision,
@@ -31,8 +33,6 @@
PermissionDecisionRequest,
SessionLogLevel,
SessionRpc,
- ToolCallResult,
- ToolsHandlePendingToolCallRequest,
UIElicitationRequest,
UIElicitationResponse,
UIElicitationResponseAction,
@@ -1403,16 +1403,16 @@ async def _execute_tool_and_respond(
# failures send the full structured result to preserve metadata.
if tool_result._from_exception:
await self.rpc.tools.handle_pending_tool_call(
- ToolsHandlePendingToolCallRequest(
+ HandlePendingToolCallRequest(
request_id=request_id,
error=tool_result.error,
)
)
else:
await self.rpc.tools.handle_pending_tool_call(
- ToolsHandlePendingToolCallRequest(
+ HandlePendingToolCallRequest(
request_id=request_id,
- result=ToolCallResult(
+ result=ExternalToolTextResultForLlm(
text_result_for_llm=tool_result.text_result_for_llm,
error=tool_result.error,
result_type=tool_result.result_type,
@@ -1423,7 +1423,7 @@ async def _execute_tool_and_respond(
except Exception as exc:
try:
await self.rpc.tools.handle_pending_tool_call(
- ToolsHandlePendingToolCallRequest(
+ HandlePendingToolCallRequest(
request_id=request_id,
error=str(exc),
)
From 5563d460692a36d62d1ff6fe720a7c8717cc2c83 Mon Sep 17 00:00:00 2001
From: Stephen Toub
Date: Thu, 30 Apr 2026 12:38:32 -0400
Subject: [PATCH 3/6] Harden Windows test cleanup against CLI 1.0.40-1
file-locking races
The 1.0.40-1 @github/copilot CLI holds the SQLite session-store.db handle open slightly longer on Windows than 1.0.39, exposing race conditions in the test fixtures. These tests were green on 1.0.40-0 and earlier, but flake on this bump.
- python/e2e/testharness/context.py: per-test cleanup now suppresses OSError from file unlink (matches the existing shutil.rmtree(ignore_errors=True) behavior used for directories)
- nodejs/test/e2e/harness/sdkTestContext.ts: rmDir retries extended from 5x2s (10s total) to 30x1s (30s total) to give Windows time to release the SQLite handle after the CLI subprocess exits
- dotnet/test/McpAndAgentsTests.cs: Should_Accept_Both_MCP_Servers_And_Custom_Agents now uses an explicit 120s timeout (instead of the 60s default) to tolerate slower MCP server spawning on Windows
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
dotnet/test/McpAndAgentsTests.cs | 3 ++-
nodejs/test/e2e/harness/sdkTestContext.ts | 4 +++-
python/e2e/testharness/context.py | 23 +++++++++++------------
3 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/dotnet/test/McpAndAgentsTests.cs b/dotnet/test/McpAndAgentsTests.cs
index 782b01123..d72c13f51 100644
--- a/dotnet/test/McpAndAgentsTests.cs
+++ b/dotnet/test/McpAndAgentsTests.cs
@@ -324,7 +324,8 @@ public async Task Should_Accept_Both_MCP_Servers_And_Custom_Agents()
await session.SendAsync(new MessageOptions { Prompt = "What is 7+7?" });
- var message = await TestHelper.GetFinalAssistantMessageAsync(session);
+ // Use a longer timeout to tolerate slower MCP server spawning on Windows.
+ var message = await TestHelper.GetFinalAssistantMessageAsync(session, TimeSpan.FromSeconds(120));
Assert.NotNull(message);
Assert.Contains("14", message!.Data.Content);
diff --git a/nodejs/test/e2e/harness/sdkTestContext.ts b/nodejs/test/e2e/harness/sdkTestContext.ts
index f17419295..403da26e4 100644
--- a/nodejs/test/e2e/harness/sdkTestContext.ts
+++ b/nodejs/test/e2e/harness/sdkTestContext.ts
@@ -112,5 +112,7 @@ function getTrafficCapturePath(testContext: TestContext): string {
}
function rmDir(message: string, path: string): Promise {
- return retry(message, () => rm(path, { recursive: true, force: true }), 5, 2000);
+ // Use longer retries (30s total) to tolerate Windows holding SQLite
+ // session-store.db open briefly after the CLI subprocess exits.
+ return retry(message, () => rm(path, { recursive: true, force: true }), 30, 1000);
}
diff --git a/python/e2e/testharness/context.py b/python/e2e/testharness/context.py
index 09a279d0d..514834522 100644
--- a/python/e2e/testharness/context.py
+++ b/python/e2e/testharness/context.py
@@ -4,6 +4,7 @@
Provides isolated directories and a replaying proxy for testing the SDK.
"""
+import contextlib
import os
import re
import shutil
@@ -113,18 +114,16 @@ async def configure_for_test(self, test_file: str, test_name: str):
await self._proxy.configure(abs_snapshot_path, self.work_dir)
# Clear temp directories between tests (but leave them in place)
- # Use ignore_errors=True to handle race conditions where files may still
- # be written by background processes during cleanup
- for item in Path(self.home_dir).iterdir():
- if item.is_dir():
- shutil.rmtree(item, ignore_errors=True)
- else:
- item.unlink(missing_ok=True)
- for item in Path(self.work_dir).iterdir():
- if item.is_dir():
- shutil.rmtree(item, ignore_errors=True)
- else:
- item.unlink(missing_ok=True)
+ # Use ignore_errors=True / suppress(OSError) to handle race conditions
+ # where files (e.g., SQLite session-store.db on Windows) may still be
+ # held open by a background process during cleanup.
+ for base_dir in (self.home_dir, self.work_dir):
+ for item in Path(base_dir).iterdir():
+ if item.is_dir():
+ shutil.rmtree(item, ignore_errors=True)
+ else:
+ with contextlib.suppress(OSError):
+ item.unlink(missing_ok=True)
def get_env(self) -> dict:
"""Return environment variables configured for isolated testing."""
From d1826bb210032c2e2b82a5d513f92a26f195d691 Mon Sep 17 00:00:00 2001
From: Stephen Toub
Date: Thu, 30 Apr 2026 12:47:36 -0400
Subject: [PATCH 4/6] Make Windows test cleanup soft-fail to fully tolerate CLI
1.0.40-1 SQLite race
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The previous tightening (30s rmDir retry; suppress(OSError) for unlink in central context.py) was not enough on Windows: the @github/copilot 1.0.40-1 CLI keeps the SQLite session-store.db handle open longer than 30 seconds in some cases, and three additional multi-client test files have their own configure_for_test methods with the same unlink-without-suppression pattern.
- python/e2e/test_commands.py, test_multi_client.py, test_ui_elicitation_multi_client.py: wrap item.unlink(missing_ok=True) in contextlib.suppress(OSError), matching the change in testharness/context.py
- nodejs/test/e2e/harness/sdkTestContext.ts: rmDir now warns instead of throwing if the temp dir cannot be removed after the 30s retry budget — temp dirs are reclaimed by the OS / GitHub Actions runner anyway, so a stale temp dir should not fail the entire test suite when 245/254 tests passed
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
nodejs/test/e2e/harness/sdkTestContext.ts | 19 ++++++++++++-----
python/e2e/test_commands.py | 4 +++-
python/e2e/test_multi_client.py | 21 +++++++++----------
.../e2e/test_ui_elicitation_multi_client.py | 4 +++-
4 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/nodejs/test/e2e/harness/sdkTestContext.ts b/nodejs/test/e2e/harness/sdkTestContext.ts
index 403da26e4..474a4e0f4 100644
--- a/nodejs/test/e2e/harness/sdkTestContext.ts
+++ b/nodejs/test/e2e/harness/sdkTestContext.ts
@@ -11,7 +11,7 @@ import { fileURLToPath } from "url";
import { afterAll, afterEach, beforeEach, onTestFailed, TestContext } from "vitest";
import { CopilotClient, CopilotClientOptions } from "../../../src";
import { CapiProxy } from "./CapiProxy";
-import { retry } from "./sdkTestHelper";
+import { retry, formatError } from "./sdkTestHelper";
export const isCI = process.env.GITHUB_ACTIONS === "true";
@@ -111,8 +111,17 @@ function getTrafficCapturePath(testContext: TestContext): string {
return join(SNAPSHOTS_DIR, testFileName, `${taskNameAsFilename}.yaml`);
}
-function rmDir(message: string, path: string): Promise {
- // Use longer retries (30s total) to tolerate Windows holding SQLite
- // session-store.db open briefly after the CLI subprocess exits.
- return retry(message, () => rm(path, { recursive: true, force: true }), 30, 1000);
+async function rmDir(message: string, path: string): Promise {
+ // Use longer retries to tolerate Windows holding SQLite session-store.db
+ // open briefly after the CLI subprocess exits. If the temp dir still can't
+ // be removed (e.g. CLI background writer racing with cleanup), warn and
+ // continue rather than failing the whole test run — the OS / CI runner
+ // will reclaim the temp dir on shutdown.
+ try {
+ await retry(message, () => rm(path, { recursive: true, force: true }), 30, 1000);
+ } catch (error) {
+ console.warn(
+ `WARN: ${message} failed; leaving temp dir for OS cleanup: ${formatError(error)}`
+ );
+ }
}
diff --git a/python/e2e/test_commands.py b/python/e2e/test_commands.py
index 6cc68e246..16fd1c7b7 100644
--- a/python/e2e/test_commands.py
+++ b/python/e2e/test_commands.py
@@ -7,6 +7,7 @@
"""
import asyncio
+import contextlib
import os
import shutil
import tempfile
@@ -106,7 +107,8 @@ async def configure_for_test(self, test_file: str, test_name: str):
if item.is_dir():
shutil.rmtree(item, ignore_errors=True)
else:
- item.unlink(missing_ok=True)
+ with contextlib.suppress(OSError):
+ item.unlink(missing_ok=True)
def _get_env(self) -> dict:
env = os.environ.copy()
diff --git a/python/e2e/test_multi_client.py b/python/e2e/test_multi_client.py
index 386f2eeb0..bf7fba44d 100644
--- a/python/e2e/test_multi_client.py
+++ b/python/e2e/test_multi_client.py
@@ -5,6 +5,7 @@
"""
import asyncio
+import contextlib
import os
import shutil
import tempfile
@@ -110,19 +111,17 @@ async def configure_for_test(self, test_file: str, test_name: str):
if self._proxy:
await self._proxy.configure(abs_snapshot_path, self.work_dir)
- # Clear temp directories between tests
+ # Clear temp directories between tests; tolerate Windows holding the
+ # SQLite session-store.db open briefly after the CLI subprocess exits.
from pathlib import Path
- for item in Path(self.home_dir).iterdir():
- if item.is_dir():
- shutil.rmtree(item, ignore_errors=True)
- else:
- item.unlink(missing_ok=True)
- for item in Path(self.work_dir).iterdir():
- if item.is_dir():
- shutil.rmtree(item, ignore_errors=True)
- else:
- item.unlink(missing_ok=True)
+ for base_dir in (self.home_dir, self.work_dir):
+ for item in Path(base_dir).iterdir():
+ if item.is_dir():
+ shutil.rmtree(item, ignore_errors=True)
+ else:
+ with contextlib.suppress(OSError):
+ item.unlink(missing_ok=True)
def get_env(self) -> dict:
env = os.environ.copy()
diff --git a/python/e2e/test_ui_elicitation_multi_client.py b/python/e2e/test_ui_elicitation_multi_client.py
index e12202b2f..e771107fb 100644
--- a/python/e2e/test_ui_elicitation_multi_client.py
+++ b/python/e2e/test_ui_elicitation_multi_client.py
@@ -8,6 +8,7 @@
"""
import asyncio
+import contextlib
import os
import shutil
import tempfile
@@ -113,7 +114,8 @@ async def configure_for_test(self, test_file: str, test_name: str):
if item.is_dir():
shutil.rmtree(item, ignore_errors=True)
else:
- item.unlink(missing_ok=True)
+ with contextlib.suppress(OSError):
+ item.unlink(missing_ok=True)
def _get_env(self) -> dict:
env = os.environ.copy()
From b6ec90d936ffc72bb484b234de2b97a3e84009f9 Mon Sep 17 00:00:00 2001
From: Stephen Toub
Date: Thu, 30 Apr 2026 13:46:59 -0400
Subject: [PATCH 5/6] Add ContinuePendingWork option to ResumeSessionConfig in
all SDKs
Exposes the new continuePendingWork resume option introduced by runtime PR #6099 (suspend/resume support for permission and tool call continuity). When true, the runtime continues any tool calls or permission prompts that were pending when the session was suspended; default false matches existing behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
dotnet/src/Client.cs | 6 ++--
dotnet/src/Types.cs | 15 ++++++++++
dotnet/test/CloneTests.cs | 23 +++++++++++++++
go/client.go | 3 ++
go/client_test.go | 30 ++++++++++++++++++++
go/types.go | 10 +++++++
nodejs/src/client.ts | 1 +
nodejs/src/types.ts | 12 ++++++++
nodejs/test/client.test.ts | 41 +++++++++++++++++++++++++++
python/copilot/client.py | 8 ++++++
python/copilot/session.py | 9 ++++++
python/test_client.py | 57 ++++++++++++++++++++++++++++++++++++++
12 files changed, 213 insertions(+), 2 deletions(-)
diff --git a/dotnet/src/Client.cs b/dotnet/src/Client.cs
index 791f70d45..692d511f7 100644
--- a/dotnet/src/Client.cs
+++ b/dotnet/src/Client.cs
@@ -632,7 +632,8 @@ public async Task ResumeSessionAsync(string sessionId, ResumeSes
Traceparent: traceparent,
Tracestate: tracestate,
ModelCapabilities: config.ModelCapabilities,
- GitHubToken: config.GitHubToken);
+ GitHubToken: config.GitHubToken,
+ ContinuePendingWork: config.ContinuePendingWork);
var response = await InvokeRpcAsync(
connection.Rpc, "session.resume", [request], cancellationToken);
@@ -1705,7 +1706,8 @@ internal record ResumeSessionRequest(
string? Traceparent = null,
string? Tracestate = null,
ModelCapabilitiesOverride? ModelCapabilities = null,
- string? GitHubToken = null);
+ string? GitHubToken = null,
+ bool? ContinuePendingWork = null);
internal record ResumeSessionResponse(
string SessionId,
diff --git a/dotnet/src/Types.cs b/dotnet/src/Types.cs
index 03589e16d..f674a9404 100644
--- a/dotnet/src/Types.cs
+++ b/dotnet/src/Types.cs
@@ -2005,6 +2005,7 @@ protected ResumeSessionConfig(ResumeSessionConfig? other)
DisabledSkills = other.DisabledSkills is not null ? [.. other.DisabledSkills] : null;
DisableResume = other.DisableResume;
EnableConfigDiscovery = other.EnableConfigDiscovery;
+ ContinuePendingWork = other.ContinuePendingWork;
ExcludedTools = other.ExcludedTools is not null ? [.. other.ExcludedTools] : null;
Hooks = other.Hooks;
InfiniteSessions = other.InfiniteSessions;
@@ -2140,6 +2141,20 @@ protected ResumeSessionConfig(ResumeSessionConfig? other)
///
public bool DisableResume { get; set; }
+ ///
+ /// When , instructs the runtime to continue any tool calls
+ /// or permission prompts that were still pending when the session was last suspended.
+ /// When (the default), the runtime treats pending work as
+ /// interrupted on resume.
+ ///
+ /// For permission requests, the runtime re-emits permission.requested so the
+ /// registered handler can re-prompt; for external
+ /// tool calls, the consumer is expected to supply the result via the corresponding
+ /// low-level RPC method.
+ ///
+ ///
+ public bool? ContinuePendingWork { get; set; }
+
///
/// Enable streaming of assistant message and reasoning chunks.
/// When true, assistant.message_delta and assistant.reasoning_delta events
diff --git a/dotnet/test/CloneTests.cs b/dotnet/test/CloneTests.cs
index 8ed45b062..7d25cbcae 100644
--- a/dotnet/test/CloneTests.cs
+++ b/dotnet/test/CloneTests.cs
@@ -303,4 +303,27 @@ public void ResumeSessionConfig_Clone_PreservesIncludeSubAgentStreamingEventsDef
Assert.True(clone.IncludeSubAgentStreamingEvents);
}
+
+ [Fact]
+ public void ResumeSessionConfig_Clone_CopiesContinuePendingWork()
+ {
+ var original = new ResumeSessionConfig
+ {
+ ContinuePendingWork = true,
+ };
+
+ var clone = original.Clone();
+
+ Assert.True(clone.ContinuePendingWork);
+ }
+
+ [Fact]
+ public void ResumeSessionConfig_Clone_PreservesContinuePendingWorkDefault()
+ {
+ var original = new ResumeSessionConfig();
+
+ var clone = original.Clone();
+
+ Assert.Null(clone.ContinuePendingWork);
+ }
}
diff --git a/go/client.go b/go/client.go
index abeae6db3..b05479336 100644
--- a/go/client.go
+++ b/go/client.go
@@ -779,6 +779,9 @@ func (c *Client) ResumeSessionWithOptions(ctx context.Context, sessionID string,
if config.DisableResume {
req.DisableResume = Bool(true)
}
+ if config.ContinuePendingWork {
+ req.ContinuePendingWork = Bool(true)
+ }
req.MCPServers = config.MCPServers
req.EnvValueMode = "direct"
req.CustomAgents = config.CustomAgents
diff --git a/go/client_test.go b/go/client_test.go
index 83e791333..1e90b64ab 100644
--- a/go/client_test.go
+++ b/go/client_test.go
@@ -881,6 +881,36 @@ func TestResumeSessionRequest_RequestElicitation(t *testing.T) {
})
}
+func TestResumeSessionRequest_ContinuePendingWork(t *testing.T) {
+ t.Run("forwards continuePendingWork when true", func(t *testing.T) {
+ req := resumeSessionRequest{
+ SessionID: "s1",
+ ContinuePendingWork: Bool(true),
+ }
+ data, err := json.Marshal(req)
+ if err != nil {
+ t.Fatalf("Failed to marshal: %v", err)
+ }
+ var m map[string]any
+ if err := json.Unmarshal(data, &m); err != nil {
+ t.Fatalf("Failed to unmarshal: %v", err)
+ }
+ if m["continuePendingWork"] != true {
+ t.Errorf("Expected continuePendingWork to be true, got %v", m["continuePendingWork"])
+ }
+ })
+
+ t.Run("omits continuePendingWork when not set", func(t *testing.T) {
+ req := resumeSessionRequest{SessionID: "s1"}
+ data, _ := json.Marshal(req)
+ var m map[string]any
+ json.Unmarshal(data, &m)
+ if _, ok := m["continuePendingWork"]; ok {
+ t.Error("Expected continuePendingWork to be omitted when not set")
+ }
+ })
+}
+
func TestCreateSessionRequest_IncludeSubAgentStreamingEvents(t *testing.T) {
t.Run("defaults to true when nil", func(t *testing.T) {
req := createSessionRequest{
diff --git a/go/types.go b/go/types.go
index 9b971aad4..e43bf2ed2 100644
--- a/go/types.go
+++ b/go/types.go
@@ -804,6 +804,15 @@ type ResumeSessionConfig struct {
// DisableResume, when true, skips emitting the session.resume event.
// Useful for reconnecting to a session without triggering resume-related side effects.
DisableResume bool
+ // ContinuePendingWork, when true, instructs the runtime to continue any tool calls
+ // or permission prompts that were still pending when the session was last suspended.
+ // When false (the default), the runtime treats pending work as interrupted on resume.
+ //
+ // For permission requests, the runtime re-emits permission.requested so the
+ // registered OnPermissionRequest handler can re-prompt; for external tool calls,
+ // the consumer is expected to supply the result via the corresponding low-level
+ // RPC method.
+ ContinuePendingWork bool
// OnEvent is an optional event handler registered before the session.resume RPC
// is issued, ensuring early events are delivered. See SessionConfig.OnEvent.
OnEvent SessionEventHandler
@@ -1050,6 +1059,7 @@ type resumeSessionRequest struct {
ConfigDir string `json:"configDir,omitempty"`
EnableConfigDiscovery *bool `json:"enableConfigDiscovery,omitempty"`
DisableResume *bool `json:"disableResume,omitempty"`
+ ContinuePendingWork *bool `json:"continuePendingWork,omitempty"`
Streaming *bool `json:"streaming,omitempty"`
IncludeSubAgentStreamingEvents *bool `json:"includeSubAgentStreamingEvents,omitempty"`
MCPServers map[string]MCPServerConfig `json:"mcpServers,omitempty"`
diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts
index 5eadf58dd..931ce59a4 100644
--- a/nodejs/src/client.ts
+++ b/nodejs/src/client.ts
@@ -907,6 +907,7 @@ export class CopilotClient {
disabledSkills: config.disabledSkills,
infiniteSessions: config.infiniteSessions,
disableResume: config.disableResume,
+ continuePendingWork: config.continuePendingWork,
gitHubToken: config.gitHubToken,
});
diff --git a/nodejs/src/types.ts b/nodejs/src/types.ts
index 335571b50..93f2360fa 100644
--- a/nodejs/src/types.ts
+++ b/nodejs/src/types.ts
@@ -1421,6 +1421,18 @@ export type ResumeSessionConfig = Pick<
* @default false
*/
disableResume?: boolean;
+ /**
+ * When true, the runtime continues any tool calls or permission prompts that were
+ * still pending when the session was last suspended. When false (the default), the
+ * runtime treats pending work as interrupted on resume.
+ *
+ * For permission requests, the runtime re-emits `permission.requested` so the
+ * registered `onPermissionRequest` handler can re-prompt; for external tool calls,
+ * the consumer is expected to supply the result via the corresponding low-level
+ * RPC method.
+ * @default false
+ */
+ continuePendingWork?: boolean;
};
/**
diff --git a/nodejs/test/client.test.ts b/nodejs/test/client.test.ts
index 39d6dfa76..3c5217961 100644
--- a/nodejs/test/client.test.ts
+++ b/nodejs/test/client.test.ts
@@ -166,6 +166,47 @@ describe("CopilotClient", () => {
spy.mockRestore();
});
+ it("forwards continuePendingWork in session.resume request", async () => {
+ const client = new CopilotClient();
+ await client.start();
+ onTestFinished(() => client.forceStop());
+
+ const session = await client.createSession({ onPermissionRequest: approveAll });
+ const spy = vi
+ .spyOn((client as any).connection!, "sendRequest")
+ .mockImplementation(async (method: string, params: any) => {
+ if (method === "session.resume") return { sessionId: params.sessionId };
+ throw new Error(`Unexpected method: ${method}`);
+ });
+ await client.resumeSession(session.sessionId, {
+ onPermissionRequest: approveAll,
+ continuePendingWork: true,
+ });
+
+ const payload = spy.mock.calls.find((c) => c[0] === "session.resume")![1] as any;
+ expect(payload.continuePendingWork).toBe(true);
+ spy.mockRestore();
+ });
+
+ it("omits continuePendingWork from session.resume payload when not specified", async () => {
+ const client = new CopilotClient();
+ await client.start();
+ onTestFinished(() => client.forceStop());
+
+ const session = await client.createSession({ onPermissionRequest: approveAll });
+ const spy = vi
+ .spyOn((client as any).connection!, "sendRequest")
+ .mockImplementation(async (method: string, params: any) => {
+ if (method === "session.resume") return { sessionId: params.sessionId };
+ throw new Error(`Unexpected method: ${method}`);
+ });
+ await client.resumeSession(session.sessionId, { onPermissionRequest: approveAll });
+
+ const payload = spy.mock.calls.find((c) => c[0] === "session.resume")![1] as any;
+ expect(payload.continuePendingWork).toBeUndefined();
+ spy.mockRestore();
+ });
+
it("forwards provider headers 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 c800e2158..40ea71b83 100644
--- a/python/copilot/client.py
+++ b/python/copilot/client.py
@@ -1513,6 +1513,7 @@ async def resume_session(
on_elicitation_request: ElicitationHandler | None = None,
create_session_fs_handler: CreateSessionFsHandler | None = None,
github_token: str | None = None,
+ continue_pending_work: bool | None = None,
) -> CopilotSession:
"""
Resume an existing conversation session by its ID.
@@ -1560,6 +1561,10 @@ async def resume_session(
disabled_skills: Skills to disable.
infinite_sessions: Infinite session configuration.
on_event: Callback for session events.
+ continue_pending_work: When True, instructs the runtime to continue any
+ tool calls or permission prompts that were still pending when the
+ session was last suspended. When False (the default), the runtime
+ treats pending work as interrupted on resume.
Returns:
A :class:`CopilotSession` instance for the resumed session.
@@ -1667,6 +1672,9 @@ async def resume_session(
if enable_config_discovery is not None:
payload["enableConfigDiscovery"] = enable_config_discovery
+ if continue_pending_work is not None:
+ payload["continuePendingWork"] = continue_pending_work
+
# TODO: disable_resume is not a keyword arg yet; keeping for future use
if mcp_servers:
payload["mcpServers"] = mcp_servers
diff --git a/python/copilot/session.py b/python/copilot/session.py
index dffd8a570..09f6b9cfc 100644
--- a/python/copilot/session.py
+++ b/python/copilot/session.py
@@ -962,6 +962,15 @@ class ResumeSessionConfig(TypedDict, total=False):
# When True, skips emitting the session.resume event.
# Useful for reconnecting to a session without triggering resume-related side effects.
disable_resume: bool
+ # When True, instructs the runtime to continue any tool calls or permission prompts
+ # that were still pending when the session was last suspended. When False (the
+ # default), the runtime treats pending work as interrupted on resume.
+ #
+ # For permission requests, the runtime re-emits ``permission.requested`` so the
+ # registered ``on_permission_request`` handler can re-prompt; for external tool
+ # calls, the consumer is expected to supply the result via the corresponding
+ # low-level RPC method.
+ continue_pending_work: bool
# Optional event handler registered before the session.resume RPC is issued,
# ensuring early events are delivered. See SessionConfig.on_event.
on_event: Callable[[SessionEvent], None]
diff --git a/python/test_client.py b/python/test_client.py
index ac1b735bf..1f038c99b 100644
--- a/python/test_client.py
+++ b/python/test_client.py
@@ -716,6 +716,63 @@ async def mock_request(method, params):
finally:
await client.force_stop()
+ @pytest.mark.asyncio
+ async def test_resume_session_forwards_continue_pending_work(self):
+ client = CopilotClient(SubprocessConfig(cli_path=CLI_PATH))
+ await client.start()
+
+ try:
+ session = await client.create_session(
+ on_permission_request=PermissionHandler.approve_all
+ )
+
+ captured: dict = {}
+ original_request = client._client.request
+
+ async def mock_request(method, params):
+ captured[method] = params
+ if method == "session.resume":
+ return {"sessionId": session.session_id}
+ return await original_request(method, params)
+
+ client._client.request = mock_request
+ await client.resume_session(
+ session.session_id,
+ on_permission_request=PermissionHandler.approve_all,
+ continue_pending_work=True,
+ )
+ assert captured["session.resume"]["continuePendingWork"] is True
+ finally:
+ await client.force_stop()
+
+ @pytest.mark.asyncio
+ async def test_resume_session_omits_continue_pending_work_by_default(self):
+ client = CopilotClient(SubprocessConfig(cli_path=CLI_PATH))
+ await client.start()
+
+ try:
+ session = await client.create_session(
+ on_permission_request=PermissionHandler.approve_all
+ )
+
+ captured: dict = {}
+ original_request = client._client.request
+
+ async def mock_request(method, params):
+ captured[method] = params
+ if method == "session.resume":
+ return {"sessionId": session.session_id}
+ return await original_request(method, params)
+
+ client._client.request = mock_request
+ await client.resume_session(
+ session.session_id,
+ on_permission_request=PermissionHandler.approve_all,
+ )
+ assert "continuePendingWork" not in captured["session.resume"]
+ finally:
+ await client.force_stop()
+
@pytest.mark.asyncio
async def test_set_model_sends_correct_rpc(self):
client = CopilotClient(SubprocessConfig(cli_path=CLI_PATH))
From 6fecd4a7f8045ee6563c26163f2b760d66494a03 Mon Sep 17 00:00:00 2001
From: Stephen Toub
Date: Thu, 30 Apr 2026 15:07:06 -0400
Subject: [PATCH 6/6] Bump default .NET test helper timeout from 60s to 120s
for Windows CI
Should_Work_With_Approve_All_Permission_Handler timed out on the windows-latest .NET CI job at the previous default of 60s while waiting for the first assistant message in the PermissionTests fixture. The CLI / replay-proxy cold-start cost on the first test of a fixture can exceed 60s on Windows GitHub Actions runners; subsequent tests in the same fixture run in well under a second. McpAndAgentsTests.cs already had to bump to 120s explicitly for the same reason. Apply the same 120s default in TestHelper so individual tests don't have to opt in.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
dotnet/test/Harness/TestHelper.cs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/dotnet/test/Harness/TestHelper.cs b/dotnet/test/Harness/TestHelper.cs
index 36c9be043..52e681b88 100644
--- a/dotnet/test/Harness/TestHelper.cs
+++ b/dotnet/test/Harness/TestHelper.cs
@@ -6,13 +6,19 @@ namespace GitHub.Copilot.SDK.Test.Harness;
public static class TestHelper
{
+ // Default tolerates CLI / replay-proxy cold start on Windows GitHub Actions
+ // runners, where the first test in a fixture can take ~60s before the first
+ // assistant message arrives. Subsequent tests in the same fixture typically
+ // complete in well under a second.
+ private static readonly TimeSpan DefaultEventTimeout = TimeSpan.FromSeconds(120);
+
public static async Task GetFinalAssistantMessageAsync(
CopilotSession session,
TimeSpan? timeout = null,
bool alreadyIdle = false)
{
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- using var cts = new CancellationTokenSource(timeout ?? TimeSpan.FromSeconds(60));
+ using var cts = new CancellationTokenSource(timeout ?? DefaultEventTimeout);
// Both `finalAssistantMessage` and `sawIdle` are set from two threads — the
// subscription callback (CLI read loop) and CheckExistingMessages (RPC reply).
@@ -111,7 +117,7 @@ public static async Task GetNextEventOfTypeAsync(
TimeSpan? timeout = null) where T : SessionEvent
{
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- using var cts = new CancellationTokenSource(timeout ?? TimeSpan.FromSeconds(60));
+ using var cts = new CancellationTokenSource(timeout ?? DefaultEventTimeout);
using var subscription = session.On(evt =>
{