From 42a308d1c84933c901ad9dd74fa617ca659eb38f Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 18 May 2026 22:16:11 +0000
Subject: [PATCH 1/8] Update @github/copilot to 1.0.49-6
- Updated nodejs and test harness dependencies
- Re-ran code generators
- Formatted generated code
---
dotnet/src/Generated/Rpc.cs | 774 +++++++-----------
dotnet/src/Generated/SessionEvents.cs | 550 ++++++++-----
go/rpc/zrpc.go | 327 +++++---
go/rpc/zrpc_encoding.go | 56 +-
go/rpc/zsession_events.go | 105 +--
go/zsession_events.go | 53 +-
nodejs/package-lock.json | 90 ++-
nodejs/package.json | 2 +-
nodejs/samples/package-lock.json | 2 +-
nodejs/src/generated/rpc.ts | 307 +++++---
nodejs/src/generated/session-events.ts | 104 +--
python/copilot/generated/rpc.py | 864 +++++++++++++--------
python/copilot/generated/session_events.py | 208 +++--
rust/src/generated/api_types.rs | 345 ++++----
rust/src/generated/rpc.rs | 2 +-
rust/src/generated/session_events.rs | 170 ++--
test/harness/package-lock.json | 92 ++-
test/harness/package.json | 2 +-
18 files changed, 2268 insertions(+), 1785 deletions(-)
diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs
index 7d4f8503a..1f963890a 100644
--- a/dotnet/src/Generated/Rpc.cs
+++ b/dotnet/src/Generated/Rpc.cs
@@ -167,7 +167,7 @@ public sealed class ModelPolicy
{
/// Current policy state for this model.
[JsonPropertyName("state")]
- public string State { get; set; } = string.Empty;
+ public ModelPolicyState State { get; set; }
/// Usage terms or conditions for this model.
[JsonPropertyName("terms")]
@@ -273,7 +273,7 @@ internal sealed class ToolsListRequest
/// Schema for the `AccountQuotaSnapshot` type.
public sealed class AccountQuotaSnapshot
{
- /// Number of requests included in the entitlement.
+ /// Number of requests included in the entitlement, or -1 for unlimited entitlements.
[JsonPropertyName("entitlementRequests")]
public long EntitlementRequests { get; set; }
@@ -296,7 +296,7 @@ public sealed class AccountQuotaSnapshot
/// Date when the quota resets (ISO 8601 string).
[JsonPropertyName("resetDate")]
- public string? ResetDate { get; set; }
+ public DateTimeOffset? ResetDate { get; set; }
/// Whether usage is still permitted after quota exhaustion.
[JsonPropertyName("usageAllowedWithExhaustedQuota")]
@@ -338,11 +338,11 @@ public sealed class DiscoveredMcpServer
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
- /// Configuration source.
+ /// Configuration source: user, workspace, plugin, or builtin.
[JsonPropertyName("source")]
- public DiscoveredMcpServerSource Source { get; set; }
+ public McpServerSource Source { get; set; } = null!;
- /// Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio).
+ /// Server transport type: stdio, http, sse, or memory.
[JsonPropertyName("type")]
public DiscoveredMcpServerType? Type { get; set; }
}
@@ -374,7 +374,7 @@ public sealed class McpConfigList
/// MCP server name and configuration to add to user configuration.
internal sealed class McpConfigAddRequest
{
- /// MCP server configuration (local/stdio or remote/http).
+ /// MCP server configuration (stdio process or remote HTTP/SSE).
[JsonPropertyName("config")]
public object Config { get; set; } = null!;
@@ -389,7 +389,7 @@ internal sealed class McpConfigAddRequest
/// MCP server name and replacement configuration to write to user configuration.
internal sealed class McpConfigUpdateRequest
{
- /// MCP server configuration (local/stdio or remote/http).
+ /// MCP server configuration (stdio process or remote HTTP/SSE).
[JsonPropertyName("config")]
public object Config { get; set; } = null!;
@@ -453,7 +453,7 @@ public sealed class ServerSkill
/// Source location type (e.g., project, personal-copilot, plugin, builtin).
[JsonPropertyName("source")]
- public string Source { get; set; } = string.Empty;
+ public SkillSource Source { get; set; } = null!;
/// Whether the skill can be invoked by the user as a slash command.
[JsonPropertyName("userInvocable")]
@@ -496,9 +496,21 @@ public sealed class SessionFsSetProviderResult
public bool Success { get; set; }
}
+/// Optional capabilities declared by the provider.
+public sealed class SessionFsSetProviderCapabilities
+{
+ /// Whether the provider supports SQLite query/exists operations.
+ [JsonPropertyName("sqlite")]
+ public bool? Sqlite { get; set; }
+}
+
/// Initial working directory, session-state path layout, and path conventions used to register the calling SDK client as the session filesystem provider.
internal sealed class SessionFsSetProviderRequest
{
+ /// Optional capabilities declared by the provider.
+ [JsonPropertyName("capabilities")]
+ public SessionFsSetProviderCapabilities? Capabilities { get; set; }
+
/// Path conventions used by this filesystem.
[JsonPropertyName("conventions")]
public SessionFsSetProviderConventions Conventions { get; set; }
@@ -567,7 +579,7 @@ public sealed class ConnectedRemoteSessionMetadata
/// Last session update time as an ISO 8601 string.
[JsonPropertyName("modifiedTime")]
- public string ModifiedTime { get; set; } = string.Empty;
+ public DateTimeOffset ModifiedTime { get; set; }
/// Optional friendly session name.
[JsonPropertyName("name")]
@@ -591,11 +603,11 @@ public sealed class ConnectedRemoteSessionMetadata
/// Remote session staleness deadline as an ISO 8601 string.
[JsonPropertyName("staleAt")]
- public string? StaleAt { get; set; }
+ public DateTimeOffset? StaleAt { get; set; }
/// Session start time as an ISO 8601 string.
[JsonPropertyName("startTime")]
- public string StartTime { get; set; } = string.Empty;
+ public DateTimeOffset StartTime { get; set; }
/// Remote session state returned by the backing service.
[JsonPropertyName("state")]
@@ -682,6 +694,8 @@ public sealed class SessionAuthStatus
public string? CopilotPlan { get; set; }
/// Authentication host URL.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("host")]
public string? Host { get; set; }
@@ -830,9 +844,9 @@ internal sealed class SessionModeGetRequest
/// Agent interaction mode to apply to the session.
internal sealed class ModeSetRequest
{
- /// The agent mode. Valid values: "interactive", "plan", "autopilot".
+ /// The session mode the agent is operating in.
[JsonPropertyName("mode")]
- public SessionMode Mode { get; set; }
+ public SessionMode Mode { get; set; } = null!;
/// Target session identifier.
[JsonPropertyName("sessionId")]
@@ -1325,10 +1339,10 @@ public partial class TaskInfoAgent : TaskInfo
[JsonPropertyName("error")]
public string? Error { get; set; }
- /// How the agent is currently being managed by the runtime.
+ /// Whether task execution is synchronously awaited or managed in the background.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("executionMode")]
- public TaskAgentInfoExecutionMode? ExecutionMode { get; set; }
+ public TaskExecutionMode? ExecutionMode { get; set; }
/// Unique task identifier.
[JsonPropertyName("id")]
@@ -1364,7 +1378,7 @@ public partial class TaskInfoAgent : TaskInfo
/// Current lifecycle status of the task.
[JsonPropertyName("status")]
- public required TaskAgentInfoStatus Status { get; set; }
+ public required TaskStatus Status { get; set; }
/// Tool call ID associated with this agent task.
[JsonPropertyName("toolCallId")]
@@ -1401,10 +1415,10 @@ public partial class TaskInfoShell : TaskInfo
[JsonPropertyName("description")]
public required string Description { get; set; }
- /// Whether the shell command is currently sync-waited or background-managed.
+ /// Whether task execution is synchronously awaited or managed in the background.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("executionMode")]
- public TaskShellInfoExecutionMode? ExecutionMode { get; set; }
+ public TaskExecutionMode? ExecutionMode { get; set; }
/// Unique task identifier.
[JsonPropertyName("id")]
@@ -1426,7 +1440,7 @@ public partial class TaskInfoShell : TaskInfo
/// Current lifecycle status of the task.
[JsonPropertyName("status")]
- public required TaskShellInfoStatus Status { get; set; }
+ public required TaskStatus Status { get; set; }
}
/// Background tasks currently tracked by the session.
@@ -1566,9 +1580,9 @@ public sealed class Skill
[JsonPropertyName("path")]
public string? Path { get; set; }
- /// Source location type (e.g., project, personal, plugin).
+ /// Source location type (e.g., project, personal-copilot, plugin, builtin).
[JsonPropertyName("source")]
- public string Source { get; set; } = string.Empty;
+ public SkillSource Source { get; set; } = null!;
/// Whether the skill can be invoked by the user as a slash command.
[JsonPropertyName("userInvocable")]
@@ -1661,7 +1675,7 @@ public sealed class McpServer
/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
[JsonPropertyName("status")]
- public McpServerStatus Status { get; set; }
+ public McpServerStatus Status { get; set; } = null!;
}
/// MCP servers configured for the session, with their connection status.
@@ -1728,6 +1742,8 @@ internal sealed class SessionMcpReloadRequest
public sealed class McpOauthLoginResult
{
/// URL the caller should open in a browser to complete OAuth. Omitted when cached tokens were still valid and no browser interaction was needed — the server is already reconnected in that case. When present, the runtime starts the callback listener before returning and continues the flow in the background; completion is signaled via session.mcp_server_status_changed.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("authorizationUrl")]
public string? AuthorizationUrl { get; set; }
}
@@ -2055,10 +2071,10 @@ public partial class SlashCommandInvocationResultAgentPrompt : SlashCommandInvoc
[JsonPropertyName("displayPrompt")]
public required string DisplayPrompt { get; set; }
- /// Optional target session mode.
+ /// Optional target session mode for the agent prompt.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("mode")]
- public SlashCommandAgentPromptMode? Mode { get; set; }
+ public SessionMode? Mode { get; set; }
/// Prompt to submit to the agent.
[JsonPropertyName("prompt")]
@@ -2971,6 +2987,8 @@ public sealed class RemoteEnableResult
public bool RemoteSteerable { get; set; }
/// GitHub frontend URL for this session.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("url")]
public string? Url { get; set; }
}
@@ -3253,6 +3271,67 @@ public sealed class SessionFsRenameRequest
public string Src { get; set; } = string.Empty;
}
+/// Query results including rows, columns, and rows affected, or a filesystem error if execution failed.
+public sealed class SessionFsSqliteQueryResult
+{
+ /// Column names from the result set.
+ [JsonPropertyName("columns")]
+ public IList Columns { get => field ??= []; set; }
+
+ /// Describes a filesystem error.
+ [JsonPropertyName("error")]
+ public SessionFsError? Error { get; set; }
+
+ /// Last inserted row ID (for INSERT).
+ [JsonPropertyName("lastInsertRowid")]
+ public double? LastInsertRowid { get; set; }
+
+ /// For SELECT: array of row objects. For others: empty array.
+ [JsonPropertyName("rows")]
+ public IList> Rows { get => field ??= []; set; }
+
+ /// Number of rows affected (for INSERT/UPDATE/DELETE).
+ [Range((double)0, (double)long.MaxValue)]
+ [JsonPropertyName("rowsAffected")]
+ public long RowsAffected { get; set; }
+}
+
+/// SQL query, query type, and optional bind parameters for executing a SQLite query against the per-session database.
+public sealed class SessionFsSqliteQueryRequest
+{
+ /// Optional named bind parameters.
+ [JsonPropertyName("params")]
+ public IDictionary? Params { get; set; }
+
+ /// SQL query to execute.
+ [JsonPropertyName("query")]
+ public string Query { get; set; } = string.Empty;
+
+ /// How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected).
+ [JsonPropertyName("queryType")]
+ public SessionFsSqliteQueryType QueryType { get; set; }
+
+ /// Target session identifier.
+ [JsonPropertyName("sessionId")]
+ public string SessionId { get; set; } = string.Empty;
+}
+
+/// Indicates whether the per-session SQLite database already exists.
+public sealed class SessionFsSqliteExistsResult
+{
+ /// Whether the session database already exists.
+ [JsonPropertyName("exists")]
+ public bool Exists { get; set; }
+}
+
+/// Identifies the target session.
+public sealed class SessionFsSqliteExistsRequest
+{
+ /// Target session identifier.
+ [JsonPropertyName("sessionId")]
+ public string SessionId { get; set; } = string.Empty;
+}
+
/// Model capability category for grouping in the model picker.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
@@ -3386,48 +3465,45 @@ public override void Write(Utf8JsonWriter writer, ModelPickerPriceCategory value
}
-/// Configuration source.
+/// Current policy state for this model.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct DiscoveredMcpServerSource : IEquatable
+public readonly struct ModelPolicyState : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public DiscoveredMcpServerSource(string value)
+ public ModelPolicyState(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
- /// Gets the user value.
- public static DiscoveredMcpServerSource User { get; } = new("user");
-
- /// Gets the workspace value.
- public static DiscoveredMcpServerSource Workspace { get; } = new("workspace");
+ /// Gets the enabled value.
+ public static ModelPolicyState Enabled { get; } = new("enabled");
- /// Gets the plugin value.
- public static DiscoveredMcpServerSource Plugin { get; } = new("plugin");
+ /// Gets the disabled value.
+ public static ModelPolicyState Disabled { get; } = new("disabled");
- /// Gets the builtin value.
- public static DiscoveredMcpServerSource Builtin { get; } = new("builtin");
+ /// Gets the unconfigured value.
+ public static ModelPolicyState Unconfigured { get; } = new("unconfigured");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(DiscoveredMcpServerSource left, DiscoveredMcpServerSource right) => left.Equals(right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(ModelPolicyState left, ModelPolicyState right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(DiscoveredMcpServerSource left, DiscoveredMcpServerSource right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(ModelPolicyState left, ModelPolicyState right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is DiscoveredMcpServerSource other && Equals(other);
+ public override bool Equals(object? obj) => obj is ModelPolicyState other && Equals(other);
///
- public bool Equals(DiscoveredMcpServerSource other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(ModelPolicyState other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -3435,26 +3511,26 @@ public DiscoveredMcpServerSource(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override DiscoveredMcpServerSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override ModelPolicyState Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, DiscoveredMcpServerSource value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, ModelPolicyState value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(DiscoveredMcpServerSource));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ModelPolicyState));
}
}
}
-/// Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio).
+/// Server transport type: stdio, http, sse, or memory.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
public readonly struct DiscoveredMcpServerType : IEquatable
@@ -3788,71 +3864,6 @@ public override void Write(Utf8JsonWriter writer, AuthInfoType value, JsonSerial
}
-/// The agent mode. Valid values: "interactive", "plan", "autopilot".
-[JsonConverter(typeof(Converter))]
-[DebuggerDisplay("{Value,nq}")]
-public readonly struct SessionMode : IEquatable
-{
- private readonly string? _value;
-
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
- [JsonConstructor]
- public SessionMode(string value)
- {
- ArgumentException.ThrowIfNullOrWhiteSpace(value);
- _value = value;
- }
-
- /// Gets the value associated with this .
- public string Value => _value ?? string.Empty;
-
- /// Gets the interactive value.
- public static SessionMode Interactive { get; } = new("interactive");
-
- /// Gets the plan value.
- public static SessionMode Plan { get; } = new("plan");
-
- /// Gets the autopilot value.
- public static SessionMode Autopilot { get; } = new("autopilot");
-
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(SessionMode left, SessionMode right) => left.Equals(right);
-
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(SessionMode left, SessionMode right) => !(left == right);
-
- ///
- public override bool Equals(object? obj) => obj is SessionMode other && Equals(other);
-
- ///
- public bool Equals(SessionMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
-
- ///
- public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
-
- ///
- public override string ToString() => Value;
-
- /// Provides a for serializing instances.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
- {
- ///
- public override SessionMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
- }
-
- ///
- public override void Write(Utf8JsonWriter writer, SessionMode value, JsonSerializerOptions options)
- {
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SessionMode));
- }
- }
-}
-
-
/// Defines the allowed values.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
@@ -4054,42 +4065,42 @@ public override void Write(Utf8JsonWriter writer, InstructionsSourcesType value,
}
-/// How the agent is currently being managed by the runtime.
+/// Whether task execution is synchronously awaited or managed in the background.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct TaskAgentInfoExecutionMode : IEquatable
+public readonly struct TaskExecutionMode : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public TaskAgentInfoExecutionMode(string value)
+ public TaskExecutionMode(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
/// Gets the sync value.
- public static TaskAgentInfoExecutionMode Sync { get; } = new("sync");
+ public static TaskExecutionMode Sync { get; } = new("sync");
/// Gets the background value.
- public static TaskAgentInfoExecutionMode Background { get; } = new("background");
+ public static TaskExecutionMode Background { get; } = new("background");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(TaskAgentInfoExecutionMode left, TaskAgentInfoExecutionMode right) => left.Equals(right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(TaskExecutionMode left, TaskExecutionMode right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(TaskAgentInfoExecutionMode left, TaskAgentInfoExecutionMode right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(TaskExecutionMode left, TaskExecutionMode right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is TaskAgentInfoExecutionMode other && Equals(other);
+ public override bool Equals(object? obj) => obj is TaskExecutionMode other && Equals(other);
///
- public bool Equals(TaskAgentInfoExecutionMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(TaskExecutionMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -4097,20 +4108,20 @@ public TaskAgentInfoExecutionMode(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override TaskAgentInfoExecutionMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override TaskExecutionMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, TaskAgentInfoExecutionMode value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, TaskExecutionMode value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(TaskAgentInfoExecutionMode));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(TaskExecutionMode));
}
}
}
@@ -4119,48 +4130,48 @@ public override void Write(Utf8JsonWriter writer, TaskAgentInfoExecutionMode val
/// Current lifecycle status of the task.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct TaskAgentInfoStatus : IEquatable
+public readonly struct TaskStatus : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public TaskAgentInfoStatus(string value)
+ public TaskStatus(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
/// Gets the running value.
- public static TaskAgentInfoStatus Running { get; } = new("running");
+ public static TaskStatus Running { get; } = new("running");
/// Gets the idle value.
- public static TaskAgentInfoStatus Idle { get; } = new("idle");
+ public static TaskStatus Idle { get; } = new("idle");
/// Gets the completed value.
- public static TaskAgentInfoStatus Completed { get; } = new("completed");
+ public static TaskStatus Completed { get; } = new("completed");
/// Gets the failed value.
- public static TaskAgentInfoStatus Failed { get; } = new("failed");
+ public static TaskStatus Failed { get; } = new("failed");
/// Gets the cancelled value.
- public static TaskAgentInfoStatus Cancelled { get; } = new("cancelled");
+ public static TaskStatus Cancelled { get; } = new("cancelled");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(TaskAgentInfoStatus left, TaskAgentInfoStatus right) => left.Equals(right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(TaskStatus left, TaskStatus right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(TaskAgentInfoStatus left, TaskAgentInfoStatus right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(TaskStatus left, TaskStatus right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is TaskAgentInfoStatus other && Equals(other);
+ public override bool Equals(object? obj) => obj is TaskStatus other && Equals(other);
///
- public bool Equals(TaskAgentInfoStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(TaskStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -4168,20 +4179,20 @@ public TaskAgentInfoStatus(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override TaskAgentInfoStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override TaskStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, TaskAgentInfoStatus value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, TaskStatus value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(TaskAgentInfoStatus));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(TaskStatus));
}
}
}
@@ -4249,281 +4260,6 @@ public override void Write(Utf8JsonWriter writer, TaskShellInfoAttachmentMode va
}
-/// Whether the shell command is currently sync-waited or background-managed.
-[JsonConverter(typeof(Converter))]
-[DebuggerDisplay("{Value,nq}")]
-public readonly struct TaskShellInfoExecutionMode : IEquatable
-{
- private readonly string? _value;
-
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
- [JsonConstructor]
- public TaskShellInfoExecutionMode(string value)
- {
- ArgumentException.ThrowIfNullOrWhiteSpace(value);
- _value = value;
- }
-
- /// Gets the value associated with this .
- public string Value => _value ?? string.Empty;
-
- /// Gets the sync value.
- public static TaskShellInfoExecutionMode Sync { get; } = new("sync");
-
- /// Gets the background value.
- public static TaskShellInfoExecutionMode Background { get; } = new("background");
-
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(TaskShellInfoExecutionMode left, TaskShellInfoExecutionMode right) => left.Equals(right);
-
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(TaskShellInfoExecutionMode left, TaskShellInfoExecutionMode right) => !(left == right);
-
- ///
- public override bool Equals(object? obj) => obj is TaskShellInfoExecutionMode other && Equals(other);
-
- ///
- public bool Equals(TaskShellInfoExecutionMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
-
- ///
- public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
-
- ///
- public override string ToString() => Value;
-
- /// Provides a for serializing instances.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
- {
- ///
- public override TaskShellInfoExecutionMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
- }
-
- ///
- public override void Write(Utf8JsonWriter writer, TaskShellInfoExecutionMode value, JsonSerializerOptions options)
- {
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(TaskShellInfoExecutionMode));
- }
- }
-}
-
-
-/// Current lifecycle status of the task.
-[JsonConverter(typeof(Converter))]
-[DebuggerDisplay("{Value,nq}")]
-public readonly struct TaskShellInfoStatus : IEquatable
-{
- private readonly string? _value;
-
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
- [JsonConstructor]
- public TaskShellInfoStatus(string value)
- {
- ArgumentException.ThrowIfNullOrWhiteSpace(value);
- _value = value;
- }
-
- /// Gets the value associated with this .
- public string Value => _value ?? string.Empty;
-
- /// Gets the running value.
- public static TaskShellInfoStatus Running { get; } = new("running");
-
- /// Gets the idle value.
- public static TaskShellInfoStatus Idle { get; } = new("idle");
-
- /// Gets the completed value.
- public static TaskShellInfoStatus Completed { get; } = new("completed");
-
- /// Gets the failed value.
- public static TaskShellInfoStatus Failed { get; } = new("failed");
-
- /// Gets the cancelled value.
- public static TaskShellInfoStatus Cancelled { get; } = new("cancelled");
-
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(TaskShellInfoStatus left, TaskShellInfoStatus right) => left.Equals(right);
-
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(TaskShellInfoStatus left, TaskShellInfoStatus right) => !(left == right);
-
- ///
- public override bool Equals(object? obj) => obj is TaskShellInfoStatus other && Equals(other);
-
- ///
- public bool Equals(TaskShellInfoStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
-
- ///
- public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
-
- ///
- public override string ToString() => Value;
-
- /// Provides a for serializing instances.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
- {
- ///
- public override TaskShellInfoStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
- }
-
- ///
- public override void Write(Utf8JsonWriter writer, TaskShellInfoStatus value, JsonSerializerOptions options)
- {
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(TaskShellInfoStatus));
- }
- }
-}
-
-
-/// Configuration source: user, workspace, plugin, or builtin.
-[JsonConverter(typeof(Converter))]
-[DebuggerDisplay("{Value,nq}")]
-public readonly struct McpServerSource : IEquatable
-{
- private readonly string? _value;
-
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
- [JsonConstructor]
- public McpServerSource(string value)
- {
- ArgumentException.ThrowIfNullOrWhiteSpace(value);
- _value = value;
- }
-
- /// Gets the value associated with this .
- public string Value => _value ?? string.Empty;
-
- /// Gets the user value.
- public static McpServerSource User { get; } = new("user");
-
- /// Gets the workspace value.
- public static McpServerSource Workspace { get; } = new("workspace");
-
- /// Gets the plugin value.
- public static McpServerSource Plugin { get; } = new("plugin");
-
- /// Gets the builtin value.
- public static McpServerSource Builtin { get; } = new("builtin");
-
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(McpServerSource left, McpServerSource right) => left.Equals(right);
-
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(McpServerSource left, McpServerSource right) => !(left == right);
-
- ///
- public override bool Equals(object? obj) => obj is McpServerSource other && Equals(other);
-
- ///
- public bool Equals(McpServerSource other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
-
- ///
- public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
-
- ///
- public override string ToString() => Value;
-
- /// Provides a for serializing instances.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
- {
- ///
- public override McpServerSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
- }
-
- ///
- public override void Write(Utf8JsonWriter writer, McpServerSource value, JsonSerializerOptions options)
- {
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpServerSource));
- }
- }
-}
-
-
-/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
-[JsonConverter(typeof(Converter))]
-[DebuggerDisplay("{Value,nq}")]
-public readonly struct McpServerStatus : IEquatable
-{
- private readonly string? _value;
-
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
- [JsonConstructor]
- public McpServerStatus(string value)
- {
- ArgumentException.ThrowIfNullOrWhiteSpace(value);
- _value = value;
- }
-
- /// Gets the value associated with this .
- public string Value => _value ?? string.Empty;
-
- /// Gets the connected value.
- public static McpServerStatus Connected { get; } = new("connected");
-
- /// Gets the failed value.
- public static McpServerStatus Failed { get; } = new("failed");
-
- /// Gets the needs-auth value.
- public static McpServerStatus NeedsAuth { get; } = new("needs-auth");
-
- /// Gets the pending value.
- public static McpServerStatus Pending { get; } = new("pending");
-
- /// Gets the disabled value.
- public static McpServerStatus Disabled { get; } = new("disabled");
-
- /// Gets the not_configured value.
- public static McpServerStatus NotConfigured { get; } = new("not_configured");
-
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(McpServerStatus left, McpServerStatus right) => left.Equals(right);
-
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(McpServerStatus left, McpServerStatus right) => !(left == right);
-
- ///
- public override bool Equals(object? obj) => obj is McpServerStatus other && Equals(other);
-
- ///
- public bool Equals(McpServerStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
-
- ///
- public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
-
- ///
- public override string ToString() => Value;
-
- /// Provides a for serializing instances.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
- {
- ///
- public override McpServerStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
- }
-
- ///
- public override void Write(Utf8JsonWriter writer, McpServerStatus value, JsonSerializerOptions options)
- {
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpServerStatus));
- }
- }
-}
-
-
/// Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/).
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
@@ -4778,71 +4514,6 @@ public override void Write(Utf8JsonWriter writer, SlashCommandKind value, JsonSe
}
-/// Optional target session mode.
-[JsonConverter(typeof(Converter))]
-[DebuggerDisplay("{Value,nq}")]
-public readonly struct SlashCommandAgentPromptMode : IEquatable
-{
- private readonly string? _value;
-
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
- [JsonConstructor]
- public SlashCommandAgentPromptMode(string value)
- {
- ArgumentException.ThrowIfNullOrWhiteSpace(value);
- _value = value;
- }
-
- /// Gets the value associated with this .
- public string Value => _value ?? string.Empty;
-
- /// Gets the interactive value.
- public static SlashCommandAgentPromptMode Interactive { get; } = new("interactive");
-
- /// Gets the plan value.
- public static SlashCommandAgentPromptMode Plan { get; } = new("plan");
-
- /// Gets the autopilot value.
- public static SlashCommandAgentPromptMode Autopilot { get; } = new("autopilot");
-
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(SlashCommandAgentPromptMode left, SlashCommandAgentPromptMode right) => left.Equals(right);
-
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(SlashCommandAgentPromptMode left, SlashCommandAgentPromptMode right) => !(left == right);
-
- ///
- public override bool Equals(object? obj) => obj is SlashCommandAgentPromptMode other && Equals(other);
-
- ///
- public bool Equals(SlashCommandAgentPromptMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
-
- ///
- public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
-
- ///
- public override string ToString() => Value;
-
- /// Provides a for serializing instances.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
- {
- ///
- public override SlashCommandAgentPromptMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
- }
-
- ///
- public override void Write(Utf8JsonWriter writer, SlashCommandAgentPromptMode value, JsonSerializerOptions options)
- {
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SlashCommandAgentPromptMode));
- }
- }
-}
-
-
/// The user's response: accept (submitted), decline (rejected), or cancel (dismissed).
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
@@ -5162,6 +4833,71 @@ public override void Write(Utf8JsonWriter writer, SessionFsReaddirWithTypesEntry
}
+/// How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected).
+[JsonConverter(typeof(Converter))]
+[DebuggerDisplay("{Value,nq}")]
+public readonly struct SessionFsSqliteQueryType : IEquatable
+{
+ private readonly string? _value;
+
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
+ [JsonConstructor]
+ public SessionFsSqliteQueryType(string value)
+ {
+ ArgumentException.ThrowIfNullOrWhiteSpace(value);
+ _value = value;
+ }
+
+ /// Gets the value associated with this .
+ public string Value => _value ?? string.Empty;
+
+ /// Gets the exec value.
+ public static SessionFsSqliteQueryType Exec { get; } = new("exec");
+
+ /// Gets the query value.
+ public static SessionFsSqliteQueryType Query { get; } = new("query");
+
+ /// Gets the run value.
+ public static SessionFsSqliteQueryType Run { get; } = new("run");
+
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(SessionFsSqliteQueryType left, SessionFsSqliteQueryType right) => left.Equals(right);
+
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(SessionFsSqliteQueryType left, SessionFsSqliteQueryType right) => !(left == right);
+
+ ///
+ public override bool Equals(object? obj) => obj is SessionFsSqliteQueryType other && Equals(other);
+
+ ///
+ public bool Equals(SessionFsSqliteQueryType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+
+ ///
+ public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
+
+ ///
+ public override string ToString() => Value;
+
+ /// Provides a for serializing instances.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public sealed class Converter : JsonConverter
+ {
+ ///
+ public override SessionFsSqliteQueryType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
+ }
+
+ ///
+ public override void Write(Utf8JsonWriter writer, SessionFsSqliteQueryType value, JsonSerializerOptions options)
+ {
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SessionFsSqliteQueryType));
+ }
+ }
+}
+
+
/// Provides server-scoped RPC methods (no session required).
public sealed class ServerRpc
{
@@ -5329,7 +5065,7 @@ public async Task ListAsync(CancellationToken cancellationToken =
/// Adds an MCP server to user configuration.
/// Unique name for the MCP server.
- /// MCP server configuration (local/stdio or remote/http).
+ /// MCP server configuration (stdio process or remote HTTP/SSE).
/// The to monitor for cancellation requests. The default is .
public async Task AddAsync(string name, object config, CancellationToken cancellationToken = default)
{
@@ -5339,7 +5075,7 @@ public async Task AddAsync(string name, object config, CancellationToken cancell
/// Updates an MCP server in user configuration.
/// Name of the MCP server to update.
- /// MCP server configuration (local/stdio or remote/http).
+ /// MCP server configuration (stdio process or remote HTTP/SSE).
/// The to monitor for cancellation requests. The default is .
public async Task UpdateAsync(string name, object config, CancellationToken cancellationToken = default)
{
@@ -5435,11 +5171,12 @@ internal ServerSessionFsApi(JsonRpc rpc)
/// Initial working directory for sessions.
/// Path within each session's SessionFs where the runtime stores files for that session.
/// Path conventions used by this filesystem.
+ /// Optional capabilities declared by the provider.
/// The to monitor for cancellation requests. The default is .
/// Indicates whether the calling client was registered as the session filesystem provider.
- public async Task SetProviderAsync(string initialCwd, string sessionStatePath, SessionFsSetProviderConventions conventions, CancellationToken cancellationToken = default)
+ public async Task SetProviderAsync(string initialCwd, string sessionStatePath, SessionFsSetProviderConventions conventions, SessionFsSetProviderCapabilities? capabilities = null, CancellationToken cancellationToken = default)
{
- var request = new SessionFsSetProviderRequest { InitialCwd = initialCwd, SessionStatePath = sessionStatePath, Conventions = conventions };
+ var request = new SessionFsSetProviderRequest { InitialCwd = initialCwd, SessionStatePath = sessionStatePath, Conventions = conventions, Capabilities = capabilities };
return await CopilotClient.InvokeRpcAsync(_rpc, "sessionFs.setProvider", [request], cancellationToken);
}
}
@@ -5671,7 +5408,7 @@ internal ModeApi(JsonRpc rpc, string sessionId)
/// Gets the current agent interaction mode.
/// The to monitor for cancellation requests. The default is .
- /// The agent mode. Valid values: "interactive", "plan", "autopilot".
+ /// The session mode the agent is operating in.
public async Task GetAsync(CancellationToken cancellationToken = default)
{
var request = new SessionModeGetRequest { SessionId = _sessionId };
@@ -5679,7 +5416,7 @@ public async Task GetAsync(CancellationToken cancellationToken = de
}
/// Sets the current agent interaction mode.
- /// The agent mode. Valid values: "interactive", "plan", "autopilot".
+ /// The session mode the agent is operating in.
/// The to monitor for cancellation requests. The default is .
public async Task SetAsync(SessionMode mode, CancellationToken cancellationToken = default)
{
@@ -6531,6 +6268,16 @@ public interface ISessionFsHandler
/// The to monitor for cancellation requests. The default is .
/// Describes a filesystem error.
Task RenameAsync(SessionFsRenameRequest request, CancellationToken cancellationToken = default);
+ /// Executes a SQLite query against the per-session database.
+ /// SQL query, query type, and optional bind parameters for executing a SQLite query against the per-session database.
+ /// The to monitor for cancellation requests. The default is .
+ /// Query results including rows, columns, and rows affected, or a filesystem error if execution failed.
+ Task SqliteQueryAsync(SessionFsSqliteQueryRequest request, CancellationToken cancellationToken = default);
+ /// Checks whether the per-session SQLite database already exists, without creating it.
+ /// Identifies the target session.
+ /// The to monitor for cancellation requests. The default is .
+ /// Indicates whether the per-session SQLite database already exists.
+ Task SqliteExistsAsync(SessionFsSqliteExistsRequest request, CancellationToken cancellationToken = default);
}
/// Provides all client session API handler groups for a session.
@@ -6610,6 +6357,18 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, Func>)(async (request, cancellationToken) =>
+ {
+ var handler = getHandlers(request.SessionId).SessionFs;
+ if (handler is null) throw new InvalidOperationException($"No sessionFs handler registered for session: {request.SessionId}");
+ return await handler.SqliteQueryAsync(request, cancellationToken);
+ }), singleObjectParam: true);
+ rpc.SetLocalRpcMethod("sessionFs.sqliteExists", (Func>)(async (request, cancellationToken) =>
+ {
+ var handler = getHandlers(request.SessionId).SessionFs;
+ if (handler is null) throw new InvalidOperationException($"No sessionFs handler registered for session: {request.SessionId}");
+ return await handler.SqliteExistsAsync(request, cancellationToken);
+ }), singleObjectParam: true);
}
}
@@ -6624,7 +6383,11 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, FuncReasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh").
+ /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max").
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("reasoningEffort")]
public string? ReasoningEffort { get; set; }
@@ -1281,7 +1281,7 @@ public sealed partial class SessionResumeData
[JsonPropertyName("eventCount")]
public required double EventCount { get; set; }
- /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh").
+ /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max").
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("reasoningEffort")]
public string? ReasoningEffort { get; set; }
@@ -1393,8 +1393,9 @@ public sealed partial class SessionScheduleCreatedData
public required long Id { get; set; }
/// Interval between ticks in milliseconds.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonPropertyName("intervalMs")]
- public required long IntervalMs { get; set; }
+ public required TimeSpan IntervalMs { get; set; }
/// Prompt text that gets enqueued on every tick.
[JsonPropertyName("prompt")]
@@ -1498,13 +1499,13 @@ public sealed partial class SessionModelChangeData
/// Agent mode change details including previous and new modes.
public sealed partial class SessionModeChangedData
{
- /// Agent mode after the change (e.g., "interactive", "plan", "autopilot").
+ /// The session mode the agent is operating in.
[JsonPropertyName("newMode")]
- public required string NewMode { get; set; }
+ public required SessionMode NewMode { get; set; }
- /// Agent mode before the change (e.g., "interactive", "plan", "autopilot").
+ /// The session mode the agent is operating in.
[JsonPropertyName("previousMode")]
- public required string PreviousMode { get; set; }
+ public required SessionMode PreviousMode { get; set; }
}
/// Plan file operation details indicating what changed.
@@ -1540,6 +1541,8 @@ public sealed partial class SessionHandoffData
public required DateTimeOffset HandoffTime { get; set; }
/// GitHub host URL for the source session (e.g., https://github.com or https://tenant.ghe.com).
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("host")]
public string? Host { get; set; }
@@ -1667,8 +1670,9 @@ public sealed partial class SessionShutdownData
public double? ToolDefinitionsTokens { get; set; }
/// Cumulative time spent in API calls during the session, in milliseconds.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonPropertyName("totalApiDurationMs")]
- public required double TotalApiDurationMs { get; set; }
+ public required TimeSpan TotalApiDurationMs { get; set; }
/// Session-wide accumulated nano-AI units cost.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -2134,9 +2138,10 @@ public sealed partial class AssistantUsageData
public double? Cost { get; set; }
/// Duration of the API call in milliseconds.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("duration")]
- public double? Duration { get; set; }
+ public TimeSpan? Duration { get; set; }
/// What initiated this API call (e.g., "sub-agent", "mcp-sampling"); absent for user-initiated calls.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -2149,9 +2154,10 @@ public sealed partial class AssistantUsageData
public double? InputTokens { get; set; }
/// Average inter-token latency in milliseconds. Only available for streaming requests.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("interTokenLatencyMs")]
- public double? InterTokenLatencyMs { get; set; }
+ public TimeSpan? InterTokenLatencyMs { get; set; }
/// Model identifier used for this API call.
[JsonPropertyName("model")]
@@ -2179,7 +2185,7 @@ public sealed partial class AssistantUsageData
[JsonPropertyName("quotaSnapshots")]
public IDictionary? QuotaSnapshots { get; set; }
- /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh").
+ /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max").
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("reasoningEffort")]
public string? ReasoningEffort { get; set; }
@@ -2190,9 +2196,10 @@ public sealed partial class AssistantUsageData
public double? ReasoningTokens { get; set; }
/// Time to first token in milliseconds. Only available for streaming requests.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("ttftMs")]
- public double? TtftMs { get; set; }
+ public TimeSpan? TtftMs { get; set; }
}
/// Failed LLM API call metadata for telemetry.
@@ -2204,9 +2211,10 @@ public sealed partial class ModelCallFailureData
public string? ApiCallId { get; set; }
/// Duration of the failed API call in milliseconds.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("durationMs")]
- public double? DurationMs { get; set; }
+ public TimeSpan? DurationMs { get; set; }
/// Raw provider/runtime error message for restricted telemetry.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -2453,9 +2461,10 @@ public sealed partial class SubagentCompletedData
public required string AgentName { get; set; }
/// Wall-clock duration of the sub-agent execution in milliseconds.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("durationMs")]
- public double? DurationMs { get; set; }
+ public TimeSpan? DurationMs { get; set; }
/// Model used by the sub-agent.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -2489,9 +2498,10 @@ public sealed partial class SubagentFailedData
public required string AgentName { get; set; }
/// Wall-clock duration of the sub-agent execution in milliseconds.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("durationMs")]
- public double? DurationMs { get; set; }
+ public TimeSpan? DurationMs { get; set; }
/// Error message describing why the sub-agent failed.
[JsonPropertyName("error")]
@@ -2790,6 +2800,8 @@ public sealed partial class McpOauthRequiredData
public required string ServerName { get; set; }
/// URL of the MCP server that requires OAuth.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("serverUrl")]
public required string ServerUrl { get; set; }
@@ -2945,9 +2957,9 @@ public sealed partial class AutoModeSwitchCompletedData
[JsonPropertyName("requestId")]
public required string RequestId { get; set; }
- /// The user's choice: 'yes', 'yes_always', or 'no'.
+ /// The user's auto-mode-switch choice.
[JsonPropertyName("response")]
- public required string Response { get; set; }
+ public required AutoModeSwitchResponse Response { get; set; }
}
/// SDK command registration change notification.
@@ -2970,17 +2982,17 @@ public sealed partial class CapabilitiesChangedData
/// Plan approval request with plan content and available user actions.
public sealed partial class ExitPlanModeRequestedData
{
- /// Available actions the user can take (e.g., approve, edit, reject).
+ /// Available actions the user can take.
[JsonPropertyName("actions")]
- public required string[] Actions { get; set; }
+ public required ExitPlanModeAction[] Actions { get; set; }
/// Full content of the plan file.
[JsonPropertyName("planContent")]
public required string PlanContent { get; set; }
- /// The recommended action for the user to take.
+ /// Recommended action to preselect for the user.
[JsonPropertyName("recommendedAction")]
- public required string RecommendedAction { get; set; }
+ public required ExitPlanModeAction RecommendedAction { get; set; }
/// Unique identifier for this request; used to respond via session.respondToExitPlanMode().
[JsonPropertyName("requestId")]
@@ -3013,10 +3025,10 @@ public sealed partial class ExitPlanModeCompletedData
[JsonPropertyName("requestId")]
public required string RequestId { get; set; }
- /// Which action the user selected (e.g. 'autopilot', 'interactive', 'exit_only').
+ /// Action selected by the user.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("selectedAction")]
- public string? SelectedAction { get; set; }
+ public ExitPlanModeAction? SelectedAction { get; set; }
}
/// Schema for the `ToolsUpdatedData` type.
@@ -3071,9 +3083,9 @@ public sealed partial class SessionMcpServerStatusChangedData
[JsonPropertyName("serverName")]
public required string ServerName { get; set; }
- /// New connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
+ /// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
[JsonPropertyName("status")]
- public required McpServerStatusChangedStatus Status { get; set; }
+ public required McpServerStatus Status { get; set; }
}
/// Schema for the `ExtensionsLoadedData` type.
@@ -3297,9 +3309,10 @@ public sealed partial class CompactionCompleteCompactionTokensUsed
public CompactionCompleteCompactionTokensUsedCopilotUsage? CopilotUsage { get; set; }
/// Duration of the compaction LLM call in milliseconds.
+ [JsonConverter(typeof(MillisecondsTimeSpanConverter))]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("duration")]
- public double? Duration { get; set; }
+ public TimeSpan? Duration { get; set; }
/// Input tokens consumed by the compaction LLM call.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -3458,6 +3471,8 @@ public sealed partial class UserMessageAttachmentGithubReference : UserMessageAt
public required string Title { get; set; }
/// URL to the referenced item on GitHub.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("url")]
public required string Url { get; set; }
}
@@ -4147,6 +4162,8 @@ public sealed partial class PermissionRequestShellCommand
public sealed partial class PermissionRequestShellPossibleUrl
{
/// URL that may be accessed by the command.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("url")]
public required string Url { get; set; }
}
@@ -4308,6 +4325,8 @@ public sealed partial class PermissionRequestUrl : PermissionRequest
public string? ToolCallId { get; set; }
/// URL to be fetched.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("url")]
public required string Url { get; set; }
}
@@ -4619,6 +4638,8 @@ public sealed partial class PermissionPromptRequestUrl : PermissionPromptRequest
public string? ToolCallId { get; set; }
/// URL to be fetched.
+ [Url]
+ [StringSyntax(StringSyntaxAttribute.Uri)]
[JsonPropertyName("url")]
public required string Url { get; set; }
}
@@ -4634,7 +4655,7 @@ public sealed partial class PermissionPromptRequestMemory : PermissionPromptRequ
/// Whether this is a store or vote memory operation.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("action")]
- public PermissionPromptRequestMemoryAction? Action { get; set; }
+ public PermissionRequestMemoryAction? Action { get; set; }
/// Source references for the stored fact (store only).
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -4644,7 +4665,7 @@ public sealed partial class PermissionPromptRequestMemory : PermissionPromptRequ
/// Vote direction (vote only).
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("direction")]
- public PermissionPromptRequestMemoryDirection? Direction { get; set; }
+ public PermissionRequestMemoryDirection? Direction { get; set; }
/// The fact being stored or voted on.
[JsonPropertyName("fact")]
@@ -5177,9 +5198,9 @@ public sealed partial class SkillsLoadedSkill
[JsonPropertyName("path")]
public string? Path { get; set; }
- /// Source location type of the skill (e.g., project, personal, plugin).
+ /// Source location type (e.g., project, personal-copilot, plugin, builtin).
[JsonPropertyName("source")]
- public required string Source { get; set; }
+ public required SkillSource Source { get; set; }
/// Whether the skill can be invoked by the user as a slash command.
[JsonPropertyName("userInvocable")]
@@ -5240,11 +5261,11 @@ public sealed partial class McpServersLoadedServer
/// Configuration source: user, workspace, plugin, or builtin.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("source")]
- public string? Source { get; set; }
+ public McpServerSource? Source { get; set; }
/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
[JsonPropertyName("status")]
- public required McpServersLoadedServerStatus Status { get; set; }
+ public required McpServerStatus Status { get; set; }
}
/// Schema for the `ExtensionsLoadedExtension` type.
@@ -5393,6 +5414,70 @@ public override void Write(Utf8JsonWriter writer, ReasoningSummary value, JsonSe
}
}
+/// The session mode the agent is operating in.
+[JsonConverter(typeof(Converter))]
+[DebuggerDisplay("{Value,nq}")]
+public readonly struct SessionMode : IEquatable
+{
+ private readonly string? _value;
+
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
+ [JsonConstructor]
+ public SessionMode(string value)
+ {
+ ArgumentException.ThrowIfNullOrWhiteSpace(value);
+ _value = value;
+ }
+
+ /// Gets the value associated with this .
+ public string Value => _value ?? string.Empty;
+
+ /// Gets the interactive value.
+ public static SessionMode Interactive { get; } = new("interactive");
+
+ /// Gets the plan value.
+ public static SessionMode Plan { get; } = new("plan");
+
+ /// Gets the autopilot value.
+ public static SessionMode Autopilot { get; } = new("autopilot");
+
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(SessionMode left, SessionMode right) => left.Equals(right);
+
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(SessionMode left, SessionMode right) => !(left == right);
+
+ ///
+ public override bool Equals(object? obj) => obj is SessionMode other && Equals(other);
+
+ ///
+ public bool Equals(SessionMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+
+ ///
+ public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
+
+ ///
+ public override string ToString() => Value;
+
+ /// Provides a for serializing instances.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public sealed class Converter : JsonConverter
+ {
+ ///
+ public override SessionMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
+ }
+
+ ///
+ public override void Write(Utf8JsonWriter writer, SessionMode value, JsonSerializerOptions options)
+ {
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SessionMode));
+ }
+ }
+}
+
/// The type of operation performed on the plan file.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
@@ -6332,42 +6417,45 @@ public override void Write(Utf8JsonWriter writer, PermissionRequestMemoryDirecti
}
}
-/// Whether this is a store or vote memory operation.
+/// Underlying permission kind that needs path approval.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct PermissionPromptRequestMemoryAction : IEquatable
+public readonly struct PermissionPromptRequestPathAccessKind : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public PermissionPromptRequestMemoryAction(string value)
+ public PermissionPromptRequestPathAccessKind(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
- /// Gets the store value.
- public static PermissionPromptRequestMemoryAction Store { get; } = new("store");
+ /// Gets the read value.
+ public static PermissionPromptRequestPathAccessKind Read { get; } = new("read");
- /// Gets the vote value.
- public static PermissionPromptRequestMemoryAction Vote { get; } = new("vote");
+ /// Gets the shell value.
+ public static PermissionPromptRequestPathAccessKind Shell { get; } = new("shell");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(PermissionPromptRequestMemoryAction left, PermissionPromptRequestMemoryAction right) => left.Equals(right);
+ /// Gets the write value.
+ public static PermissionPromptRequestPathAccessKind Write { get; } = new("write");
+
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(PermissionPromptRequestPathAccessKind left, PermissionPromptRequestPathAccessKind right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(PermissionPromptRequestMemoryAction left, PermissionPromptRequestMemoryAction right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(PermissionPromptRequestPathAccessKind left, PermissionPromptRequestPathAccessKind right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is PermissionPromptRequestMemoryAction other && Equals(other);
+ public override bool Equals(object? obj) => obj is PermissionPromptRequestPathAccessKind other && Equals(other);
///
- public bool Equals(PermissionPromptRequestMemoryAction other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(PermissionPromptRequestPathAccessKind other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -6375,60 +6463,60 @@ public PermissionPromptRequestMemoryAction(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override PermissionPromptRequestMemoryAction Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override PermissionPromptRequestPathAccessKind Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, PermissionPromptRequestMemoryAction value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, PermissionPromptRequestPathAccessKind value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(PermissionPromptRequestMemoryAction));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(PermissionPromptRequestPathAccessKind));
}
}
}
-/// Vote direction (vote only).
+/// Elicitation mode; "form" for structured input, "url" for browser-based. Defaults to "form" when absent.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct PermissionPromptRequestMemoryDirection : IEquatable
+public readonly struct ElicitationRequestedMode : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public PermissionPromptRequestMemoryDirection(string value)
+ public ElicitationRequestedMode(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
- /// Gets the upvote value.
- public static PermissionPromptRequestMemoryDirection Upvote { get; } = new("upvote");
+ /// Gets the form value.
+ public static ElicitationRequestedMode Form { get; } = new("form");
- /// Gets the downvote value.
- public static PermissionPromptRequestMemoryDirection Downvote { get; } = new("downvote");
+ /// Gets the url value.
+ public static ElicitationRequestedMode Url { get; } = new("url");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(PermissionPromptRequestMemoryDirection left, PermissionPromptRequestMemoryDirection right) => left.Equals(right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(ElicitationRequestedMode left, ElicitationRequestedMode right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(PermissionPromptRequestMemoryDirection left, PermissionPromptRequestMemoryDirection right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(ElicitationRequestedMode left, ElicitationRequestedMode right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is PermissionPromptRequestMemoryDirection other && Equals(other);
+ public override bool Equals(object? obj) => obj is ElicitationRequestedMode other && Equals(other);
///
- public bool Equals(PermissionPromptRequestMemoryDirection other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(ElicitationRequestedMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -6436,63 +6524,63 @@ public PermissionPromptRequestMemoryDirection(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override PermissionPromptRequestMemoryDirection Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override ElicitationRequestedMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, PermissionPromptRequestMemoryDirection value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, ElicitationRequestedMode value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(PermissionPromptRequestMemoryDirection));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ElicitationRequestedMode));
}
}
}
-/// Underlying permission kind that needs path approval.
+/// The user action: "accept" (submitted form), "decline" (explicitly refused), or "cancel" (dismissed).
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct PermissionPromptRequestPathAccessKind : IEquatable
+public readonly struct ElicitationCompletedAction : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public PermissionPromptRequestPathAccessKind(string value)
+ public ElicitationCompletedAction(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
- /// Gets the read value.
- public static PermissionPromptRequestPathAccessKind Read { get; } = new("read");
+ /// Gets the accept value.
+ public static ElicitationCompletedAction Accept { get; } = new("accept");
- /// Gets the shell value.
- public static PermissionPromptRequestPathAccessKind Shell { get; } = new("shell");
+ /// Gets the decline value.
+ public static ElicitationCompletedAction Decline { get; } = new("decline");
- /// Gets the write value.
- public static PermissionPromptRequestPathAccessKind Write { get; } = new("write");
+ /// Gets the cancel value.
+ public static ElicitationCompletedAction Cancel { get; } = new("cancel");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(PermissionPromptRequestPathAccessKind left, PermissionPromptRequestPathAccessKind right) => left.Equals(right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(ElicitationCompletedAction left, ElicitationCompletedAction right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(PermissionPromptRequestPathAccessKind left, PermissionPromptRequestPathAccessKind right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(ElicitationCompletedAction left, ElicitationCompletedAction right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is PermissionPromptRequestPathAccessKind other && Equals(other);
+ public override bool Equals(object? obj) => obj is ElicitationCompletedAction other && Equals(other);
///
- public bool Equals(PermissionPromptRequestPathAccessKind other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(ElicitationCompletedAction other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -6500,60 +6588,63 @@ public PermissionPromptRequestPathAccessKind(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override PermissionPromptRequestPathAccessKind Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override ElicitationCompletedAction Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, PermissionPromptRequestPathAccessKind value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, ElicitationCompletedAction value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(PermissionPromptRequestPathAccessKind));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ElicitationCompletedAction));
}
}
}
-/// Elicitation mode; "form" for structured input, "url" for browser-based. Defaults to "form" when absent.
+/// The user's auto-mode-switch choice.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct ElicitationRequestedMode : IEquatable
+public readonly struct AutoModeSwitchResponse : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public ElicitationRequestedMode(string value)
+ public AutoModeSwitchResponse(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
- /// Gets the form value.
- public static ElicitationRequestedMode Form { get; } = new("form");
+ /// Gets the yes value.
+ public static AutoModeSwitchResponse Yes { get; } = new("yes");
- /// Gets the url value.
- public static ElicitationRequestedMode Url { get; } = new("url");
+ /// Gets the yes_always value.
+ public static AutoModeSwitchResponse YesAlways { get; } = new("yes_always");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(ElicitationRequestedMode left, ElicitationRequestedMode right) => left.Equals(right);
+ /// Gets the no value.
+ public static AutoModeSwitchResponse No { get; } = new("no");
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(ElicitationRequestedMode left, ElicitationRequestedMode right) => !(left == right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(AutoModeSwitchResponse left, AutoModeSwitchResponse right) => left.Equals(right);
+
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(AutoModeSwitchResponse left, AutoModeSwitchResponse right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is ElicitationRequestedMode other && Equals(other);
+ public override bool Equals(object? obj) => obj is AutoModeSwitchResponse other && Equals(other);
///
- public bool Equals(ElicitationRequestedMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(AutoModeSwitchResponse other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -6561,63 +6652,66 @@ public ElicitationRequestedMode(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override ElicitationRequestedMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override AutoModeSwitchResponse Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, ElicitationRequestedMode value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, AutoModeSwitchResponse value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ElicitationRequestedMode));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AutoModeSwitchResponse));
}
}
}
-/// The user action: "accept" (submitted form), "decline" (explicitly refused), or "cancel" (dismissed).
+/// Exit plan mode action.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct ElicitationCompletedAction : IEquatable
+public readonly struct ExitPlanModeAction : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public ElicitationCompletedAction(string value)
+ public ExitPlanModeAction(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
- /// Gets the accept value.
- public static ElicitationCompletedAction Accept { get; } = new("accept");
+ /// Gets the exit_only value.
+ public static ExitPlanModeAction ExitOnly { get; } = new("exit_only");
- /// Gets the decline value.
- public static ElicitationCompletedAction Decline { get; } = new("decline");
+ /// Gets the interactive value.
+ public static ExitPlanModeAction Interactive { get; } = new("interactive");
- /// Gets the cancel value.
- public static ElicitationCompletedAction Cancel { get; } = new("cancel");
+ /// Gets the autopilot value.
+ public static ExitPlanModeAction Autopilot { get; } = new("autopilot");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(ElicitationCompletedAction left, ElicitationCompletedAction right) => left.Equals(right);
+ /// Gets the autopilot_fleet value.
+ public static ExitPlanModeAction AutopilotFleet { get; } = new("autopilot_fleet");
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(ElicitationCompletedAction left, ElicitationCompletedAction right) => !(left == right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(ExitPlanModeAction left, ExitPlanModeAction right) => left.Equals(right);
+
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(ExitPlanModeAction left, ExitPlanModeAction right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is ElicitationCompletedAction other && Equals(other);
+ public override bool Equals(object? obj) => obj is ExitPlanModeAction other && Equals(other);
///
- public bool Equals(ElicitationCompletedAction other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(ExitPlanModeAction other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -6625,72 +6719,75 @@ public ElicitationCompletedAction(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override ElicitationCompletedAction Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override ExitPlanModeAction Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, ElicitationCompletedAction value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, ExitPlanModeAction value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ElicitationCompletedAction));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ExitPlanModeAction));
}
}
}
-/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
+/// Source location type (e.g., project, personal-copilot, plugin, builtin).
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct McpServersLoadedServerStatus : IEquatable
+public readonly struct SkillSource : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public McpServersLoadedServerStatus(string value)
+ public SkillSource(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
- /// Gets the connected value.
- public static McpServersLoadedServerStatus Connected { get; } = new("connected");
+ /// Gets the project value.
+ public static SkillSource Project { get; } = new("project");
- /// Gets the failed value.
- public static McpServersLoadedServerStatus Failed { get; } = new("failed");
+ /// Gets the inherited value.
+ public static SkillSource Inherited { get; } = new("inherited");
- /// Gets the needs-auth value.
- public static McpServersLoadedServerStatus NeedsAuth { get; } = new("needs-auth");
+ /// Gets the personal-copilot value.
+ public static SkillSource PersonalCopilot { get; } = new("personal-copilot");
- /// Gets the pending value.
- public static McpServersLoadedServerStatus Pending { get; } = new("pending");
+ /// Gets the personal-agents value.
+ public static SkillSource PersonalAgents { get; } = new("personal-agents");
- /// Gets the disabled value.
- public static McpServersLoadedServerStatus Disabled { get; } = new("disabled");
+ /// Gets the plugin value.
+ public static SkillSource Plugin { get; } = new("plugin");
- /// Gets the not_configured value.
- public static McpServersLoadedServerStatus NotConfigured { get; } = new("not_configured");
+ /// Gets the custom value.
+ public static SkillSource Custom { get; } = new("custom");
+
+ /// Gets the builtin value.
+ public static SkillSource Builtin { get; } = new("builtin");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(McpServersLoadedServerStatus left, McpServersLoadedServerStatus right) => left.Equals(right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(SkillSource left, SkillSource right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(McpServersLoadedServerStatus left, McpServersLoadedServerStatus right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(SkillSource left, SkillSource right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is McpServersLoadedServerStatus other && Equals(other);
+ public override bool Equals(object? obj) => obj is SkillSource other && Equals(other);
///
- public bool Equals(McpServersLoadedServerStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(SkillSource other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -6698,72 +6795,139 @@ public McpServersLoadedServerStatus(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override McpServersLoadedServerStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override SkillSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, McpServersLoadedServerStatus value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, SkillSource value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpServersLoadedServerStatus));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(SkillSource));
}
}
}
-/// New connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
+/// Configuration source: user, workspace, plugin, or builtin.
+[JsonConverter(typeof(Converter))]
+[DebuggerDisplay("{Value,nq}")]
+public readonly struct McpServerSource : IEquatable
+{
+ private readonly string? _value;
+
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
+ [JsonConstructor]
+ public McpServerSource(string value)
+ {
+ ArgumentException.ThrowIfNullOrWhiteSpace(value);
+ _value = value;
+ }
+
+ /// Gets the value associated with this .
+ public string Value => _value ?? string.Empty;
+
+ /// Gets the user value.
+ public static McpServerSource User { get; } = new("user");
+
+ /// Gets the workspace value.
+ public static McpServerSource Workspace { get; } = new("workspace");
+
+ /// Gets the plugin value.
+ public static McpServerSource Plugin { get; } = new("plugin");
+
+ /// Gets the builtin value.
+ public static McpServerSource Builtin { get; } = new("builtin");
+
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(McpServerSource left, McpServerSource right) => left.Equals(right);
+
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(McpServerSource left, McpServerSource right) => !(left == right);
+
+ ///
+ public override bool Equals(object? obj) => obj is McpServerSource other && Equals(other);
+
+ ///
+ public bool Equals(McpServerSource other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+
+ ///
+ public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
+
+ ///
+ public override string ToString() => Value;
+
+ /// Provides a for serializing instances.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public sealed class Converter : JsonConverter
+ {
+ ///
+ public override McpServerSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
+ }
+
+ ///
+ public override void Write(Utf8JsonWriter writer, McpServerSource value, JsonSerializerOptions options)
+ {
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpServerSource));
+ }
+ }
+}
+
+/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
[JsonConverter(typeof(Converter))]
[DebuggerDisplay("{Value,nq}")]
-public readonly struct McpServerStatusChangedStatus : IEquatable
+public readonly struct McpServerStatus : IEquatable
{
private readonly string? _value;
- /// Initializes a new instance of the struct.
- /// The value to associate with this .
+ /// Initializes a new instance of the struct.
+ /// The value to associate with this .
[JsonConstructor]
- public McpServerStatusChangedStatus(string value)
+ public McpServerStatus(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);
_value = value;
}
- /// Gets the value associated with this .
+ /// Gets the value associated with this .
public string Value => _value ?? string.Empty;
/// Gets the connected value.
- public static McpServerStatusChangedStatus Connected { get; } = new("connected");
+ public static McpServerStatus Connected { get; } = new("connected");
/// Gets the failed value.
- public static McpServerStatusChangedStatus Failed { get; } = new("failed");
+ public static McpServerStatus Failed { get; } = new("failed");
/// Gets the needs-auth value.
- public static McpServerStatusChangedStatus NeedsAuth { get; } = new("needs-auth");
+ public static McpServerStatus NeedsAuth { get; } = new("needs-auth");
/// Gets the pending value.
- public static McpServerStatusChangedStatus Pending { get; } = new("pending");
+ public static McpServerStatus Pending { get; } = new("pending");
/// Gets the disabled value.
- public static McpServerStatusChangedStatus Disabled { get; } = new("disabled");
+ public static McpServerStatus Disabled { get; } = new("disabled");
/// Gets the not_configured value.
- public static McpServerStatusChangedStatus NotConfigured { get; } = new("not_configured");
+ public static McpServerStatus NotConfigured { get; } = new("not_configured");
- /// Returns a value indicating whether two instances are equivalent.
- public static bool operator ==(McpServerStatusChangedStatus left, McpServerStatusChangedStatus right) => left.Equals(right);
+ /// Returns a value indicating whether two instances are equivalent.
+ public static bool operator ==(McpServerStatus left, McpServerStatus right) => left.Equals(right);
- /// Returns a value indicating whether two instances are not equivalent.
- public static bool operator !=(McpServerStatusChangedStatus left, McpServerStatusChangedStatus right) => !(left == right);
+ /// Returns a value indicating whether two instances are not equivalent.
+ public static bool operator !=(McpServerStatus left, McpServerStatus right) => !(left == right);
///
- public override bool Equals(object? obj) => obj is McpServerStatusChangedStatus other && Equals(other);
+ public override bool Equals(object? obj) => obj is McpServerStatus other && Equals(other);
///
- public bool Equals(McpServerStatusChangedStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
+ public bool Equals(McpServerStatus other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);
///
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
@@ -6771,20 +6935,20 @@ public McpServerStatusChangedStatus(string value)
///
public override string ToString() => Value;
- /// Provides a for serializing instances.
+ /// Provides a for serializing instances.
[EditorBrowsable(EditorBrowsableState.Never)]
- public sealed class Converter : JsonConverter
+ public sealed class Converter : JsonConverter
{
///
- public override McpServerStatusChangedStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override McpServerStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new(GitHub.Copilot.SDK.GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert));
}
///
- public override void Write(Utf8JsonWriter writer, McpServerStatusChangedStatus value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, McpServerStatus value, JsonSerializerOptions options)
{
- GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpServerStatusChangedStatus));
+ GitHub.Copilot.SDK.GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpServerStatus));
}
}
}
diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go
index 0e5b30214..e8cf96a12 100644
--- a/go/rpc/zrpc.go
+++ b/go/rpc/zrpc.go
@@ -26,7 +26,7 @@ type AccountGetQuotaResult struct {
// Schema for the `AccountQuotaSnapshot` type.
type AccountQuotaSnapshot struct {
- // Number of requests included in the entitlement
+ // Number of requests included in the entitlement, or -1 for unlimited entitlements
EntitlementRequests int64 `json:"entitlementRequests"`
// Whether the user has an unlimited usage entitlement
IsUnlimitedEntitlement bool `json:"isUnlimitedEntitlement"`
@@ -37,7 +37,7 @@ type AccountQuotaSnapshot struct {
// Percentage of entitlement remaining
RemainingPercentage float64 `json:"remainingPercentage"`
// Date when the quota resets (ISO 8601 string)
- ResetDate *string `json:"resetDate,omitempty"`
+ ResetDate *time.Time `json:"resetDate,omitempty"`
// Whether usage is still permitted after quota exhaustion
UsageAllowedWithExhaustedQuota bool `json:"usageAllowedWithExhaustedQuota"`
// Number of requests used so far this period
@@ -154,7 +154,7 @@ type ConnectedRemoteSessionMetadata struct {
// Neutral SDK discriminator for the connected remote session kind.
Kind ConnectedRemoteSessionMetadataKind `json:"kind"`
// Last session update time as an ISO 8601 string.
- ModifiedTime string `json:"modifiedTime"`
+ ModifiedTime time.Time `json:"modifiedTime"`
// Optional friendly session name.
Name *string `json:"name,omitempty"`
// Pull request number associated with the session.
@@ -166,9 +166,9 @@ type ConnectedRemoteSessionMetadata struct {
// SDK session ID for the connected remote session.
SessionID string `json:"sessionId"`
// Remote session staleness deadline as an ISO 8601 string.
- StaleAt *string `json:"staleAt,omitempty"`
+ StaleAt *time.Time `json:"staleAt,omitempty"`
// Session start time as an ISO 8601 string.
- StartTime string `json:"startTime"`
+ StartTime time.Time `json:"startTime"`
// Remote session state returned by the backing service.
State *string `json:"state,omitempty"`
// Optional session summary.
@@ -223,9 +223,9 @@ type DiscoveredMcpServer struct {
Enabled bool `json:"enabled"`
// Server name (config key)
Name string `json:"name"`
- // Configuration source
- Source DiscoveredMcpServerSource `json:"source"`
- // Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)
+ // Configuration source: user, workspace, plugin, or builtin
+ Source McpServerSource `json:"source"`
+ // Server transport type: stdio, http, sse, or memory
Type *DiscoveredMcpServerType `json:"type,omitempty"`
}
@@ -279,6 +279,8 @@ func (ExternalToolTextResultForLlm) externalToolResult() {}
// Expanded external tool result payload
type ExternalToolTextResultForLlm struct {
+ // Base64-encoded binary results returned to the model
+ BinaryResultsForLlm []ExternalToolTextResultForLlmBinaryResultsForLlm `json:"binaryResultsForLlm,omitempty"`
// Structured content blocks from the tool
Contents []ExternalToolTextResultForLlmContent `json:"contents,omitempty"`
// Optional error message for failed executions
@@ -294,6 +296,19 @@ type ExternalToolTextResultForLlm struct {
ToolTelemetry map[string]any `json:"toolTelemetry,omitempty"`
}
+// Binary result returned by a tool for the model
+type ExternalToolTextResultForLlmBinaryResultsForLlm struct {
+ // Base64-encoded binary data
+ Data string `json:"data"`
+ // Human-readable description of the binary data
+ Description *string `json:"description,omitempty"`
+ // MIME type of the binary data
+ MIMEType string `json:"mimeType"`
+ // Binary result type discriminator. Use "image" for images and "resource" for other binary
+ // data.
+ Type ExternalToolTextResultForLlmBinaryResultsForLlmType `json:"type"`
+}
+
// A content block within a tool result, which may be text, terminal output, image, audio,
// or a resource
type ExternalToolTextResultForLlmContent interface {
@@ -451,11 +466,11 @@ type FilterMapping interface {
filterMapping()
}
-type FilterMappingEnumMap map[string]FilterMappingValue
+func (ContentFilterMode) filterMapping() {}
-func (FilterMappingEnumMap) filterMapping() {}
+type FilterMappingEnumMap map[string]ContentFilterMode
-func (FilterMappingString) filterMapping() {}
+func (FilterMappingEnumMap) filterMapping() {}
// Optional user prompt to combine with the fleet orchestration instructions.
// Experimental: FleetStartRequest is part of an experimental API and may change or be
@@ -584,7 +599,7 @@ type LogResult struct {
// MCP server name and configuration to add to user configuration.
type McpConfigAddRequest struct {
- // MCP server configuration (local/stdio or remote/http)
+ // MCP server configuration (stdio process or remote HTTP/SSE)
Config McpServerConfig `json:"config"`
// Unique name for the MCP server
Name string `json:"name"`
@@ -631,7 +646,7 @@ type McpConfigRemoveResult struct {
// MCP server name and replacement configuration to write to user configuration.
type McpConfigUpdateRequest struct {
- // MCP server configuration (local/stdio or remote/http)
+ // MCP server configuration (stdio process or remote HTTP/SSE)
Config McpServerConfig `json:"config"`
// Name of the MCP server to update
Name string `json:"name"`
@@ -716,7 +731,7 @@ type McpServer struct {
Status McpServerStatus `json:"status"`
}
-// MCP server configuration (local/stdio or remote/http)
+// MCP server configuration (stdio process or remote HTTP/SSE)
type McpServerConfig interface {
mcpServerConfig()
}
@@ -729,6 +744,8 @@ func (RawMcpServerConfigData) mcpServerConfig() {}
// Remote MCP server configuration accessed over HTTP or SSE.
type McpServerConfigHTTP struct {
+ // Additional authentication configuration for this server.
+ Auth *McpServerConfigHTTPAuth `json:"auth,omitempty"`
// Content filtering mode to apply to all tools, or a map of tool name to content filtering
// mode.
FilterMapping FilterMapping `json:"filterMapping,omitempty"`
@@ -755,15 +772,15 @@ type McpServerConfigHTTP struct {
func (McpServerConfigHTTP) mcpServerConfig() {}
-// Local MCP server configuration launched as a child process.
-type McpServerConfigLocal struct {
- // Command-line arguments passed to the local MCP server process.
- Args []string `json:"args"`
- // Executable command used to start the local MCP server process.
+// Stdio MCP server configuration launched as a child process.
+type McpServerConfigStdio struct {
+ // Command-line arguments passed to the Stdio MCP server process.
+ Args []string `json:"args,omitempty"`
+ // Executable command used to start the Stdio MCP server process.
Command string `json:"command"`
- // Working directory for the local MCP server process.
+ // Working directory for the Stdio MCP server process.
Cwd *string `json:"cwd,omitempty"`
- // Environment variables to pass to the local MCP server process.
+ // Environment variables to pass to the Stdio MCP server process.
Env map[string]string `json:"env,omitempty"`
// Content filtering mode to apply to all tools, or a map of tool name to content filtering
// mode.
@@ -775,11 +792,15 @@ type McpServerConfigLocal struct {
Timeout *int64 `json:"timeout,omitempty"`
// Tools to include. Defaults to all tools if not specified.
Tools []string `json:"tools,omitempty"`
- // Local transport type. Defaults to "local".
- Type *McpServerConfigLocalType `json:"type,omitempty"`
}
-func (McpServerConfigLocal) mcpServerConfig() {}
+func (McpServerConfigStdio) mcpServerConfig() {}
+
+// Additional authentication configuration for this server.
+type McpServerConfigHTTPAuth struct {
+ // Fixed port for the OAuth redirect callback server.
+ RedirectPort *int64 `json:"redirectPort,omitempty"`
+}
// MCP servers configured for the session, with their connection status.
// Experimental: McpServerList is part of an experimental API and may change or be removed.
@@ -919,7 +940,7 @@ type ModelList struct {
// Policy state (if applicable)
type ModelPolicy struct {
// Current policy state for this model
- State string `json:"state"`
+ State ModelPolicyState `json:"state"`
// Usage terms or conditions for this model
Terms *string `json:"terms,omitempty"`
}
@@ -950,7 +971,7 @@ type ModelSwitchToResult struct {
// Agent interaction mode to apply to the session.
type ModeSetRequest struct {
- // The agent mode. Valid values: "interactive", "plan", "autopilot".
+ // The session mode the agent is operating in
Mode SessionMode `json:"mode"`
}
@@ -1451,7 +1472,7 @@ type ServerSkill struct {
// The project path this skill belongs to (only for project/inherited skills)
ProjectPath *string `json:"projectPath,omitempty"`
// Source location type (e.g., project, personal-copilot, plugin, builtin)
- Source string `json:"source"`
+ Source SkillSource `json:"source"`
// Whether the skill can be invoked by the user as a slash command
UserInvocable bool `json:"userInvocable"`
}
@@ -1628,9 +1649,17 @@ type SessionFsRmRequest struct {
SessionID string `json:"sessionId"`
}
+// Optional capabilities declared by the provider
+type SessionFsSetProviderCapabilities struct {
+ // Whether the provider supports SQLite query/exists operations
+ Sqlite *bool `json:"sqlite,omitempty"`
+}
+
// Initial working directory, session-state path layout, and path conventions used to
// register the calling SDK client as the session filesystem provider.
type SessionFsSetProviderRequest struct {
+ // Optional capabilities declared by the provider
+ Capabilities *SessionFsSetProviderCapabilities `json:"capabilities,omitempty"`
// Path conventions used by this filesystem
Conventions SessionFsSetProviderConventions `json:"conventions"`
// Initial working directory for sessions
@@ -1645,6 +1674,47 @@ type SessionFsSetProviderResult struct {
Success bool `json:"success"`
}
+// Identifies the target session.
+type SessionFsSqliteExistsRequest struct {
+ // Target session identifier
+ SessionID string `json:"sessionId"`
+}
+
+// Indicates whether the per-session SQLite database already exists.
+type SessionFsSqliteExistsResult struct {
+ // Whether the session database already exists
+ Exists bool `json:"exists"`
+}
+
+// SQL query, query type, and optional bind parameters for executing a SQLite query against
+// the per-session database.
+type SessionFsSqliteQueryRequest struct {
+ // Optional named bind parameters
+ Params map[string]any `json:"params,omitempty"`
+ // SQL query to execute
+ Query string `json:"query"`
+ // How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT
+ // (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
+ QueryType SessionFsSqliteQueryType `json:"queryType"`
+ // Target session identifier
+ SessionID string `json:"sessionId"`
+}
+
+// Query results including rows, columns, and rows affected, or a filesystem error if
+// execution failed.
+type SessionFsSqliteQueryResult struct {
+ // Column names from the result set
+ Columns []string `json:"columns"`
+ // Describes a filesystem error.
+ Error *SessionFsError `json:"error,omitempty"`
+ // Last inserted row ID (for INSERT)
+ LastInsertRowid *float64 `json:"lastInsertRowid,omitempty"`
+ // For SELECT: array of row objects. For others: empty array.
+ Rows []map[string]any `json:"rows"`
+ // Number of rows affected (for INSERT/UPDATE/DELETE)
+ RowsAffected int64 `json:"rowsAffected"`
+}
+
// Path whose metadata should be returned from the client-provided session filesystem.
type SessionFsStatRequest struct {
// Path using SessionFs conventions
@@ -1795,8 +1865,8 @@ type Skill struct {
Name string `json:"name"`
// Absolute path to the skill file
Path *string `json:"path,omitempty"`
- // Source location type (e.g., project, personal, plugin)
- Source string `json:"source"`
+ // Source location type (e.g., project, personal-copilot, plugin, builtin)
+ Source SkillSource `json:"source"`
// Whether the skill can be invoked by the user as a slash command
UserInvocable bool `json:"userInvocable"`
}
@@ -1905,8 +1975,8 @@ func (r RawSlashCommandInvocationResultData) Kind() SlashCommandInvocationResult
type SlashCommandAgentPromptResult struct {
// Prompt text to display to the user
DisplayPrompt string `json:"displayPrompt"`
- // Optional target session mode
- Mode *SlashCommandAgentPromptMode `json:"mode,omitempty"`
+ // Optional target session mode for the agent prompt
+ Mode *SessionMode `json:"mode,omitempty"`
// Prompt to submit to the agent
Prompt string `json:"prompt"`
// True when the invocation mutated user runtime settings; consumers caching settings should
@@ -1985,8 +2055,8 @@ type TaskAgentInfo struct {
Description string `json:"description"`
// Error message when the task failed
Error *string `json:"error,omitempty"`
- // How the agent is currently being managed by the runtime
- ExecutionMode *TaskAgentInfoExecutionMode `json:"executionMode,omitempty"`
+ // Whether task execution is synchronously awaited or managed in the background
+ ExecutionMode *TaskExecutionMode `json:"executionMode,omitempty"`
// Unique task identifier
ID string `json:"id"`
// ISO 8601 timestamp when the agent entered idle state
@@ -2002,7 +2072,7 @@ type TaskAgentInfo struct {
// ISO 8601 timestamp when the task was started
StartedAt time.Time `json:"startedAt"`
// Current lifecycle status of the task
- Status TaskAgentInfoStatus `json:"status"`
+ Status TaskStatus `json:"status"`
// Tool call ID associated with this agent task
ToolCallID string `json:"toolCallId"`
}
@@ -2025,8 +2095,8 @@ type TaskShellInfo struct {
CompletedAt *time.Time `json:"completedAt,omitempty"`
// Short description of the task
Description string `json:"description"`
- // Whether the shell command is currently sync-waited or background-managed
- ExecutionMode *TaskShellInfoExecutionMode `json:"executionMode,omitempty"`
+ // Whether task execution is synchronously awaited or managed in the background
+ ExecutionMode *TaskExecutionMode `json:"executionMode,omitempty"`
// Unique task identifier
ID string `json:"id"`
// Path to the detached shell log, when available
@@ -2036,7 +2106,7 @@ type TaskShellInfo struct {
// ISO 8601 timestamp when the task was started
StartedAt time.Time `json:"startedAt"`
// Current lifecycle status of the task
- Status TaskShellInfoStatus `json:"status"`
+ Status TaskStatus `json:"status"`
}
func (TaskShellInfo) taskInfo() {}
@@ -2583,17 +2653,18 @@ const (
ConnectedRemoteSessionMetadataKindRemoteSession ConnectedRemoteSessionMetadataKind = "remote-session"
)
-// Configuration source
-type DiscoveredMcpServerSource string
+// Controls how MCP tool result content is filtered: none leaves content unchanged, markdown
+// sanitizes HTML while preserving Markdown-friendly output, and hidden_characters removes
+// characters that can hide directives.
+type ContentFilterMode string
const (
- DiscoveredMcpServerSourceBuiltin DiscoveredMcpServerSource = "builtin"
- DiscoveredMcpServerSourcePlugin DiscoveredMcpServerSource = "plugin"
- DiscoveredMcpServerSourceUser DiscoveredMcpServerSource = "user"
- DiscoveredMcpServerSourceWorkspace DiscoveredMcpServerSource = "workspace"
+ ContentFilterModeHiddenCharacters ContentFilterMode = "hidden_characters"
+ ContentFilterModeMarkdown ContentFilterMode = "markdown"
+ ContentFilterModeNone ContentFilterMode = "none"
)
-// Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)
+// Server transport type: stdio, http, sse, or memory
type DiscoveredMcpServerType string
const (
@@ -2621,6 +2692,15 @@ const (
ExtensionStatusStarting ExtensionStatus = "starting"
)
+// Binary result type discriminator. Use "image" for images and "resource" for other binary
+// data.
+type ExternalToolTextResultForLlmBinaryResultsForLlmType string
+
+const (
+ ExternalToolTextResultForLlmBinaryResultsForLlmTypeImage ExternalToolTextResultForLlmBinaryResultsForLlmType = "image"
+ ExternalToolTextResultForLlmBinaryResultsForLlmTypeResource ExternalToolTextResultForLlmBinaryResultsForLlmType = "resource"
+)
+
// Theme variant this icon is intended for
type ExternalToolTextResultForLlmContentResourceLinkIconTheme string
@@ -2641,24 +2721,6 @@ const (
ExternalToolTextResultForLlmContentTypeText ExternalToolTextResultForLlmContentType = "text"
)
-// Allowed values for the `FilterMappingString` enumeration.
-type FilterMappingString string
-
-const (
- FilterMappingStringHiddenCharacters FilterMappingString = "hidden_characters"
- FilterMappingStringMarkdown FilterMappingString = "markdown"
- FilterMappingStringNone FilterMappingString = "none"
-)
-
-// Allowed values for the `FilterMappingValue` enumeration.
-type FilterMappingValue string
-
-const (
- FilterMappingValueHiddenCharacters FilterMappingValue = "hidden_characters"
- FilterMappingValueMarkdown FilterMappingValue = "markdown"
- FilterMappingValueNone FilterMappingValue = "none"
-)
-
// Where this source lives — used for UI grouping
type InstructionsSourcesLocation string
@@ -2696,14 +2758,6 @@ const (
McpServerConfigHTTPTypeSse McpServerConfigHTTPType = "sse"
)
-// Local transport type. Defaults to "local".
-type McpServerConfigLocalType string
-
-const (
- McpServerConfigLocalTypeLocal McpServerConfigLocalType = "local"
- McpServerConfigLocalTypeStdio McpServerConfigLocalType = "stdio"
-)
-
// Configuration source: user, workspace, plugin, or builtin
type McpServerSource string
@@ -2745,6 +2799,15 @@ const (
ModelPickerPriceCategoryVeryHigh ModelPickerPriceCategory = "very_high"
)
+// Current policy state for this model
+type ModelPolicyState string
+
+const (
+ ModelPolicyStateDisabled ModelPolicyState = "disabled"
+ ModelPolicyStateEnabled ModelPolicyState = "enabled"
+ ModelPolicyStateUnconfigured ModelPolicyState = "unconfigured"
+)
+
// Kind discriminator for PermissionDecisionApproveForLocationApproval.
type PermissionDecisionApproveForLocationApprovalKind string
@@ -2830,6 +2893,16 @@ const (
SessionFsSetProviderConventionsWindows SessionFsSetProviderConventions = "windows"
)
+// How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT
+// (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
+type SessionFsSqliteQueryType string
+
+const (
+ SessionFsSqliteQueryTypeExec SessionFsSqliteQueryType = "exec"
+ SessionFsSqliteQueryTypeQuery SessionFsSqliteQueryType = "query"
+ SessionFsSqliteQueryTypeRun SessionFsSqliteQueryType = "run"
+)
+
// Log severity level. Determines how the message is displayed in the timeline. Defaults to
// "info".
type SessionLogLevel string
@@ -2840,7 +2913,7 @@ const (
SessionLogLevelWarning SessionLogLevel = "warning"
)
-// The agent mode. Valid values: "interactive", "plan", "autopilot".
+// The session mode the agent is operating in
type SessionMode string
const (
@@ -2858,13 +2931,17 @@ const (
ShellKillSignalSIGTERM ShellKillSignal = "SIGTERM"
)
-// Optional target session mode
-type SlashCommandAgentPromptMode string
+// Source location type (e.g., project, personal-copilot, plugin, builtin)
+type SkillSource string
const (
- SlashCommandAgentPromptModeAutopilot SlashCommandAgentPromptMode = "autopilot"
- SlashCommandAgentPromptModeInteractive SlashCommandAgentPromptMode = "interactive"
- SlashCommandAgentPromptModePlan SlashCommandAgentPromptMode = "plan"
+ SkillSourceBuiltin SkillSource = "builtin"
+ SkillSourceCustom SkillSource = "custom"
+ SkillSourceInherited SkillSource = "inherited"
+ SkillSourcePersonalAgents SkillSource = "personal-agents"
+ SkillSourcePersonalCopilot SkillSource = "personal-copilot"
+ SkillSourcePlugin SkillSource = "plugin"
+ SkillSourceProject SkillSource = "project"
)
// Optional completion hint for the input (e.g. 'directory' for filesystem path completion)
@@ -2893,23 +2970,12 @@ const (
SlashCommandKindSkill SlashCommandKind = "skill"
)
-// How the agent is currently being managed by the runtime
-type TaskAgentInfoExecutionMode string
-
-const (
- TaskAgentInfoExecutionModeBackground TaskAgentInfoExecutionMode = "background"
- TaskAgentInfoExecutionModeSync TaskAgentInfoExecutionMode = "sync"
-)
-
-// Current lifecycle status of the task
-type TaskAgentInfoStatus string
+// Whether task execution is synchronously awaited or managed in the background
+type TaskExecutionMode string
const (
- TaskAgentInfoStatusCancelled TaskAgentInfoStatus = "cancelled"
- TaskAgentInfoStatusCompleted TaskAgentInfoStatus = "completed"
- TaskAgentInfoStatusFailed TaskAgentInfoStatus = "failed"
- TaskAgentInfoStatusIdle TaskAgentInfoStatus = "idle"
- TaskAgentInfoStatusRunning TaskAgentInfoStatus = "running"
+ TaskExecutionModeBackground TaskExecutionMode = "background"
+ TaskExecutionModeSync TaskExecutionMode = "sync"
)
// Type discriminator for TaskInfo.
@@ -2929,23 +2995,15 @@ const (
TaskShellInfoAttachmentModeDetached TaskShellInfoAttachmentMode = "detached"
)
-// Whether the shell command is currently sync-waited or background-managed
-type TaskShellInfoExecutionMode string
-
-const (
- TaskShellInfoExecutionModeBackground TaskShellInfoExecutionMode = "background"
- TaskShellInfoExecutionModeSync TaskShellInfoExecutionMode = "sync"
-)
-
// Current lifecycle status of the task
-type TaskShellInfoStatus string
+type TaskStatus string
const (
- TaskShellInfoStatusCancelled TaskShellInfoStatus = "cancelled"
- TaskShellInfoStatusCompleted TaskShellInfoStatus = "completed"
- TaskShellInfoStatusFailed TaskShellInfoStatus = "failed"
- TaskShellInfoStatusIdle TaskShellInfoStatus = "idle"
- TaskShellInfoStatusRunning TaskShellInfoStatus = "running"
+ TaskStatusCancelled TaskStatus = "cancelled"
+ TaskStatusCompleted TaskStatus = "completed"
+ TaskStatusFailed TaskStatus = "failed"
+ TaskStatusIdle TaskStatus = "idle"
+ TaskStatusRunning TaskStatus = "running"
)
// Type discriminator. Always "string".
@@ -3943,7 +4001,7 @@ type ModeApi sessionApi
//
// RPC method: session.mode.get.
//
-// Returns: The agent mode. Valid values: "interactive", "plan", "autopilot".
+// Returns: The session mode the agent is operating in
func (a *ModeApi) Get(ctx context.Context) (*SessionMode, error) {
req := map[string]any{"sessionId": a.sessionID}
raw, err := a.client.Request("session.mode.get", req)
@@ -4934,6 +4992,25 @@ type SessionFsHandler interface {
//
// Returns: Describes a filesystem error.
Rm(request *SessionFsRmRequest) (*SessionFsError, error)
+ // SqliteExists checks whether the per-session SQLite database already exists, without
+ // creating it.
+ //
+ // RPC method: sessionFs.sqliteExists.
+ //
+ // Parameters: Identifies the target session.
+ //
+ // Returns: Indicates whether the per-session SQLite database already exists.
+ SqliteExists(request *SessionFsSqliteExistsRequest) (*SessionFsSqliteExistsResult, error)
+ // SqliteQuery executes a SQLite query against the per-session database.
+ //
+ // RPC method: sessionFs.sqliteQuery.
+ //
+ // Parameters: SQL query, query type, and optional bind parameters for executing a SQLite
+ // query against the per-session database.
+ //
+ // Returns: Query results including rows, columns, and rows affected, or a filesystem error
+ // if execution failed.
+ SqliteQuery(request *SessionFsSqliteQueryRequest) (*SessionFsSqliteQueryResult, error)
// Stat gets metadata for a path in the client-provided session filesystem.
//
// RPC method: sessionFs.stat.
@@ -5126,6 +5203,44 @@ func RegisterClientSessionApiHandlers(client *jsonrpc2.Client, getHandlers func(
}
return raw, nil
})
+ client.SetRequestHandler("sessionFs.sqliteExists", func(params json.RawMessage) (json.RawMessage, *jsonrpc2.Error) {
+ var request SessionFsSqliteExistsRequest
+ if err := json.Unmarshal(params, &request); err != nil {
+ return nil, &jsonrpc2.Error{Code: -32602, Message: fmt.Sprintf("Invalid params: %v", err)}
+ }
+ handlers := getHandlers(request.SessionID)
+ if handlers == nil || handlers.SessionFs == nil {
+ return nil, &jsonrpc2.Error{Code: -32603, Message: fmt.Sprintf("No sessionFs handler registered for session: %s", request.SessionID)}
+ }
+ result, err := handlers.SessionFs.SqliteExists(&request)
+ if err != nil {
+ return nil, clientSessionHandlerError(err)
+ }
+ raw, err := json.Marshal(result)
+ if err != nil {
+ return nil, &jsonrpc2.Error{Code: -32603, Message: fmt.Sprintf("Failed to marshal response: %v", err)}
+ }
+ return raw, nil
+ })
+ client.SetRequestHandler("sessionFs.sqliteQuery", func(params json.RawMessage) (json.RawMessage, *jsonrpc2.Error) {
+ var request SessionFsSqliteQueryRequest
+ if err := json.Unmarshal(params, &request); err != nil {
+ return nil, &jsonrpc2.Error{Code: -32602, Message: fmt.Sprintf("Invalid params: %v", err)}
+ }
+ handlers := getHandlers(request.SessionID)
+ if handlers == nil || handlers.SessionFs == nil {
+ return nil, &jsonrpc2.Error{Code: -32603, Message: fmt.Sprintf("No sessionFs handler registered for session: %s", request.SessionID)}
+ }
+ result, err := handlers.SessionFs.SqliteQuery(&request)
+ if err != nil {
+ return nil, clientSessionHandlerError(err)
+ }
+ raw, err := json.Marshal(result)
+ if err != nil {
+ return nil, &jsonrpc2.Error{Code: -32603, Message: fmt.Sprintf("Failed to marshal response: %v", err)}
+ }
+ return raw, nil
+ })
client.SetRequestHandler("sessionFs.stat", func(params json.RawMessage) (json.RawMessage, *jsonrpc2.Error) {
var request SessionFsStatRequest
if err := json.Unmarshal(params, &request); err != nil {
diff --git a/go/rpc/zrpc_encoding.go b/go/rpc/zrpc_encoding.go
index ed6610c74..554b13893 100644
--- a/go/rpc/zrpc_encoding.go
+++ b/go/rpc/zrpc_encoding.go
@@ -289,17 +289,19 @@ func (r ExternalToolTextResultForLlmContentText) MarshalJSON() ([]byte, error) {
func (r *ExternalToolTextResultForLlm) UnmarshalJSON(data []byte) error {
type rawExternalToolTextResultForLlm struct {
- Contents []json.RawMessage `json:"contents,omitempty"`
- Error *string `json:"error,omitempty"`
- ResultType *string `json:"resultType,omitempty"`
- SessionLog *string `json:"sessionLog,omitempty"`
- TextResultForLlm string `json:"textResultForLlm"`
- ToolTelemetry map[string]any `json:"toolTelemetry,omitempty"`
+ BinaryResultsForLlm []ExternalToolTextResultForLlmBinaryResultsForLlm `json:"binaryResultsForLlm,omitempty"`
+ Contents []json.RawMessage `json:"contents,omitempty"`
+ Error *string `json:"error,omitempty"`
+ ResultType *string `json:"resultType,omitempty"`
+ SessionLog *string `json:"sessionLog,omitempty"`
+ TextResultForLlm string `json:"textResultForLlm"`
+ ToolTelemetry map[string]any `json:"toolTelemetry,omitempty"`
}
var raw rawExternalToolTextResultForLlm
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
+ r.BinaryResultsForLlm = raw.BinaryResultsForLlm
if raw.Contents != nil {
r.Contents = make([]ExternalToolTextResultForLlmContent, 0, len(raw.Contents))
for _, rawItem := range raw.Contents {
@@ -348,7 +350,7 @@ func unmarshalFilterMapping(data []byte) (FilterMapping, error) {
}
}
{
- var value FilterMappingString
+ var value ContentFilterMode
if err := json.Unmarshal(data, &value); err == nil {
return value, nil
}
@@ -380,7 +382,6 @@ func (r *HandlePendingToolCallRequest) UnmarshalJSON(data []byte) error {
func matchesMcpServerConfigHTTP(data []byte) bool {
var rawGroup0 struct {
- Args json.RawMessage `json:"args"`
Command json.RawMessage `json:"command"`
URL json.RawMessage `json:"url"`
}
@@ -390,24 +391,17 @@ func matchesMcpServerConfigHTTP(data []byte) bool {
if rawGroup0.URL == nil {
return false
}
- if rawGroup0.Args != nil {
- return false
- }
return rawGroup0.Command == nil
}
-func matchesMcpServerConfigLocal(data []byte) bool {
+func matchesMcpServerConfigStdio(data []byte) bool {
var rawGroup0 struct {
- Args json.RawMessage `json:"args"`
Command json.RawMessage `json:"command"`
URL json.RawMessage `json:"url"`
}
if err := json.Unmarshal(data, &rawGroup0); err != nil {
return false
}
- if rawGroup0.Args == nil {
- return false
- }
if rawGroup0.Command == nil {
return false
}
@@ -425,8 +419,8 @@ func unmarshalMcpServerConfig(data []byte) (McpServerConfig, error) {
}
return &d, nil
}
- if matchesMcpServerConfigLocal(data) {
- var d McpServerConfigLocal
+ if matchesMcpServerConfigStdio(data) {
+ var d McpServerConfigStdio
if err := json.Unmarshal(data, &d); err != nil {
return nil, err
}
@@ -444,6 +438,7 @@ func (r RawMcpServerConfigData) MarshalJSON() ([]byte, error) {
func (r *McpServerConfigHTTP) UnmarshalJSON(data []byte) error {
type rawMcpServerConfigHTTP struct {
+ Auth *McpServerConfigHTTPAuth `json:"auth,omitempty"`
FilterMapping json.RawMessage `json:"filterMapping,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
IsDefaultServer *bool `json:"isDefaultServer,omitempty"`
@@ -459,6 +454,7 @@ func (r *McpServerConfigHTTP) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
+ r.Auth = raw.Auth
if raw.FilterMapping != nil {
value, err := unmarshalFilterMapping(raw.FilterMapping)
if err != nil {
@@ -478,19 +474,18 @@ func (r *McpServerConfigHTTP) UnmarshalJSON(data []byte) error {
return nil
}
-func (r *McpServerConfigLocal) UnmarshalJSON(data []byte) error {
- type rawMcpServerConfigLocal struct {
- Args []string `json:"args"`
- Command string `json:"command"`
- Cwd *string `json:"cwd,omitempty"`
- Env map[string]string `json:"env,omitempty"`
- FilterMapping json.RawMessage `json:"filterMapping,omitempty"`
- IsDefaultServer *bool `json:"isDefaultServer,omitempty"`
- Timeout *int64 `json:"timeout,omitempty"`
- Tools []string `json:"tools,omitempty"`
- Type *McpServerConfigLocalType `json:"type,omitempty"`
+func (r *McpServerConfigStdio) UnmarshalJSON(data []byte) error {
+ type rawMcpServerConfigStdio struct {
+ Args []string `json:"args,omitempty"`
+ Command string `json:"command"`
+ Cwd *string `json:"cwd,omitempty"`
+ Env map[string]string `json:"env,omitempty"`
+ FilterMapping json.RawMessage `json:"filterMapping,omitempty"`
+ IsDefaultServer *bool `json:"isDefaultServer,omitempty"`
+ Timeout *int64 `json:"timeout,omitempty"`
+ Tools []string `json:"tools,omitempty"`
}
- var raw rawMcpServerConfigLocal
+ var raw rawMcpServerConfigStdio
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
@@ -508,7 +503,6 @@ func (r *McpServerConfigLocal) UnmarshalJSON(data []byte) error {
r.IsDefaultServer = raw.IsDefaultServer
r.Timeout = raw.Timeout
r.Tools = raw.Tools
- r.Type = raw.Type
return nil
}
diff --git a/go/rpc/zsession_events.go b/go/rpc/zsession_events.go
index 265c2a772..15e7088ea 100644
--- a/go/rpc/zsession_events.go
+++ b/go/rpc/zsession_events.go
@@ -147,10 +147,10 @@ func (*AssistantIntentData) Type() SessionEventType { return SessionEventTypeAss
// Agent mode change details including previous and new modes
type SessionModeChangedData struct {
- // Agent mode after the change (e.g., "interactive", "plan", "autopilot")
- NewMode string `json:"newMode"`
- // Agent mode before the change (e.g., "interactive", "plan", "autopilot")
- PreviousMode string `json:"previousMode"`
+ // The session mode the agent is operating in
+ NewMode SessionMode `json:"newMode"`
+ // The session mode the agent is operating in
+ PreviousMode SessionMode `json:"previousMode"`
}
func (*SessionModeChangedData) sessionEventData() {}
@@ -209,8 +209,8 @@ func (*AssistantMessageData) Type() SessionEventType { return SessionEventTypeAs
type AutoModeSwitchCompletedData struct {
// Request ID of the resolved request; clients should dismiss any UI for this request
RequestID string `json:"requestId"`
- // The user's choice: 'yes', 'yes_always', or 'no'
- Response string `json:"response"`
+ // The user's auto-mode-switch choice
+ Response AutoModeSwitchResponse `json:"response"`
}
func (*AutoModeSwitchCompletedData) sessionEventData() {}
@@ -552,7 +552,7 @@ type AssistantUsageData struct {
ProviderCallID *string `json:"providerCallId,omitempty"`
// Per-quota resource usage snapshots, keyed by quota identifier
QuotaSnapshots map[string]AssistantUsageQuotaSnapshot `json:"quotaSnapshots,omitempty"`
- // Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ // Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
ReasoningEffort *string `json:"reasoningEffort,omitempty"`
// Number of output tokens used for reasoning (e.g., chain-of-thought)
ReasoningTokens *float64 `json:"reasoningTokens,omitempty"`
@@ -677,12 +677,12 @@ func (*PermissionRequestedData) Type() SessionEventType { return SessionEventTyp
// Plan approval request with plan content and available user actions
type ExitPlanModeRequestedData struct {
- // Available actions the user can take (e.g., approve, edit, reject)
- Actions []string `json:"actions"`
+ // Available actions the user can take
+ Actions []ExitPlanModeAction `json:"actions"`
// Full content of the plan file
PlanContent string `json:"planContent"`
- // The recommended action for the user to take
- RecommendedAction string `json:"recommendedAction"`
+ // Recommended action to preselect for the user
+ RecommendedAction ExitPlanModeAction `json:"recommendedAction"`
// Unique identifier for this request; used to respond via session.respondToExitPlanMode()
RequestID string `json:"requestId"`
// Summary of the plan that was created
@@ -713,8 +713,8 @@ type ExitPlanModeCompletedData struct {
Feedback *string `json:"feedback,omitempty"`
// Request ID of the resolved exit plan mode request; clients should dismiss any UI for this request
RequestID string `json:"requestId"`
- // Which action the user selected (e.g. 'autopilot', 'interactive', 'exit_only')
- SelectedAction *string `json:"selectedAction,omitempty"`
+ // Action selected by the user
+ SelectedAction *ExitPlanModeAction `json:"selectedAction,omitempty"`
}
func (*ExitPlanModeCompletedData) sessionEventData() {}
@@ -857,8 +857,8 @@ func (*SessionExtensionsLoadedData) Type() SessionEventType {
type SessionMcpServerStatusChangedData struct {
// Name of the MCP server whose status changed
ServerName string `json:"serverName"`
- // New connection status: connected, failed, needs-auth, pending, disabled, or not_configured
- Status McpServerStatusChangedStatus `json:"status"`
+ // Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+ Status McpServerStatus `json:"status"`
}
func (*SessionMcpServerStatusChangedData) sessionEventData() {}
@@ -964,7 +964,7 @@ type SessionStartData struct {
DetachedFromSpawningParentSessionID *string `json:"detachedFromSpawningParentSessionId,omitempty"`
// Identifier of the software producing the events (e.g., "copilot-agent")
Producer string `json:"producer"`
- // Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ // Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
ReasoningEffort *string `json:"reasoningEffort,omitempty"`
// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
ReasoningSummary *ReasoningSummary `json:"reasoningSummary,omitempty"`
@@ -993,7 +993,7 @@ type SessionResumeData struct {
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. "none", "low", "medium", "high", "xhigh")
+ // Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
ReasoningEffort *string `json:"reasoningEffort,omitempty"`
// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
ReasoningSummary *ReasoningSummary `json:"reasoningSummary,omitempty"`
@@ -1659,9 +1659,9 @@ type McpServersLoadedServer struct {
// Server name (config key)
Name string `json:"name"`
// Configuration source: user, workspace, plugin, or builtin
- Source *string `json:"source,omitempty"`
+ Source *McpServerSource `json:"source,omitempty"`
// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
- Status McpServersLoadedServerStatus `json:"status"`
+ Status McpServerStatus `json:"status"`
}
// Derived user-facing permission prompt details for UI consumers
@@ -1787,11 +1787,11 @@ func (PermissionPromptRequestMcp) Kind() PermissionPromptRequestKind {
// Memory operation permission prompt
type PermissionPromptRequestMemory struct {
// Whether this is a store or vote memory operation
- Action *PermissionPromptRequestMemoryAction `json:"action,omitempty"`
+ Action *PermissionRequestMemoryAction `json:"action,omitempty"`
// Source references for the stored fact (store only)
Citations *string `json:"citations,omitempty"`
// Vote direction (vote only)
- Direction *PermissionPromptRequestMemoryDirection `json:"direction,omitempty"`
+ Direction *PermissionRequestMemoryDirection `json:"direction,omitempty"`
// The fact being stored or voted on
Fact string `json:"fact"`
// Reason for the vote (vote only)
@@ -2282,8 +2282,8 @@ type SkillsLoadedSkill struct {
Name string `json:"name"`
// Absolute path to the skill file, if available
Path *string `json:"path,omitempty"`
- // Source location type of the skill (e.g., project, personal, plugin)
- Source string `json:"source"`
+ // Source location type (e.g., project, personal-copilot, plugin, builtin)
+ Source SkillSource `json:"source"`
// Whether the skill can be invoked by the user as a slash command
UserInvocable bool `json:"userInvocable"`
}
@@ -2820,6 +2820,15 @@ const (
AssistantUsageAPIEndpointWsResponses AssistantUsageAPIEndpoint = "ws:/responses"
)
+// The user's auto-mode-switch choice
+type AutoModeSwitchResponse string
+
+const (
+ AutoModeSwitchResponseNo AutoModeSwitchResponse = "no"
+ AutoModeSwitchResponseYes AutoModeSwitchResponse = "yes"
+ AutoModeSwitchResponseYesAlways AutoModeSwitchResponse = "yes_always"
+)
+
// The user action: "accept" (submitted form), "decline" (explicitly refused), or "cancel" (dismissed)
type ElicitationCompletedAction string
@@ -2844,6 +2853,16 @@ const (
ElicitationRequestedSchemaTypeObject ElicitationRequestedSchemaType = "object"
)
+// Exit plan mode action
+type ExitPlanModeAction string
+
+const (
+ ExitPlanModeActionAutopilot ExitPlanModeAction = "autopilot"
+ ExitPlanModeActionAutopilotFleet ExitPlanModeAction = "autopilot_fleet"
+ ExitPlanModeActionExitOnly ExitPlanModeAction = "exit_only"
+ ExitPlanModeActionInteractive ExitPlanModeAction = "interactive"
+)
+
// Discovery source
type ExtensionsLoadedExtensionSource string
@@ -2877,30 +2896,6 @@ const (
McpOauthRequiredStaticClientConfigGrantTypeClientCredentials McpOauthRequiredStaticClientConfigGrantType = "client_credentials"
)
-// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
-type McpServersLoadedServerStatus string
-
-const (
- McpServersLoadedServerStatusConnected McpServersLoadedServerStatus = "connected"
- McpServersLoadedServerStatusDisabled McpServersLoadedServerStatus = "disabled"
- McpServersLoadedServerStatusFailed McpServersLoadedServerStatus = "failed"
- McpServersLoadedServerStatusNeedsAuth McpServersLoadedServerStatus = "needs-auth"
- McpServersLoadedServerStatusNotConfigured McpServersLoadedServerStatus = "not_configured"
- McpServersLoadedServerStatusPending McpServersLoadedServerStatus = "pending"
-)
-
-// New connection status: connected, failed, needs-auth, pending, disabled, or not_configured
-type McpServerStatusChangedStatus string
-
-const (
- McpServerStatusChangedStatusConnected McpServerStatusChangedStatus = "connected"
- McpServerStatusChangedStatusDisabled McpServerStatusChangedStatus = "disabled"
- McpServerStatusChangedStatusFailed McpServerStatusChangedStatus = "failed"
- McpServerStatusChangedStatusNeedsAuth McpServerStatusChangedStatus = "needs-auth"
- McpServerStatusChangedStatusNotConfigured McpServerStatusChangedStatus = "not_configured"
- McpServerStatusChangedStatusPending McpServerStatusChangedStatus = "pending"
-)
-
// Where the failed model call originated
type ModelCallFailureSource string
@@ -2927,22 +2922,6 @@ const (
PermissionPromptRequestKindWrite PermissionPromptRequestKind = "write"
)
-// Whether this is a store or vote memory operation
-type PermissionPromptRequestMemoryAction string
-
-const (
- PermissionPromptRequestMemoryActionStore PermissionPromptRequestMemoryAction = "store"
- PermissionPromptRequestMemoryActionVote PermissionPromptRequestMemoryAction = "vote"
-)
-
-// Vote direction (vote only)
-type PermissionPromptRequestMemoryDirection string
-
-const (
- PermissionPromptRequestMemoryDirectionDownvote PermissionPromptRequestMemoryDirection = "downvote"
- PermissionPromptRequestMemoryDirectionUpvote PermissionPromptRequestMemoryDirection = "upvote"
-)
-
// Underlying permission kind that needs path approval
type PermissionPromptRequestPathAccessKind string
diff --git a/go/zsession_events.go b/go/zsession_events.go
index 170b58c93..b5ed49a97 100644
--- a/go/zsession_events.go
+++ b/go/zsession_events.go
@@ -29,6 +29,7 @@ type (
AttachmentType = rpc.AttachmentType
AutoModeSwitchCompletedData = rpc.AutoModeSwitchCompletedData
AutoModeSwitchRequestedData = rpc.AutoModeSwitchRequestedData
+ AutoModeSwitchResponse = rpc.AutoModeSwitchResponse
CapabilitiesChangedData = rpc.CapabilitiesChangedData
CapabilitiesChangedUI = rpc.CapabilitiesChangedUI
CommandCompletedData = rpc.CommandCompletedData
@@ -54,6 +55,7 @@ type (
ElicitationRequestedSchemaType = rpc.ElicitationRequestedSchemaType
EmbeddedBlobResourceContents = rpc.EmbeddedBlobResourceContents
EmbeddedTextResourceContents = rpc.EmbeddedTextResourceContents
+ ExitPlanModeAction = rpc.ExitPlanModeAction
ExitPlanModeCompletedData = rpc.ExitPlanModeCompletedData
ExitPlanModeRequestedData = rpc.ExitPlanModeRequestedData
ExtensionsLoadedExtension = rpc.ExtensionsLoadedExtension
@@ -71,8 +73,8 @@ type (
McpOauthRequiredStaticClientConfig = rpc.McpOauthRequiredStaticClientConfig
McpOauthRequiredStaticClientConfigGrantType = rpc.McpOauthRequiredStaticClientConfigGrantType
McpServersLoadedServer = rpc.McpServersLoadedServer
- McpServersLoadedServerStatus = rpc.McpServersLoadedServerStatus
- McpServerStatusChangedStatus = rpc.McpServerStatusChangedStatus
+ McpServerSource = rpc.McpServerSource
+ McpServerStatus = rpc.McpServerStatus
ModelCallFailureData = rpc.ModelCallFailureData
ModelCallFailureSource = rpc.ModelCallFailureSource
PendingMessagesModifiedData = rpc.PendingMessagesModifiedData
@@ -95,8 +97,6 @@ type (
PermissionPromptRequestKind = rpc.PermissionPromptRequestKind
PermissionPromptRequestMcp = rpc.PermissionPromptRequestMcp
PermissionPromptRequestMemory = rpc.PermissionPromptRequestMemory
- PermissionPromptRequestMemoryAction = rpc.PermissionPromptRequestMemoryAction
- PermissionPromptRequestMemoryDirection = rpc.PermissionPromptRequestMemoryDirection
PermissionPromptRequestPath = rpc.PermissionPromptRequestPath
PermissionPromptRequestPathAccessKind = rpc.PermissionPromptRequestPathAccessKind
PermissionPromptRequestRead = rpc.PermissionPromptRequestRead
@@ -152,6 +152,7 @@ type (
SessionInfoData = rpc.SessionInfoData
SessionMcpServersLoadedData = rpc.SessionMcpServersLoadedData
SessionMcpServerStatusChangedData = rpc.SessionMcpServerStatusChangedData
+ SessionMode = rpc.SessionMode
SessionModeChangedData = rpc.SessionModeChangedData
SessionModelChangeData = rpc.SessionModelChangeData
SessionPlanChangedData = rpc.SessionPlanChangedData
@@ -179,6 +180,7 @@ type (
ShutdownType = rpc.ShutdownType
SkillInvokedData = rpc.SkillInvokedData
SkillsLoadedSkill = rpc.SkillsLoadedSkill
+ SkillSource = rpc.SkillSource
SubagentCompletedData = rpc.SubagentCompletedData
SubagentDeselectedData = rpc.SubagentDeselectedData
SubagentFailedData = rpc.SubagentFailedData
@@ -262,12 +264,19 @@ const (
AttachmentTypeFile = rpc.AttachmentTypeFile
AttachmentTypeGithubReference = rpc.AttachmentTypeGithubReference
AttachmentTypeSelection = rpc.AttachmentTypeSelection
+ AutoModeSwitchResponseNo = rpc.AutoModeSwitchResponseNo
+ AutoModeSwitchResponseYes = rpc.AutoModeSwitchResponseYes
+ AutoModeSwitchResponseYesAlways = rpc.AutoModeSwitchResponseYesAlways
ElicitationCompletedActionAccept = rpc.ElicitationCompletedActionAccept
ElicitationCompletedActionCancel = rpc.ElicitationCompletedActionCancel
ElicitationCompletedActionDecline = rpc.ElicitationCompletedActionDecline
ElicitationRequestedModeForm = rpc.ElicitationRequestedModeForm
ElicitationRequestedModeURL = rpc.ElicitationRequestedModeURL
ElicitationRequestedSchemaTypeObject = rpc.ElicitationRequestedSchemaTypeObject
+ ExitPlanModeActionAutopilot = rpc.ExitPlanModeActionAutopilot
+ ExitPlanModeActionAutopilotFleet = rpc.ExitPlanModeActionAutopilotFleet
+ ExitPlanModeActionExitOnly = rpc.ExitPlanModeActionExitOnly
+ ExitPlanModeActionInteractive = rpc.ExitPlanModeActionInteractive
ExtensionsLoadedExtensionSourceProject = rpc.ExtensionsLoadedExtensionSourceProject
ExtensionsLoadedExtensionSourceUser = rpc.ExtensionsLoadedExtensionSourceUser
ExtensionsLoadedExtensionStatusDisabled = rpc.ExtensionsLoadedExtensionStatusDisabled
@@ -277,18 +286,16 @@ const (
HandoffSourceTypeLocal = rpc.HandoffSourceTypeLocal
HandoffSourceTypeRemote = rpc.HandoffSourceTypeRemote
McpOauthRequiredStaticClientConfigGrantTypeClientCredentials = rpc.McpOauthRequiredStaticClientConfigGrantTypeClientCredentials
- McpServersLoadedServerStatusConnected = rpc.McpServersLoadedServerStatusConnected
- McpServersLoadedServerStatusDisabled = rpc.McpServersLoadedServerStatusDisabled
- McpServersLoadedServerStatusFailed = rpc.McpServersLoadedServerStatusFailed
- McpServersLoadedServerStatusNeedsAuth = rpc.McpServersLoadedServerStatusNeedsAuth
- McpServersLoadedServerStatusNotConfigured = rpc.McpServersLoadedServerStatusNotConfigured
- McpServersLoadedServerStatusPending = rpc.McpServersLoadedServerStatusPending
- McpServerStatusChangedStatusConnected = rpc.McpServerStatusChangedStatusConnected
- McpServerStatusChangedStatusDisabled = rpc.McpServerStatusChangedStatusDisabled
- McpServerStatusChangedStatusFailed = rpc.McpServerStatusChangedStatusFailed
- McpServerStatusChangedStatusNeedsAuth = rpc.McpServerStatusChangedStatusNeedsAuth
- McpServerStatusChangedStatusNotConfigured = rpc.McpServerStatusChangedStatusNotConfigured
- McpServerStatusChangedStatusPending = rpc.McpServerStatusChangedStatusPending
+ McpServerSourceBuiltin = rpc.McpServerSourceBuiltin
+ McpServerSourcePlugin = rpc.McpServerSourcePlugin
+ McpServerSourceUser = rpc.McpServerSourceUser
+ McpServerSourceWorkspace = rpc.McpServerSourceWorkspace
+ McpServerStatusConnected = rpc.McpServerStatusConnected
+ McpServerStatusDisabled = rpc.McpServerStatusDisabled
+ McpServerStatusFailed = rpc.McpServerStatusFailed
+ McpServerStatusNeedsAuth = rpc.McpServerStatusNeedsAuth
+ McpServerStatusNotConfigured = rpc.McpServerStatusNotConfigured
+ McpServerStatusPending = rpc.McpServerStatusPending
ModelCallFailureSourceMcpSampling = rpc.ModelCallFailureSourceMcpSampling
ModelCallFailureSourceSubagent = rpc.ModelCallFailureSourceSubagent
ModelCallFailureSourceTopLevel = rpc.ModelCallFailureSourceTopLevel
@@ -303,10 +310,6 @@ const (
PermissionPromptRequestKindRead = rpc.PermissionPromptRequestKindRead
PermissionPromptRequestKindURL = rpc.PermissionPromptRequestKindURL
PermissionPromptRequestKindWrite = rpc.PermissionPromptRequestKindWrite
- PermissionPromptRequestMemoryActionStore = rpc.PermissionPromptRequestMemoryActionStore
- PermissionPromptRequestMemoryActionVote = rpc.PermissionPromptRequestMemoryActionVote
- PermissionPromptRequestMemoryDirectionDownvote = rpc.PermissionPromptRequestMemoryDirectionDownvote
- PermissionPromptRequestMemoryDirectionUpvote = rpc.PermissionPromptRequestMemoryDirectionUpvote
PermissionPromptRequestPathAccessKindRead = rpc.PermissionPromptRequestPathAccessKindRead
PermissionPromptRequestPathAccessKindShell = rpc.PermissionPromptRequestPathAccessKindShell
PermissionPromptRequestPathAccessKindWrite = rpc.PermissionPromptRequestPathAccessKindWrite
@@ -420,8 +423,18 @@ const (
SessionEventTypeUserInputCompleted = rpc.SessionEventTypeUserInputCompleted
SessionEventTypeUserInputRequested = rpc.SessionEventTypeUserInputRequested
SessionEventTypeUserMessage = rpc.SessionEventTypeUserMessage
+ SessionModeAutopilot = rpc.SessionModeAutopilot
+ SessionModeInteractive = rpc.SessionModeInteractive
+ SessionModePlan = rpc.SessionModePlan
ShutdownTypeError = rpc.ShutdownTypeError
ShutdownTypeRoutine = rpc.ShutdownTypeRoutine
+ SkillSourceBuiltin = rpc.SkillSourceBuiltin
+ SkillSourceCustom = rpc.SkillSourceCustom
+ SkillSourceInherited = rpc.SkillSourceInherited
+ SkillSourcePersonalAgents = rpc.SkillSourcePersonalAgents
+ SkillSourcePersonalCopilot = rpc.SkillSourcePersonalCopilot
+ SkillSourcePlugin = rpc.SkillSourcePlugin
+ SkillSourceProject = rpc.SkillSourceProject
SystemMessageRoleDeveloper = rpc.SystemMessageRoleDeveloper
SystemMessageRoleSystem = rpc.SystemMessageRoleSystem
SystemNotificationAgentCompletedStatusCompleted = rpc.SystemNotificationAgentCompletedStatusCompleted
diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json
index b043d72d5..d2976852d 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.49-1",
+ "@github/copilot": "^1.0.49-6",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
@@ -663,26 +663,28 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.49-1.tgz",
- "integrity": "sha512-1euPT6WXtLWnoqz1SXHdcqmktucdkfwfZn/Eo4iQ1FAjZo7awuN86rVb1feDwxY4vlSGbzNmK+GDKDgs9qZCDg==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.49-6.tgz",
+ "integrity": "sha512-9ptx1Vs6aJvybo7vN1gGHNPHt5JqmhIZWyurnMMFjoZh6DAq9NO+0yWBP1WL752ycFDE/kKR+OgKC64O+UsLQw==",
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.49-1",
- "@github/copilot-darwin-x64": "1.0.49-1",
- "@github/copilot-linux-arm64": "1.0.49-1",
- "@github/copilot-linux-x64": "1.0.49-1",
- "@github/copilot-win32-arm64": "1.0.49-1",
- "@github/copilot-win32-x64": "1.0.49-1"
+ "@github/copilot-darwin-arm64": "1.0.49-6",
+ "@github/copilot-darwin-x64": "1.0.49-6",
+ "@github/copilot-linux-arm64": "1.0.49-6",
+ "@github/copilot-linux-x64": "1.0.49-6",
+ "@github/copilot-linuxmusl-arm64": "1.0.49-6",
+ "@github/copilot-linuxmusl-x64": "1.0.49-6",
+ "@github/copilot-win32-arm64": "1.0.49-6",
+ "@github/copilot-win32-x64": "1.0.49-6"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.49-1.tgz",
- "integrity": "sha512-EgHdwlkYSJ+RmHAelGGpQxQe5/dgq3BlvToc0VmYEUCWO93ESEql7XBqCWYeASg3USUp8n87kf3mr2eXIECvLA==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-e+0T9DIfaE5GyFnsIUQWSGhi/Ont9/iENLb43jyAsASxY+gWxqWyUHVD7kYJpunMODNjg0FNXgCEAX5YUyKOXQ==",
"cpu": [
"arm64"
],
@@ -696,9 +698,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.49-1.tgz",
- "integrity": "sha512-YPtOW5q3vWB9Covn08jxqIdIjcCuJi/MgIlYk1ulKTINi5uK5a6NlsX2mDaGWL/svhDwDlhFEa3oUV41yOjTkg==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.49-6.tgz",
+ "integrity": "sha512-zgcMxEszygPvmki/A6aydLTMYyQhHQrQ5z+7BA/yGbuyghRKfe0mYG56QKRp5PsJJ01YK2Kr+G7EqgHypS5PVA==",
"cpu": [
"x64"
],
@@ -712,9 +714,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.49-1.tgz",
- "integrity": "sha512-eEh0ec1UlWg8IdV2/3Zaxr/PAA86GclEFUcGNkwc9JceOgw5nhIdytsjCwXJUcRTzHsGrAoTS+Vad1RSvKSmYQ==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-0/KlHumd38nYP/fNGVHaxSdqdRKV8cESaytTPyGq0ncfPMZzcqZhkgv6qur1XMai0zh0ZGpwxqzB3kwMrNJCoQ==",
"cpu": [
"arm64"
],
@@ -728,9 +730,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.49-1.tgz",
- "integrity": "sha512-9+HxOVAbgCqcoyfAXyfaFxgIbAfHWCh699WuOfWViX2fjoKO3V0ZVHEergR4gVEgvnjvnmD0TZhT7+kTzqPK6A==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.49-6.tgz",
+ "integrity": "sha512-LWfl79uh0i2/OTKikliZ3b0pnheVkEA2CYJTZUapfTSXKHQlQQIMR7HBhD6GCaOkVvHYgaH5WQVviedmS88N7g==",
"cpu": [
"x64"
],
@@ -743,10 +745,42 @@
"copilot-linux-x64": "copilot"
}
},
+ "node_modules/@github/copilot-linuxmusl-arm64": {
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-O9DdXVMdNdrgucLr4gd4djbzTdH8MGitNOWqIxTbsPy9YMd/OQ9JTEDCqPuezbiVzI0emS9NyrdSBasvcVI1VQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "SEE LICENSE IN LICENSE.md",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "bin": {
+ "copilot-linuxmusl-arm64": "copilot"
+ }
+ },
+ "node_modules/@github/copilot-linuxmusl-x64": {
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.49-6.tgz",
+ "integrity": "sha512-Yj8FTs9JcHvXw/FS8PEK0IxWa/qf+5UWPejburofi7hwiaC4wb+pX0AzhWee4jKcJ1YbZBEyWFMvBEK6xZ0TmA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "SEE LICENSE IN LICENSE.md",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "bin": {
+ "copilot-linuxmusl-x64": "copilot"
+ }
+ },
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.49-1.tgz",
- "integrity": "sha512-nsOz2rdk1Il3KJ24x3Hdv27MvotrKygIC/ok6acvq+xFwsYxR5Kt5bL1veBAGZVEG8K+0r2DfHi9NZHazBYK8A==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-u7GOWUIWRsS5IUdprXN2nWsTSTdM//m/LfqmOp1dfAxdSBOL4dF1Up3tEi8+f+HaCqIQhYQMryRux9KP4bUEnw==",
"cpu": [
"arm64"
],
@@ -760,9 +794,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.49-1.tgz",
- "integrity": "sha512-RZbU3GESkfwd8UC1h5AeceVfCOfXjMA+sDKfIUyk8Pl8EukTNtNSf+WEKK1HzSxbxdbIu9DJyBL375JMwDiH4A==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.49-6.tgz",
+ "integrity": "sha512-ayxTr2+miHaguaF0QrV6a/QvoMY4wUaTaYkZ7657ONOnR6BcFV9SNtnrlpLrbiIRkP6T0QZQXhROLaQwF7vrdw==",
"cpu": [
"x64"
],
diff --git a/nodejs/package.json b/nodejs/package.json
index ef06e3631..da8e93f3a 100644
--- a/nodejs/package.json
+++ b/nodejs/package.json
@@ -56,7 +56,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
- "@github/copilot": "^1.0.49-1",
+ "@github/copilot": "^1.0.49-6",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json
index 4d317f0d9..db82994f2 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.49-1",
+ "@github/copilot": "^1.0.49-6",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts
index 9dcfedaca..f8feacdbb 100644
--- a/nodejs/src/generated/rpc.ts
+++ b/nodejs/src/generated/rpc.ts
@@ -5,7 +5,7 @@
import type { MessageConnection } from "vscode-jsonrpc/node.js";
-import type { EmbeddedBlobResourceContents, EmbeddedTextResourceContents, ReasoningSummary } from "./session-events.js";
+import type { EmbeddedBlobResourceContents, EmbeddedTextResourceContents, McpServerSource, McpServerStatus, ReasoningSummary, SessionMode, SkillSource } from "./session-events.js";
/**
* Authentication type
@@ -43,19 +43,19 @@ export type QueuedCommandResult = QueuedCommandHandled | QueuedCommandNotHandled
*/
export type ConnectedRemoteSessionMetadataKind = "remote-session" | "coding-agent";
/**
- * Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)
+ * Controls how MCP tool result content is filtered: none leaves content unchanged, markdown sanitizes HTML while preserving Markdown-friendly output, and hidden_characters removes characters that can hide directives.
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "DiscoveredMcpServerType".
+ * via the `definition` "ContentFilterMode".
*/
-export type DiscoveredMcpServerType = "stdio" | "http" | "sse" | "memory";
+export type ContentFilterMode = "none" | "markdown" | "hidden_characters";
/**
- * Configuration source
+ * Server transport type: stdio, http, sse, or memory
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "DiscoveredMcpServerSource".
+ * via the `definition` "DiscoveredMcpServerType".
*/
-export type DiscoveredMcpServerSource = "user" | "workspace" | "plugin" | "builtin";
+export type DiscoveredMcpServerType = "stdio" | "http" | "sse" | "memory";
/**
* Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/)
*
@@ -77,6 +77,13 @@ export type ExtensionStatus = "running" | "disabled" | "failed" | "starting";
* via the `definition` "ExternalToolResult".
*/
export type ExternalToolResult = string | ExternalToolTextResultForLlm;
+/**
+ * Binary result type discriminator. Use "image" for images and "resource" for other binary data.
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmBinaryResultsForLlmType".
+ */
+export type ExternalToolTextResultForLlmBinaryResultsForLlmType = "image" | "resource";
/**
* A content block within a tool result, which may be text, terminal output, image, audio, or a resource
*
@@ -114,23 +121,9 @@ export type ExternalToolTextResultForLlmContentResourceDetails =
*/
export type FilterMapping =
| {
- [k: string]: FilterMappingValue;
+ [k: string]: ContentFilterMode;
}
- | FilterMappingString;
-/**
- * Allowed values for the `FilterMappingValue` enumeration.
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "FilterMappingValue".
- */
-export type FilterMappingValue = "none" | "markdown" | "hidden_characters";
-/**
- * Allowed values for the `FilterMappingString` enumeration.
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "FilterMappingString".
- */
-export type FilterMappingString = "none" | "markdown" | "hidden_characters";
+ | ContentFilterMode;
/**
* Category of instruction source — used for merge logic
*
@@ -153,19 +146,12 @@ export type InstructionsSourcesLocation = "user" | "repository" | "working-direc
*/
export type SessionLogLevel = "info" | "warning" | "error";
/**
- * MCP server configuration (local/stdio or remote/http)
+ * MCP server configuration (stdio process or remote HTTP/SSE)
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
* via the `definition` "McpServerConfig".
*/
-export type McpServerConfig = McpServerConfigLocal | McpServerConfigHttp;
-/**
- * Local transport type. Defaults to "local".
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "McpServerConfigLocalType".
- */
-export type McpServerConfigLocalType = "local" | "stdio";
+export type McpServerConfig = McpServerConfigStdio | McpServerConfigHttp;
/**
* Remote transport type. Defaults to "http" when omitted.
*
@@ -181,19 +167,12 @@ export type McpServerConfigHttpType = "http" | "sse";
*/
export type McpServerConfigHttpOauthGrantType = "authorization_code" | "client_credentials";
/**
- * Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+ * Current policy state for this model
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "McpServerStatus".
+ * via the `definition` "ModelPolicyState".
*/
-export type McpServerStatus = "connected" | "failed" | "needs-auth" | "pending" | "disabled" | "not_configured";
-/**
- * Configuration source: user, workspace, plugin, or builtin
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "McpServerSource".
- */
-export type McpServerSource = "user" | "workspace" | "plugin" | "builtin";
+export type ModelPolicyState = "enabled" | "disabled" | "unconfigured";
/**
* Model capability category for grouping in the model picker
*
@@ -208,13 +187,6 @@ export type ModelPickerCategory = "lightweight" | "versatile" | "powerful";
* via the `definition` "ModelPickerPriceCategory".
*/
export type ModelPickerPriceCategory = "low" | "medium" | "high" | "very_high";
-/**
- * The agent mode. Valid values: "interactive", "plan", "autopilot".
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "SessionMode".
- */
-export type SessionMode = "interactive" | "plan" | "autopilot";
/**
* Decision to apply to a pending permission request.
*
@@ -289,19 +261,19 @@ export type SessionFsReaddirWithTypesEntryType = "file" | "directory";
*/
export type SessionFsSetProviderConventions = "windows" | "posix";
/**
- * Signal to send (default: SIGTERM)
+ * How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "ShellKillSignal".
+ * via the `definition` "SessionFsSqliteQueryType".
*/
-export type ShellKillSignal = "SIGTERM" | "SIGKILL" | "SIGINT";
+export type SessionFsSqliteQueryType = "exec" | "query" | "run";
/**
- * Optional target session mode
+ * Signal to send (default: SIGTERM)
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "SlashCommandAgentPromptMode".
+ * via the `definition` "ShellKillSignal".
*/
-export type SlashCommandAgentPromptMode = "interactive" | "plan" | "autopilot";
+export type ShellKillSignal = "SIGTERM" | "SIGKILL" | "SIGINT";
/**
* Result of invoking the slash command (text output, prompt to send to the agent, or completion).
*
@@ -316,16 +288,16 @@ export type SlashCommandInvocationResult =
* Current lifecycle status of the task
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "TaskAgentInfoStatus".
+ * via the `definition` "TaskStatus".
*/
-export type TaskAgentInfoStatus = "running" | "idle" | "completed" | "failed" | "cancelled";
+export type TaskStatus = "running" | "idle" | "completed" | "failed" | "cancelled";
/**
- * How the agent is currently being managed by the runtime
+ * Whether task execution is synchronously awaited or managed in the background
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "TaskAgentInfoExecutionMode".
+ * via the `definition` "TaskExecutionMode".
*/
-export type TaskAgentInfoExecutionMode = "sync" | "background";
+export type TaskExecutionMode = "sync" | "background";
/**
* Schema for the `TaskInfo` type.
*
@@ -333,13 +305,6 @@ export type TaskAgentInfoExecutionMode = "sync" | "background";
* via the `definition` "TaskInfo".
*/
export type TaskInfo = TaskAgentInfo | TaskShellInfo;
-/**
- * Current lifecycle status of the task
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "TaskShellInfoStatus".
- */
-export type TaskShellInfoStatus = "running" | "idle" | "completed" | "failed" | "cancelled";
/**
* Whether the shell runs inside a managed PTY session or as an independent background process
*
@@ -347,13 +312,6 @@ export type TaskShellInfoStatus = "running" | "idle" | "completed" | "failed" |
* via the `definition` "TaskShellInfoAttachmentMode".
*/
export type TaskShellInfoAttachmentMode = "attached" | "detached";
-/**
- * Whether the shell command is currently sync-waited or background-managed
- *
- * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "TaskShellInfoExecutionMode".
- */
-export type TaskShellInfoExecutionMode = "sync" | "background";
/**
* Schema for the `UIElicitationFieldValue` type.
*
@@ -397,6 +355,8 @@ export type UIElicitationSchemaPropertyNumberType = "number" | "integer";
*/
export type UIElicitationResponseAction = "accept" | "decline" | "cancel";
+export type SessionMode = SessionMode;
+
export interface AccountGetQuotaRequest {
/**
* GitHub token for per-user quota lookup. When provided, resolves this token to determine the user's quota instead of using the global auth.
@@ -429,7 +389,7 @@ export interface AccountQuotaSnapshot {
*/
isUnlimitedEntitlement: boolean;
/**
- * Number of requests included in the entitlement
+ * Number of requests included in the entitlement, or -1 for unlimited entitlements
*/
entitlementRequests: number;
/**
@@ -860,7 +820,7 @@ export interface DiscoveredMcpServer {
*/
name: string;
type?: DiscoveredMcpServerType;
- source: DiscoveredMcpServerSource;
+ source: McpServerSource;
/**
* Whether the server is enabled (not in the disabled list)
*/
@@ -956,12 +916,37 @@ export interface ExternalToolTextResultForLlm {
toolTelemetry?: {
[k: string]: unknown;
};
+ /**
+ * Base64-encoded binary results returned to the model
+ */
+ binaryResultsForLlm?: ExternalToolTextResultForLlmBinaryResultsForLlm[];
/**
* Structured content blocks from the tool
*/
contents?: ExternalToolTextResultForLlmContent[];
[k: string]: unknown;
}
+/**
+ * Binary result returned by a tool for the model
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "ExternalToolTextResultForLlmBinaryResultsForLlm".
+ */
+export interface ExternalToolTextResultForLlmBinaryResultsForLlm {
+ type: ExternalToolTextResultForLlmBinaryResultsForLlmType;
+ /**
+ * Base64-encoded binary data
+ */
+ data: string;
+ /**
+ * MIME type of the binary data
+ */
+ mimeType: string;
+ /**
+ * Human-readable description of the binary data
+ */
+ description?: string;
+}
/**
* Plain text content block
*
@@ -1344,17 +1329,16 @@ export interface McpConfigAddRequest {
config: McpServerConfig;
}
/**
- * Local MCP server configuration launched as a child process.
+ * Stdio MCP server configuration launched as a child process.
*
* This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
- * via the `definition` "McpServerConfigLocal".
+ * via the `definition` "McpServerConfigStdio".
*/
-export interface McpServerConfigLocal {
+export interface McpServerConfigStdio {
/**
* Tools to include. Defaults to all tools if not specified.
*/
tools?: string[];
- type?: McpServerConfigLocalType;
/**
* Whether this server is a built-in fallback used when the user has not configured their own server.
*/
@@ -1365,19 +1349,19 @@ export interface McpServerConfigLocal {
*/
timeout?: number;
/**
- * Executable command used to start the local MCP server process.
+ * Executable command used to start the Stdio MCP server process.
*/
command: string;
/**
- * Command-line arguments passed to the local MCP server process.
+ * Command-line arguments passed to the Stdio MCP server process.
*/
- args: string[];
+ args?: string[];
/**
- * Working directory for the local MCP server process.
+ * Working directory for the Stdio MCP server process.
*/
cwd?: string;
/**
- * Environment variables to pass to the local MCP server process.
+ * Environment variables to pass to the Stdio MCP server process.
*/
env?: {
[k: string]: string;
@@ -1423,6 +1407,19 @@ export interface McpServerConfigHttp {
*/
oauthPublicClient?: boolean;
oauthGrantType?: McpServerConfigHttpOauthGrantType;
+ auth?: McpServerConfigHttpAuth;
+}
+/**
+ * Additional authentication configuration for this server.
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "McpServerConfigHttpAuth".
+ */
+export interface McpServerConfigHttpAuth {
+ /**
+ * Fixed port for the OAuth redirect callback server.
+ */
+ redirectPort?: number;
}
/**
* MCP server names to disable for new sessions.
@@ -1709,10 +1706,7 @@ export interface ModelCapabilitiesLimitsVision {
* via the `definition` "ModelPolicy".
*/
export interface ModelPolicy {
- /**
- * Current policy state for this model
- */
- state: string;
+ state: ModelPolicyState;
/**
* Usage terms or conditions for this model
*/
@@ -2491,10 +2485,7 @@ export interface ServerSkill {
* Description of what the skill does
*/
description: string;
- /**
- * Source location type (e.g., project, personal-copilot, plugin, builtin)
- */
- source: string;
+ source: SkillSource;
/**
* Whether the skill can be invoked by the user as a slash command
*/
@@ -2786,6 +2777,18 @@ export interface SessionFsRmRequest {
*/
force?: boolean;
}
+/**
+ * Optional capabilities declared by the provider
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "SessionFsSetProviderCapabilities".
+ */
+export interface SessionFsSetProviderCapabilities {
+ /**
+ * Whether the provider supports SQLite query/exists operations
+ */
+ sqlite?: boolean;
+}
/**
* Initial working directory, session-state path layout, and path conventions used to register the calling SDK client as the session filesystem provider.
*
@@ -2802,6 +2805,7 @@ export interface SessionFsSetProviderRequest {
*/
sessionStatePath: string;
conventions: SessionFsSetProviderConventions;
+ capabilities?: SessionFsSetProviderCapabilities;
}
/**
* Indicates whether the calling client was registered as the session filesystem provider.
@@ -2815,6 +2819,68 @@ export interface SessionFsSetProviderResult {
*/
success: boolean;
}
+/**
+ * Indicates whether the per-session SQLite database already exists.
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "SessionFsSqliteExistsResult".
+ */
+export interface SessionFsSqliteExistsResult {
+ /**
+ * Whether the session database already exists
+ */
+ exists: boolean;
+}
+/**
+ * SQL query, query type, and optional bind parameters for executing a SQLite query against the per-session database.
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "SessionFsSqliteQueryRequest".
+ */
+export interface SessionFsSqliteQueryRequest {
+ /**
+ * Target session identifier
+ */
+ sessionId: string;
+ /**
+ * SQL query to execute
+ */
+ query: string;
+ queryType: SessionFsSqliteQueryType;
+ /**
+ * Optional named bind parameters
+ */
+ params?: {
+ [k: string]: string | number | null;
+ };
+}
+/**
+ * Query results including rows, columns, and rows affected, or a filesystem error if execution failed.
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "SessionFsSqliteQueryResult".
+ */
+export interface SessionFsSqliteQueryResult {
+ /**
+ * For SELECT: array of row objects. For others: empty array.
+ */
+ rows: {
+ [k: string]: unknown;
+ }[];
+ /**
+ * Column names from the result set
+ */
+ columns: string[];
+ /**
+ * Number of rows affected (for INSERT/UPDATE/DELETE)
+ */
+ rowsAffected: number;
+ /**
+ * Last inserted row ID (for INSERT)
+ */
+ lastInsertRowid?: number;
+ error?: SessionFsError;
+}
/**
* Path whose metadata should be returned from the client-provided session filesystem.
*
@@ -2994,10 +3060,7 @@ export interface Skill {
* Description of what the skill does
*/
description: string;
- /**
- * Source location type (e.g., project, personal, plugin)
- */
- source: string;
+ source: SkillSource;
/**
* Whether the skill can be invoked by the user as a slash command
*/
@@ -3114,7 +3177,7 @@ export interface SlashCommandAgentPromptResult {
* Prompt text to display to the user
*/
displayPrompt: string;
- mode?: SlashCommandAgentPromptMode;
+ mode?: SessionMode;
/**
* True when the invocation mutated user runtime settings; consumers caching settings should refresh
*/
@@ -3191,7 +3254,7 @@ export interface TaskAgentInfo {
* Short description of the task
*/
description: string;
- status: TaskAgentInfoStatus;
+ status: TaskStatus;
/**
* ISO 8601 timestamp when the task was started
*/
@@ -3228,7 +3291,7 @@ export interface TaskAgentInfo {
* Model used for the task when specified
*/
model?: string;
- executionMode?: TaskAgentInfoExecutionMode;
+ executionMode?: TaskExecutionMode;
/**
* Whether the task is currently in the original sync wait and can be moved to background mode. False once it is already backgrounded, idle, finished, or no longer has a promotable sync waiter.
*/
@@ -3261,7 +3324,7 @@ export interface TaskShellInfo {
* Short description of the task
*/
description: string;
- status: TaskShellInfoStatus;
+ status: TaskStatus;
/**
* ISO 8601 timestamp when the task was started
*/
@@ -3275,7 +3338,7 @@ export interface TaskShellInfo {
*/
command: string;
attachmentMode: TaskShellInfoAttachmentMode;
- executionMode?: TaskShellInfoExecutionMode;
+ executionMode?: TaskExecutionMode;
/**
* Whether this shell task can be promoted to background mode
*/
@@ -4108,6 +4171,18 @@ export interface WorkspacesReadFileResult {
*/
content: string;
}
+/**
+ * Identifies the target session.
+ *
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
+ * via the `definition` "SessionFsSqliteExistsRequest".
+ */
+export interface SessionFsSqliteExistsRequest {
+ /**
+ * Target session identifier
+ */
+ sessionId: string;
+}
/** Create typed server-scoped RPC methods (no session required). */
export function createServerRpc(connection: MessageConnection) {
@@ -4322,7 +4397,7 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin
/**
* Gets the current agent interaction mode.
*
- * @returns The agent mode. Valid values: "interactive", "plan", "autopilot".
+ * @returns The session mode the agent is operating in
*/
get: async (): Promise =>
connection.sendRequest("session.mode.get", { sessionId }),
@@ -4884,6 +4959,22 @@ export interface SessionFsHandler {
* @returns Describes a filesystem error.
*/
rename(params: SessionFsRenameRequest): Promise;
+ /**
+ * Executes a SQLite query against the per-session database.
+ *
+ * @param params SQL query, query type, and optional bind parameters for executing a SQLite query against the per-session database.
+ *
+ * @returns Query results including rows, columns, and rows affected, or a filesystem error if execution failed.
+ */
+ sqliteQuery(params: SessionFsSqliteQueryRequest): Promise;
+ /**
+ * Checks whether the per-session SQLite database already exists, without creating it.
+ *
+ * @param params Identifies the target session.
+ *
+ * @returns Indicates whether the per-session SQLite database already exists.
+ */
+ sqliteExists(params: SessionFsSqliteExistsRequest): Promise;
}
/** All client session API handler groups. */
@@ -4951,4 +5042,14 @@ export function registerClientSessionApiHandlers(
if (!handler) throw new Error(`No sessionFs handler registered for session: ${params.sessionId}`);
return handler.rename(params);
});
+ connection.onRequest("sessionFs.sqliteQuery", async (params: SessionFsSqliteQueryRequest) => {
+ const handler = getHandlers(params.sessionId).sessionFs;
+ if (!handler) throw new Error(`No sessionFs handler registered for session: ${params.sessionId}`);
+ return handler.sqliteQuery(params);
+ });
+ connection.onRequest("sessionFs.sqliteExists", async (params: SessionFsSqliteExistsRequest) => {
+ const handler = getHandlers(params.sessionId).sessionFs;
+ if (!handler) throw new Error(`No sessionFs handler registered for session: ${params.sessionId}`);
+ return handler.sqliteExists(params);
+ });
}
diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts
index 5b5404975..64c9e10ba 100644
--- a/nodejs/src/generated/session-events.ts
+++ b/nodejs/src/generated/session-events.ts
@@ -96,6 +96,10 @@ export type WorkingDirectoryContextHostType = "github" | "ado";
* Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
*/
export type ReasoningSummary = "none" | "concise" | "detailed";
+/**
+ * The session mode the agent is operating in
+ */
+export type SessionMode = "interactive" | "plan" | "autopilot";
/**
* The type of operation performed on the plan file
*/
@@ -218,14 +222,6 @@ export type PermissionPromptRequest =
| PermissionPromptRequestHook
| PermissionPromptRequestExtensionManagement
| PermissionPromptRequestExtensionPermissionAccess;
-/**
- * Whether this is a store or vote memory operation
- */
-export type PermissionPromptRequestMemoryAction = "store" | "vote";
-/**
- * Vote direction (vote only)
- */
-export type PermissionPromptRequestMemoryDirection = "upvote" | "downvote";
/**
* Underlying permission kind that needs path approval
*/
@@ -280,25 +276,32 @@ export type CustomNotificationPayload =
[k: string]: unknown;
};
/**
- * Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+ * The user's auto-mode-switch choice
*/
-export type McpServersLoadedServerStatus =
- | "connected"
- | "failed"
- | "needs-auth"
- | "pending"
- | "disabled"
- | "not_configured";
+export type AutoModeSwitchResponse = "yes" | "yes_always" | "no";
/**
- * New connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+ * Exit plan mode action
*/
-export type McpServerStatusChangedStatus =
- | "connected"
- | "failed"
- | "needs-auth"
- | "pending"
- | "disabled"
- | "not_configured";
+export type ExitPlanModeAction = "exit_only" | "interactive" | "autopilot" | "autopilot_fleet";
+/**
+ * Source location type (e.g., project, personal-copilot, plugin, builtin)
+ */
+export type SkillSource =
+ | "project"
+ | "inherited"
+ | "personal-copilot"
+ | "personal-agents"
+ | "plugin"
+ | "custom"
+ | "builtin";
+/**
+ * Configuration source: user, workspace, plugin, or builtin
+ */
+export type McpServerSource = "user" | "workspace" | "plugin" | "builtin";
+/**
+ * Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+ */
+export type McpServerStatus = "connected" | "failed" | "needs-auth" | "pending" | "disabled" | "not_configured";
/**
* Discovery source
*/
@@ -360,7 +363,7 @@ export interface StartData {
*/
producer: string;
/**
- * Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ * Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
*/
reasoningEffort?: string;
reasoningSummary?: ReasoningSummary;
@@ -467,7 +470,7 @@ export interface ResumeData {
*/
eventCount: number;
/**
- * Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ * Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
*/
reasoningEffort?: string;
reasoningSummary?: ReasoningSummary;
@@ -955,14 +958,8 @@ export interface ModeChangedEvent {
* Agent mode change details including previous and new modes
*/
export interface ModeChangedData {
- /**
- * Agent mode after the change (e.g., "interactive", "plan", "autopilot")
- */
- newMode: string;
- /**
- * Agent mode before the change (e.g., "interactive", "plan", "autopilot")
- */
- previousMode: string;
+ newMode: SessionMode;
+ previousMode: SessionMode;
}
/**
* Session event "session.plan_changed". Plan file operation details indicating what changed
@@ -2559,7 +2556,7 @@ export interface AssistantUsageData {
[k: string]: AssistantUsageQuotaSnapshot;
};
/**
- * Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ * Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
*/
reasoningEffort?: string;
/**
@@ -4379,12 +4376,12 @@ export interface PermissionPromptRequestUrl {
* Memory operation permission prompt
*/
export interface PermissionPromptRequestMemory {
- action?: PermissionPromptRequestMemoryAction;
+ action?: PermissionRequestMemoryAction;
/**
* Source references for the stored fact (store only)
*/
citations?: string;
- direction?: PermissionPromptRequestMemoryDirection;
+ direction?: PermissionRequestMemoryDirection;
/**
* The fact being stored or voted on
*/
@@ -5585,10 +5582,7 @@ export interface AutoModeSwitchCompletedData {
* Request ID of the resolved request; clients should dismiss any UI for this request
*/
requestId: string;
- /**
- * The user's choice: 'yes', 'yes_always', or 'no'
- */
- response: string;
+ response: AutoModeSwitchResponse;
}
/**
* Session event "commands.changed". SDK command registration change notification
@@ -5722,17 +5716,14 @@ export interface ExitPlanModeRequestedEvent {
*/
export interface ExitPlanModeRequestedData {
/**
- * Available actions the user can take (e.g., approve, edit, reject)
+ * Available actions the user can take
*/
- actions: string[];
+ actions: ExitPlanModeAction[];
/**
* Full content of the plan file
*/
planContent: string;
- /**
- * The recommended action for the user to take
- */
- recommendedAction: string;
+ recommendedAction: ExitPlanModeAction;
/**
* Unique identifier for this request; used to respond via session.respondToExitPlanMode()
*/
@@ -5792,10 +5783,7 @@ export interface ExitPlanModeCompletedData {
* Request ID of the resolved exit plan mode request; clients should dismiss any UI for this request
*/
requestId: string;
- /**
- * Which action the user selected (e.g. 'autopilot', 'interactive', 'exit_only')
- */
- selectedAction?: string;
+ selectedAction?: ExitPlanModeAction;
}
/**
* Session event "session.tools_updated".
@@ -5929,10 +5917,7 @@ export interface SkillsLoadedSkill {
* Absolute path to the skill file, if available
*/
path?: string;
- /**
- * Source location type of the skill (e.g., project, personal, plugin)
- */
- source: string;
+ source: SkillSource;
/**
* Whether the skill can be invoked by the user as a slash command
*/
@@ -6073,11 +6058,8 @@ export interface McpServersLoadedServer {
* Server name (config key)
*/
name: string;
- /**
- * Configuration source: user, workspace, plugin, or builtin
- */
- source?: string;
- status: McpServersLoadedServerStatus;
+ source?: McpServerSource;
+ status: McpServerStatus;
}
/**
* Session event "session.mcp_server_status_changed".
@@ -6117,7 +6099,7 @@ export interface McpServerStatusChangedData {
* Name of the MCP server whose status changed
*/
serverName: string;
- status: McpServerStatusChangedStatus;
+ status: McpServerStatus;
}
/**
* Session event "session.extensions_loaded".
diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py
index d7ca62c0a..e7c969fd6 100644
--- a/python/copilot/generated/rpc.py
+++ b/python/copilot/generated/rpc.py
@@ -5,7 +5,7 @@
from typing import TYPE_CHECKING
-from .session_events import EmbeddedBlobResourceContents, EmbeddedTextResourceContents, ReasoningSummary
+from .session_events import EmbeddedBlobResourceContents, EmbeddedTextResourceContents, McpServerSource, McpServerStatus, ReasoningSummary, SessionMode, SkillSource
if TYPE_CHECKING:
from .._jsonrpc import JsonRpcClient
@@ -51,6 +51,9 @@ def from_float(x: Any) -> float:
assert isinstance(x, (float, int)) and not isinstance(x, bool)
return float(x)
+def from_datetime(x: Any) -> datetime:
+ return dateutil.parser.parse(x)
+
def to_float(x: Any) -> float:
assert isinstance(x, (int, float))
return x
@@ -71,9 +74,6 @@ def to_enum(c: type[EnumT], x: Any) -> EnumT:
assert isinstance(x, c)
return x.value
-def from_datetime(x: Any) -> datetime:
- return dateutil.parser.parse(x)
-
@dataclass
class AccountGetQuotaRequest:
git_hub_token: str | None = None
@@ -98,7 +98,7 @@ class AccountQuotaSnapshot:
"""Schema for the `AccountQuotaSnapshot` type."""
entitlement_requests: int
- """Number of requests included in the entitlement"""
+ """Number of requests included in the entitlement, or -1 for unlimited entitlements"""
is_unlimited_entitlement: bool
"""Whether the user has an unlimited usage entitlement"""
@@ -118,7 +118,7 @@ class AccountQuotaSnapshot:
used_requests: int
"""Number of requests used so far this period"""
- reset_date: str | None = None
+ reset_date: datetime | None = None
"""Date when the quota resets (ISO 8601 string)"""
@staticmethod
@@ -131,7 +131,7 @@ def from_dict(obj: Any) -> 'AccountQuotaSnapshot':
remaining_percentage = from_float(obj.get("remainingPercentage"))
usage_allowed_with_exhausted_quota = from_bool(obj.get("usageAllowedWithExhaustedQuota"))
used_requests = from_int(obj.get("usedRequests"))
- reset_date = from_union([from_str, from_none], obj.get("resetDate"))
+ reset_date = from_union([from_datetime, from_none], obj.get("resetDate"))
return AccountQuotaSnapshot(entitlement_requests, is_unlimited_entitlement, overage, overage_allowed_with_exhausted_quota, remaining_percentage, usage_allowed_with_exhausted_quota, used_requests, reset_date)
def to_dict(self) -> dict:
@@ -144,7 +144,7 @@ def to_dict(self) -> dict:
result["usageAllowedWithExhaustedQuota"] = from_bool(self.usage_allowed_with_exhausted_quota)
result["usedRequests"] = from_int(self.used_requests)
if self.reset_date is not None:
- result["resetDate"] = from_union([from_str, from_none], self.reset_date)
+ result["resetDate"] = from_union([lambda x: x.isoformat(), from_none], self.reset_date)
return result
@dataclass
@@ -447,6 +447,15 @@ def to_dict(self) -> dict:
result["owner"] = from_str(self.owner)
return result
+class ContentFilterMode(Enum):
+ """Controls how MCP tool result content is filtered: none leaves content unchanged, markdown
+ sanitizes HTML while preserving Markdown-friendly output, and hidden_characters removes
+ characters that can hide directives.
+ """
+ HIDDEN_CHARACTERS = "hidden_characters"
+ MARKDOWN = "markdown"
+ NONE = "none"
+
@dataclass
class CurrentModel:
"""The currently selected model for the session."""
@@ -466,18 +475,25 @@ def to_dict(self) -> dict:
result["modelId"] = from_union([from_str, from_none], self.model_id)
return result
-class MCPServerSource(Enum):
- """Configuration source
+@dataclass
+class ExternalRefMCPServerSource:
+ """Configuration source: user, workspace, plugin, or builtin"""
+
+ external_ref_marker_external_ref_mcp_server_source: str
- Configuration source: user, workspace, plugin, or builtin
- """
- BUILTIN = "builtin"
- PLUGIN = "plugin"
- USER = "user"
- WORKSPACE = "workspace"
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalRefMCPServerSource':
+ assert isinstance(obj, dict)
+ external_ref_marker_external_ref_mcp_server_source = from_str(obj.get("__externalRefMarker___ExternalRef_McpServerSource"))
+ return ExternalRefMCPServerSource(external_ref_marker_external_ref_mcp_server_source)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["__externalRefMarker___ExternalRef_McpServerSource"] = from_str(self.external_ref_marker_external_ref_mcp_server_source)
+ return result
class DiscoveredMCPServerType(Enum):
- """Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)"""
+ """Server transport type: stdio, http, sse, or memory"""
HTTP = "http"
MEMORY = "memory"
@@ -536,6 +552,13 @@ def to_dict(self) -> dict:
result["id"] = from_str(self.id)
return result
+class ExternalToolTextResultForLlmBinaryResultsForLlmType(Enum):
+ """Binary result type discriminator. Use "image" for images and "resource" for other binary
+ data.
+ """
+ IMAGE = "image"
+ RESOURCE = "resource"
+
class ExternalToolTextResultForLlmContentResourceLinkIconTheme(Enum):
"""Theme variant this icon is intended for"""
@@ -568,15 +591,6 @@ class ExternalToolTextResultForLlmContentTerminalType(Enum):
class KindEnum(Enum):
TEXT = "text"
-class FilterMappingString(Enum):
- """Allowed values for the `FilterMappingValue` enumeration.
-
- Allowed values for the `FilterMappingString` enumeration.
- """
- HIDDEN_CHARACTERS = "hidden_characters"
- MARKDOWN = "markdown"
- NONE = "none"
-
# Experimental: this type is part of an experimental API and may change or be removed.
@dataclass
class FleetStartRequest:
@@ -761,21 +775,36 @@ def to_dict(self) -> dict:
result["eventId"] = str(self.event_id)
return result
+@dataclass
+class MCPServerConfigHTTPAuth:
+ """Additional authentication configuration for this server."""
+
+ redirect_port: int | None = None
+ """Fixed port for the OAuth redirect callback server."""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'MCPServerConfigHTTPAuth':
+ assert isinstance(obj, dict)
+ redirect_port = from_union([from_int, from_none], obj.get("redirectPort"))
+ return MCPServerConfigHTTPAuth(redirect_port)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ if self.redirect_port is not None:
+ result["redirectPort"] = from_union([from_int, from_none], self.redirect_port)
+ return result
+
class MCPServerConfigHTTPOauthGrantType(Enum):
"""OAuth grant type to use when authenticating to the remote MCP server."""
AUTHORIZATION_CODE = "authorization_code"
CLIENT_CREDENTIALS = "client_credentials"
-class MCPServerConfigType(Enum):
- """Local transport type. Defaults to "local".
+class MCPServerConfigHTTPType(Enum):
+ """Remote transport type. Defaults to "http" when omitted."""
- Remote transport type. Defaults to "http" when omitted.
- """
HTTP = "http"
- LOCAL = "local"
SSE = "sse"
- STDIO = "stdio"
@dataclass
class MCPConfigDisableRequest:
@@ -962,36 +991,40 @@ def to_dict(self) -> dict:
result["authorizationUrl"] = from_union([from_str, from_none], self.authorization_url)
return result
-class MCPServerStatus(Enum):
+@dataclass
+class ExternalRefMCPServerStatus:
"""Connection status: connected, failed, needs-auth, pending, disabled, or not_configured"""
- CONNECTED = "connected"
- DISABLED = "disabled"
- FAILED = "failed"
- NEEDS_AUTH = "needs-auth"
- NOT_CONFIGURED = "not_configured"
- PENDING = "pending"
+ external_ref_marker_external_ref_mcp_server_status: str
-class MCPServerConfigHTTPType(Enum):
- """Remote transport type. Defaults to "http" when omitted."""
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalRefMCPServerStatus':
+ assert isinstance(obj, dict)
+ external_ref_marker_external_ref_mcp_server_status = from_str(obj.get("__externalRefMarker___ExternalRef_McpServerStatus"))
+ return ExternalRefMCPServerStatus(external_ref_marker_external_ref_mcp_server_status)
- HTTP = "http"
- SSE = "sse"
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["__externalRefMarker___ExternalRef_McpServerStatus"] = from_str(self.external_ref_marker_external_ref_mcp_server_status)
+ return result
-class MCPServerConfigLocalType(Enum):
- """Local transport type. Defaults to "local"."""
+@dataclass
+class ModeSetRequest:
+ """Agent interaction mode to apply to the session."""
- LOCAL = "local"
- STDIO = "stdio"
+ mode: SessionMode
+ """The session mode the agent is operating in"""
-class Mode(Enum):
- """The agent mode. Valid values: "interactive", "plan", "autopilot".
+ @staticmethod
+ def from_dict(obj: Any) -> 'ModeSetRequest':
+ assert isinstance(obj, dict)
+ mode = SessionMode.from_dict(obj.get("mode"))
+ return ModeSetRequest(mode)
- Optional target session mode
- """
- AUTOPILOT = "autopilot"
- INTERACTIVE = "interactive"
- PLAN = "plan"
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["mode"] = to_class(SessionMode, self.mode)
+ return result
@dataclass
class ModelBillingTokenPrices:
@@ -1095,29 +1128,12 @@ class ModelPickerPriceCategory(Enum):
MEDIUM = "medium"
VERY_HIGH = "very_high"
-@dataclass
-class ModelPolicy:
- """Policy state (if applicable)"""
-
- state: str
+class ModelPolicyState(Enum):
"""Current policy state for this model"""
- terms: str | None = None
- """Usage terms or conditions for this model"""
-
- @staticmethod
- def from_dict(obj: Any) -> 'ModelPolicy':
- assert isinstance(obj, dict)
- state = from_str(obj.get("state"))
- terms = from_union([from_str, from_none], obj.get("terms"))
- return ModelPolicy(state, terms)
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["state"] = from_str(self.state)
- if self.terms is not None:
- result["terms"] = from_union([from_str, from_none], self.terms)
- return result
+ DISABLED = "disabled"
+ ENABLED = "enabled"
+ UNCONFIGURED = "unconfigured"
@dataclass
class ModelCapabilitiesOverrideLimitsVision:
@@ -1614,7 +1630,7 @@ class ServerSkill:
name: str
"""Unique identifier for the skill"""
- source: str
+ source: SkillSource
"""Source location type (e.g., project, personal-copilot, plugin, builtin)"""
user_invocable: bool
@@ -1632,7 +1648,7 @@ def from_dict(obj: Any) -> 'ServerSkill':
description = from_str(obj.get("description"))
enabled = from_bool(obj.get("enabled"))
name = from_str(obj.get("name"))
- source = from_str(obj.get("source"))
+ source = SkillSource.from_dict(obj.get("source"))
user_invocable = from_bool(obj.get("userInvocable"))
path = from_union([from_str, from_none], obj.get("path"))
project_path = from_union([from_str, from_none], obj.get("projectPath"))
@@ -1643,7 +1659,7 @@ def to_dict(self) -> dict:
result["description"] = from_str(self.description)
result["enabled"] = from_bool(self.enabled)
result["name"] = from_str(self.name)
- result["source"] = from_str(self.source)
+ result["source"] = to_class(SkillSource, self.source)
result["userInvocable"] = from_bool(self.user_invocable)
if self.path is not None:
result["path"] = from_union([from_str, from_none], self.path)
@@ -1910,6 +1926,25 @@ def to_dict(self) -> dict:
result["recursive"] = from_union([from_bool, from_none], self.recursive)
return result
+@dataclass
+class SessionFSSetProviderCapabilities:
+ """Optional capabilities declared by the provider"""
+
+ sqlite: bool | None = None
+ """Whether the provider supports SQLite query/exists operations"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionFSSetProviderCapabilities':
+ assert isinstance(obj, dict)
+ sqlite = from_union([from_bool, from_none], obj.get("sqlite"))
+ return SessionFSSetProviderCapabilities(sqlite)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ if self.sqlite is not None:
+ result["sqlite"] = from_union([from_bool, from_none], self.sqlite)
+ return result
+
class SessionFSSetProviderConventions(Enum):
"""Path conventions used by this filesystem"""
@@ -1934,6 +1969,50 @@ def to_dict(self) -> dict:
result["success"] = from_bool(self.success)
return result
+@dataclass
+class SessionFSSqliteExistsRequest:
+ """Identifies the target session."""
+
+ session_id: str
+ """Target session identifier"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionFSSqliteExistsRequest':
+ assert isinstance(obj, dict)
+ session_id = from_str(obj.get("sessionId"))
+ return SessionFSSqliteExistsRequest(session_id)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["sessionId"] = from_str(self.session_id)
+ return result
+
+@dataclass
+class SessionFSSqliteExistsResult:
+ """Indicates whether the per-session SQLite database already exists."""
+
+ exists: bool
+ """Whether the session database already exists"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionFSSqliteExistsResult':
+ assert isinstance(obj, dict)
+ exists = from_bool(obj.get("exists"))
+ return SessionFSSqliteExistsResult(exists)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["exists"] = from_bool(self.exists)
+ return result
+
+class SessionFSSqliteQueryType(Enum):
+ """How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT
+ (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
+ """
+ EXEC = "exec"
+ QUERY = "query"
+ RUN = "run"
+
@dataclass
class SessionFSStatRequest:
"""Path whose metadata should be returned from the client-provided session filesystem."""
@@ -2138,8 +2217,8 @@ class Skill:
name: str
"""Unique identifier for the skill"""
- source: str
- """Source location type (e.g., project, personal, plugin)"""
+ source: SkillSource
+ """Source location type (e.g., project, personal-copilot, plugin, builtin)"""
user_invocable: bool
"""Whether the skill can be invoked by the user as a slash command"""
@@ -2153,7 +2232,7 @@ def from_dict(obj: Any) -> 'Skill':
description = from_str(obj.get("description"))
enabled = from_bool(obj.get("enabled"))
name = from_str(obj.get("name"))
- source = from_str(obj.get("source"))
+ source = SkillSource.from_dict(obj.get("source"))
user_invocable = from_bool(obj.get("userInvocable"))
path = from_union([from_str, from_none], obj.get("path"))
return Skill(description, enabled, name, source, user_invocable, path)
@@ -2163,7 +2242,7 @@ def to_dict(self) -> dict:
result["description"] = from_str(self.description)
result["enabled"] = from_bool(self.enabled)
result["name"] = from_str(self.name)
- result["source"] = from_str(self.source)
+ result["source"] = to_class(SkillSource, self.source)
result["userInvocable"] = from_bool(self.user_invocable)
if self.path is not None:
result["path"] = from_union([from_str, from_none], self.path)
@@ -2267,15 +2346,13 @@ class SlashCommandInvocationResultKind(Enum):
COMPLETED = "completed"
TEXT = "text"
-class TaskInfoExecutionMode(Enum):
- """How the agent is currently being managed by the runtime
+class TaskExecutionMode(Enum):
+ """Whether task execution is synchronously awaited or managed in the background"""
- Whether the shell command is currently sync-waited or background-managed
- """
BACKGROUND = "background"
SYNC = "sync"
-class TaskInfoStatus(Enum):
+class TaskStatus(Enum):
"""Current lifecycle status of the task"""
CANCELLED = "cancelled"
@@ -3101,7 +3178,7 @@ class ConnectedRemoteSessionMetadata:
kind: ConnectedRemoteSessionMetadataKind
"""Neutral SDK discriminator for the connected remote session kind."""
- modified_time: str
+ modified_time: datetime
"""Last session update time as an ISO 8601 string."""
repository: ConnectedRemoteSessionMetadataRepository
@@ -3110,7 +3187,7 @@ class ConnectedRemoteSessionMetadata:
session_id: str
"""SDK session ID for the connected remote session."""
- start_time: str
+ start_time: datetime
"""Session start time as an ISO 8601 string."""
name: str | None = None
@@ -3122,7 +3199,7 @@ class ConnectedRemoteSessionMetadata:
resource_id: str | None = None
"""Original remote resource identifier."""
- stale_at: str | None = None
+ stale_at: datetime | None = None
"""Remote session staleness deadline as an ISO 8601 string."""
state: str | None = None
@@ -3135,14 +3212,14 @@ class ConnectedRemoteSessionMetadata:
def from_dict(obj: Any) -> 'ConnectedRemoteSessionMetadata':
assert isinstance(obj, dict)
kind = ConnectedRemoteSessionMetadataKind(obj.get("kind"))
- modified_time = from_str(obj.get("modifiedTime"))
+ modified_time = from_datetime(obj.get("modifiedTime"))
repository = ConnectedRemoteSessionMetadataRepository.from_dict(obj.get("repository"))
session_id = from_str(obj.get("sessionId"))
- start_time = from_str(obj.get("startTime"))
+ start_time = from_datetime(obj.get("startTime"))
name = from_union([from_str, from_none], obj.get("name"))
pull_request_number = from_union([from_int, from_none], obj.get("pullRequestNumber"))
resource_id = from_union([from_str, from_none], obj.get("resourceId"))
- stale_at = from_union([from_str, from_none], obj.get("staleAt"))
+ stale_at = from_union([from_datetime, from_none], obj.get("staleAt"))
state = from_union([from_str, from_none], obj.get("state"))
summary = from_union([from_str, from_none], obj.get("summary"))
return ConnectedRemoteSessionMetadata(kind, modified_time, repository, session_id, start_time, name, pull_request_number, resource_id, stale_at, state, summary)
@@ -3150,10 +3227,10 @@ def from_dict(obj: Any) -> 'ConnectedRemoteSessionMetadata':
def to_dict(self) -> dict:
result: dict = {}
result["kind"] = to_enum(ConnectedRemoteSessionMetadataKind, self.kind)
- result["modifiedTime"] = from_str(self.modified_time)
+ result["modifiedTime"] = self.modified_time.isoformat()
result["repository"] = to_class(ConnectedRemoteSessionMetadataRepository, self.repository)
result["sessionId"] = from_str(self.session_id)
- result["startTime"] = from_str(self.start_time)
+ result["startTime"] = self.start_time.isoformat()
if self.name is not None:
result["name"] = from_union([from_str, from_none], self.name)
if self.pull_request_number is not None:
@@ -3161,13 +3238,75 @@ def to_dict(self) -> dict:
if self.resource_id is not None:
result["resourceId"] = from_union([from_str, from_none], self.resource_id)
if self.stale_at is not None:
- result["staleAt"] = from_union([from_str, from_none], self.stale_at)
+ result["staleAt"] = from_union([lambda x: x.isoformat(), from_none], self.stale_at)
if self.state is not None:
result["state"] = from_union([from_str, from_none], self.state)
if self.summary is not None:
result["summary"] = from_union([from_str, from_none], self.summary)
return result
+@dataclass
+class MCPServerConfigStdio:
+ """Stdio MCP server configuration launched as a child process."""
+
+ command: str
+ """Executable command used to start the Stdio MCP server process."""
+
+ args: list[str] | None = None
+ """Command-line arguments passed to the Stdio MCP server process."""
+
+ cwd: str | None = None
+ """Working directory for the Stdio MCP server process."""
+
+ env: dict[str, str] | None = None
+ """Environment variables to pass to the Stdio MCP server process."""
+
+ filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode | None = None
+ """Content filtering mode to apply to all tools, or a map of tool name to content filtering
+ mode.
+ """
+ is_default_server: bool | None = None
+ """Whether this server is a built-in fallback used when the user has not configured their
+ own server.
+ """
+ timeout: int | None = None
+ """Timeout in milliseconds for tool calls to this server."""
+
+ tools: list[str] | None = None
+ """Tools to include. Defaults to all tools if not specified."""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'MCPServerConfigStdio':
+ assert isinstance(obj, dict)
+ command = from_str(obj.get("command"))
+ args = from_union([lambda x: from_list(from_str, x), from_none], obj.get("args"))
+ cwd = from_union([from_str, from_none], obj.get("cwd"))
+ env = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("env"))
+ filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode, from_none], obj.get("filterMapping"))
+ is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer"))
+ timeout = from_union([from_int, from_none], obj.get("timeout"))
+ tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools"))
+ return MCPServerConfigStdio(command, args, cwd, env, filter_mapping, is_default_server, timeout, tools)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["command"] = from_str(self.command)
+ if self.args is not None:
+ result["args"] = from_union([lambda x: from_list(from_str, x), from_none], self.args)
+ if self.cwd is not None:
+ result["cwd"] = from_union([from_str, from_none], self.cwd)
+ if self.env is not None:
+ result["env"] = from_union([lambda x: from_dict(from_str, x), from_none], self.env)
+ if self.filter_mapping is not None:
+ result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(ContentFilterMode, x), x), lambda x: to_enum(ContentFilterMode, x), from_none], self.filter_mapping)
+ if self.is_default_server is not None:
+ result["isDefaultServer"] = from_union([from_bool, from_none], self.is_default_server)
+ if self.timeout is not None:
+ result["timeout"] = from_union([from_int, from_none], self.timeout)
+ if self.tools is not None:
+ result["tools"] = from_union([lambda x: from_list(from_str, x), from_none], self.tools)
+ return result
+
@dataclass
class DiscoveredMCPServer:
"""Schema for the `DiscoveredMcpServer` type."""
@@ -3178,18 +3317,18 @@ class DiscoveredMCPServer:
name: str
"""Server name (config key)"""
- source: MCPServerSource
- """Configuration source"""
+ source: ExternalRefMCPServerSource
+ """Configuration source: user, workspace, plugin, or builtin"""
type: DiscoveredMCPServerType | None = None
- """Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)"""
+ """Server transport type: stdio, http, sse, or memory"""
@staticmethod
def from_dict(obj: Any) -> 'DiscoveredMCPServer':
assert isinstance(obj, dict)
enabled = from_bool(obj.get("enabled"))
name = from_str(obj.get("name"))
- source = MCPServerSource(obj.get("source"))
+ source = ExternalRefMCPServerSource.from_dict(obj.get("source"))
type = from_union([DiscoveredMCPServerType, from_none], obj.get("type"))
return DiscoveredMCPServer(enabled, name, source, type)
@@ -3197,7 +3336,7 @@ def to_dict(self) -> dict:
result: dict = {}
result["enabled"] = from_bool(self.enabled)
result["name"] = from_str(self.name)
- result["source"] = to_enum(MCPServerSource, self.source)
+ result["source"] = to_class(ExternalRefMCPServerSource, self.source)
if self.type is not None:
result["type"] = from_union([lambda x: to_enum(DiscoveredMCPServerType, x), from_none], self.type)
return result
@@ -3241,6 +3380,41 @@ def to_dict(self) -> dict:
result["pid"] = from_union([from_int, from_none], self.pid)
return result
+@dataclass
+class ExternalToolTextResultForLlmBinaryResultsForLlm:
+ """Binary result returned by a tool for the model"""
+
+ data: str
+ """Base64-encoded binary data"""
+
+ mime_type: str
+ """MIME type of the binary data"""
+
+ type: ExternalToolTextResultForLlmBinaryResultsForLlmType
+ """Binary result type discriminator. Use "image" for images and "resource" for other binary
+ data.
+ """
+ description: str | None = None
+ """Human-readable description of the binary data"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ExternalToolTextResultForLlmBinaryResultsForLlm':
+ assert isinstance(obj, dict)
+ data = from_str(obj.get("data"))
+ mime_type = from_str(obj.get("mimeType"))
+ type = ExternalToolTextResultForLlmBinaryResultsForLlmType(obj.get("type"))
+ description = from_union([from_str, from_none], obj.get("description"))
+ return ExternalToolTextResultForLlmBinaryResultsForLlm(data, mime_type, type, description)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["data"] = from_str(self.data)
+ result["mimeType"] = from_str(self.mime_type)
+ result["type"] = to_enum(ExternalToolTextResultForLlmBinaryResultsForLlmType, self.type)
+ if self.description is not None:
+ result["description"] = from_union([from_str, from_none], self.description)
+ return result
+
@dataclass
class ExternalToolTextResultForLlmContentResourceLinkIcon:
"""Icon image for a resource"""
@@ -3589,25 +3763,25 @@ def to_dict(self) -> dict:
@dataclass
class MCPServerConfig:
- """MCP server configuration (local/stdio or remote/http)
+ """MCP server configuration (stdio process or remote HTTP/SSE)
- Local MCP server configuration launched as a child process.
+ Stdio MCP server configuration launched as a child process.
Remote MCP server configuration accessed over HTTP or SSE.
"""
args: list[str] | None = None
- """Command-line arguments passed to the local MCP server process."""
+ """Command-line arguments passed to the Stdio MCP server process."""
command: str | None = None
- """Executable command used to start the local MCP server process."""
+ """Executable command used to start the Stdio MCP server process."""
cwd: str | None = None
- """Working directory for the local MCP server process."""
+ """Working directory for the Stdio MCP server process."""
env: dict[str, str] | None = None
- """Environment variables to pass to the local MCP server process."""
+ """Environment variables to pass to the Stdio MCP server process."""
- filter_mapping: dict[str, FilterMappingString] | FilterMappingString | None = None
+ filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode | None = None
"""Content filtering mode to apply to all tools, or a map of tool name to content filtering
mode.
"""
@@ -3621,11 +3795,9 @@ class MCPServerConfig:
tools: list[str] | None = None
"""Tools to include. Defaults to all tools if not specified."""
- type: MCPServerConfigType | None = None
- """Local transport type. Defaults to "local".
+ auth: MCPServerConfigHTTPAuth | None = None
+ """Additional authentication configuration for this server."""
- Remote transport type. Defaults to "http" when omitted.
- """
headers: dict[str, str] | None = None
"""HTTP headers to include in requests to the remote MCP server."""
@@ -3638,6 +3810,9 @@ class MCPServerConfig:
oauth_public_client: bool | None = None
"""Whether the configured OAuth client is public and does not require a client secret."""
+ type: MCPServerConfigHTTPType | None = None
+ """Remote transport type. Defaults to "http" when omitted."""
+
url: str | None = None
"""URL of the remote MCP server endpoint."""
@@ -3648,17 +3823,18 @@ def from_dict(obj: Any) -> 'MCPServerConfig':
command = from_union([from_str, from_none], obj.get("command"))
cwd = from_union([from_str, from_none], obj.get("cwd"))
env = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("env"))
- filter_mapping = from_union([lambda x: from_dict(FilterMappingString, x), FilterMappingString, from_none], obj.get("filterMapping"))
+ filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode, from_none], obj.get("filterMapping"))
is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer"))
timeout = from_union([from_int, from_none], obj.get("timeout"))
tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools"))
- type = from_union([MCPServerConfigType, from_none], obj.get("type"))
+ auth = from_union([MCPServerConfigHTTPAuth.from_dict, from_none], obj.get("auth"))
headers = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("headers"))
oauth_client_id = from_union([from_str, from_none], obj.get("oauthClientId"))
oauth_grant_type = from_union([MCPServerConfigHTTPOauthGrantType, from_none], obj.get("oauthGrantType"))
oauth_public_client = from_union([from_bool, from_none], obj.get("oauthPublicClient"))
+ type = from_union([MCPServerConfigHTTPType, from_none], obj.get("type"))
url = from_union([from_str, from_none], obj.get("url"))
- return MCPServerConfig(args, command, cwd, env, filter_mapping, is_default_server, timeout, tools, type, headers, oauth_client_id, oauth_grant_type, oauth_public_client, url)
+ return MCPServerConfig(args, command, cwd, env, filter_mapping, is_default_server, timeout, tools, auth, headers, oauth_client_id, oauth_grant_type, oauth_public_client, type, url)
def to_dict(self) -> dict:
result: dict = {}
@@ -3671,15 +3847,15 @@ def to_dict(self) -> dict:
if self.env is not None:
result["env"] = from_union([lambda x: from_dict(from_str, x), from_none], self.env)
if self.filter_mapping is not None:
- result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(FilterMappingString, x), x), lambda x: to_enum(FilterMappingString, x), from_none], self.filter_mapping)
+ result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(ContentFilterMode, x), x), lambda x: to_enum(ContentFilterMode, x), from_none], self.filter_mapping)
if self.is_default_server is not None:
result["isDefaultServer"] = from_union([from_bool, from_none], self.is_default_server)
if self.timeout is not None:
result["timeout"] = from_union([from_int, from_none], self.timeout)
if self.tools is not None:
result["tools"] = from_union([lambda x: from_list(from_str, x), from_none], self.tools)
- if self.type is not None:
- result["type"] = from_union([lambda x: to_enum(MCPServerConfigType, x), from_none], self.type)
+ if self.auth is not None:
+ result["auth"] = from_union([lambda x: to_class(MCPServerConfigHTTPAuth, x), from_none], self.auth)
if self.headers is not None:
result["headers"] = from_union([lambda x: from_dict(from_str, x), from_none], self.headers)
if self.oauth_client_id is not None:
@@ -3688,45 +3864,12 @@ def to_dict(self) -> dict:
result["oauthGrantType"] = from_union([lambda x: to_enum(MCPServerConfigHTTPOauthGrantType, x), from_none], self.oauth_grant_type)
if self.oauth_public_client is not None:
result["oauthPublicClient"] = from_union([from_bool, from_none], self.oauth_public_client)
+ if self.type is not None:
+ result["type"] = from_union([lambda x: to_enum(MCPServerConfigHTTPType, x), from_none], self.type)
if self.url is not None:
result["url"] = from_union([from_str, from_none], self.url)
return result
-@dataclass
-class MCPServer:
- """Schema for the `McpServer` type."""
-
- name: str
- """Server name (config key)"""
-
- status: MCPServerStatus
- """Connection status: connected, failed, needs-auth, pending, disabled, or not_configured"""
-
- error: str | None = None
- """Error message if the server failed to connect"""
-
- source: MCPServerSource | None = None
- """Configuration source: user, workspace, plugin, or builtin"""
-
- @staticmethod
- def from_dict(obj: Any) -> 'MCPServer':
- assert isinstance(obj, dict)
- name = from_str(obj.get("name"))
- status = MCPServerStatus(obj.get("status"))
- error = from_union([from_str, from_none], obj.get("error"))
- source = from_union([MCPServerSource, from_none], obj.get("source"))
- return MCPServer(name, status, error, source)
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["name"] = from_str(self.name)
- result["status"] = to_enum(MCPServerStatus, self.status)
- if self.error is not None:
- result["error"] = from_union([from_str, from_none], self.error)
- if self.source is not None:
- result["source"] = from_union([lambda x: to_enum(MCPServerSource, x), from_none], self.source)
- return result
-
@dataclass
class MCPServerConfigHTTP:
"""Remote MCP server configuration accessed over HTTP or SSE."""
@@ -3734,7 +3877,10 @@ class MCPServerConfigHTTP:
url: str
"""URL of the remote MCP server endpoint."""
- filter_mapping: dict[str, FilterMappingString] | FilterMappingString | None = None
+ auth: MCPServerConfigHTTPAuth | None = None
+ """Additional authentication configuration for this server."""
+
+ filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode | None = None
"""Content filtering mode to apply to all tools, or a map of tool name to content filtering
mode.
"""
@@ -3767,7 +3913,8 @@ class MCPServerConfigHTTP:
def from_dict(obj: Any) -> 'MCPServerConfigHTTP':
assert isinstance(obj, dict)
url = from_str(obj.get("url"))
- filter_mapping = from_union([lambda x: from_dict(FilterMappingString, x), FilterMappingString, from_none], obj.get("filterMapping"))
+ auth = from_union([MCPServerConfigHTTPAuth.from_dict, from_none], obj.get("auth"))
+ filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode, from_none], obj.get("filterMapping"))
headers = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("headers"))
is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer"))
oauth_client_id = from_union([from_str, from_none], obj.get("oauthClientId"))
@@ -3776,13 +3923,15 @@ def from_dict(obj: Any) -> 'MCPServerConfigHTTP':
timeout = from_union([from_int, from_none], obj.get("timeout"))
tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools"))
type = from_union([MCPServerConfigHTTPType, from_none], obj.get("type"))
- return MCPServerConfigHTTP(url, filter_mapping, headers, is_default_server, oauth_client_id, oauth_grant_type, oauth_public_client, timeout, tools, type)
+ return MCPServerConfigHTTP(url, auth, filter_mapping, headers, is_default_server, oauth_client_id, oauth_grant_type, oauth_public_client, timeout, tools, type)
def to_dict(self) -> dict:
result: dict = {}
result["url"] = from_str(self.url)
+ if self.auth is not None:
+ result["auth"] = from_union([lambda x: to_class(MCPServerConfigHTTPAuth, x), from_none], self.auth)
if self.filter_mapping is not None:
- result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(FilterMappingString, x), x), lambda x: to_enum(FilterMappingString, x), from_none], self.filter_mapping)
+ result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(ContentFilterMode, x), x), lambda x: to_enum(ContentFilterMode, x), from_none], self.filter_mapping)
if self.headers is not None:
result["headers"] = from_union([lambda x: from_dict(from_str, x), from_none], self.headers)
if self.is_default_server is not None:
@@ -3802,88 +3951,38 @@ def to_dict(self) -> dict:
return result
@dataclass
-class MCPServerConfigLocal:
- """Local MCP server configuration launched as a child process."""
-
- args: list[str]
- """Command-line arguments passed to the local MCP server process."""
-
- command: str
- """Executable command used to start the local MCP server process."""
-
- cwd: str | None = None
- """Working directory for the local MCP server process."""
-
- env: dict[str, str] | None = None
- """Environment variables to pass to the local MCP server process."""
-
- filter_mapping: dict[str, FilterMappingString] | FilterMappingString | None = None
- """Content filtering mode to apply to all tools, or a map of tool name to content filtering
- mode.
- """
- is_default_server: bool | None = None
- """Whether this server is a built-in fallback used when the user has not configured their
- own server.
- """
- timeout: int | None = None
- """Timeout in milliseconds for tool calls to this server."""
-
- tools: list[str] | None = None
- """Tools to include. Defaults to all tools if not specified."""
-
- type: MCPServerConfigLocalType | None = None
- """Local transport type. Defaults to "local"."""
+class MCPServer:
+ """Schema for the `McpServer` type."""
- @staticmethod
- def from_dict(obj: Any) -> 'MCPServerConfigLocal':
- assert isinstance(obj, dict)
- args = from_list(from_str, obj.get("args"))
- command = from_str(obj.get("command"))
- cwd = from_union([from_str, from_none], obj.get("cwd"))
- env = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("env"))
- filter_mapping = from_union([lambda x: from_dict(FilterMappingString, x), FilterMappingString, from_none], obj.get("filterMapping"))
- is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer"))
- timeout = from_union([from_int, from_none], obj.get("timeout"))
- tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools"))
- type = from_union([MCPServerConfigLocalType, from_none], obj.get("type"))
- return MCPServerConfigLocal(args, command, cwd, env, filter_mapping, is_default_server, timeout, tools, type)
+ name: str
+ """Server name (config key)"""
- def to_dict(self) -> dict:
- result: dict = {}
- result["args"] = from_list(from_str, self.args)
- result["command"] = from_str(self.command)
- if self.cwd is not None:
- result["cwd"] = from_union([from_str, from_none], self.cwd)
- if self.env is not None:
- result["env"] = from_union([lambda x: from_dict(from_str, x), from_none], self.env)
- if self.filter_mapping is not None:
- result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(FilterMappingString, x), x), lambda x: to_enum(FilterMappingString, x), from_none], self.filter_mapping)
- if self.is_default_server is not None:
- result["isDefaultServer"] = from_union([from_bool, from_none], self.is_default_server)
- if self.timeout is not None:
- result["timeout"] = from_union([from_int, from_none], self.timeout)
- if self.tools is not None:
- result["tools"] = from_union([lambda x: from_list(from_str, x), from_none], self.tools)
- if self.type is not None:
- result["type"] = from_union([lambda x: to_enum(MCPServerConfigLocalType, x), from_none], self.type)
- return result
+ status: ExternalRefMCPServerStatus
+ """Connection status: connected, failed, needs-auth, pending, disabled, or not_configured"""
-@dataclass
-class ModeSetRequest:
- """Agent interaction mode to apply to the session."""
+ error: str | None = None
+ """Error message if the server failed to connect"""
- mode: Mode
- """The agent mode. Valid values: "interactive", "plan", "autopilot"."""
+ source: ExternalRefMCPServerSource | None = None
+ """Configuration source: user, workspace, plugin, or builtin"""
@staticmethod
- def from_dict(obj: Any) -> 'ModeSetRequest':
+ def from_dict(obj: Any) -> 'MCPServer':
assert isinstance(obj, dict)
- mode = Mode(obj.get("mode"))
- return ModeSetRequest(mode)
+ name = from_str(obj.get("name"))
+ status = ExternalRefMCPServerStatus.from_dict(obj.get("status"))
+ error = from_union([from_str, from_none], obj.get("error"))
+ source = from_union([ExternalRefMCPServerSource.from_dict, from_none], obj.get("source"))
+ return MCPServer(name, status, error, source)
def to_dict(self) -> dict:
result: dict = {}
- result["mode"] = to_enum(Mode, self.mode)
+ result["name"] = from_str(self.name)
+ result["status"] = to_class(ExternalRefMCPServerStatus, self.status)
+ if self.error is not None:
+ result["error"] = from_union([from_str, from_none], self.error)
+ if self.source is not None:
+ result["source"] = from_union([lambda x: to_class(ExternalRefMCPServerSource, x), from_none], self.source)
return result
@dataclass
@@ -3948,6 +4047,30 @@ def to_dict(self) -> dict:
result["vision"] = from_union([lambda x: to_class(ModelCapabilitiesLimitsVision, x), from_none], self.vision)
return result
+@dataclass
+class ModelPolicy:
+ """Policy state (if applicable)"""
+
+ state: ModelPolicyState
+ """Current policy state for this model"""
+
+ terms: str | None = None
+ """Usage terms or conditions for this model"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'ModelPolicy':
+ assert isinstance(obj, dict)
+ state = ModelPolicyState(obj.get("state"))
+ terms = from_union([from_str, from_none], obj.get("terms"))
+ return ModelPolicy(state, terms)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["state"] = to_enum(ModelPolicyState, self.state)
+ if self.terms is not None:
+ result["terms"] = from_union([from_str, from_none], self.terms)
+ return result
+
@dataclass
class ModelCapabilitiesOverrideLimits:
"""Token limits for prompts, outputs, and context window"""
@@ -4573,19 +4696,61 @@ class SessionFSSetProviderRequest:
session_state_path: str
"""Path within each session's SessionFs where the runtime stores files for that session"""
+ capabilities: SessionFSSetProviderCapabilities | None = None
+ """Optional capabilities declared by the provider"""
+
@staticmethod
def from_dict(obj: Any) -> 'SessionFSSetProviderRequest':
assert isinstance(obj, dict)
conventions = SessionFSSetProviderConventions(obj.get("conventions"))
initial_cwd = from_str(obj.get("initialCwd"))
session_state_path = from_str(obj.get("sessionStatePath"))
- return SessionFSSetProviderRequest(conventions, initial_cwd, session_state_path)
+ capabilities = from_union([SessionFSSetProviderCapabilities.from_dict, from_none], obj.get("capabilities"))
+ return SessionFSSetProviderRequest(conventions, initial_cwd, session_state_path, capabilities)
def to_dict(self) -> dict:
result: dict = {}
result["conventions"] = to_enum(SessionFSSetProviderConventions, self.conventions)
result["initialCwd"] = from_str(self.initial_cwd)
result["sessionStatePath"] = from_str(self.session_state_path)
+ if self.capabilities is not None:
+ result["capabilities"] = from_union([lambda x: to_class(SessionFSSetProviderCapabilities, x), from_none], self.capabilities)
+ return result
+
+@dataclass
+class SessionFSSqliteQueryRequest:
+ """SQL query, query type, and optional bind parameters for executing a SQLite query against
+ the per-session database.
+ """
+ query: str
+ """SQL query to execute"""
+
+ query_type: SessionFSSqliteQueryType
+ """How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT
+ (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
+ """
+ session_id: str
+ """Target session identifier"""
+
+ params: dict[str, Optional[float | str]] | None = None
+ """Optional named bind parameters"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionFSSqliteQueryRequest':
+ assert isinstance(obj, dict)
+ query = from_str(obj.get("query"))
+ query_type = SessionFSSqliteQueryType(obj.get("queryType"))
+ session_id = from_str(obj.get("sessionId"))
+ params = from_union([lambda x: from_dict(lambda x: from_union([from_none, from_float, from_str], x), x), from_none], obj.get("params"))
+ return SessionFSSqliteQueryRequest(query, query_type, session_id, params)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["query"] = from_str(self.query)
+ result["queryType"] = to_enum(SessionFSSqliteQueryType, self.query_type)
+ result["sessionId"] = from_str(self.session_id)
+ if self.params is not None:
+ result["params"] = from_union([lambda x: from_dict(lambda x: from_union([from_none, to_float, from_str], x), x), from_none], self.params)
return result
@dataclass
@@ -4662,8 +4827,8 @@ class SlashCommandAgentPromptResult:
prompt: str
"""Prompt to submit to the agent"""
- mode: Mode | None = None
- """Optional target session mode"""
+ mode: SessionMode | None = None
+ """Optional target session mode for the agent prompt"""
runtime_settings_changed: bool | None = None
"""True when the invocation mutated user runtime settings; consumers caching settings should
@@ -4676,7 +4841,7 @@ def from_dict(obj: Any) -> 'SlashCommandAgentPromptResult':
display_prompt = from_str(obj.get("displayPrompt"))
kind = SlashCommandAgentPromptResultKind(obj.get("kind"))
prompt = from_str(obj.get("prompt"))
- mode = from_union([Mode, from_none], obj.get("mode"))
+ mode = from_union([SessionMode.from_dict, from_none], obj.get("mode"))
runtime_settings_changed = from_union([from_bool, from_none], obj.get("runtimeSettingsChanged"))
return SlashCommandAgentPromptResult(display_prompt, kind, prompt, mode, runtime_settings_changed)
@@ -4686,7 +4851,7 @@ def to_dict(self) -> dict:
result["kind"] = to_enum(SlashCommandAgentPromptResultKind, self.kind)
result["prompt"] = from_str(self.prompt)
if self.mode is not None:
- result["mode"] = from_union([lambda x: to_enum(Mode, x), from_none], self.mode)
+ result["mode"] = from_union([lambda x: to_class(SessionMode, x), from_none], self.mode)
if self.runtime_settings_changed is not None:
result["runtimeSettingsChanged"] = from_union([from_bool, from_none], self.runtime_settings_changed)
return result
@@ -4743,7 +4908,7 @@ class TaskShellInfo:
started_at: datetime
"""ISO 8601 timestamp when the task was started"""
- status: TaskInfoStatus
+ status: TaskStatus
"""Current lifecycle status of the task"""
type: TaskShellInfoType
@@ -4755,8 +4920,8 @@ class TaskShellInfo:
completed_at: datetime | None = None
"""ISO 8601 timestamp when the task finished"""
- execution_mode: TaskInfoExecutionMode | None = None
- """Whether the shell command is currently sync-waited or background-managed"""
+ execution_mode: TaskExecutionMode | None = None
+ """Whether task execution is synchronously awaited or managed in the background"""
log_path: str | None = None
"""Path to the detached shell log, when available"""
@@ -4772,11 +4937,11 @@ def from_dict(obj: Any) -> 'TaskShellInfo':
description = from_str(obj.get("description"))
id = from_str(obj.get("id"))
started_at = from_datetime(obj.get("startedAt"))
- status = TaskInfoStatus(obj.get("status"))
+ status = TaskStatus(obj.get("status"))
type = TaskShellInfoType(obj.get("type"))
can_promote_to_background = from_union([from_bool, from_none], obj.get("canPromoteToBackground"))
completed_at = from_union([from_datetime, from_none], obj.get("completedAt"))
- execution_mode = from_union([TaskInfoExecutionMode, from_none], obj.get("executionMode"))
+ execution_mode = from_union([TaskExecutionMode, from_none], obj.get("executionMode"))
log_path = from_union([from_str, from_none], obj.get("logPath"))
pid = from_union([from_int, from_none], obj.get("pid"))
return TaskShellInfo(attachment_mode, command, description, id, started_at, status, type, can_promote_to_background, completed_at, execution_mode, log_path, pid)
@@ -4788,14 +4953,14 @@ def to_dict(self) -> dict:
result["description"] = from_str(self.description)
result["id"] = from_str(self.id)
result["startedAt"] = self.started_at.isoformat()
- result["status"] = to_enum(TaskInfoStatus, self.status)
+ result["status"] = to_enum(TaskStatus, self.status)
result["type"] = to_enum(TaskShellInfoType, self.type)
if self.can_promote_to_background is not None:
result["canPromoteToBackground"] = from_union([from_bool, from_none], self.can_promote_to_background)
if self.completed_at is not None:
result["completedAt"] = from_union([lambda x: x.isoformat(), from_none], self.completed_at)
if self.execution_mode is not None:
- result["executionMode"] = from_union([lambda x: to_enum(TaskInfoExecutionMode, x), from_none], self.execution_mode)
+ result["executionMode"] = from_union([lambda x: to_enum(TaskExecutionMode, x), from_none], self.execution_mode)
if self.log_path is not None:
result["logPath"] = from_union([from_str, from_none], self.log_path)
if self.pid is not None:
@@ -5605,7 +5770,7 @@ class MCPConfigAddRequest:
"""MCP server name and configuration to add to user configuration."""
config: MCPServerConfig
- """MCP server configuration (local/stdio or remote/http)"""
+ """MCP server configuration (stdio process or remote HTTP/SSE)"""
name: str
"""Unique name for the MCP server"""
@@ -5646,7 +5811,7 @@ class MCPConfigUpdateRequest:
"""MCP server name and replacement configuration to write to user configuration."""
config: MCPServerConfig
- """MCP server configuration (local/stdio or remote/http)"""
+ """MCP server configuration (stdio process or remote HTTP/SSE)"""
name: str
"""Name of the MCP server to update"""
@@ -5778,6 +5943,47 @@ def to_dict(self) -> dict:
result["error"] = from_union([lambda x: to_class(SessionFSError, x), from_none], self.error)
return result
+@dataclass
+class SessionFSSqliteQueryResult:
+ """Query results including rows, columns, and rows affected, or a filesystem error if
+ execution failed.
+ """
+ columns: list[str]
+ """Column names from the result set"""
+
+ rows: list[dict[str, Any]]
+ """For SELECT: array of row objects. For others: empty array."""
+
+ rows_affected: int
+ """Number of rows affected (for INSERT/UPDATE/DELETE)"""
+
+ error: SessionFSError | None = None
+ """Describes a filesystem error."""
+
+ last_insert_rowid: float | None = None
+ """Last inserted row ID (for INSERT)"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionFSSqliteQueryResult':
+ assert isinstance(obj, dict)
+ columns = from_list(from_str, obj.get("columns"))
+ rows = from_list(lambda x: from_dict(lambda x: x, x), obj.get("rows"))
+ rows_affected = from_int(obj.get("rowsAffected"))
+ error = from_union([SessionFSError.from_dict, from_none], obj.get("error"))
+ last_insert_rowid = from_union([from_float, from_none], obj.get("lastInsertRowid"))
+ return SessionFSSqliteQueryResult(columns, rows, rows_affected, error, last_insert_rowid)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["columns"] = from_list(from_str, self.columns)
+ result["rows"] = from_list(lambda x: from_dict(lambda x: x, x), self.rows)
+ result["rowsAffected"] = from_int(self.rows_affected)
+ if self.error is not None:
+ result["error"] = from_union([lambda x: to_class(SessionFSError, x), from_none], self.error)
+ if self.last_insert_rowid is not None:
+ result["lastInsertRowid"] = from_union([to_float, from_none], self.last_insert_rowid)
+ return result
+
@dataclass
class SessionFSStatResult:
"""Filesystem metadata for the requested path, or a filesystem error if the stat failed."""
@@ -5881,8 +6087,8 @@ class SlashCommandInvocationResult:
display_prompt: str | None = None
"""Prompt text to display to the user"""
- mode: Mode | None = None
- """Optional target session mode"""
+ mode: SessionMode | None = None
+ """Optional target session mode for the agent prompt"""
prompt: str | None = None
"""Prompt to submit to the agent"""
@@ -5899,7 +6105,7 @@ def from_dict(obj: Any) -> 'SlashCommandInvocationResult':
runtime_settings_changed = from_union([from_bool, from_none], obj.get("runtimeSettingsChanged"))
text = from_union([from_str, from_none], obj.get("text"))
display_prompt = from_union([from_str, from_none], obj.get("displayPrompt"))
- mode = from_union([Mode, from_none], obj.get("mode"))
+ mode = from_union([SessionMode.from_dict, from_none], obj.get("mode"))
prompt = from_union([from_str, from_none], obj.get("prompt"))
message = from_union([from_str, from_none], obj.get("message"))
return SlashCommandInvocationResult(kind, markdown, preserve_ansi, runtime_settings_changed, text, display_prompt, mode, prompt, message)
@@ -5918,7 +6124,7 @@ def to_dict(self) -> dict:
if self.display_prompt is not None:
result["displayPrompt"] = from_union([from_str, from_none], self.display_prompt)
if self.mode is not None:
- result["mode"] = from_union([lambda x: to_enum(Mode, x), from_none], self.mode)
+ result["mode"] = from_union([lambda x: to_class(SessionMode, x), from_none], self.mode)
if self.prompt is not None:
result["prompt"] = from_union([from_str, from_none], self.prompt)
if self.message is not None:
@@ -6577,6 +6783,9 @@ class ExternalToolTextResultForLlm:
text_result_for_llm: str
"""Text result returned to the model"""
+ binary_results_for_llm: list[ExternalToolTextResultForLlmBinaryResultsForLlm] | None = None
+ """Base64-encoded binary results returned to the model"""
+
contents: list[ExternalToolTextResultForLlmContent] | None = None
"""Structured content blocks from the tool"""
@@ -6597,16 +6806,19 @@ class ExternalToolTextResultForLlm:
def from_dict(obj: Any) -> 'ExternalToolTextResultForLlm':
assert isinstance(obj, dict)
text_result_for_llm = from_str(obj.get("textResultForLlm"))
+ binary_results_for_llm = from_union([lambda x: from_list(ExternalToolTextResultForLlmBinaryResultsForLlm.from_dict, x), from_none], obj.get("binaryResultsForLlm"))
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)
+ return ExternalToolTextResultForLlm(text_result_for_llm, binary_results_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.binary_results_for_llm is not None:
+ result["binaryResultsForLlm"] = from_union([lambda x: from_list(lambda x: to_class(ExternalToolTextResultForLlmBinaryResultsForLlm, x), x), from_none], self.binary_results_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:
@@ -7021,7 +7233,7 @@ class TaskAgentInfo:
started_at: datetime
"""ISO 8601 timestamp when the task was started"""
- status: TaskInfoStatus
+ status: TaskStatus
"""Current lifecycle status of the task"""
tool_call_id: str
@@ -7047,8 +7259,8 @@ class TaskAgentInfo:
error: str | None = None
"""Error message when the task failed"""
- execution_mode: TaskInfoExecutionMode | None = None
- """How the agent is currently being managed by the runtime"""
+ execution_mode: TaskExecutionMode | None = None
+ """Whether task execution is synchronously awaited or managed in the background"""
idle_since: datetime | None = None
"""ISO 8601 timestamp when the agent entered idle state"""
@@ -7070,7 +7282,7 @@ def from_dict(obj: Any) -> 'TaskAgentInfo':
id = from_str(obj.get("id"))
prompt = from_str(obj.get("prompt"))
started_at = from_datetime(obj.get("startedAt"))
- status = TaskInfoStatus(obj.get("status"))
+ status = TaskStatus(obj.get("status"))
tool_call_id = from_str(obj.get("toolCallId"))
type = TaskAgentInfoType(obj.get("type"))
active_started_at = from_union([from_datetime, from_none], obj.get("activeStartedAt"))
@@ -7078,7 +7290,7 @@ def from_dict(obj: Any) -> 'TaskAgentInfo':
can_promote_to_background = from_union([from_bool, from_none], obj.get("canPromoteToBackground"))
completed_at = from_union([from_datetime, from_none], obj.get("completedAt"))
error = from_union([from_str, from_none], obj.get("error"))
- execution_mode = from_union([TaskInfoExecutionMode, from_none], obj.get("executionMode"))
+ execution_mode = from_union([TaskExecutionMode, from_none], obj.get("executionMode"))
idle_since = from_union([from_datetime, from_none], obj.get("idleSince"))
latest_response = from_union([from_str, from_none], obj.get("latestResponse"))
model = from_union([from_str, from_none], obj.get("model"))
@@ -7092,7 +7304,7 @@ def to_dict(self) -> dict:
result["id"] = from_str(self.id)
result["prompt"] = from_str(self.prompt)
result["startedAt"] = self.started_at.isoformat()
- result["status"] = to_enum(TaskInfoStatus, self.status)
+ result["status"] = to_enum(TaskStatus, self.status)
result["toolCallId"] = from_str(self.tool_call_id)
result["type"] = to_enum(TaskAgentInfoType, self.type)
if self.active_started_at is not None:
@@ -7106,7 +7318,7 @@ def to_dict(self) -> dict:
if self.error is not None:
result["error"] = from_union([from_str, from_none], self.error)
if self.execution_mode is not None:
- result["executionMode"] = from_union([lambda x: to_enum(TaskInfoExecutionMode, x), from_none], self.execution_mode)
+ result["executionMode"] = from_union([lambda x: to_enum(TaskExecutionMode, x), from_none], self.execution_mode)
if self.idle_since is not None:
result["idleSince"] = from_union([lambda x: x.isoformat(), from_none], self.idle_since)
if self.latest_response is not None:
@@ -7134,7 +7346,7 @@ class TaskInfo:
started_at: datetime
"""ISO 8601 timestamp when the task was started"""
- status: TaskInfoStatus
+ status: TaskStatus
"""Current lifecycle status of the task"""
type: TaskInfoType
@@ -7162,11 +7374,9 @@ class TaskInfo:
error: str | None = None
"""Error message when the task failed"""
- execution_mode: TaskInfoExecutionMode | None = None
- """How the agent is currently being managed by the runtime
+ execution_mode: TaskExecutionMode | None = None
+ """Whether task execution is synchronously awaited or managed in the background"""
- Whether the shell command is currently sync-waited or background-managed
- """
idle_since: datetime | None = None
"""ISO 8601 timestamp when the agent entered idle state"""
@@ -7204,7 +7414,7 @@ def from_dict(obj: Any) -> 'TaskInfo':
description = from_str(obj.get("description"))
id = from_str(obj.get("id"))
started_at = from_datetime(obj.get("startedAt"))
- status = TaskInfoStatus(obj.get("status"))
+ status = TaskStatus(obj.get("status"))
type = TaskInfoType(obj.get("type"))
active_started_at = from_union([from_datetime, from_none], obj.get("activeStartedAt"))
active_time_ms = from_union([from_int, from_none], obj.get("activeTimeMs"))
@@ -7212,7 +7422,7 @@ def from_dict(obj: Any) -> 'TaskInfo':
can_promote_to_background = from_union([from_bool, from_none], obj.get("canPromoteToBackground"))
completed_at = from_union([from_datetime, from_none], obj.get("completedAt"))
error = from_union([from_str, from_none], obj.get("error"))
- execution_mode = from_union([TaskInfoExecutionMode, from_none], obj.get("executionMode"))
+ execution_mode = from_union([TaskExecutionMode, from_none], obj.get("executionMode"))
idle_since = from_union([from_datetime, from_none], obj.get("idleSince"))
latest_response = from_union([from_str, from_none], obj.get("latestResponse"))
model = from_union([from_str, from_none], obj.get("model"))
@@ -7230,7 +7440,7 @@ def to_dict(self) -> dict:
result["description"] = from_str(self.description)
result["id"] = from_str(self.id)
result["startedAt"] = self.started_at.isoformat()
- result["status"] = to_enum(TaskInfoStatus, self.status)
+ result["status"] = to_enum(TaskStatus, self.status)
result["type"] = to_enum(TaskInfoType, self.type)
if self.active_started_at is not None:
result["activeStartedAt"] = from_union([lambda x: x.isoformat(), from_none], self.active_started_at)
@@ -7245,7 +7455,7 @@ def to_dict(self) -> dict:
if self.error is not None:
result["error"] = from_union([from_str, from_none], self.error)
if self.execution_mode is not None:
- result["executionMode"] = from_union([lambda x: to_enum(TaskInfoExecutionMode, x), from_none], self.execution_mode)
+ result["executionMode"] = from_union([lambda x: to_enum(TaskExecutionMode, x), from_none], self.execution_mode)
if self.idle_since is not None:
result["idleSince"] = from_union([lambda x: x.isoformat(), from_none], self.idle_since)
if self.latest_response is not None:
@@ -7312,9 +7522,9 @@ class RPC:
connect_remote_session_params: ConnectRemoteSessionParams
connect_request: ConnectRequest
connect_result: ConnectResult
+ content_filter_mode: ContentFilterMode
current_model: CurrentModel
discovered_mcp_server: DiscoveredMCPServer
- discovered_mcp_server_source: MCPServerSource
discovered_mcp_server_type: DiscoveredMCPServerType
extension: Extension
extension_list: ExtensionList
@@ -7324,6 +7534,8 @@ class RPC:
extension_status: ExtensionStatus
external_tool_result: ExternalToolTextResultForLlm | str
external_tool_text_result_for_llm: ExternalToolTextResultForLlm
+ external_tool_text_result_for_llm_binary_results_for_llm: ExternalToolTextResultForLlmBinaryResultsForLlm
+ external_tool_text_result_for_llm_binary_results_for_llm_type: ExternalToolTextResultForLlmBinaryResultsForLlmType
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
@@ -7334,9 +7546,7 @@ class RPC:
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
+ filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode
fleet_start_request: FleetStartRequest
fleet_start_result: FleetStartResult
handle_pending_tool_call_request: HandlePendingToolCallRequest
@@ -7366,13 +7576,11 @@ class RPC:
mcp_server: MCPServer
mcp_server_config: MCPServerConfig
mcp_server_config_http: MCPServerConfigHTTP
+ mcp_server_config_http_auth: MCPServerConfigHTTPAuth
mcp_server_config_http_oauth_grant_type: MCPServerConfigHTTPOauthGrantType
mcp_server_config_http_type: MCPServerConfigHTTPType
- mcp_server_config_local: MCPServerConfigLocal
- mcp_server_config_local_type: MCPServerConfigLocalType
+ mcp_server_config_stdio: MCPServerConfigStdio
mcp_server_list: MCPServerList
- mcp_server_source: MCPServerSource
- mcp_server_status: MCPServerStatus
model: Model
model_billing: ModelBilling
model_billing_token_prices: ModelBillingTokenPrices
@@ -7388,6 +7596,7 @@ class RPC:
model_picker_category: ModelPickerCategory
model_picker_price_category: ModelPickerPriceCategory
model_policy: ModelPolicy
+ model_policy_state: ModelPolicyState
models_list_request: ModelsListRequest
model_switch_to_request: ModelSwitchToRequest
model_switch_to_result: ModelSwitchToResult
@@ -7459,14 +7668,20 @@ class RPC:
session_fs_read_file_result: SessionFSReadFileResult
session_fs_rename_request: SessionFSRenameRequest
session_fs_rm_request: SessionFSRmRequest
+ session_fs_set_provider_capabilities: SessionFSSetProviderCapabilities
session_fs_set_provider_conventions: SessionFSSetProviderConventions
session_fs_set_provider_request: SessionFSSetProviderRequest
session_fs_set_provider_result: SessionFSSetProviderResult
+ session_fs_sqlite_exists_request: SessionFSSqliteExistsRequest
+ session_fs_sqlite_exists_result: SessionFSSqliteExistsResult
+ session_fs_sqlite_query_request: SessionFSSqliteQueryRequest
+ session_fs_sqlite_query_result: SessionFSSqliteQueryResult
+ session_fs_sqlite_query_type: SessionFSSqliteQueryType
session_fs_stat_request: SessionFSStatRequest
session_fs_stat_result: SessionFSStatResult
session_fs_write_file_request: SessionFSWriteFileRequest
session_log_level: SessionLogLevel
- session_mode: Mode
+ session_mode: SessionMode
sessions_fork_request: SessionsForkRequest
sessions_fork_result: SessionsForkResult
shell_exec_request: ShellExecRequest
@@ -7481,7 +7696,6 @@ class RPC:
skills_discover_request: SkillsDiscoverRequest
skills_enable_request: SkillsEnableRequest
skills_load_diagnostics: SkillsLoadDiagnostics
- slash_command_agent_prompt_mode: Mode
slash_command_agent_prompt_result: SlashCommandAgentPromptResult
slash_command_completed_result: SlashCommandCompletedResult
slash_command_info: SlashCommandInfo
@@ -7491,16 +7705,13 @@ class RPC:
slash_command_kind: SlashCommandKind
slash_command_text_result: SlashCommandTextResult
task_agent_info: TaskAgentInfo
- task_agent_info_execution_mode: TaskInfoExecutionMode
- task_agent_info_status: TaskInfoStatus
+ task_execution_mode: TaskExecutionMode
task_info: TaskInfo
task_list: TaskList
tasks_cancel_request: TasksCancelRequest
tasks_cancel_result: TasksCancelResult
task_shell_info: TaskShellInfo
task_shell_info_attachment_mode: TaskShellInfoAttachmentMode
- task_shell_info_execution_mode: TaskInfoExecutionMode
- task_shell_info_status: TaskInfoStatus
tasks_promote_to_background_request: TasksPromoteToBackgroundRequest
tasks_promote_to_background_result: TasksPromoteToBackgroundResult
tasks_remove_request: TasksRemoveRequest
@@ -7509,6 +7720,7 @@ class RPC:
tasks_send_message_result: TasksSendMessageResult
tasks_start_agent_request: TasksStartAgentRequest
tasks_start_agent_result: TasksStartAgentResult
+ task_status: TaskStatus
tool: Tool
tool_list: ToolList
tools_list_request: ToolsListRequest
@@ -7573,9 +7785,9 @@ def from_dict(obj: Any) -> 'RPC':
connect_remote_session_params = ConnectRemoteSessionParams.from_dict(obj.get("ConnectRemoteSessionParams"))
connect_request = ConnectRequest.from_dict(obj.get("ConnectRequest"))
connect_result = ConnectResult.from_dict(obj.get("ConnectResult"))
+ content_filter_mode = ContentFilterMode(obj.get("ContentFilterMode"))
current_model = CurrentModel.from_dict(obj.get("CurrentModel"))
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"))
extension = Extension.from_dict(obj.get("Extension"))
extension_list = ExtensionList.from_dict(obj.get("ExtensionList"))
@@ -7585,6 +7797,8 @@ def from_dict(obj: Any) -> 'RPC':
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_binary_results_for_llm = ExternalToolTextResultForLlmBinaryResultsForLlm.from_dict(obj.get("ExternalToolTextResultForLlmBinaryResultsForLlm"))
+ external_tool_text_result_for_llm_binary_results_for_llm_type = ExternalToolTextResultForLlmBinaryResultsForLlmType(obj.get("ExternalToolTextResultForLlmBinaryResultsForLlmType"))
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"))
@@ -7595,9 +7809,7 @@ def from_dict(obj: Any) -> 'RPC':
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"))
+ filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode], obj.get("FilterMapping"))
fleet_start_request = FleetStartRequest.from_dict(obj.get("FleetStartRequest"))
fleet_start_result = FleetStartResult.from_dict(obj.get("FleetStartResult"))
handle_pending_tool_call_request = HandlePendingToolCallRequest.from_dict(obj.get("HandlePendingToolCallRequest"))
@@ -7627,13 +7839,11 @@ def from_dict(obj: Any) -> 'RPC':
mcp_server = MCPServer.from_dict(obj.get("McpServer"))
mcp_server_config = MCPServerConfig.from_dict(obj.get("McpServerConfig"))
mcp_server_config_http = MCPServerConfigHTTP.from_dict(obj.get("McpServerConfigHttp"))
+ mcp_server_config_http_auth = MCPServerConfigHTTPAuth.from_dict(obj.get("McpServerConfigHttpAuth"))
mcp_server_config_http_oauth_grant_type = MCPServerConfigHTTPOauthGrantType(obj.get("McpServerConfigHttpOauthGrantType"))
mcp_server_config_http_type = MCPServerConfigHTTPType(obj.get("McpServerConfigHttpType"))
- mcp_server_config_local = MCPServerConfigLocal.from_dict(obj.get("McpServerConfigLocal"))
- mcp_server_config_local_type = MCPServerConfigLocalType(obj.get("McpServerConfigLocalType"))
+ mcp_server_config_stdio = MCPServerConfigStdio.from_dict(obj.get("McpServerConfigStdio"))
mcp_server_list = MCPServerList.from_dict(obj.get("McpServerList"))
- mcp_server_source = MCPServerSource(obj.get("McpServerSource"))
- mcp_server_status = MCPServerStatus(obj.get("McpServerStatus"))
model = Model.from_dict(obj.get("Model"))
model_billing = ModelBilling.from_dict(obj.get("ModelBilling"))
model_billing_token_prices = ModelBillingTokenPrices.from_dict(obj.get("ModelBillingTokenPrices"))
@@ -7649,6 +7859,7 @@ def from_dict(obj: Any) -> 'RPC':
model_picker_category = ModelPickerCategory(obj.get("ModelPickerCategory"))
model_picker_price_category = ModelPickerPriceCategory(obj.get("ModelPickerPriceCategory"))
model_policy = ModelPolicy.from_dict(obj.get("ModelPolicy"))
+ model_policy_state = ModelPolicyState(obj.get("ModelPolicyState"))
models_list_request = ModelsListRequest.from_dict(obj.get("ModelsListRequest"))
model_switch_to_request = ModelSwitchToRequest.from_dict(obj.get("ModelSwitchToRequest"))
model_switch_to_result = ModelSwitchToResult.from_dict(obj.get("ModelSwitchToResult"))
@@ -7720,14 +7931,20 @@ def from_dict(obj: Any) -> 'RPC':
session_fs_read_file_result = SessionFSReadFileResult.from_dict(obj.get("SessionFsReadFileResult"))
session_fs_rename_request = SessionFSRenameRequest.from_dict(obj.get("SessionFsRenameRequest"))
session_fs_rm_request = SessionFSRmRequest.from_dict(obj.get("SessionFsRmRequest"))
+ session_fs_set_provider_capabilities = SessionFSSetProviderCapabilities.from_dict(obj.get("SessionFsSetProviderCapabilities"))
session_fs_set_provider_conventions = SessionFSSetProviderConventions(obj.get("SessionFsSetProviderConventions"))
session_fs_set_provider_request = SessionFSSetProviderRequest.from_dict(obj.get("SessionFsSetProviderRequest"))
session_fs_set_provider_result = SessionFSSetProviderResult.from_dict(obj.get("SessionFsSetProviderResult"))
+ session_fs_sqlite_exists_request = SessionFSSqliteExistsRequest.from_dict(obj.get("SessionFsSqliteExistsRequest"))
+ session_fs_sqlite_exists_result = SessionFSSqliteExistsResult.from_dict(obj.get("SessionFsSqliteExistsResult"))
+ session_fs_sqlite_query_request = SessionFSSqliteQueryRequest.from_dict(obj.get("SessionFsSqliteQueryRequest"))
+ session_fs_sqlite_query_result = SessionFSSqliteQueryResult.from_dict(obj.get("SessionFsSqliteQueryResult"))
+ session_fs_sqlite_query_type = SessionFSSqliteQueryType(obj.get("SessionFsSqliteQueryType"))
session_fs_stat_request = SessionFSStatRequest.from_dict(obj.get("SessionFsStatRequest"))
session_fs_stat_result = SessionFSStatResult.from_dict(obj.get("SessionFsStatResult"))
session_fs_write_file_request = SessionFSWriteFileRequest.from_dict(obj.get("SessionFsWriteFileRequest"))
session_log_level = SessionLogLevel(obj.get("SessionLogLevel"))
- session_mode = Mode(obj.get("SessionMode"))
+ session_mode = SessionMode.from_dict(obj.get("SessionMode"))
sessions_fork_request = SessionsForkRequest.from_dict(obj.get("SessionsForkRequest"))
sessions_fork_result = SessionsForkResult.from_dict(obj.get("SessionsForkResult"))
shell_exec_request = ShellExecRequest.from_dict(obj.get("ShellExecRequest"))
@@ -7742,7 +7959,6 @@ def from_dict(obj: Any) -> 'RPC':
skills_discover_request = SkillsDiscoverRequest.from_dict(obj.get("SkillsDiscoverRequest"))
skills_enable_request = SkillsEnableRequest.from_dict(obj.get("SkillsEnableRequest"))
skills_load_diagnostics = SkillsLoadDiagnostics.from_dict(obj.get("SkillsLoadDiagnostics"))
- slash_command_agent_prompt_mode = Mode(obj.get("SlashCommandAgentPromptMode"))
slash_command_agent_prompt_result = SlashCommandAgentPromptResult.from_dict(obj.get("SlashCommandAgentPromptResult"))
slash_command_completed_result = SlashCommandCompletedResult.from_dict(obj.get("SlashCommandCompletedResult"))
slash_command_info = SlashCommandInfo.from_dict(obj.get("SlashCommandInfo"))
@@ -7752,16 +7968,13 @@ def from_dict(obj: Any) -> 'RPC':
slash_command_kind = SlashCommandKind(obj.get("SlashCommandKind"))
slash_command_text_result = SlashCommandTextResult.from_dict(obj.get("SlashCommandTextResult"))
task_agent_info = TaskAgentInfo.from_dict(obj.get("TaskAgentInfo"))
- task_agent_info_execution_mode = TaskInfoExecutionMode(obj.get("TaskAgentInfoExecutionMode"))
- task_agent_info_status = TaskInfoStatus(obj.get("TaskAgentInfoStatus"))
+ task_execution_mode = TaskExecutionMode(obj.get("TaskExecutionMode"))
task_info = TaskInfo.from_dict(obj.get("TaskInfo"))
task_list = TaskList.from_dict(obj.get("TaskList"))
tasks_cancel_request = TasksCancelRequest.from_dict(obj.get("TasksCancelRequest"))
tasks_cancel_result = TasksCancelResult.from_dict(obj.get("TasksCancelResult"))
task_shell_info = TaskShellInfo.from_dict(obj.get("TaskShellInfo"))
task_shell_info_attachment_mode = TaskShellInfoAttachmentMode(obj.get("TaskShellInfoAttachmentMode"))
- task_shell_info_execution_mode = TaskInfoExecutionMode(obj.get("TaskShellInfoExecutionMode"))
- task_shell_info_status = TaskInfoStatus(obj.get("TaskShellInfoStatus"))
tasks_promote_to_background_request = TasksPromoteToBackgroundRequest.from_dict(obj.get("TasksPromoteToBackgroundRequest"))
tasks_promote_to_background_result = TasksPromoteToBackgroundResult.from_dict(obj.get("TasksPromoteToBackgroundResult"))
tasks_remove_request = TasksRemoveRequest.from_dict(obj.get("TasksRemoveRequest"))
@@ -7770,6 +7983,7 @@ def from_dict(obj: Any) -> 'RPC':
tasks_send_message_result = TasksSendMessageResult.from_dict(obj.get("TasksSendMessageResult"))
tasks_start_agent_request = TasksStartAgentRequest.from_dict(obj.get("TasksStartAgentRequest"))
tasks_start_agent_result = TasksStartAgentResult.from_dict(obj.get("TasksStartAgentResult"))
+ task_status = TaskStatus(obj.get("TaskStatus"))
tool = Tool.from_dict(obj.get("Tool"))
tool_list = ToolList.from_dict(obj.get("ToolList"))
tools_list_request = ToolsListRequest.from_dict(obj.get("ToolsListRequest"))
@@ -7807,7 +8021,7 @@ def from_dict(obj: Any) -> 'RPC':
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, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, connected_remote_session_metadata, connected_remote_session_metadata_kind, connected_remote_session_metadata_repository, connect_remote_session_params, connect_request, connect_result, 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, 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_oauth_grant_type, 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_billing_token_prices, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_picker_category, model_picker_price_category, model_policy, 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_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_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, queued_command_handled, queued_command_not_handled, queued_command_result, remote_enable_request, remote_enable_result, remote_session_connection_result, remote_session_mode, 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, skills_load_diagnostics, slash_command_agent_prompt_mode, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_text_result, 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_send_message_request, tasks_send_message_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)
+ 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, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, connected_remote_session_metadata, connected_remote_session_metadata_kind, connected_remote_session_metadata_repository, connect_remote_session_params, connect_request, connect_result, content_filter_mode, current_model, discovered_mcp_server, discovered_mcp_server_type, extension, extension_list, extensions_disable_request, extensions_enable_request, extension_source, extension_status, external_tool_result, external_tool_text_result_for_llm, external_tool_text_result_for_llm_binary_results_for_llm, external_tool_text_result_for_llm_binary_results_for_llm_type, external_tool_text_result_for_llm_content, external_tool_text_result_for_llm_content_audio, external_tool_text_result_for_llm_content_image, external_tool_text_result_for_llm_content_resource, external_tool_text_result_for_llm_content_resource_details, external_tool_text_result_for_llm_content_resource_link, external_tool_text_result_for_llm_content_resource_link_icon, external_tool_text_result_for_llm_content_resource_link_icon_theme, external_tool_text_result_for_llm_content_terminal, external_tool_text_result_for_llm_content_text, filter_mapping, fleet_start_request, fleet_start_result, 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_auth, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_list, model, model_billing, model_billing_token_prices, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_picker_category, model_picker_price_category, model_policy, model_policy_state, 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_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_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, queued_command_handled, queued_command_not_handled, queued_command_result, remote_enable_request, remote_enable_result, remote_session_connection_result, remote_session_mode, 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_capabilities, session_fs_set_provider_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_sqlite_exists_request, session_fs_sqlite_exists_result, session_fs_sqlite_query_request, session_fs_sqlite_query_result, session_fs_sqlite_query_type, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_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, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_text_result, task_agent_info, task_execution_mode, task_info, task_list, tasks_cancel_request, tasks_cancel_result, task_shell_info, task_shell_info_attachment_mode, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, 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 = {}
@@ -7834,9 +8048,9 @@ def to_dict(self) -> dict:
result["ConnectRemoteSessionParams"] = to_class(ConnectRemoteSessionParams, self.connect_remote_session_params)
result["ConnectRequest"] = to_class(ConnectRequest, self.connect_request)
result["ConnectResult"] = to_class(ConnectResult, self.connect_result)
+ result["ContentFilterMode"] = to_enum(ContentFilterMode, self.content_filter_mode)
result["CurrentModel"] = to_class(CurrentModel, self.current_model)
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["Extension"] = to_class(Extension, self.extension)
result["ExtensionList"] = to_class(ExtensionList, self.extension_list)
@@ -7846,6 +8060,8 @@ def to_dict(self) -> dict:
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["ExternalToolTextResultForLlmBinaryResultsForLlm"] = to_class(ExternalToolTextResultForLlmBinaryResultsForLlm, self.external_tool_text_result_for_llm_binary_results_for_llm)
+ result["ExternalToolTextResultForLlmBinaryResultsForLlmType"] = to_enum(ExternalToolTextResultForLlmBinaryResultsForLlmType, self.external_tool_text_result_for_llm_binary_results_for_llm_type)
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)
@@ -7856,9 +8072,7 @@ def to_dict(self) -> dict:
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["FilterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(ContentFilterMode, x), x), lambda x: to_enum(ContentFilterMode, x)], self.filter_mapping)
result["FleetStartRequest"] = to_class(FleetStartRequest, self.fleet_start_request)
result["FleetStartResult"] = to_class(FleetStartResult, self.fleet_start_result)
result["HandlePendingToolCallRequest"] = to_class(HandlePendingToolCallRequest, self.handle_pending_tool_call_request)
@@ -7888,13 +8102,11 @@ def to_dict(self) -> dict:
result["McpServer"] = to_class(MCPServer, self.mcp_server)
result["McpServerConfig"] = to_class(MCPServerConfig, self.mcp_server_config)
result["McpServerConfigHttp"] = to_class(MCPServerConfigHTTP, self.mcp_server_config_http)
+ result["McpServerConfigHttpAuth"] = to_class(MCPServerConfigHTTPAuth, self.mcp_server_config_http_auth)
result["McpServerConfigHttpOauthGrantType"] = to_enum(MCPServerConfigHTTPOauthGrantType, self.mcp_server_config_http_oauth_grant_type)
result["McpServerConfigHttpType"] = to_enum(MCPServerConfigHTTPType, self.mcp_server_config_http_type)
- result["McpServerConfigLocal"] = to_class(MCPServerConfigLocal, self.mcp_server_config_local)
- result["McpServerConfigLocalType"] = to_enum(MCPServerConfigLocalType, self.mcp_server_config_local_type)
+ result["McpServerConfigStdio"] = to_class(MCPServerConfigStdio, self.mcp_server_config_stdio)
result["McpServerList"] = to_class(MCPServerList, self.mcp_server_list)
- result["McpServerSource"] = to_enum(MCPServerSource, self.mcp_server_source)
- result["McpServerStatus"] = to_enum(MCPServerStatus, self.mcp_server_status)
result["Model"] = to_class(Model, self.model)
result["ModelBilling"] = to_class(ModelBilling, self.model_billing)
result["ModelBillingTokenPrices"] = to_class(ModelBillingTokenPrices, self.model_billing_token_prices)
@@ -7910,6 +8122,7 @@ def to_dict(self) -> dict:
result["ModelPickerCategory"] = to_enum(ModelPickerCategory, self.model_picker_category)
result["ModelPickerPriceCategory"] = to_enum(ModelPickerPriceCategory, self.model_picker_price_category)
result["ModelPolicy"] = to_class(ModelPolicy, self.model_policy)
+ result["ModelPolicyState"] = to_enum(ModelPolicyState, self.model_policy_state)
result["ModelsListRequest"] = to_class(ModelsListRequest, self.models_list_request)
result["ModelSwitchToRequest"] = to_class(ModelSwitchToRequest, self.model_switch_to_request)
result["ModelSwitchToResult"] = to_class(ModelSwitchToResult, self.model_switch_to_result)
@@ -7981,14 +8194,20 @@ def to_dict(self) -> dict:
result["SessionFsReadFileResult"] = to_class(SessionFSReadFileResult, self.session_fs_read_file_result)
result["SessionFsRenameRequest"] = to_class(SessionFSRenameRequest, self.session_fs_rename_request)
result["SessionFsRmRequest"] = to_class(SessionFSRmRequest, self.session_fs_rm_request)
+ result["SessionFsSetProviderCapabilities"] = to_class(SessionFSSetProviderCapabilities, self.session_fs_set_provider_capabilities)
result["SessionFsSetProviderConventions"] = to_enum(SessionFSSetProviderConventions, self.session_fs_set_provider_conventions)
result["SessionFsSetProviderRequest"] = to_class(SessionFSSetProviderRequest, self.session_fs_set_provider_request)
result["SessionFsSetProviderResult"] = to_class(SessionFSSetProviderResult, self.session_fs_set_provider_result)
+ result["SessionFsSqliteExistsRequest"] = to_class(SessionFSSqliteExistsRequest, self.session_fs_sqlite_exists_request)
+ result["SessionFsSqliteExistsResult"] = to_class(SessionFSSqliteExistsResult, self.session_fs_sqlite_exists_result)
+ result["SessionFsSqliteQueryRequest"] = to_class(SessionFSSqliteQueryRequest, self.session_fs_sqlite_query_request)
+ result["SessionFsSqliteQueryResult"] = to_class(SessionFSSqliteQueryResult, self.session_fs_sqlite_query_result)
+ result["SessionFsSqliteQueryType"] = to_enum(SessionFSSqliteQueryType, self.session_fs_sqlite_query_type)
result["SessionFsStatRequest"] = to_class(SessionFSStatRequest, self.session_fs_stat_request)
result["SessionFsStatResult"] = to_class(SessionFSStatResult, self.session_fs_stat_result)
result["SessionFsWriteFileRequest"] = to_class(SessionFSWriteFileRequest, self.session_fs_write_file_request)
result["SessionLogLevel"] = to_enum(SessionLogLevel, self.session_log_level)
- result["SessionMode"] = to_enum(Mode, self.session_mode)
+ result["SessionMode"] = to_class(SessionMode, self.session_mode)
result["SessionsForkRequest"] = to_class(SessionsForkRequest, self.sessions_fork_request)
result["SessionsForkResult"] = to_class(SessionsForkResult, self.sessions_fork_result)
result["ShellExecRequest"] = to_class(ShellExecRequest, self.shell_exec_request)
@@ -8003,7 +8222,6 @@ def to_dict(self) -> dict:
result["SkillsDiscoverRequest"] = to_class(SkillsDiscoverRequest, self.skills_discover_request)
result["SkillsEnableRequest"] = to_class(SkillsEnableRequest, self.skills_enable_request)
result["SkillsLoadDiagnostics"] = to_class(SkillsLoadDiagnostics, self.skills_load_diagnostics)
- result["SlashCommandAgentPromptMode"] = to_enum(Mode, self.slash_command_agent_prompt_mode)
result["SlashCommandAgentPromptResult"] = to_class(SlashCommandAgentPromptResult, self.slash_command_agent_prompt_result)
result["SlashCommandCompletedResult"] = to_class(SlashCommandCompletedResult, self.slash_command_completed_result)
result["SlashCommandInfo"] = to_class(SlashCommandInfo, self.slash_command_info)
@@ -8013,16 +8231,13 @@ def to_dict(self) -> dict:
result["SlashCommandKind"] = to_enum(SlashCommandKind, self.slash_command_kind)
result["SlashCommandTextResult"] = to_class(SlashCommandTextResult, self.slash_command_text_result)
result["TaskAgentInfo"] = to_class(TaskAgentInfo, self.task_agent_info)
- result["TaskAgentInfoExecutionMode"] = to_enum(TaskInfoExecutionMode, self.task_agent_info_execution_mode)
- result["TaskAgentInfoStatus"] = to_enum(TaskInfoStatus, self.task_agent_info_status)
+ result["TaskExecutionMode"] = to_enum(TaskExecutionMode, self.task_execution_mode)
result["TaskInfo"] = to_class(TaskInfo, self.task_info)
result["TaskList"] = to_class(TaskList, self.task_list)
result["TasksCancelRequest"] = to_class(TasksCancelRequest, self.tasks_cancel_request)
result["TasksCancelResult"] = to_class(TasksCancelResult, self.tasks_cancel_result)
result["TaskShellInfo"] = to_class(TaskShellInfo, self.task_shell_info)
result["TaskShellInfoAttachmentMode"] = to_enum(TaskShellInfoAttachmentMode, self.task_shell_info_attachment_mode)
- result["TaskShellInfoExecutionMode"] = to_enum(TaskInfoExecutionMode, self.task_shell_info_execution_mode)
- result["TaskShellInfoStatus"] = to_enum(TaskInfoStatus, self.task_shell_info_status)
result["TasksPromoteToBackgroundRequest"] = to_class(TasksPromoteToBackgroundRequest, self.tasks_promote_to_background_request)
result["TasksPromoteToBackgroundResult"] = to_class(TasksPromoteToBackgroundResult, self.tasks_promote_to_background_result)
result["TasksRemoveRequest"] = to_class(TasksRemoveRequest, self.tasks_remove_request)
@@ -8031,6 +8246,7 @@ def to_dict(self) -> dict:
result["TasksSendMessageResult"] = to_class(TasksSendMessageResult, self.tasks_send_message_result)
result["TasksStartAgentRequest"] = to_class(TasksStartAgentRequest, self.tasks_start_agent_request)
result["TasksStartAgentResult"] = to_class(TasksStartAgentResult, self.tasks_start_agent_result)
+ result["TaskStatus"] = to_enum(TaskStatus, self.task_status)
result["Tool"] = to_class(Tool, self.tool)
result["ToolList"] = to_class(ToolList, self.tool_list)
result["ToolsListRequest"] = to_class(ToolsListRequest, self.tools_list_request)
@@ -8077,16 +8293,8 @@ def rpc_to_dict(x: RPC) -> Any:
return to_class(RPC, x)
-DiscoveredMcpServerSource = MCPServerSource
ExternalToolResult = ExternalToolTextResultForLlm
FilterMapping = dict
-FilterMappingValue = FilterMappingString
-SessionMode = Mode
-SlashCommandAgentPromptMode = Mode
-TaskAgentInfoExecutionMode = TaskInfoExecutionMode
-TaskAgentInfoStatus = TaskInfoStatus
-TaskShellInfoExecutionMode = TaskInfoExecutionMode
-TaskShellInfoStatus = TaskInfoStatus
def _timeout_kwargs(timeout: float | None) -> dict:
"""Build keyword arguments for optional timeout forwarding."""
@@ -8298,9 +8506,9 @@ def __init__(self, client: "JsonRpcClient", session_id: str):
self._client = client
self._session_id = session_id
- async def get(self, *, timeout: float | None = None) -> Mode:
- "Gets the current agent interaction mode.\n\nReturns:\n The agent mode. Valid values: \"interactive\", \"plan\", \"autopilot\"."
- return Mode(await self._client.request("session.mode.get", {"sessionId": self._session_id}, **_timeout_kwargs(timeout)))
+ async def get(self, *, timeout: float | None = None) -> SessionMode:
+ "Gets the current agent interaction mode.\n\nReturns:\n The session mode the agent is operating in"
+ return SessionMode(await self._client.request("session.mode.get", {"sessionId": self._session_id}, **_timeout_kwargs(timeout)))
async def set(self, params: ModeSetRequest, *, timeout: float | None = None) -> None:
"Sets the current agent interaction mode.\n\nArgs:\n params: Agent interaction mode to apply to the session."
@@ -8785,6 +8993,12 @@ async def rm(self, params: SessionFSRmRequest) -> SessionFSError | None:
async def rename(self, params: SessionFSRenameRequest) -> SessionFSError | None:
"Renames or moves a path in the client-provided session filesystem.\n\nArgs:\n params: Source and destination paths for renaming or moving an entry in the client-provided session filesystem.\n\nReturns:\n Describes a filesystem error."
pass
+ async def sqlite_query(self, params: SessionFSSqliteQueryRequest) -> SessionFSSqliteQueryResult:
+ "Executes a SQLite query against the per-session database.\n\nArgs:\n params: SQL query, query type, and optional bind parameters for executing a SQLite query against the per-session database.\n\nReturns:\n Query results including rows, columns, and rows affected, or a filesystem error if execution failed."
+ pass
+ async def sqlite_exists(self, params: SessionFSSqliteExistsRequest) -> SessionFSSqliteExistsResult:
+ "Checks whether the per-session SQLite database already exists, without creating it.\n\nArgs:\n params: Identifies the target session.\n\nReturns:\n Indicates whether the per-session SQLite database already exists."
+ pass
@dataclass
class ClientSessionApiHandlers:
@@ -8865,3 +9079,17 @@ async def handle_session_fs_rename(params: dict) -> dict | None:
result = await handler.rename(request)
return result.to_dict() if result is not None else None
client.set_request_handler("sessionFs.rename", handle_session_fs_rename)
+ async def handle_session_fs_sqlite_query(params: dict) -> dict | None:
+ request = SessionFSSqliteQueryRequest.from_dict(params)
+ handler = get_handlers(request.session_id).session_fs
+ if handler is None: raise RuntimeError(f"No session_fs handler registered for session: {request.session_id}")
+ result = await handler.sqlite_query(request)
+ return result.to_dict()
+ client.set_request_handler("sessionFs.sqliteQuery", handle_session_fs_sqlite_query)
+ async def handle_session_fs_sqlite_exists(params: dict) -> dict | None:
+ request = SessionFSSqliteExistsRequest.from_dict(params)
+ handler = get_handlers(request.session_id).session_fs
+ if handler is None: raise RuntimeError(f"No session_fs handler registered for session: {request.session_id}")
+ result = await handler.sqlite_exists(request)
+ return result.to_dict()
+ client.set_request_handler("sessionFs.sqliteExists", handle_session_fs_sqlite_exists)
diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py
index 696d5a0e5..a540dda0a 100644
--- a/python/copilot/generated/session_events.py
+++ b/python/copilot/generated/session_events.py
@@ -7,7 +7,7 @@
from collections.abc import Callable
from dataclasses import dataclass
-from datetime import datetime
+from datetime import datetime, timedelta
from enum import Enum
from typing import Any, TypeVar, cast
from uuid import UUID
@@ -43,6 +43,23 @@ def to_float(x: Any) -> float:
return float(x)
+def from_timedelta(x: Any) -> timedelta:
+ assert isinstance(x, (float, int)) and not isinstance(x, bool)
+ return timedelta(milliseconds=float(x))
+
+
+def to_timedelta_int(x: timedelta) -> int:
+ assert isinstance(x, timedelta)
+ milliseconds = x.total_seconds() * 1000.0
+ assert milliseconds.is_integer()
+ return int(milliseconds)
+
+
+def to_timedelta(x: timedelta) -> float:
+ assert isinstance(x, timedelta)
+ return x.total_seconds() * 1000.0
+
+
def from_bool(x: Any) -> bool:
assert isinstance(x, bool)
return x
@@ -228,6 +245,8 @@ def _compat_to_json_value(value: Any) -> Any:
return value.value
if isinstance(value, datetime):
return value.isoformat()
+ if isinstance(value, timedelta):
+ return value.total_seconds() * 1000.0
if isinstance(value, UUID):
return str(value)
if isinstance(value, list):
@@ -663,10 +682,10 @@ class AssistantUsageData:
cache_write_tokens: float | None = None
copilot_usage: AssistantUsageCopilotUsage | None = None
cost: float | None = None
- duration: float | None = None
+ duration: timedelta | None = None
initiator: str | None = None
input_tokens: float | None = None
- inter_token_latency_ms: float | None = None
+ inter_token_latency_ms: timedelta | None = None
output_tokens: float | None = None
# Deprecated: this field is deprecated.
parent_tool_call_id: str | None = None
@@ -674,7 +693,7 @@ class AssistantUsageData:
quota_snapshots: dict[str, AssistantUsageQuotaSnapshot] | None = None
reasoning_effort: str | None = None
reasoning_tokens: float | None = None
- ttft_ms: float | None = None
+ ttft_ms: timedelta | None = None
@staticmethod
def from_dict(obj: Any) -> "AssistantUsageData":
@@ -686,17 +705,17 @@ def from_dict(obj: Any) -> "AssistantUsageData":
cache_write_tokens = from_union([from_none, from_float], obj.get("cacheWriteTokens"))
copilot_usage = from_union([from_none, AssistantUsageCopilotUsage.from_dict], obj.get("copilotUsage"))
cost = from_union([from_none, from_float], obj.get("cost"))
- duration = from_union([from_none, from_float], obj.get("duration"))
+ duration = from_union([from_none, from_timedelta], obj.get("duration"))
initiator = from_union([from_none, from_str], obj.get("initiator"))
input_tokens = from_union([from_none, from_float], obj.get("inputTokens"))
- inter_token_latency_ms = from_union([from_none, from_float], obj.get("interTokenLatencyMs"))
+ inter_token_latency_ms = from_union([from_none, from_timedelta], obj.get("interTokenLatencyMs"))
output_tokens = from_union([from_none, from_float], obj.get("outputTokens"))
parent_tool_call_id = from_union([from_none, from_str], obj.get("parentToolCallId"))
provider_call_id = from_union([from_none, from_str], obj.get("providerCallId"))
quota_snapshots = from_union([from_none, lambda x: from_dict(AssistantUsageQuotaSnapshot.from_dict, x)], obj.get("quotaSnapshots"))
reasoning_effort = from_union([from_none, from_str], obj.get("reasoningEffort"))
reasoning_tokens = from_union([from_none, from_float], obj.get("reasoningTokens"))
- ttft_ms = from_union([from_none, from_float], obj.get("ttftMs"))
+ ttft_ms = from_union([from_none, from_timedelta], obj.get("ttftMs"))
return AssistantUsageData(
model=model,
api_call_id=api_call_id,
@@ -734,13 +753,13 @@ def to_dict(self) -> dict:
if self.cost is not None:
result["cost"] = from_union([from_none, to_float], self.cost)
if self.duration is not None:
- result["duration"] = from_union([from_none, to_float], self.duration)
+ result["duration"] = from_union([from_none, to_timedelta], self.duration)
if self.initiator is not None:
result["initiator"] = from_union([from_none, from_str], self.initiator)
if self.input_tokens is not None:
result["inputTokens"] = from_union([from_none, to_float], self.input_tokens)
if self.inter_token_latency_ms is not None:
- result["interTokenLatencyMs"] = from_union([from_none, to_float], self.inter_token_latency_ms)
+ result["interTokenLatencyMs"] = from_union([from_none, to_timedelta], self.inter_token_latency_ms)
if self.output_tokens is not None:
result["outputTokens"] = from_union([from_none, to_float], self.output_tokens)
if self.parent_tool_call_id is not None:
@@ -754,7 +773,7 @@ def to_dict(self) -> dict:
if self.reasoning_tokens is not None:
result["reasoningTokens"] = from_union([from_none, to_float], self.reasoning_tokens)
if self.ttft_ms is not None:
- result["ttftMs"] = from_union([from_none, to_float], self.ttft_ms)
+ result["ttftMs"] = from_union([from_none, to_timedelta], self.ttft_ms)
return result
@@ -810,13 +829,13 @@ def to_dict(self) -> dict:
class AutoModeSwitchCompletedData:
"Auto mode switch completion notification"
request_id: str
- response: str
+ response: AutoModeSwitchResponse
@staticmethod
def from_dict(obj: Any) -> "AutoModeSwitchCompletedData":
assert isinstance(obj, dict)
request_id = from_str(obj.get("requestId"))
- response = from_str(obj.get("response"))
+ response = parse_enum(AutoModeSwitchResponse, obj.get("response"))
return AutoModeSwitchCompletedData(
request_id=request_id,
response=response,
@@ -825,7 +844,7 @@ def from_dict(obj: Any) -> "AutoModeSwitchCompletedData":
def to_dict(self) -> dict:
result: dict = {}
result["requestId"] = from_str(self.request_id)
- result["response"] = from_str(self.response)
+ result["response"] = to_enum(AutoModeSwitchResponse, self.response)
return result
@@ -1020,7 +1039,7 @@ class CompactionCompleteCompactionTokensUsed:
cache_read_tokens: float | None = None
cache_write_tokens: float | None = None
copilot_usage: CompactionCompleteCompactionTokensUsedCopilotUsage | None = None
- duration: float | None = None
+ duration: timedelta | None = None
input_tokens: float | None = None
model: str | None = None
output_tokens: float | None = None
@@ -1031,7 +1050,7 @@ def from_dict(obj: Any) -> "CompactionCompleteCompactionTokensUsed":
cache_read_tokens = from_union([from_none, from_float], obj.get("cacheReadTokens"))
cache_write_tokens = from_union([from_none, from_float], obj.get("cacheWriteTokens"))
copilot_usage = from_union([from_none, CompactionCompleteCompactionTokensUsedCopilotUsage.from_dict], obj.get("copilotUsage"))
- duration = from_union([from_none, from_float], obj.get("duration"))
+ duration = from_union([from_none, from_timedelta], obj.get("duration"))
input_tokens = from_union([from_none, from_float], obj.get("inputTokens"))
model = from_union([from_none, from_str], obj.get("model"))
output_tokens = from_union([from_none, from_float], obj.get("outputTokens"))
@@ -1054,7 +1073,7 @@ def to_dict(self) -> dict:
if self.copilot_usage is not None:
result["copilotUsage"] = from_union([from_none, lambda x: to_class(CompactionCompleteCompactionTokensUsedCopilotUsage, x)], self.copilot_usage)
if self.duration is not None:
- result["duration"] = from_union([from_none, to_float], self.duration)
+ result["duration"] = from_union([from_none, to_timedelta], self.duration)
if self.input_tokens is not None:
result["inputTokens"] = from_union([from_none, to_float], self.input_tokens)
if self.model is not None:
@@ -1334,7 +1353,7 @@ class ExitPlanModeCompletedData:
approved: bool | None = None
auto_approve_edits: bool | None = None
feedback: str | None = None
- selected_action: str | None = None
+ selected_action: ExitPlanModeAction | None = None
@staticmethod
def from_dict(obj: Any) -> "ExitPlanModeCompletedData":
@@ -1343,7 +1362,7 @@ def from_dict(obj: Any) -> "ExitPlanModeCompletedData":
approved = from_union([from_none, from_bool], obj.get("approved"))
auto_approve_edits = from_union([from_none, from_bool], obj.get("autoApproveEdits"))
feedback = from_union([from_none, from_str], obj.get("feedback"))
- selected_action = from_union([from_none, from_str], obj.get("selectedAction"))
+ selected_action = from_union([from_none, lambda x: parse_enum(ExitPlanModeAction, x)], obj.get("selectedAction"))
return ExitPlanModeCompletedData(
request_id=request_id,
approved=approved,
@@ -1362,25 +1381,25 @@ def to_dict(self) -> dict:
if self.feedback is not None:
result["feedback"] = from_union([from_none, from_str], self.feedback)
if self.selected_action is not None:
- result["selectedAction"] = from_union([from_none, from_str], self.selected_action)
+ result["selectedAction"] = from_union([from_none, lambda x: to_enum(ExitPlanModeAction, x)], self.selected_action)
return result
@dataclass
class ExitPlanModeRequestedData:
"Plan approval request with plan content and available user actions"
- actions: list[str]
+ actions: list[ExitPlanModeAction]
plan_content: str
- recommended_action: str
+ recommended_action: ExitPlanModeAction
request_id: str
summary: str
@staticmethod
def from_dict(obj: Any) -> "ExitPlanModeRequestedData":
assert isinstance(obj, dict)
- actions = from_list(from_str, obj.get("actions"))
+ actions = from_list(lambda x: parse_enum(ExitPlanModeAction, x), obj.get("actions"))
plan_content = from_str(obj.get("planContent"))
- recommended_action = from_str(obj.get("recommendedAction"))
+ recommended_action = parse_enum(ExitPlanModeAction, obj.get("recommendedAction"))
request_id = from_str(obj.get("requestId"))
summary = from_str(obj.get("summary"))
return ExitPlanModeRequestedData(
@@ -1393,9 +1412,9 @@ def from_dict(obj: Any) -> "ExitPlanModeRequestedData":
def to_dict(self) -> dict:
result: dict = {}
- result["actions"] = from_list(from_str, self.actions)
+ result["actions"] = from_list(lambda x: to_enum(ExitPlanModeAction, x), self.actions)
result["planContent"] = from_str(self.plan_content)
- result["recommendedAction"] = from_str(self.recommended_action)
+ result["recommendedAction"] = to_enum(ExitPlanModeAction, self.recommended_action)
result["requestId"] = from_str(self.request_id)
result["summary"] = from_str(self.summary)
return result
@@ -1698,17 +1717,17 @@ def to_dict(self) -> dict:
class McpServersLoadedServer:
"Schema for the `McpServersLoadedServer` type."
name: str
- status: McpServersLoadedServerStatus
+ status: McpServerStatus
error: str | None = None
- source: str | None = None
+ source: McpServerSource | None = None
@staticmethod
def from_dict(obj: Any) -> "McpServersLoadedServer":
assert isinstance(obj, dict)
name = from_str(obj.get("name"))
- status = parse_enum(McpServersLoadedServerStatus, obj.get("status"))
+ status = parse_enum(McpServerStatus, obj.get("status"))
error = from_union([from_none, from_str], obj.get("error"))
- source = from_union([from_none, from_str], obj.get("source"))
+ source = from_union([from_none, lambda x: parse_enum(McpServerSource, x)], obj.get("source"))
return McpServersLoadedServer(
name=name,
status=status,
@@ -1719,11 +1738,11 @@ def from_dict(obj: Any) -> "McpServersLoadedServer":
def to_dict(self) -> dict:
result: dict = {}
result["name"] = from_str(self.name)
- result["status"] = to_enum(McpServersLoadedServerStatus, self.status)
+ result["status"] = to_enum(McpServerStatus, self.status)
if self.error is not None:
result["error"] = from_union([from_none, from_str], self.error)
if self.source is not None:
- result["source"] = from_union([from_none, from_str], self.source)
+ result["source"] = from_union([from_none, lambda x: to_enum(McpServerSource, x)], self.source)
return result
@@ -1732,7 +1751,7 @@ class ModelCallFailureData:
"Failed LLM API call metadata for telemetry"
source: ModelCallFailureSource
api_call_id: str | None = None
- duration_ms: float | None = None
+ duration_ms: timedelta | None = None
error_message: str | None = None
initiator: str | None = None
model: str | None = None
@@ -1744,7 +1763,7 @@ def from_dict(obj: Any) -> "ModelCallFailureData":
assert isinstance(obj, dict)
source = parse_enum(ModelCallFailureSource, obj.get("source"))
api_call_id = from_union([from_none, from_str], obj.get("apiCallId"))
- duration_ms = from_union([from_none, from_float], obj.get("durationMs"))
+ duration_ms = from_union([from_none, from_timedelta], obj.get("durationMs"))
error_message = from_union([from_none, from_str], obj.get("errorMessage"))
initiator = from_union([from_none, from_str], obj.get("initiator"))
model = from_union([from_none, from_str], obj.get("model"))
@@ -1767,7 +1786,7 @@ def to_dict(self) -> dict:
if self.api_call_id is not None:
result["apiCallId"] = from_union([from_none, from_str], self.api_call_id)
if self.duration_ms is not None:
- result["durationMs"] = from_union([from_none, to_float], self.duration_ms)
+ result["durationMs"] = from_union([from_none, to_timedelta], self.duration_ms)
if self.error_message is not None:
result["errorMessage"] = from_union([from_none, from_str], self.error_message)
if self.initiator is not None:
@@ -1826,14 +1845,14 @@ class PermissionPromptRequest:
"Derived user-facing permission prompt details for UI consumers"
kind: PermissionPromptRequestKind
access_kind: PermissionPromptRequestPathAccessKind | None = None
- action: PermissionPromptRequestMemoryAction | None = None
+ action: PermissionRequestMemoryAction | None = None
args: Any | None = None
can_offer_session_approval: bool | None = None
capabilities: list[str] | None = None
citations: str | None = None
command_identifiers: list[str] | None = None
diff: str | None = None
- direction: PermissionPromptRequestMemoryDirection | None = None
+ direction: PermissionRequestMemoryDirection | None = None
extension_name: str | None = None
fact: str | None = None
file_name: str | None = None
@@ -1860,14 +1879,14 @@ def from_dict(obj: Any) -> "PermissionPromptRequest":
assert isinstance(obj, dict)
kind = parse_enum(PermissionPromptRequestKind, obj.get("kind"))
access_kind = from_union([from_none, lambda x: parse_enum(PermissionPromptRequestPathAccessKind, x)], obj.get("accessKind"))
- action = from_union([from_none, lambda x: parse_enum(PermissionPromptRequestMemoryAction, x)], obj.get("action", "store"))
+ action = from_union([from_none, lambda x: parse_enum(PermissionRequestMemoryAction, x)], obj.get("action", "store"))
args = from_union([from_none, lambda x: x], obj.get("args"))
can_offer_session_approval = from_union([from_none, from_bool], obj.get("canOfferSessionApproval"))
capabilities = from_union([from_none, lambda x: from_list(from_str, x)], obj.get("capabilities"))
citations = from_union([from_none, from_str], obj.get("citations"))
command_identifiers = from_union([from_none, lambda x: from_list(from_str, x)], obj.get("commandIdentifiers"))
diff = from_union([from_none, from_str], obj.get("diff"))
- direction = from_union([from_none, lambda x: parse_enum(PermissionPromptRequestMemoryDirection, x)], obj.get("direction"))
+ direction = from_union([from_none, lambda x: parse_enum(PermissionRequestMemoryDirection, x)], obj.get("direction"))
extension_name = from_union([from_none, from_str], obj.get("extensionName"))
fact = from_union([from_none, from_str], obj.get("fact"))
file_name = from_union([from_none, from_str], obj.get("fileName"))
@@ -1927,7 +1946,7 @@ def to_dict(self) -> dict:
if self.access_kind is not None:
result["accessKind"] = from_union([from_none, lambda x: to_enum(PermissionPromptRequestPathAccessKind, x)], self.access_kind)
if self.action is not None:
- result["action"] = from_union([from_none, lambda x: to_enum(PermissionPromptRequestMemoryAction, x)], self.action)
+ result["action"] = from_union([from_none, lambda x: to_enum(PermissionRequestMemoryAction, x)], self.action)
if self.args is not None:
result["args"] = from_union([from_none, lambda x: x], self.args)
if self.can_offer_session_approval is not None:
@@ -1941,7 +1960,7 @@ def to_dict(self) -> dict:
if self.diff is not None:
result["diff"] = from_union([from_none, from_str], self.diff)
if self.direction is not None:
- result["direction"] = from_union([from_none, lambda x: to_enum(PermissionPromptRequestMemoryDirection, x)], self.direction)
+ result["direction"] = from_union([from_none, lambda x: to_enum(PermissionRequestMemoryDirection, x)], self.direction)
if self.extension_name is not None:
result["extensionName"] = from_union([from_none, from_str], self.extension_name)
if self.fact is not None:
@@ -2793,13 +2812,13 @@ def to_dict(self) -> dict:
class SessionMcpServerStatusChangedData:
"Schema for the `McpServerStatusChangedData` type."
server_name: str
- status: McpServerStatusChangedStatus
+ status: McpServerStatus
@staticmethod
def from_dict(obj: Any) -> "SessionMcpServerStatusChangedData":
assert isinstance(obj, dict)
server_name = from_str(obj.get("serverName"))
- status = parse_enum(McpServerStatusChangedStatus, obj.get("status"))
+ status = parse_enum(McpServerStatus, obj.get("status"))
return SessionMcpServerStatusChangedData(
server_name=server_name,
status=status,
@@ -2808,7 +2827,7 @@ def from_dict(obj: Any) -> "SessionMcpServerStatusChangedData":
def to_dict(self) -> dict:
result: dict = {}
result["serverName"] = from_str(self.server_name)
- result["status"] = to_enum(McpServerStatusChangedStatus, self.status)
+ result["status"] = to_enum(McpServerStatus, self.status)
return result
@@ -2834,14 +2853,14 @@ def to_dict(self) -> dict:
@dataclass
class SessionModeChangedData:
"Agent mode change details including previous and new modes"
- new_mode: str
- previous_mode: str
+ new_mode: SessionMode
+ previous_mode: SessionMode
@staticmethod
def from_dict(obj: Any) -> "SessionModeChangedData":
assert isinstance(obj, dict)
- new_mode = from_str(obj.get("newMode"))
- previous_mode = from_str(obj.get("previousMode"))
+ new_mode = parse_enum(SessionMode, obj.get("newMode"))
+ previous_mode = parse_enum(SessionMode, obj.get("previousMode"))
return SessionModeChangedData(
new_mode=new_mode,
previous_mode=previous_mode,
@@ -2849,8 +2868,8 @@ def from_dict(obj: Any) -> "SessionModeChangedData":
def to_dict(self) -> dict:
result: dict = {}
- result["newMode"] = from_str(self.new_mode)
- result["previousMode"] = from_str(self.previous_mode)
+ result["newMode"] = to_enum(SessionMode, self.new_mode)
+ result["previousMode"] = to_enum(SessionMode, self.previous_mode)
return result
@@ -3027,7 +3046,7 @@ def to_dict(self) -> dict:
class SessionScheduleCreatedData:
"Scheduled prompt registered via /every or /after"
id: int
- interval_ms: int
+ interval_ms: timedelta
prompt: str
display_prompt: str | None = None
recurring: bool | None = None
@@ -3036,7 +3055,7 @@ class SessionScheduleCreatedData:
def from_dict(obj: Any) -> "SessionScheduleCreatedData":
assert isinstance(obj, dict)
id = from_int(obj.get("id"))
- interval_ms = from_int(obj.get("intervalMs"))
+ interval_ms = from_timedelta(obj.get("intervalMs"))
prompt = from_str(obj.get("prompt"))
display_prompt = from_union([from_none, from_str], obj.get("displayPrompt"))
recurring = from_union([from_none, from_bool], obj.get("recurring"))
@@ -3051,7 +3070,7 @@ def from_dict(obj: Any) -> "SessionScheduleCreatedData":
def to_dict(self) -> dict:
result: dict = {}
result["id"] = to_int(self.id)
- result["intervalMs"] = to_int(self.interval_ms)
+ result["intervalMs"] = to_timedelta_int(self.interval_ms)
result["prompt"] = from_str(self.prompt)
if self.display_prompt is not None:
result["displayPrompt"] = from_union([from_none, from_str], self.display_prompt)
@@ -3067,7 +3086,7 @@ class SessionShutdownData:
model_metrics: dict[str, ShutdownModelMetric]
session_start_time: float
shutdown_type: ShutdownType
- total_api_duration_ms: float
+ total_api_duration_ms: timedelta
total_premium_requests: float
conversation_tokens: float | None = None
current_model: str | None = None
@@ -3085,7 +3104,7 @@ def from_dict(obj: Any) -> "SessionShutdownData":
model_metrics = from_dict(ShutdownModelMetric.from_dict, obj.get("modelMetrics"))
session_start_time = from_float(obj.get("sessionStartTime"))
shutdown_type = parse_enum(ShutdownType, obj.get("shutdownType"))
- total_api_duration_ms = from_float(obj.get("totalApiDurationMs"))
+ total_api_duration_ms = from_timedelta(obj.get("totalApiDurationMs"))
total_premium_requests = from_float(obj.get("totalPremiumRequests"))
conversation_tokens = from_union([from_none, from_float], obj.get("conversationTokens"))
current_model = from_union([from_none, from_str], obj.get("currentModel"))
@@ -3118,7 +3137,7 @@ def to_dict(self) -> dict:
result["modelMetrics"] = from_dict(lambda x: to_class(ShutdownModelMetric, x), self.model_metrics)
result["sessionStartTime"] = to_float(self.session_start_time)
result["shutdownType"] = to_enum(ShutdownType, self.shutdown_type)
- result["totalApiDurationMs"] = to_float(self.total_api_duration_ms)
+ result["totalApiDurationMs"] = to_timedelta(self.total_api_duration_ms)
result["totalPremiumRequests"] = to_float(self.total_premium_requests)
if self.conversation_tokens is not None:
result["conversationTokens"] = from_union([from_none, to_float], self.conversation_tokens)
@@ -3669,7 +3688,7 @@ class SkillsLoadedSkill:
description: str
enabled: bool
name: str
- source: str
+ source: SkillSource
user_invocable: bool
path: str | None = None
@@ -3679,7 +3698,7 @@ def from_dict(obj: Any) -> "SkillsLoadedSkill":
description = from_str(obj.get("description"))
enabled = from_bool(obj.get("enabled"))
name = from_str(obj.get("name"))
- source = from_str(obj.get("source"))
+ source = parse_enum(SkillSource, obj.get("source"))
user_invocable = from_bool(obj.get("userInvocable"))
path = from_union([from_none, from_str], obj.get("path"))
return SkillsLoadedSkill(
@@ -3696,7 +3715,7 @@ def to_dict(self) -> dict:
result["description"] = from_str(self.description)
result["enabled"] = from_bool(self.enabled)
result["name"] = from_str(self.name)
- result["source"] = from_str(self.source)
+ result["source"] = to_enum(SkillSource, self.source)
result["userInvocable"] = from_bool(self.user_invocable)
if self.path is not None:
result["path"] = from_union([from_none, from_str], self.path)
@@ -3709,7 +3728,7 @@ class SubagentCompletedData:
agent_display_name: str
agent_name: str
tool_call_id: str
- duration_ms: float | None = None
+ duration_ms: timedelta | None = None
model: str | None = None
total_tokens: float | None = None
total_tool_calls: float | None = None
@@ -3720,7 +3739,7 @@ def from_dict(obj: Any) -> "SubagentCompletedData":
agent_display_name = from_str(obj.get("agentDisplayName"))
agent_name = from_str(obj.get("agentName"))
tool_call_id = from_str(obj.get("toolCallId"))
- duration_ms = from_union([from_none, from_float], obj.get("durationMs"))
+ duration_ms = from_union([from_none, from_timedelta], obj.get("durationMs"))
model = from_union([from_none, from_str], obj.get("model"))
total_tokens = from_union([from_none, from_float], obj.get("totalTokens"))
total_tool_calls = from_union([from_none, from_float], obj.get("totalToolCalls"))
@@ -3740,7 +3759,7 @@ def to_dict(self) -> dict:
result["agentName"] = from_str(self.agent_name)
result["toolCallId"] = from_str(self.tool_call_id)
if self.duration_ms is not None:
- result["durationMs"] = from_union([from_none, to_float], self.duration_ms)
+ result["durationMs"] = from_union([from_none, to_timedelta], self.duration_ms)
if self.model is not None:
result["model"] = from_union([from_none, from_str], self.model)
if self.total_tokens is not None:
@@ -3769,7 +3788,7 @@ class SubagentFailedData:
agent_name: str
error: str
tool_call_id: str
- duration_ms: float | None = None
+ duration_ms: timedelta | None = None
model: str | None = None
total_tokens: float | None = None
total_tool_calls: float | None = None
@@ -3781,7 +3800,7 @@ def from_dict(obj: Any) -> "SubagentFailedData":
agent_name = from_str(obj.get("agentName"))
error = from_str(obj.get("error"))
tool_call_id = from_str(obj.get("toolCallId"))
- duration_ms = from_union([from_none, from_float], obj.get("durationMs"))
+ duration_ms = from_union([from_none, from_timedelta], obj.get("durationMs"))
model = from_union([from_none, from_str], obj.get("model"))
total_tokens = from_union([from_none, from_float], obj.get("totalTokens"))
total_tool_calls = from_union([from_none, from_float], obj.get("totalToolCalls"))
@@ -3803,7 +3822,7 @@ def to_dict(self) -> dict:
result["error"] = from_str(self.error)
result["toolCallId"] = from_str(self.tool_call_id)
if self.duration_ms is not None:
- result["durationMs"] = from_union([from_none, to_float], self.duration_ms)
+ result["durationMs"] = from_union([from_none, to_timedelta], self.duration_ms)
if self.model is not None:
result["model"] = from_union([from_none, from_str], self.model)
if self.total_tokens is not None:
@@ -4829,6 +4848,13 @@ class AssistantUsageApiEndpoint(Enum):
WS_RESPONSES = "ws:/responses"
+class AutoModeSwitchResponse(Enum):
+ "The user's auto-mode-switch choice"
+ YES = "yes"
+ YES_ALWAYS = "yes_always"
+ NO = "no"
+
+
class ElicitationCompletedAction(Enum):
"The user action: \"accept\" (submitted form), \"decline\" (explicitly refused), or \"cancel\" (dismissed)"
ACCEPT = "accept"
@@ -4842,6 +4868,14 @@ class ElicitationRequestedMode(Enum):
URL = "url"
+class ExitPlanModeAction(Enum):
+ "Exit plan mode action"
+ EXIT_ONLY = "exit_only"
+ INTERACTIVE = "interactive"
+ AUTOPILOT = "autopilot"
+ AUTOPILOT_FLEET = "autopilot_fleet"
+
+
class ExtensionsLoadedExtensionSource(Enum):
"Discovery source"
PROJECT = "project"
@@ -4862,17 +4896,15 @@ class HandoffSourceType(Enum):
LOCAL = "local"
-class McpServerStatusChangedStatus(Enum):
- "New connection status: connected, failed, needs-auth, pending, disabled, or not_configured"
- CONNECTED = "connected"
- FAILED = "failed"
- NEEDS_AUTH = "needs-auth"
- PENDING = "pending"
- DISABLED = "disabled"
- NOT_CONFIGURED = "not_configured"
+class McpServerSource(Enum):
+ "Configuration source: user, workspace, plugin, or builtin"
+ USER = "user"
+ WORKSPACE = "workspace"
+ PLUGIN = "plugin"
+ BUILTIN = "builtin"
-class McpServersLoadedServerStatus(Enum):
+class McpServerStatus(Enum):
"Connection status: connected, failed, needs-auth, pending, disabled, or not_configured"
CONNECTED = "connected"
FAILED = "failed"
@@ -4904,18 +4936,6 @@ class PermissionPromptRequestKind(Enum):
EXTENSION_PERMISSION_ACCESS = "extension-permission-access"
-class PermissionPromptRequestMemoryAction(Enum):
- "Whether this is a store or vote memory operation"
- STORE = "store"
- VOTE = "vote"
-
-
-class PermissionPromptRequestMemoryDirection(Enum):
- "Vote direction (vote only)"
- UPVOTE = "upvote"
- DOWNVOTE = "downvote"
-
-
class PermissionPromptRequestPathAccessKind(Enum):
"Underlying permission kind that needs path approval"
READ = "read"
@@ -4976,12 +4996,30 @@ class ReasoningSummary(Enum):
DETAILED = "detailed"
+class SessionMode(Enum):
+ "The session mode the agent is operating in"
+ INTERACTIVE = "interactive"
+ PLAN = "plan"
+ AUTOPILOT = "autopilot"
+
+
class ShutdownType(Enum):
"Whether the session ended normally (\"routine\") or due to a crash/fatal error (\"error\")"
ROUTINE = "routine"
ERROR = "error"
+class SkillSource(Enum):
+ "Source location type (e.g., project, personal-copilot, plugin, builtin)"
+ PROJECT = "project"
+ INHERITED = "inherited"
+ PERSONAL_COPILOT = "personal-copilot"
+ PERSONAL_AGENTS = "personal-agents"
+ PLUGIN = "plugin"
+ CUSTOM = "custom"
+ BUILTIN = "builtin"
+
+
class SystemMessageRole(Enum):
"Message role: \"system\" for system prompts, \"developer\" for developer-injected instructions"
SYSTEM = "system"
diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs
index 936d90758..b3857191f 100644
--- a/rust/src/generated/api_types.rs
+++ b/rust/src/generated/api_types.rs
@@ -6,7 +6,9 @@ use std::collections::HashMap;
use serde::{Deserialize, Serialize};
-use super::session_events::ReasoningSummary;
+use super::session_events::{
+ McpServerSource, McpServerStatus, ReasoningSummary, SessionMode, SkillSource,
+};
use crate::types::{RequestId, SessionId};
/// JSON-RPC method name constants.
@@ -188,6 +190,10 @@ pub mod rpc_methods {
pub const SESSIONFS_RM: &str = "sessionFs.rm";
/// `sessionFs.rename`
pub const SESSIONFS_RENAME: &str = "sessionFs.rename";
+ /// `sessionFs.sqliteQuery`
+ pub const SESSIONFS_SQLITEQUERY: &str = "sessionFs.sqliteQuery";
+ /// `sessionFs.sqliteExists`
+ pub const SESSIONFS_SQLITEEXISTS: &str = "sessionFs.sqliteExists";
}
/// Optional GitHub token used to look up quota for a specific user instead of the global auth context.
@@ -203,7 +209,7 @@ pub struct AccountGetQuotaRequest {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AccountQuotaSnapshot {
- /// Number of requests included in the entitlement
+ /// Number of requests included in the entitlement, or -1 for unlimited entitlements
pub entitlement_requests: i64,
/// Whether the user has an unlimited usage entitlement
pub is_unlimited_entitlement: bool,
@@ -488,9 +494,9 @@ pub struct DiscoveredMcpServer {
pub enabled: bool,
/// Server name (config key)
pub name: String,
- /// Configuration source
- pub source: DiscoveredMcpServerSource,
- /// Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)
+ /// Configuration source: user, workspace, plugin, or builtin
+ pub source: McpServerSource,
+ /// Server transport type: stdio, http, sse, or memory
#[serde(skip_serializing_if = "Option::is_none")]
pub r#type: Option,
}
@@ -536,10 +542,28 @@ pub struct ExtensionsEnableRequest {
pub id: String,
}
+/// Binary result returned by a tool for the model
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ExternalToolTextResultForLlmBinaryResultsForLlm {
+ /// Base64-encoded binary data
+ pub data: String,
+ /// Human-readable description of the binary data
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub description: Option,
+ /// MIME type of the binary data
+ pub mime_type: String,
+ /// Binary result type discriminator. Use "image" for images and "resource" for other binary data.
+ pub r#type: ExternalToolTextResultForLlmBinaryResultsForLlmType,
+}
+
/// Expanded external tool result payload
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalToolTextResultForLlm {
+ /// Base64-encoded binary results returned to the model
+ #[serde(default)]
+ pub binary_results_for_llm: Vec,
/// Structured content blocks from the tool
#[serde(default)]
pub contents: Vec,
@@ -815,7 +839,7 @@ pub struct LogResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpConfigAddRequest {
- /// MCP server configuration (local/stdio or remote/http)
+ /// MCP server configuration (stdio process or remote HTTP/SSE)
pub config: serde_json::Value,
/// Unique name for the MCP server
pub name: String,
@@ -857,7 +881,7 @@ pub struct McpConfigRemoveRequest {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpConfigUpdateRequest {
- /// MCP server configuration (local/stdio or remote/http)
+ /// MCP server configuration (stdio process or remote HTTP/SSE)
pub config: serde_json::Value,
/// Name of the MCP server to update
pub name: String,
@@ -938,10 +962,22 @@ pub struct McpServer {
pub status: McpServerStatus,
}
+/// Additional authentication configuration for this server.
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct McpServerConfigHttpAuth {
+ /// Fixed port for the OAuth redirect callback server.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub redirect_port: Option,
+}
+
/// Remote MCP server configuration accessed over HTTP or SSE.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct McpServerConfigHttp {
+ /// Additional authentication configuration for this server.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub auth: Option,
/// Content filtering mode to apply to all tools, or a map of tool name to content filtering mode.
#[serde(skip_serializing_if = "Option::is_none")]
pub filter_mapping: Option,
@@ -973,18 +1009,19 @@ pub struct McpServerConfigHttp {
pub url: String,
}
-/// Local MCP server configuration launched as a child process.
+/// Stdio MCP server configuration launched as a child process.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct McpServerConfigLocal {
- /// Command-line arguments passed to the local MCP server process.
+pub struct McpServerConfigStdio {
+ /// Command-line arguments passed to the Stdio MCP server process.
+ #[serde(default)]
pub args: Vec,
- /// Executable command used to start the local MCP server process.
+ /// Executable command used to start the Stdio MCP server process.
pub command: String,
- /// Working directory for the local MCP server process.
+ /// Working directory for the Stdio MCP server process.
#[serde(skip_serializing_if = "Option::is_none")]
pub cwd: Option,
- /// Environment variables to pass to the local MCP server process.
+ /// Environment variables to pass to the Stdio MCP server process.
#[serde(default)]
pub env: HashMap,
/// Content filtering mode to apply to all tools, or a map of tool name to content filtering mode.
@@ -999,9 +1036,6 @@ pub struct McpServerConfigLocal {
/// Tools to include. Defaults to all tools if not specified.
#[serde(default)]
pub tools: Vec,
- /// Local transport type. Defaults to "local".
- #[serde(skip_serializing_if = "Option::is_none")]
- pub r#type: Option,
}
/// MCP servers configured for the session, with their connection status.
@@ -1107,7 +1141,7 @@ pub struct ModelCapabilities {
#[serde(rename_all = "camelCase")]
pub struct ModelPolicy {
/// Current policy state for this model
- pub state: String,
+ pub state: ModelPolicyState,
/// Usage terms or conditions for this model
#[serde(skip_serializing_if = "Option::is_none")]
pub terms: Option,
@@ -1253,7 +1287,7 @@ pub struct ModelSwitchToResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ModeSetRequest {
- /// The agent mode. Valid values: "interactive", "plan", "autopilot".
+ /// The session mode the agent is operating in
pub mode: SessionMode,
}
@@ -1687,7 +1721,7 @@ pub struct ServerSkill {
#[serde(skip_serializing_if = "Option::is_none")]
pub project_path: Option,
/// Source location type (e.g., project, personal-copilot, plugin, builtin)
- pub source: String,
+ pub source: SkillSource,
/// Whether the skill can be invoked by the user as a slash command
pub user_invocable: bool,
}
@@ -1868,10 +1902,22 @@ pub struct SessionFsRmRequest {
pub recursive: Option,
}
+/// Optional capabilities declared by the provider
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SessionFsSetProviderCapabilities {
+ /// Whether the provider supports SQLite query/exists operations
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub sqlite: Option,
+}
+
/// Initial working directory, session-state path layout, and path conventions used to register the calling SDK client as the session filesystem provider.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsSetProviderRequest {
+ /// Optional capabilities declared by the provider
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub capabilities: Option,
/// Path conventions used by this filesystem
pub conventions: SessionFsSetProviderConventions,
/// Initial working directory for sessions
@@ -1888,6 +1934,45 @@ pub struct SessionFsSetProviderResult {
pub success: bool,
}
+/// Indicates whether the per-session SQLite database already exists.
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SessionFsSqliteExistsResult {
+ /// Whether the session database already exists
+ pub exists: bool,
+}
+
+/// SQL query, query type, and optional bind parameters for executing a SQLite query against the per-session database.
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SessionFsSqliteQueryRequest {
+ /// Optional named bind parameters
+ #[serde(default)]
+ pub params: HashMap,
+ /// SQL query to execute
+ pub query: String,
+ /// How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
+ pub query_type: SessionFsSqliteQueryType,
+}
+
+/// Query results including rows, columns, and rows affected, or a filesystem error if execution failed.
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SessionFsSqliteQueryResult {
+ /// Column names from the result set
+ pub columns: Vec,
+ /// Describes a filesystem error.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub error: Option,
+ /// Last inserted row ID (for INSERT)
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub last_insert_rowid: Option,
+ /// For SELECT: array of row objects. For others: empty array.
+ pub rows: Vec>,
+ /// Number of rows affected (for INSERT/UPDATE/DELETE)
+ pub rows_affected: i64,
+}
+
/// Path whose metadata should be returned from the client-provided session filesystem.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -2007,8 +2092,8 @@ pub struct Skill {
/// Absolute path to the skill file
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option,
- /// Source location type (e.g., project, personal, plugin)
- pub source: String,
+ /// Source location type (e.g., project, personal-copilot, plugin, builtin)
+ pub source: SkillSource,
/// Whether the skill can be invoked by the user as a slash command
pub user_invocable: bool,
}
@@ -2075,9 +2160,9 @@ pub struct SlashCommandAgentPromptResult {
pub display_prompt: String,
/// Agent prompt result discriminator
pub kind: SlashCommandAgentPromptResultKind,
- /// Optional target session mode
+ /// Optional target session mode for the agent prompt
#[serde(skip_serializing_if = "Option::is_none")]
- pub mode: Option,
+ pub mode: Option,
/// Prompt to submit to the agent
pub prompt: String,
/// True when the invocation mutated user runtime settings; consumers caching settings should refresh
@@ -2141,9 +2226,9 @@ pub struct TaskAgentInfo {
/// Error message when the task failed
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option,
- /// How the agent is currently being managed by the runtime
+ /// Whether task execution is synchronously awaited or managed in the background
#[serde(skip_serializing_if = "Option::is_none")]
- pub execution_mode: Option,
+ pub execution_mode: Option,
/// Unique task identifier
pub id: String,
/// ISO 8601 timestamp when the agent entered idle state
@@ -2163,7 +2248,7 @@ pub struct TaskAgentInfo {
/// ISO 8601 timestamp when the task was started
pub started_at: String,
/// Current lifecycle status of the task
- pub status: TaskAgentInfoStatus,
+ pub status: TaskStatus,
/// Tool call ID associated with this agent task
pub tool_call_id: String,
/// Task kind
@@ -2210,9 +2295,9 @@ pub struct TaskShellInfo {
pub completed_at: Option,
/// Short description of the task
pub description: String,
- /// Whether the shell command is currently sync-waited or background-managed
+ /// Whether task execution is synchronously awaited or managed in the background
#[serde(skip_serializing_if = "Option::is_none")]
- pub execution_mode: Option,
+ pub execution_mode: Option,
/// Unique task identifier
pub id: String,
/// Path to the detached shell log, when available
@@ -2224,7 +2309,7 @@ pub struct TaskShellInfo {
/// ISO 8601 timestamp when the task was started
pub started_at: String,
/// Current lifecycle status of the task
- pub status: TaskShellInfoStatus,
+ pub status: TaskStatus,
/// Task kind
pub r#type: TaskShellInfoType,
}
@@ -3457,6 +3542,14 @@ pub struct SessionRemoteDisableParams {
pub session_id: SessionId,
}
+/// Identifies the target session.
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SessionFsSqliteExistsParams {
+ /// Target session identifier
+ pub session_id: SessionId,
+}
+
/// Authentication type
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum AuthInfoType {
@@ -3519,24 +3612,22 @@ pub enum ConnectedRemoteSessionMetadataKind {
Unknown,
}
-/// Configuration source
+/// Controls how MCP tool result content is filtered: none leaves content unchanged, markdown sanitizes HTML while preserving Markdown-friendly output, and hidden_characters removes characters that can hide directives.
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum DiscoveredMcpServerSource {
- #[serde(rename = "user")]
- User,
- #[serde(rename = "workspace")]
- Workspace,
- #[serde(rename = "plugin")]
- Plugin,
- #[serde(rename = "builtin")]
- Builtin,
+pub enum ContentFilterMode {
+ #[serde(rename = "none")]
+ None,
+ #[serde(rename = "markdown")]
+ Markdown,
+ #[serde(rename = "hidden_characters")]
+ HiddenCharacters,
/// Unknown variant for forward compatibility.
#[default]
#[serde(other)]
Unknown,
}
-/// Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)
+/// Server transport type: stdio, http, sse, or memory
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum DiscoveredMcpServerType {
#[serde(rename = "stdio")]
@@ -3583,6 +3674,19 @@ pub enum ExtensionStatus {
Unknown,
}
+/// Binary result type discriminator. Use "image" for images and "resource" for other binary data.
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum ExternalToolTextResultForLlmBinaryResultsForLlmType {
+ #[serde(rename = "image")]
+ Image,
+ #[serde(rename = "resource")]
+ Resource,
+ /// Unknown variant for forward compatibility.
+ #[default]
+ #[serde(other)]
+ Unknown,
+}
+
/// Content block type discriminator
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum ExternalToolTextResultForLlmContentAudioType {
@@ -3644,36 +3748,6 @@ pub enum ExternalToolTextResultForLlmContentTextType {
Text,
}
-/// Allowed values for the `FilterMappingString` enumeration.
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum FilterMappingString {
- #[serde(rename = "none")]
- None,
- #[serde(rename = "markdown")]
- Markdown,
- #[serde(rename = "hidden_characters")]
- HiddenCharacters,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
-/// Allowed values for the `FilterMappingValue` enumeration.
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum FilterMappingValue {
- #[serde(rename = "none")]
- None,
- #[serde(rename = "markdown")]
- Markdown,
- #[serde(rename = "hidden_characters")]
- HiddenCharacters,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
/// Where this source lives — used for UI grouping
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum InstructionsSourcesLocation {
@@ -3725,44 +3799,6 @@ pub enum SessionLogLevel {
Unknown,
}
-/// Configuration source: user, workspace, plugin, or builtin
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum McpServerSource {
- #[serde(rename = "user")]
- User,
- #[serde(rename = "workspace")]
- Workspace,
- #[serde(rename = "plugin")]
- Plugin,
- #[serde(rename = "builtin")]
- Builtin,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
-/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum McpServerStatus {
- #[serde(rename = "connected")]
- Connected,
- #[serde(rename = "failed")]
- Failed,
- #[serde(rename = "needs-auth")]
- NeedsAuth,
- #[serde(rename = "pending")]
- Pending,
- #[serde(rename = "disabled")]
- Disabled,
- #[serde(rename = "not_configured")]
- NotConfigured,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
/// OAuth grant type to use when authenticating to the remote MCP server.
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum McpServerConfigHttpOauthGrantType {
@@ -3789,19 +3825,6 @@ pub enum McpServerConfigHttpType {
Unknown,
}
-/// Local transport type. Defaults to "local".
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum McpServerConfigLocalType {
- #[serde(rename = "local")]
- Local,
- #[serde(rename = "stdio")]
- Stdio,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
/// Model capability category for grouping in the model picker
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum ModelPickerCategory {
@@ -3834,15 +3857,15 @@ pub enum ModelPickerPriceCategory {
Unknown,
}
-/// The agent mode. Valid values: "interactive", "plan", "autopilot".
+/// Current policy state for this model
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum SessionMode {
- #[serde(rename = "interactive")]
- Interactive,
- #[serde(rename = "plan")]
- Plan,
- #[serde(rename = "autopilot")]
- Autopilot,
+pub enum ModelPolicyState {
+ #[serde(rename = "enabled")]
+ Enabled,
+ #[serde(rename = "disabled")]
+ Disabled,
+ #[serde(rename = "unconfigured")]
+ Unconfigured,
/// Unknown variant for forward compatibility.
#[default]
#[serde(other)]
@@ -4137,27 +4160,27 @@ pub enum SessionFsSetProviderConventions {
Unknown,
}
-/// Signal to send (default: SIGTERM)
+/// How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum ShellKillSignal {
- SIGTERM,
- SIGKILL,
- SIGINT,
+pub enum SessionFsSqliteQueryType {
+ #[serde(rename = "exec")]
+ Exec,
+ #[serde(rename = "query")]
+ Query,
+ #[serde(rename = "run")]
+ Run,
/// Unknown variant for forward compatibility.
#[default]
#[serde(other)]
Unknown,
}
-/// Optional target session mode
+/// Signal to send (default: SIGTERM)
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum SlashCommandAgentPromptMode {
- #[serde(rename = "interactive")]
- Interactive,
- #[serde(rename = "plan")]
- Plan,
- #[serde(rename = "autopilot")]
- Autopilot,
+pub enum ShellKillSignal {
+ SIGTERM,
+ SIGKILL,
+ SIGINT,
/// Unknown variant for forward compatibility.
#[default]
#[serde(other)]
@@ -4197,9 +4220,9 @@ pub enum SlashCommandInvocationResult {
Completed(SlashCommandCompletedResult),
}
-/// How the agent is currently being managed by the runtime
+/// Whether task execution is synchronously awaited or managed in the background
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum TaskAgentInfoExecutionMode {
+pub enum TaskExecutionMode {
#[serde(rename = "sync")]
Sync,
#[serde(rename = "background")]
@@ -4212,7 +4235,7 @@ pub enum TaskAgentInfoExecutionMode {
/// Current lifecycle status of the task
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum TaskAgentInfoStatus {
+pub enum TaskStatus {
#[serde(rename = "running")]
Running,
#[serde(rename = "idle")]
@@ -4250,38 +4273,6 @@ pub enum TaskShellInfoAttachmentMode {
Unknown,
}
-/// Whether the shell command is currently sync-waited or background-managed
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum TaskShellInfoExecutionMode {
- #[serde(rename = "sync")]
- Sync,
- #[serde(rename = "background")]
- Background,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
-/// Current lifecycle status of the task
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum TaskShellInfoStatus {
- #[serde(rename = "running")]
- Running,
- #[serde(rename = "idle")]
- Idle,
- #[serde(rename = "completed")]
- Completed,
- #[serde(rename = "failed")]
- Failed,
- #[serde(rename = "cancelled")]
- Cancelled,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
/// Task kind
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum TaskShellInfoType {
diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs
index 519f23f05..f477db536 100644
--- a/rust/src/generated/rpc.rs
+++ b/rust/src/generated/rpc.rs
@@ -1419,7 +1419,7 @@ impl<'a> SessionRpcMode<'a> {
///
/// # Returns
///
- /// The agent mode. Valid values: "interactive", "plan", "autopilot".
+ /// The session mode the agent is operating in
pub async fn get(&self) -> Result {
let wire_params = serde_json::json!({ "sessionId": self.session.id() });
let _value = self
diff --git a/rust/src/generated/session_events.rs b/rust/src/generated/session_events.rs
index 2c615420c..459c03b77 100644
--- a/rust/src/generated/session_events.rs
+++ b/rust/src/generated/session_events.rs
@@ -420,7 +420,7 @@ pub struct SessionStartData {
pub detached_from_spawning_parent_session_id: Option,
/// Identifier of the software producing the events (e.g., "copilot-agent")
pub producer: String,
- /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option,
/// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
@@ -455,7 +455,7 @@ pub struct SessionResumeData {
pub continue_pending_work: Option,
/// Total number of persisted events in the session at the time of resume
pub event_count: f64,
- /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option,
/// Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
@@ -612,10 +612,10 @@ pub struct SessionModelChangeData {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionModeChangedData {
- /// Agent mode after the change (e.g., "interactive", "plan", "autopilot")
- pub new_mode: String,
- /// Agent mode before the change (e.g., "interactive", "plan", "autopilot")
- pub previous_mode: String,
+ /// The session mode the agent is operating in
+ pub new_mode: SessionMode,
+ /// The session mode the agent is operating in
+ pub previous_mode: SessionMode,
}
/// Session event "session.plan_changed". Plan file operation details indicating what changed
@@ -1297,7 +1297,7 @@ pub struct AssistantUsageData {
/// Per-quota resource usage snapshots, keyed by quota identifier
#[serde(default)]
pub quota_snapshots: HashMap,
- /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh")
+ /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max")
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option,
/// Number of output tokens used for reasoning (e.g., chain-of-thought)
@@ -2100,13 +2100,13 @@ pub struct PermissionPromptRequestUrl {
pub struct PermissionPromptRequestMemory {
/// Whether this is a store or vote memory operation
#[serde(skip_serializing_if = "Option::is_none")]
- pub action: Option,
+ pub action: Option,
/// Source references for the stored fact (store only)
#[serde(skip_serializing_if = "Option::is_none")]
pub citations: Option,
/// Vote direction (vote only)
#[serde(skip_serializing_if = "Option::is_none")]
- pub direction: Option,
+ pub direction: Option,
/// The fact being stored or voted on
pub fact: String,
/// Prompt kind discriminator
@@ -2663,8 +2663,8 @@ pub struct AutoModeSwitchRequestedData {
pub struct AutoModeSwitchCompletedData {
/// Request ID of the resolved request; clients should dismiss any UI for this request
pub request_id: RequestId,
- /// The user's choice: 'yes', 'yes_always', or 'no'
- pub response: String,
+ /// The user's auto-mode-switch choice
+ pub response: AutoModeSwitchResponse,
}
/// Schema for the `CommandsChangedCommand` type.
@@ -2708,12 +2708,12 @@ pub struct CapabilitiesChangedData {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExitPlanModeRequestedData {
- /// Available actions the user can take (e.g., approve, edit, reject)
- pub actions: Vec,
+ /// Available actions the user can take
+ pub actions: Vec,
/// Full content of the plan file
pub plan_content: String,
- /// The recommended action for the user to take
- pub recommended_action: String,
+ /// Recommended action to preselect for the user
+ pub recommended_action: ExitPlanModeAction,
/// Unique identifier for this request; used to respond via session.respondToExitPlanMode()
pub request_id: RequestId,
/// Summary of the plan that was created
@@ -2735,9 +2735,9 @@ pub struct ExitPlanModeCompletedData {
pub feedback: Option,
/// Request ID of the resolved exit plan mode request; clients should dismiss any UI for this request
pub request_id: RequestId,
- /// Which action the user selected (e.g. 'autopilot', 'interactive', 'exit_only')
+ /// Action selected by the user
#[serde(skip_serializing_if = "Option::is_none")]
- pub selected_action: Option,
+ pub selected_action: Option,
}
/// Session event "session.tools_updated".
@@ -2766,8 +2766,8 @@ pub struct SkillsLoadedSkill {
/// Absolute path to the skill file, if available
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option,
- /// Source location type of the skill (e.g., project, personal, plugin)
- pub source: String,
+ /// Source location type (e.g., project, personal-copilot, plugin, builtin)
+ pub source: SkillSource,
/// Whether the skill can be invoked by the user as a slash command
pub user_invocable: bool,
}
@@ -2826,9 +2826,9 @@ pub struct McpServersLoadedServer {
pub name: String,
/// Configuration source: user, workspace, plugin, or builtin
#[serde(skip_serializing_if = "Option::is_none")]
- pub source: Option,
+ pub source: Option,
/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
- pub status: McpServersLoadedServerStatus,
+ pub status: McpServerStatus,
}
/// Session event "session.mcp_servers_loaded".
@@ -2845,8 +2845,8 @@ pub struct SessionMcpServersLoadedData {
pub struct SessionMcpServerStatusChangedData {
/// Name of the MCP server whose status changed
pub server_name: String,
- /// New connection status: connected, failed, needs-auth, pending, disabled, or not_configured
- pub status: McpServerStatusChangedStatus,
+ /// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+ pub status: McpServerStatus,
}
/// Schema for the `ExtensionsLoadedExtension` type.
@@ -2899,6 +2899,21 @@ pub enum ReasoningSummary {
Unknown,
}
+/// The session mode the agent is operating in
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum SessionMode {
+ #[serde(rename = "interactive")]
+ Interactive,
+ #[serde(rename = "plan")]
+ Plan,
+ #[serde(rename = "autopilot")]
+ Autopilot,
+ /// Unknown variant for forward compatibility.
+ #[default]
+ #[serde(other)]
+ Unknown,
+}
+
/// The type of operation performed on the plan file
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PlanChangedOperation {
@@ -3286,32 +3301,6 @@ pub enum PermissionPromptRequestUrlKind {
Url,
}
-/// Whether this is a store or vote memory operation
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum PermissionPromptRequestMemoryAction {
- #[serde(rename = "store")]
- Store,
- #[serde(rename = "vote")]
- Vote,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
-/// Vote direction (vote only)
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum PermissionPromptRequestMemoryDirection {
- #[serde(rename = "upvote")]
- Upvote,
- #[serde(rename = "downvote")]
- Downvote,
- /// Unknown variant for forward compatibility.
- #[default]
- #[serde(other)]
- Unknown,
-}
-
/// Prompt kind discriminator
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PermissionPromptRequestMemoryKind {
@@ -3603,30 +3592,81 @@ pub enum McpOauthRequiredStaticClientConfigGrantType {
ClientCredentials,
}
-/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+/// The user's auto-mode-switch choice
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum McpServersLoadedServerStatus {
- #[serde(rename = "connected")]
- Connected,
- #[serde(rename = "failed")]
- Failed,
- #[serde(rename = "needs-auth")]
- NeedsAuth,
- #[serde(rename = "pending")]
- Pending,
- #[serde(rename = "disabled")]
- Disabled,
- #[serde(rename = "not_configured")]
- NotConfigured,
+pub enum AutoModeSwitchResponse {
+ #[serde(rename = "yes")]
+ Yes,
+ #[serde(rename = "yes_always")]
+ YesAlways,
+ #[serde(rename = "no")]
+ No,
+ /// Unknown variant for forward compatibility.
+ #[default]
+ #[serde(other)]
+ Unknown,
+}
+
+/// Exit plan mode action
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum ExitPlanModeAction {
+ #[serde(rename = "exit_only")]
+ ExitOnly,
+ #[serde(rename = "interactive")]
+ Interactive,
+ #[serde(rename = "autopilot")]
+ Autopilot,
+ #[serde(rename = "autopilot_fleet")]
+ AutopilotFleet,
/// Unknown variant for forward compatibility.
#[default]
#[serde(other)]
Unknown,
}
-/// New connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+/// Source location type (e.g., project, personal-copilot, plugin, builtin)
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum SkillSource {
+ #[serde(rename = "project")]
+ Project,
+ #[serde(rename = "inherited")]
+ Inherited,
+ #[serde(rename = "personal-copilot")]
+ PersonalCopilot,
+ #[serde(rename = "personal-agents")]
+ PersonalAgents,
+ #[serde(rename = "plugin")]
+ Plugin,
+ #[serde(rename = "custom")]
+ Custom,
+ #[serde(rename = "builtin")]
+ Builtin,
+ /// Unknown variant for forward compatibility.
+ #[default]
+ #[serde(other)]
+ Unknown,
+}
+
+/// Configuration source: user, workspace, plugin, or builtin
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum McpServerSource {
+ #[serde(rename = "user")]
+ User,
+ #[serde(rename = "workspace")]
+ Workspace,
+ #[serde(rename = "plugin")]
+ Plugin,
+ #[serde(rename = "builtin")]
+ Builtin,
+ /// Unknown variant for forward compatibility.
+ #[default]
+ #[serde(other)]
+ Unknown,
+}
+
+/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub enum McpServerStatusChangedStatus {
+pub enum McpServerStatus {
#[serde(rename = "connected")]
Connected,
#[serde(rename = "failed")]
diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json
index 6cc3fe72f..dad0ea1d1 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.49-1",
+ "@github/copilot": "^1.0.49-6",
"@modelcontextprotocol/sdk": "^1.26.0",
"@types/node": "^25.3.3",
"@types/node-forge": "^1.3.14",
@@ -464,27 +464,29 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.49-1.tgz",
- "integrity": "sha512-1euPT6WXtLWnoqz1SXHdcqmktucdkfwfZn/Eo4iQ1FAjZo7awuN86rVb1feDwxY4vlSGbzNmK+GDKDgs9qZCDg==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.49-6.tgz",
+ "integrity": "sha512-9ptx1Vs6aJvybo7vN1gGHNPHt5JqmhIZWyurnMMFjoZh6DAq9NO+0yWBP1WL752ycFDE/kKR+OgKC64O+UsLQw==",
"dev": true,
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.49-1",
- "@github/copilot-darwin-x64": "1.0.49-1",
- "@github/copilot-linux-arm64": "1.0.49-1",
- "@github/copilot-linux-x64": "1.0.49-1",
- "@github/copilot-win32-arm64": "1.0.49-1",
- "@github/copilot-win32-x64": "1.0.49-1"
+ "@github/copilot-darwin-arm64": "1.0.49-6",
+ "@github/copilot-darwin-x64": "1.0.49-6",
+ "@github/copilot-linux-arm64": "1.0.49-6",
+ "@github/copilot-linux-x64": "1.0.49-6",
+ "@github/copilot-linuxmusl-arm64": "1.0.49-6",
+ "@github/copilot-linuxmusl-x64": "1.0.49-6",
+ "@github/copilot-win32-arm64": "1.0.49-6",
+ "@github/copilot-win32-x64": "1.0.49-6"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.49-1.tgz",
- "integrity": "sha512-EgHdwlkYSJ+RmHAelGGpQxQe5/dgq3BlvToc0VmYEUCWO93ESEql7XBqCWYeASg3USUp8n87kf3mr2eXIECvLA==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-e+0T9DIfaE5GyFnsIUQWSGhi/Ont9/iENLb43jyAsASxY+gWxqWyUHVD7kYJpunMODNjg0FNXgCEAX5YUyKOXQ==",
"cpu": [
"arm64"
],
@@ -499,9 +501,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.49-1.tgz",
- "integrity": "sha512-YPtOW5q3vWB9Covn08jxqIdIjcCuJi/MgIlYk1ulKTINi5uK5a6NlsX2mDaGWL/svhDwDlhFEa3oUV41yOjTkg==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.49-6.tgz",
+ "integrity": "sha512-zgcMxEszygPvmki/A6aydLTMYyQhHQrQ5z+7BA/yGbuyghRKfe0mYG56QKRp5PsJJ01YK2Kr+G7EqgHypS5PVA==",
"cpu": [
"x64"
],
@@ -516,9 +518,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.49-1.tgz",
- "integrity": "sha512-eEh0ec1UlWg8IdV2/3Zaxr/PAA86GclEFUcGNkwc9JceOgw5nhIdytsjCwXJUcRTzHsGrAoTS+Vad1RSvKSmYQ==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-0/KlHumd38nYP/fNGVHaxSdqdRKV8cESaytTPyGq0ncfPMZzcqZhkgv6qur1XMai0zh0ZGpwxqzB3kwMrNJCoQ==",
"cpu": [
"arm64"
],
@@ -533,9 +535,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.49-1.tgz",
- "integrity": "sha512-9+HxOVAbgCqcoyfAXyfaFxgIbAfHWCh699WuOfWViX2fjoKO3V0ZVHEergR4gVEgvnjvnmD0TZhT7+kTzqPK6A==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.49-6.tgz",
+ "integrity": "sha512-LWfl79uh0i2/OTKikliZ3b0pnheVkEA2CYJTZUapfTSXKHQlQQIMR7HBhD6GCaOkVvHYgaH5WQVviedmS88N7g==",
"cpu": [
"x64"
],
@@ -549,10 +551,44 @@
"copilot-linux-x64": "copilot"
}
},
+ "node_modules/@github/copilot-linuxmusl-arm64": {
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-O9DdXVMdNdrgucLr4gd4djbzTdH8MGitNOWqIxTbsPy9YMd/OQ9JTEDCqPuezbiVzI0emS9NyrdSBasvcVI1VQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.md",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "bin": {
+ "copilot-linuxmusl-arm64": "copilot"
+ }
+ },
+ "node_modules/@github/copilot-linuxmusl-x64": {
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.49-6.tgz",
+ "integrity": "sha512-Yj8FTs9JcHvXw/FS8PEK0IxWa/qf+5UWPejburofi7hwiaC4wb+pX0AzhWee4jKcJ1YbZBEyWFMvBEK6xZ0TmA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE.md",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "bin": {
+ "copilot-linuxmusl-x64": "copilot"
+ }
+ },
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.49-1.tgz",
- "integrity": "sha512-nsOz2rdk1Il3KJ24x3Hdv27MvotrKygIC/ok6acvq+xFwsYxR5Kt5bL1veBAGZVEG8K+0r2DfHi9NZHazBYK8A==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.49-6.tgz",
+ "integrity": "sha512-u7GOWUIWRsS5IUdprXN2nWsTSTdM//m/LfqmOp1dfAxdSBOL4dF1Up3tEi8+f+HaCqIQhYQMryRux9KP4bUEnw==",
"cpu": [
"arm64"
],
@@ -567,9 +603,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.49-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.49-1.tgz",
- "integrity": "sha512-RZbU3GESkfwd8UC1h5AeceVfCOfXjMA+sDKfIUyk8Pl8EukTNtNSf+WEKK1HzSxbxdbIu9DJyBL375JMwDiH4A==",
+ "version": "1.0.49-6",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.49-6.tgz",
+ "integrity": "sha512-ayxTr2+miHaguaF0QrV6a/QvoMY4wUaTaYkZ7657ONOnR6BcFV9SNtnrlpLrbiIRkP6T0QZQXhROLaQwF7vrdw==",
"cpu": [
"x64"
],
diff --git a/test/harness/package.json b/test/harness/package.json
index 57082e2b9..4b00a3939 100644
--- a/test/harness/package.json
+++ b/test/harness/package.json
@@ -11,7 +11,7 @@
"test": "vitest run"
},
"devDependencies": {
- "@github/copilot": "^1.0.49-1",
+ "@github/copilot": "^1.0.49-6",
"@modelcontextprotocol/sdk": "^1.26.0",
"@types/node": "^25.3.3",
"@types/node-forge": "^1.3.14",
From e97d23cc50b24f4039ed45426dabcaac112da8d9 Mon Sep 17 00:00:00 2001
From: Copilot <223556219+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 22:17:29 -0400
Subject: [PATCH 2/8] Fix SDK fallout from Copilot update
Add SessionFS SQLite support across SDKs and fix generated type issues exposed by the updated Copilot schema.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
dotnet/src/Client.cs | 2 +-
dotnet/src/Generated/Rpc.cs | 10 +-
dotnet/src/SessionFsProvider.cs | 47 ++++++
dotnet/src/Types.cs | 19 ---
dotnet/test/E2E/ModeHandlersE2ETests.cs | 12 +-
.../test/E2E/RpcEventSideEffectsE2ETests.cs | 6 +-
dotnet/test/E2E/RpcServerE2ETests.cs | 2 +-
.../test/E2E/RpcTasksAndHandlersE2ETests.cs | 8 +-
dotnet/test/E2E/SessionFsE2ETests.cs | 27 +++
dotnet/test/E2E/SkillsE2ETests.cs | 2 +-
dotnet/test/Harness/E2ETestContext.cs | 14 +-
dotnet/test/Unit/ForwardCompatibilityTests.cs | 6 +-
.../Unit/SessionEventSerializationTests.cs | 2 +-
go/internal/e2e/per_session_auth_e2e_test.go | 24 ++-
go/internal/e2e/rpc_mcp_config_e2e_test.go | 6 +-
go/internal/e2e/rpc_server_e2e_test.go | 7 +-
go/internal/e2e/session_fs_e2e_test.go | 39 +++++
go/internal/e2e/testharness/context.go | 30 +++-
go/rpc/generated_rpc_api_shape_test.go | 8 +-
go/rpc/generated_rpc_union_test.go | 14 +-
go/session_fs_provider.go | 25 +++
go/types.go | 12 --
nodejs/src/generated/rpc.ts | 2 -
nodejs/src/sessionFsProvider.ts | 32 ++++
nodejs/src/types.ts | 2 +-
nodejs/test/e2e/harness/sdkTestContext.ts | 20 ++-
nodejs/test/e2e/per_session_auth.e2e.test.ts | 46 +++--
nodejs/test/e2e/session_fs.e2e.test.ts | 57 +++++++
nodejs/test/session_fs_adapter.test.ts | 43 +++++
python/copilot/generated/rpc.py | 2 +-
python/copilot/session_fs_provider.py | 40 +++++
python/e2e/test_per_session_auth_e2e.py | 42 ++++-
python/e2e/test_session_fs_e2e.py | 83 ++++++++-
python/e2e/testharness/__init__.py | 3 +-
python/e2e/testharness/context.py | 25 ++-
rust/src/generated/api_types.rs | 1 +
rust/src/generated/rpc.rs | 1 +
rust/src/lib.rs | 1 +
rust/src/session_fs.rs | 28 +++-
rust/src/session_fs_dispatch.rs | 62 ++++++-
rust/src/types.rs | 2 +-
rust/tests/e2e/mode_handlers.rs | 37 ++--
rust/tests/e2e/rpc_additional_edge_cases.rs | 3 +-
rust/tests/e2e/rpc_event_side_effects.rs | 6 +-
rust/tests/e2e/rpc_session_state.rs | 5 +-
rust/tests/e2e/session_fs.rs | 64 ++++++-
rust/tests/session_test.rs | 158 ++++++++++++++++++
scripts/codegen/csharp.ts | 14 +-
scripts/codegen/python.ts | 1 +
scripts/codegen/rust.ts | 37 ++++
scripts/codegen/typescript.ts | 7 +-
51 files changed, 979 insertions(+), 167 deletions(-)
diff --git a/dotnet/src/Client.cs b/dotnet/src/Client.cs
index 4a5cceefb..067a0de58 100644
--- a/dotnet/src/Client.cs
+++ b/dotnet/src/Client.cs
@@ -1302,7 +1302,7 @@ await Rpc.SessionFs.SetProviderAsync(
_options.SessionFs.InitialCwd,
_options.SessionFs.SessionStatePath,
_options.SessionFs.Conventions,
- cancellationToken);
+ cancellationToken: cancellationToken);
}
private void ConfigureSessionFsHandlers(CopilotSession session, Func? createSessionFsHandler)
diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs
index 1f963890a..6cf9fe071 100644
--- a/dotnet/src/Generated/Rpc.cs
+++ b/dotnet/src/Generated/Rpc.cs
@@ -340,7 +340,7 @@ public sealed class DiscoveredMcpServer
/// Configuration source: user, workspace, plugin, or builtin.
[JsonPropertyName("source")]
- public McpServerSource Source { get; set; } = null!;
+ public McpServerSource Source { get; set; }
/// Server transport type: stdio, http, sse, or memory.
[JsonPropertyName("type")]
@@ -453,7 +453,7 @@ public sealed class ServerSkill
/// Source location type (e.g., project, personal-copilot, plugin, builtin).
[JsonPropertyName("source")]
- public SkillSource Source { get; set; } = null!;
+ public SkillSource Source { get; set; }
/// Whether the skill can be invoked by the user as a slash command.
[JsonPropertyName("userInvocable")]
@@ -846,7 +846,7 @@ internal sealed class ModeSetRequest
{
/// The session mode the agent is operating in.
[JsonPropertyName("mode")]
- public SessionMode Mode { get; set; } = null!;
+ public SessionMode Mode { get; set; }
/// Target session identifier.
[JsonPropertyName("sessionId")]
@@ -1582,7 +1582,7 @@ public sealed class Skill
/// Source location type (e.g., project, personal-copilot, plugin, builtin).
[JsonPropertyName("source")]
- public SkillSource Source { get; set; } = null!;
+ public SkillSource Source { get; set; }
/// Whether the skill can be invoked by the user as a slash command.
[JsonPropertyName("userInvocable")]
@@ -1675,7 +1675,7 @@ public sealed class McpServer
/// Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.
[JsonPropertyName("status")]
- public McpServerStatus Status { get; set; } = null!;
+ public McpServerStatus Status { get; set; }
}
/// MCP servers configured for the session, with their connection status.
diff --git a/dotnet/src/SessionFsProvider.cs b/dotnet/src/SessionFsProvider.cs
index 25230244c..df26d6384 100644
--- a/dotnet/src/SessionFsProvider.cs
+++ b/dotnet/src/SessionFsProvider.cs
@@ -75,6 +75,24 @@ public abstract class SessionFsProvider : ISessionFsHandler
/// Cancellation token.
protected abstract Task RenameAsync(string src, string dest, CancellationToken cancellationToken);
+ /// Executes a SQLite query against the per-session database.
+ /// Target session identifier.
+ /// SQL query to execute.
+ /// How to execute the query.
+ /// Optional named bind parameters.
+ /// Cancellation token.
+ protected abstract Task SqliteQueryAsync(
+ string sessionId,
+ string query,
+ SessionFsSqliteQueryType queryType,
+ IDictionary? parameters,
+ CancellationToken cancellationToken);
+
+ /// Checks whether the per-session SQLite database already exists.
+ /// Target session identifier.
+ /// Cancellation token.
+ protected abstract Task SqliteExistsAsync(string sessionId, CancellationToken cancellationToken);
+
// ---- ISessionFsHandler implementation (private, handles error mapping) ----
async Task ISessionFsHandler.ReadFileAsync(SessionFsReadFileRequest request, CancellationToken cancellationToken)
@@ -226,6 +244,35 @@ async Task ISessionFsHandler.ReaddirWithTypesAs
}
}
+ async Task ISessionFsHandler.SqliteQueryAsync(SessionFsSqliteQueryRequest request, CancellationToken cancellationToken)
+ {
+ ArgumentNullException.ThrowIfNull(request);
+
+ try
+ {
+ return await SqliteQueryAsync(request.SessionId, request.Query, request.QueryType, request.Params, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ return new SessionFsSqliteQueryResult { Error = ToSessionFsError(ex) };
+ }
+ }
+
+ async Task ISessionFsHandler.SqliteExistsAsync(SessionFsSqliteExistsRequest request, CancellationToken cancellationToken)
+ {
+ ArgumentNullException.ThrowIfNull(request);
+
+ try
+ {
+ var exists = await SqliteExistsAsync(request.SessionId, cancellationToken).ConfigureAwait(false);
+ return new SessionFsSqliteExistsResult { Exists = exists };
+ }
+ catch
+ {
+ return new SessionFsSqliteExistsResult { Exists = false };
+ }
+ }
+
private static SessionFsError ToSessionFsError(Exception ex)
{
var code = ex is FileNotFoundException or DirectoryNotFoundException
diff --git a/dotnet/src/Types.cs b/dotnet/src/Types.cs
index ab38a57bd..42747bcb1 100644
--- a/dotnet/src/Types.cs
+++ b/dotnet/src/Types.cs
@@ -798,25 +798,6 @@ public class AutoModeSwitchRequest
public double? RetryAfterSeconds { get; set; }
}
-///
-/// Response to an auto-mode-switch request.
-///
-[JsonConverter(typeof(JsonStringEnumConverter))]
-public enum AutoModeSwitchResponse
-{
- /// Approve the switch for this rate-limit cycle.
- [JsonStringEnumMemberName("yes")]
- Yes,
-
- /// Approve and remember the choice for this session.
- [JsonStringEnumMemberName("yes_always")]
- YesAlways,
-
- /// Decline the switch.
- [JsonStringEnumMemberName("no")]
- No
-}
-
///
/// Context for an auto-mode-switch request invocation.
///
diff --git a/dotnet/test/E2E/ModeHandlersE2ETests.cs b/dotnet/test/E2E/ModeHandlersE2ETests.cs
index a98faa0bf..b68e9c3ed 100644
--- a/dotnet/test/E2E/ModeHandlersE2ETests.cs
+++ b/dotnet/test/E2E/ModeHandlersE2ETests.cs
@@ -47,7 +47,7 @@ public async Task Should_Invoke_Exit_Plan_Mode_Handler_When_Model_Uses_Tool()
timeoutDescription: "exit_plan_mode.requested event");
var completedEventTask = TestHelper.GetNextEventOfTypeAsync(
session,
- evt => evt.Data.Approved == true && evt.Data.SelectedAction == "interactive",
+ evt => evt.Data.Approved == true && evt.Data.SelectedAction.GetValueOrDefault() == ExitPlanModeAction.Interactive,
TimeSpan.FromSeconds(30),
timeoutDescription: "exit_plan_mode.completed event");
@@ -66,12 +66,12 @@ public async Task Should_Invoke_Exit_Plan_Mode_Handler_When_Model_Uses_Tool()
var requestedEvent = await requestedEventTask;
Assert.Equal(request.Summary, requestedEvent.Data.Summary);
- Assert.Equal(request.Actions, requestedEvent.Data.Actions);
- Assert.Equal(request.RecommendedAction, requestedEvent.Data.RecommendedAction);
+ Assert.Equal(request.Actions, requestedEvent.Data.Actions.Select(action => action.Value));
+ Assert.Equal(request.RecommendedAction, requestedEvent.Data.RecommendedAction.Value);
var completedEvent = await completedEventTask;
Assert.True(completedEvent.Data.Approved);
- Assert.Equal("interactive", completedEvent.Data.SelectedAction);
+ Assert.Equal("interactive", completedEvent.Data.SelectedAction?.Value);
Assert.Equal("Approved by the C# E2E test", completedEvent.Data.Feedback);
Assert.NotNull(response);
@@ -104,7 +104,7 @@ public async Task Should_Invoke_Auto_Mode_Switch_Handler_When_Rate_Limited()
timeoutDescription: "auto_mode_switch.requested event");
var completedEventTask = GetNextEventOfTypeAllowingRateLimitAsync(
session,
- evt => evt.Data.Response == "yes",
+ evt => evt.Data.Response == AutoModeSwitchResponse.Yes,
TimeSpan.FromSeconds(30),
timeoutDescription: "auto_mode_switch.completed event");
var modelChangeTask = GetNextEventOfTypeAllowingRateLimitAsync(
@@ -134,7 +134,7 @@ public async Task Should_Invoke_Auto_Mode_Switch_Handler_When_Rate_Limited()
Assert.Equal(request.RetryAfterSeconds, requestedEvent.Data.RetryAfterSeconds);
var completedEvent = await completedEventTask;
- Assert.Equal("yes", completedEvent.Data.Response);
+ Assert.Equal(AutoModeSwitchResponse.Yes, completedEvent.Data.Response);
var modelChange = await modelChangeTask;
Assert.Equal("rate_limit_auto_switch", modelChange.Data.Cause);
diff --git a/dotnet/test/E2E/RpcEventSideEffectsE2ETests.cs b/dotnet/test/E2E/RpcEventSideEffectsE2ETests.cs
index 821b1be43..a363b5586 100644
--- a/dotnet/test/E2E/RpcEventSideEffectsE2ETests.cs
+++ b/dotnet/test/E2E/RpcEventSideEffectsE2ETests.cs
@@ -28,15 +28,15 @@ public async Task Should_Emit_Mode_Changed_Event_When_Mode_Set()
// Subscribe before invoking RPC; events may arrive after the RPC completes.
var modeChangedTask = TestHelper.GetNextEventOfTypeAsync(
session,
- evt => evt.Data.NewMode == "plan" && evt.Data.PreviousMode == "interactive",
+ evt => evt.Data.NewMode == SessionMode.Plan && evt.Data.PreviousMode == SessionMode.Interactive,
EventTimeout,
timeoutDescription: "session.mode_changed event for interactive→plan");
await session.Rpc.Mode.SetAsync(SessionMode.Plan);
var evt = await modeChangedTask;
- Assert.Equal("plan", evt.Data.NewMode);
- Assert.Equal("interactive", evt.Data.PreviousMode);
+ Assert.Equal(SessionMode.Plan, evt.Data.NewMode);
+ Assert.Equal(SessionMode.Interactive, evt.Data.PreviousMode);
}
[Fact]
diff --git a/dotnet/test/E2E/RpcServerE2ETests.cs b/dotnet/test/E2E/RpcServerE2ETests.cs
index aef8a2fbc..847a28c3b 100644
--- a/dotnet/test/E2E/RpcServerE2ETests.cs
+++ b/dotnet/test/E2E/RpcServerE2ETests.cs
@@ -90,7 +90,7 @@ await ConfigureAuthenticatedUserAsync(
Assert.Equal(2, chatQuota.Overage);
Assert.True(chatQuota.UsageAllowedWithExhaustedQuota);
Assert.True(chatQuota.OverageAllowedWithExhaustedQuota);
- Assert.Equal("2026-04-30T00:00:00Z", chatQuota.ResetDate);
+ Assert.Equal(DateTimeOffset.Parse("2026-04-30T00:00:00Z"), chatQuota.ResetDate);
}
[Fact]
diff --git a/dotnet/test/E2E/RpcTasksAndHandlersE2ETests.cs b/dotnet/test/E2E/RpcTasksAndHandlersE2ETests.cs
index 4ccdee858..6e8860964 100644
--- a/dotnet/test/E2E/RpcTasksAndHandlersE2ETests.cs
+++ b/dotnet/test/E2E/RpcTasksAndHandlersE2ETests.cs
@@ -101,7 +101,7 @@ await TestHelper.WaitForConditionAsync(
Assert.Equal("general-purpose", task.AgentType);
Assert.Equal("Reply with TASK_AGENT_DONE exactly.", task.Prompt);
Assert.Equal("SDK background agent coverage", task.Description);
- Assert.Equal(TaskAgentInfoExecutionMode.Background, task.ExecutionMode);
+ Assert.Equal(GitHub.Copilot.SDK.Rpc.TaskExecutionMode.Background, task.ExecutionMode);
Assert.False(task.CanPromoteToBackground.GetValueOrDefault());
Assert.NotEqual(default, task.StartedAt);
@@ -114,8 +114,8 @@ await TestHelper.WaitForConditionAsync(
task = await FindAgentTaskAsync(session, started.AgentId);
return task?.LatestResponse?.Contains("TASK_AGENT_DONE", StringComparison.Ordinal) == true
|| task?.Result?.Contains("TASK_AGENT_DONE", StringComparison.Ordinal) == true
- || task?.Status == TaskAgentInfoStatus.Completed
- || task?.Status == TaskAgentInfoStatus.Failed;
+ || task?.Status == GitHub.Copilot.SDK.Rpc.TaskStatus.Completed
+ || task?.Status == GitHub.Copilot.SDK.Rpc.TaskStatus.Failed;
},
timeout: TimeSpan.FromSeconds(60),
timeoutMessage: $"Background agent task '{started.AgentId}' did not produce a final observable state.");
@@ -123,7 +123,7 @@ await TestHelper.WaitForConditionAsync(
Assert.NotNull(task);
Assert.Contains("TASK_AGENT_DONE", task.LatestResponse ?? task.Result ?? string.Empty);
- if (task.Status == TaskAgentInfoStatus.Idle)
+ if (task.Status == GitHub.Copilot.SDK.Rpc.TaskStatus.Idle)
{
var cancel = await session.Rpc.Tasks.CancelAsync(started.AgentId);
Assert.True(cancel.Cancelled);
diff --git a/dotnet/test/E2E/SessionFsE2ETests.cs b/dotnet/test/E2E/SessionFsE2ETests.cs
index 271c7f1e0..c3c317b6f 100644
--- a/dotnet/test/E2E/SessionFsE2ETests.cs
+++ b/dotnet/test/E2E/SessionFsE2ETests.cs
@@ -294,6 +294,10 @@ public async Task SessionFsProvider_Converts_Exceptions_To_Rpc_Errors()
AssertFsError((await handler.ReaddirWithTypesAsync(new SessionFsReaddirWithTypesRequest { Path = "missing-dir" })).Error);
AssertFsError(await handler.RmAsync(new SessionFsRmRequest { Path = "missing.txt" }));
AssertFsError(await handler.RenameAsync(new SessionFsRenameRequest { Src = "missing.txt", Dest = "dest.txt" }));
+ AssertFsError((await handler.SqliteQueryAsync(new SessionFsSqliteQueryRequest { Query = "select 1" })).Error);
+
+ var sqliteExists = await handler.SqliteExistsAsync(new SessionFsSqliteExistsRequest());
+ Assert.False(sqliteExists.Exists);
var unknown = (ISessionFsHandler)new ThrowingSessionFsProvider(new InvalidOperationException("bad path"));
var unknownError = await unknown.WriteFileAsync(new SessionFsWriteFileRequest { Path = "bad.txt", Content = "content" });
@@ -603,6 +607,17 @@ protected override Task RmAsync(string path, bool recursive, bool force, Cancell
protected override Task RenameAsync(string src, string dest, CancellationToken cancellationToken) =>
Task.FromException(exception);
+
+ protected override Task SqliteQueryAsync(
+ string sessionId,
+ string query,
+ SessionFsSqliteQueryType queryType,
+ IDictionary? parameters,
+ CancellationToken cancellationToken) =>
+ Task.FromException(exception);
+
+ protected override Task SqliteExistsAsync(string sessionId, CancellationToken cancellationToken) =>
+ Task.FromException(exception);
}
private sealed class TestSessionFsHandler(string sessionId, string rootDir) : SessionFsProvider
@@ -736,6 +751,18 @@ protected override Task RenameAsync(string src, string dest, CancellationToken c
return Task.CompletedTask;
}
+ protected override Task SqliteQueryAsync(
+ string sessionId,
+ string query,
+ SessionFsSqliteQueryType queryType,
+ IDictionary? parameters,
+ CancellationToken cancellationToken) =>
+ Task.FromException(
+ new NotSupportedException("SQLite session filesystem operations are not supported by this provider."));
+
+ protected override Task SqliteExistsAsync(string sessionId, CancellationToken cancellationToken) =>
+ Task.FromResult(false);
+
private string ResolvePath(string sessionPath)
{
var normalizedSessionId = NormalizeRelativePathSegment(sessionId, nameof(sessionId));
diff --git a/dotnet/test/E2E/SkillsE2ETests.cs b/dotnet/test/E2E/SkillsE2ETests.cs
index 6507cb05a..7da1d4b3e 100644
--- a/dotnet/test/E2E/SkillsE2ETests.cs
+++ b/dotnet/test/E2E/SkillsE2ETests.cs
@@ -134,7 +134,7 @@ public async Task Should_Control_Ambient_Project_Skills_With_EnableConfigDiscove
var enabledSkills = await enabledSession.Rpc.Skills.ListAsync();
var discoveredSkill = Assert.Single(enabledSkills.Skills, skill => string.Equals(skill.Name, skillName, StringComparison.Ordinal));
Assert.True(discoveredSkill.Enabled);
- Assert.Equal("project", discoveredSkill.Source);
+ Assert.Equal(SkillSource.Project, discoveredSkill.Source);
Assert.EndsWith(Path.Join(skillName, "SKILL.md"), discoveredSkill.Path);
await enabledSession.DisposeAsync();
}
diff --git a/dotnet/test/Harness/E2ETestContext.cs b/dotnet/test/Harness/E2ETestContext.cs
index 6c7d4d808..ef703c4be 100644
--- a/dotnet/test/Harness/E2ETestContext.cs
+++ b/dotnet/test/Harness/E2ETestContext.cs
@@ -10,6 +10,8 @@ namespace GitHub.Copilot.SDK.Test.Harness;
public sealed class E2ETestContext : IAsyncDisposable
{
+ private const string DefaultGitHubToken = "fake-token-for-e2e-tests";
+
public string HomeDir { get; }
public string WorkDir { get; }
public string ProxyUrl { get; }
@@ -49,6 +51,11 @@ public static async Task CreateAsync()
var proxy = new CapiProxy();
var proxyUrl = await proxy.StartAsync();
+ await proxy.SetCopilotUserByTokenAsync(DefaultGitHubToken, new CopilotUserConfig(
+ Login: "e2e-test-user",
+ CopilotPlan: "individual_pro",
+ Endpoints: new CopilotUserEndpoints(Api: proxyUrl, Telemetry: "https://localhost:1/telemetry"),
+ AnalyticsTrackingId: "e2e-test-tracking-id"));
return new E2ETestContext(homeDir, workDir, proxyUrl, proxy, repoRoot);
}
@@ -190,8 +197,8 @@ public IReadOnlyDictionary GetEnvironment()
}
if (Environment.GetEnvironmentVariable("GITHUB_ACTIONS") == "true")
{
- env["GH_TOKEN"] = "fake-token-for-e2e-tests";
- env["GITHUB_TOKEN"] = "fake-token-for-e2e-tests";
+ env["GH_TOKEN"] = DefaultGitHubToken;
+ env["GITHUB_TOKEN"] = DefaultGitHubToken;
}
return env!;
@@ -216,11 +223,10 @@ public CopilotClient CreateClient(
}
if (autoInjectGitHubToken
- && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS"))
&& string.IsNullOrEmpty(options.GitHubToken)
&& string.IsNullOrEmpty(options.CliUrl))
{
- options.GitHubToken = "fake-token-for-e2e-tests";
+ options.GitHubToken = DefaultGitHubToken;
}
var client = new CopilotClient(options);
diff --git a/dotnet/test/Unit/ForwardCompatibilityTests.cs b/dotnet/test/Unit/ForwardCompatibilityTests.cs
index a3b362344..d0265c361 100644
--- a/dotnet/test/Unit/ForwardCompatibilityTests.cs
+++ b/dotnet/test/Unit/ForwardCompatibilityTests.cs
@@ -240,7 +240,7 @@ public void RpcEnum_WithNonStringValue_ThrowsJsonException()
[Fact]
public void RpcEnum_DefaultValue_HasEmptyStringValue()
{
- GitHub.Copilot.SDK.Rpc.SessionMode mode = default;
+ GitHub.Copilot.SDK.SessionMode mode = default;
Assert.Equal(string.Empty, mode.Value);
Assert.Equal(string.Empty, mode.ToString());
@@ -249,7 +249,7 @@ public void RpcEnum_DefaultValue_HasEmptyStringValue()
[Fact]
public void RpcEnum_DefaultValueSerialization_ThrowsJsonException()
{
- GitHub.Copilot.SDK.Rpc.SessionMode mode = default;
+ GitHub.Copilot.SDK.SessionMode mode = default;
var exception = Assert.Throws(() => JsonSerializer.Serialize(
mode,
@@ -304,5 +304,5 @@ public void FromJson_UnknownEventType_PreservesAgentIdNull()
}
}
-[JsonSerializable(typeof(GitHub.Copilot.SDK.Rpc.SessionMode))]
+[JsonSerializable(typeof(GitHub.Copilot.SDK.SessionMode))]
internal partial class ForwardCompatibilityJsonContext : JsonSerializerContext;
diff --git a/dotnet/test/Unit/SessionEventSerializationTests.cs b/dotnet/test/Unit/SessionEventSerializationTests.cs
index 9299d2f2c..9e2742deb 100644
--- a/dotnet/test/Unit/SessionEventSerializationTests.cs
+++ b/dotnet/test/Unit/SessionEventSerializationTests.cs
@@ -85,7 +85,7 @@ public class SessionEventSerializationTests
{
ShutdownType = ShutdownType.Routine,
TotalPremiumRequests = 1,
- TotalApiDurationMs = 100,
+ TotalApiDurationMs = TimeSpan.FromMilliseconds(100),
SessionStartTime = 1773609948932,
CodeChanges = new ShutdownCodeChanges
{
diff --git a/go/internal/e2e/per_session_auth_e2e_test.go b/go/internal/e2e/per_session_auth_e2e_test.go
index 8fa066b73..d40546028 100644
--- a/go/internal/e2e/per_session_auth_e2e_test.go
+++ b/go/internal/e2e/per_session_auth_e2e_test.go
@@ -1,6 +1,7 @@
package e2e
import (
+ "strings"
"testing"
copilot "github.com/github/copilot-sdk/go"
@@ -99,7 +100,15 @@ func TestPerSessionAuthE2E(t *testing.T) {
t.Run("should be unauthenticated without token", func(t *testing.T) {
ctx.ConfigureForTest(t)
- session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{
+ noTokenClient := copilot.NewClient(&copilot.ClientOptions{
+ CLIPath: ctx.CLIPath,
+ Cwd: ctx.WorkDir,
+ Env: withoutAuthEnv(append(ctx.Env(), "COPILOT_DEBUG_GITHUB_API_URL="+ctx.ProxyURL)),
+ UseLoggedInUser: copilot.Bool(false),
+ })
+ t.Cleanup(func() { noTokenClient.ForceStop() })
+
+ session, err := noTokenClient.CreateSession(t.Context(), &copilot.SessionConfig{
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
})
if err != nil {
@@ -132,3 +141,16 @@ func TestPerSessionAuthE2E(t *testing.T) {
t.Logf("Got expected error: %v", err)
})
}
+
+func withoutAuthEnv(env []string) []string {
+ filtered := make([]string, 0, len(env)+3)
+ for _, entry := range env {
+ if strings.HasPrefix(entry, "COPILOT_SDK_AUTH_TOKEN=") ||
+ strings.HasPrefix(entry, "GH_TOKEN=") ||
+ strings.HasPrefix(entry, "GITHUB_TOKEN=") {
+ continue
+ }
+ filtered = append(filtered, entry)
+ }
+ return append(filtered, "COPILOT_SDK_AUTH_TOKEN=", "GH_TOKEN=", "GITHUB_TOKEN=")
+}
diff --git a/go/internal/e2e/rpc_mcp_config_e2e_test.go b/go/internal/e2e/rpc_mcp_config_e2e_test.go
index e87e5c91e..528c92080 100644
--- a/go/internal/e2e/rpc_mcp_config_e2e_test.go
+++ b/go/internal/e2e/rpc_mcp_config_e2e_test.go
@@ -21,11 +21,11 @@ func TestRpcMcpConfigE2E(t *testing.T) {
serverName := fmt.Sprintf("sdk-test-%s", randomHex(t))
- baseConfig := &rpc.McpServerConfigLocal{
+ baseConfig := &rpc.McpServerConfigStdio{
Command: "node",
Args: []string{"-v"},
}
- updatedConfig := &rpc.McpServerConfigLocal{
+ updatedConfig := &rpc.McpServerConfigStdio{
Command: "node",
Args: []string{"--version"},
}
@@ -73,7 +73,7 @@ func TestRpcMcpConfigE2E(t *testing.T) {
if !present {
t.Fatalf("Expected %q to still be present after Update", serverName)
}
- updatedLocal, ok := updated.(*rpc.McpServerConfigLocal)
+ updatedLocal, ok := updated.(*rpc.McpServerConfigStdio)
if !ok {
t.Fatalf("Expected local MCP config, got %T", updated)
}
diff --git a/go/internal/e2e/rpc_server_e2e_test.go b/go/internal/e2e/rpc_server_e2e_test.go
index 35a71e24e..7b83ca586 100644
--- a/go/internal/e2e/rpc_server_e2e_test.go
+++ b/go/internal/e2e/rpc_server_e2e_test.go
@@ -5,6 +5,7 @@ import (
"path/filepath"
"strings"
"testing"
+ "time"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/internal/e2e/testharness"
@@ -117,7 +118,11 @@ func TestRpcServerE2E(t *testing.T) {
if !chat.OverageAllowedWithExhaustedQuota {
t.Errorf("Expected OverageAllowedWithExhaustedQuota=true")
}
- if chat.ResetDate == nil || *chat.ResetDate != "2026-04-30T00:00:00Z" {
+ expectedResetDate, err := time.Parse(time.RFC3339, "2026-04-30T00:00:00Z")
+ if err != nil {
+ t.Fatalf("Parse expected reset date: %v", err)
+ }
+ if chat.ResetDate == nil || !chat.ResetDate.Equal(expectedResetDate) {
t.Errorf("Expected ResetDate='2026-04-30T00:00:00Z', got %v", chat.ResetDate)
}
})
diff --git a/go/internal/e2e/session_fs_e2e_test.go b/go/internal/e2e/session_fs_e2e_test.go
index d56dc14a3..a23613c72 100644
--- a/go/internal/e2e/session_fs_e2e_test.go
+++ b/go/internal/e2e/session_fs_e2e_test.go
@@ -473,6 +473,23 @@ func (h *testSessionFsHandler) Rename(src string, dest string) error {
return os.Rename(providerPath(h.root, h.sessionID, src), destPath)
}
+func (h *testSessionFsHandler) SqliteQuery(sessionID string, query string, queryType rpc.SessionFsSqliteQueryType, params map[string]any) (*rpc.SessionFsSqliteQueryResult, error) {
+ return &rpc.SessionFsSqliteQueryResult{
+ Columns: []string{"sessionId", "query", "queryType", "answer"},
+ Rows: []map[string]any{{
+ "sessionId": sessionID,
+ "query": query,
+ "queryType": string(queryType),
+ "answer": params["answer"],
+ }},
+ RowsAffected: 0,
+ }, nil
+}
+
+func (h *testSessionFsHandler) SqliteExists(sessionID string) (bool, error) {
+ return sessionID == h.sessionID, nil
+}
+
func providerPath(root string, sessionID string, path string) string {
trimmed := strings.TrimPrefix(path, "/")
if trimmed == "" {
@@ -636,6 +653,28 @@ func TestSessionFsHandlerOperationsE2E(t *testing.T) {
if _, err := handler.Stat("/workspace/nested/missing.txt"); err == nil || !os.IsNotExist(err) {
t.Errorf("Expected os.ErrNotExist from Stat on missing file, got %v", err)
}
+
+ sqliteResult, err := handler.SqliteQuery(sessionID, "select :answer as answer", rpc.SessionFsSqliteQueryTypeQuery, map[string]any{"answer": 42})
+ if err != nil {
+ t.Fatalf("SqliteQuery failed: %v", err)
+ }
+ if len(sqliteResult.Columns) != 4 || sqliteResult.Columns[3] != "answer" {
+ t.Errorf("Expected SQLite result columns to include answer, got %v", sqliteResult.Columns)
+ }
+ if len(sqliteResult.Rows) != 1 || sqliteResult.Rows[0]["answer"] != 42 {
+ t.Errorf("Expected SQLite result row to include answer=42, got %+v", sqliteResult.Rows)
+ }
+ if sqliteResult.RowsAffected != 0 {
+ t.Errorf("Expected RowsAffected=0, got %d", sqliteResult.RowsAffected)
+ }
+
+ sqliteExists, err := handler.SqliteExists(sessionID)
+ if err != nil {
+ t.Fatalf("SqliteExists failed: %v", err)
+ }
+ if !sqliteExists {
+ t.Error("Expected SQLite database to exist for the handler session")
+ }
}
func sliceContains(slice []string, value string) bool {
diff --git a/go/internal/e2e/testharness/context.go b/go/internal/e2e/testharness/context.go
index e8efda82f..d7d30e090 100644
--- a/go/internal/e2e/testharness/context.go
+++ b/go/internal/e2e/testharness/context.go
@@ -12,6 +12,8 @@ import (
copilot "github.com/github/copilot-sdk/go"
)
+const defaultGitHubToken = "fake-token-for-e2e-tests"
+
var (
cliPath string
cliPathOnce sync.Once
@@ -81,6 +83,20 @@ func NewTestContext(t *testing.T) *TestContext {
os.RemoveAll(workDir)
t.Fatalf("Failed to start proxy: %v", err)
}
+ if err := proxy.SetCopilotUserByToken(defaultGitHubToken, map[string]interface{}{
+ "login": "e2e-test-user",
+ "copilot_plan": "individual_pro",
+ "endpoints": map[string]interface{}{
+ "api": proxyURL,
+ "telemetry": "https://localhost:1/telemetry",
+ },
+ "analytics_tracking_id": "e2e-test-tracking-id",
+ }); err != nil {
+ proxy.StopWithOptions(true)
+ os.RemoveAll(homeDir)
+ os.RemoveAll(workDir)
+ t.Fatalf("Failed to configure default Copilot user: %v", err)
+ }
ctx := &TestContext{
CLIPath: cliPath,
@@ -167,16 +183,13 @@ func (c *TestContext) Env() []string {
env = append(env,
"COPILOT_API_URL="+c.ProxyURL,
"COPILOT_HOME="+c.HomeDir,
+ "COPILOT_SDK_AUTH_TOKEN="+defaultGitHubToken,
"GH_CONFIG_DIR="+c.HomeDir,
+ "GH_TOKEN="+defaultGitHubToken,
+ "GITHUB_TOKEN="+defaultGitHubToken,
"XDG_CONFIG_HOME="+c.HomeDir,
"XDG_STATE_HOME="+c.HomeDir,
)
- if os.Getenv("GITHUB_ACTIONS") == "true" {
- env = append(env,
- "GH_TOKEN=fake-token-for-e2e-tests",
- "GITHUB_TOKEN=fake-token-for-e2e-tests",
- )
- }
return env
}
@@ -193,9 +206,8 @@ func (c *TestContext) NewClient(opts ...func(*copilot.ClientOptions)) *copilot.C
opt(options)
}
- // Use fake token in CI to allow cached responses without real auth for spawned subprocess clients.
- if os.Getenv("GITHUB_ACTIONS") == "true" && options.GitHubToken == "" && options.CLIUrl == "" {
- options.GitHubToken = "fake-token-for-e2e-tests"
+ if options.GitHubToken == "" && options.CLIUrl == "" {
+ options.GitHubToken = defaultGitHubToken
}
return copilot.NewClient(options)
diff --git a/go/rpc/generated_rpc_api_shape_test.go b/go/rpc/generated_rpc_api_shape_test.go
index 496630c55..bddbb263d 100644
--- a/go/rpc/generated_rpc_api_shape_test.go
+++ b/go/rpc/generated_rpc_api_shape_test.go
@@ -15,9 +15,9 @@ var (
_ ExternalToolResult = ExternalToolStringResult("")
_ ExternalToolResult = (*ExternalToolTextResultForLlm)(nil)
_ FilterMapping = FilterMappingEnumMap{}
- _ FilterMapping = FilterMappingStringMarkdown
+ _ FilterMapping = ContentFilterModeMarkdown
_ McpServerConfig = (*McpServerConfigHTTP)(nil)
- _ McpServerConfig = (*McpServerConfigLocal)(nil)
+ _ McpServerConfig = (*McpServerConfigStdio)(nil)
_ UIElicitationFieldValue = UIElicitationStringValue("")
_ UIElicitationFieldValue = UIElicitationStringArrayValue(nil)
_ UIElicitationFieldValue = UIElicitationBooleanValue(false)
@@ -32,14 +32,14 @@ func TestGeneratedRPCAPIShape(t *testing.T) {
assertStructFieldType(t, file, fileSet, "HandlePendingToolCallRequest", "Result", "ExternalToolResult")
assertInterfaceType(t, file, "FilterMapping")
- assertTypeExpr(t, fileSet, findTypeSpec(t, file, "FilterMappingEnumMap").Type, "map[string]FilterMappingValue")
+ assertTypeExpr(t, fileSet, findTypeSpec(t, file, "FilterMappingEnumMap").Type, "map[string]ContentFilterMode")
assertInterfaceType(t, file, "McpServerConfig")
assertStructFieldType(t, file, fileSet, "McpConfigAddRequest", "Config", "McpServerConfig")
assertStructFieldType(t, file, fileSet, "McpConfigList", "Servers", "map[string]McpServerConfig")
assertStructFieldType(t, file, fileSet, "McpConfigUpdateRequest", "Config", "McpServerConfig")
assertStructFieldType(t, file, fileSet, "McpServerConfigHTTP", "FilterMapping", "FilterMapping")
- assertStructFieldType(t, file, fileSet, "McpServerConfigLocal", "FilterMapping", "FilterMapping")
+ assertStructFieldType(t, file, fileSet, "McpServerConfigStdio", "FilterMapping", "FilterMapping")
assertInterfaceType(t, file, "UIElicitationFieldValue")
assertTypeExpr(t, fileSet, findTypeSpec(t, file, "UIElicitationStringArrayValue").Type, "[]string")
diff --git a/go/rpc/generated_rpc_union_test.go b/go/rpc/generated_rpc_union_test.go
index b33141926..8a85ee398 100644
--- a/go/rpc/generated_rpc_union_test.go
+++ b/go/rpc/generated_rpc_union_test.go
@@ -47,7 +47,7 @@ func TestExternalToolResultJSONUnion(t *testing.T) {
}
func TestFilterMappingJSONUnion(t *testing.T) {
- var mapping FilterMapping = FilterMappingEnumMap{"secret": FilterMappingValueHiddenCharacters}
+ var mapping FilterMapping = FilterMappingEnumMap{"secret": ContentFilterModeHiddenCharacters}
raw, err := json.Marshal(mapping)
if err != nil {
t.Fatalf("marshal filter mapping map: %v", err)
@@ -61,11 +61,11 @@ func TestFilterMappingJSONUnion(t *testing.T) {
t.Fatalf("unmarshal filter mapping map: %v", err)
}
decodedMapValue, ok := decodedMap.(FilterMappingEnumMap)
- if !ok || decodedMapValue["secret"] != FilterMappingValueHiddenCharacters {
+ if !ok || decodedMapValue["secret"] != ContentFilterModeHiddenCharacters {
t.Fatalf("unmarshal filter mapping map = %#v", decodedMap)
}
- var enumValue FilterMapping = FilterMappingStringMarkdown
+ var enumValue FilterMapping = ContentFilterModeMarkdown
raw, err = json.Marshal(enumValue)
if err != nil {
t.Fatalf("marshal filter mapping enum: %v", err)
@@ -78,14 +78,14 @@ func TestFilterMappingJSONUnion(t *testing.T) {
if err != nil {
t.Fatalf("unmarshal filter mapping enum: %v", err)
}
- decodedEnumValue, ok := decodedEnum.(FilterMappingString)
- if !ok || decodedEnumValue != FilterMappingStringMarkdown {
+ decodedEnumValue, ok := decodedEnum.(ContentFilterMode)
+ if !ok || decodedEnumValue != ContentFilterModeMarkdown {
t.Fatalf("unmarshal filter mapping enum = %#v", decodedEnum)
}
}
func TestMcpServerConfigJSONUnion(t *testing.T) {
- var localConfig McpServerConfig = &McpServerConfigLocal{
+ var localConfig McpServerConfig = &McpServerConfigStdio{
Args: []string{"-v"},
Command: "node",
}
@@ -101,7 +101,7 @@ func TestMcpServerConfigJSONUnion(t *testing.T) {
if err != nil {
t.Fatalf("unmarshal local config: %v", err)
}
- decodedLocalValue, ok := decodedLocal.(*McpServerConfigLocal)
+ decodedLocalValue, ok := decodedLocal.(*McpServerConfigStdio)
if !ok || decodedLocalValue.Command != "node" || len(decodedLocalValue.Args) != 1 || decodedLocalValue.Args[0] != "-v" {
t.Fatalf("unmarshal local config = %#v", decodedLocal)
}
diff --git a/go/session_fs_provider.go b/go/session_fs_provider.go
index 197b3fc20..6051a5e4a 100644
--- a/go/session_fs_provider.go
+++ b/go/session_fs_provider.go
@@ -44,6 +44,10 @@ type SessionFsProvider interface {
Rm(path string, recursive bool, force bool) error
// Rename moves/renames a file or directory.
Rename(src string, dest string) error
+ // SqliteQuery executes a SQLite query against the provider's per-session database.
+ SqliteQuery(sessionID string, query string, queryType rpc.SessionFsSqliteQueryType, params map[string]any) (*rpc.SessionFsSqliteQueryResult, error)
+ // SqliteExists checks whether the provider has a SQLite database for the session.
+ SqliteExists(sessionID string) (bool, error)
}
// SessionFsFileInfo holds file metadata returned by SessionFsProvider.Stat.
@@ -164,6 +168,27 @@ func (a *sessionFsAdapter) Rename(request *rpc.SessionFsRenameRequest) (*rpc.Ses
return nil, nil
}
+func (a *sessionFsAdapter) SqliteQuery(request *rpc.SessionFsSqliteQueryRequest) (*rpc.SessionFsSqliteQueryResult, error) {
+ result, err := a.provider.SqliteQuery(request.SessionID, request.Query, request.QueryType, request.Params)
+ if err != nil {
+ return &rpc.SessionFsSqliteQueryResult{
+ Columns: []string{},
+ Rows: []map[string]any{},
+ RowsAffected: 0,
+ Error: toSessionFsError(err),
+ }, nil
+ }
+ return result, nil
+}
+
+func (a *sessionFsAdapter) SqliteExists(request *rpc.SessionFsSqliteExistsRequest) (*rpc.SessionFsSqliteExistsResult, error) {
+ exists, err := a.provider.SqliteExists(request.SessionID)
+ if err != nil {
+ return &rpc.SessionFsSqliteExistsResult{Exists: false}, nil
+ }
+ return &rpc.SessionFsSqliteExistsResult{Exists: exists}, nil
+}
+
func toSessionFsError(err error) *rpc.SessionFsError {
code := rpc.SessionFsErrorCodeUNKNOWN
if errors.Is(err, os.ErrNotExist) {
diff --git a/go/types.go b/go/types.go
index 1bea26d84..cc30ff9d7 100644
--- a/go/types.go
+++ b/go/types.go
@@ -327,18 +327,6 @@ type AutoModeSwitchRequest struct {
RetryAfterSeconds *float64 `json:"retryAfterSeconds,omitempty"`
}
-// AutoModeSwitchResponse is the user's response to an auto-mode-switch request.
-type AutoModeSwitchResponse string
-
-const (
- // AutoModeSwitchResponseYes approves the switch for this rate-limit cycle.
- AutoModeSwitchResponseYes AutoModeSwitchResponse = "yes"
- // AutoModeSwitchResponseYesAlways approves and remembers the choice for this session.
- AutoModeSwitchResponseYesAlways AutoModeSwitchResponse = "yes_always"
- // AutoModeSwitchResponseNo declines the switch.
- AutoModeSwitchResponseNo AutoModeSwitchResponse = "no"
-)
-
// AutoModeSwitchInvocation provides context about an auto-mode-switch request.
type AutoModeSwitchInvocation struct {
SessionID string
diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts
index f8feacdbb..05b7d5ae6 100644
--- a/nodejs/src/generated/rpc.ts
+++ b/nodejs/src/generated/rpc.ts
@@ -355,8 +355,6 @@ export type UIElicitationSchemaPropertyNumberType = "number" | "integer";
*/
export type UIElicitationResponseAction = "accept" | "decline" | "cancel";
-export type SessionMode = SessionMode;
-
export interface AccountGetQuotaRequest {
/**
* GitHub token for per-user quota lookup. When provided, resolves this token to determine the user's quota instead of using the global auth.
diff --git a/nodejs/src/sessionFsProvider.ts b/nodejs/src/sessionFsProvider.ts
index 920ea3cd1..589a30358 100644
--- a/nodejs/src/sessionFsProvider.ts
+++ b/nodejs/src/sessionFsProvider.ts
@@ -7,6 +7,8 @@ import type {
SessionFsError,
SessionFsStatResult,
SessionFsReaddirWithTypesEntry,
+ SessionFsSqliteQueryResult,
+ SessionFsSqliteQueryType,
} from "./generated/rpc.js";
/**
@@ -55,6 +57,17 @@ export interface SessionFsProvider {
/** Renames/moves a file or directory. */
rename(src: string, dest: string): Promise;
+
+ /** Executes a SQLite query against the provider's per-session database. */
+ sqliteQuery(
+ sessionId: string,
+ query: string,
+ queryType: SessionFsSqliteQueryType,
+ params?: Record
+ ): Promise;
+
+ /** Checks whether the provider has a SQLite database for the session. */
+ sqliteExists(sessionId: string): Promise;
}
/**
@@ -149,6 +162,25 @@ export function createSessionFsAdapter(provider: SessionFsProvider): SessionFsHa
return toSessionFsError(err);
}
},
+ sqliteQuery: async ({ sessionId, query, queryType, params }) => {
+ try {
+ return await provider.sqliteQuery(sessionId, query, queryType, params);
+ } catch (err) {
+ return {
+ columns: [],
+ rows: [],
+ rowsAffected: 0,
+ error: toSessionFsError(err),
+ };
+ }
+ },
+ sqliteExists: async ({ sessionId }) => {
+ try {
+ return { exists: await provider.sqliteExists(sessionId) };
+ } catch {
+ return { exists: false };
+ }
+ },
};
}
diff --git a/nodejs/src/types.ts b/nodejs/src/types.ts
index 4d38eb5b9..f18e18ac1 100644
--- a/nodejs/src/types.ts
+++ b/nodejs/src/types.ts
@@ -233,7 +233,7 @@ export type ToolResultType = "success" | "failure" | "rejected" | "denied" | "ti
export type ToolBinaryResult = {
data: string;
mimeType: string;
- type: string;
+ type: "image" | "resource";
description?: string;
};
diff --git a/nodejs/test/e2e/harness/sdkTestContext.ts b/nodejs/test/e2e/harness/sdkTestContext.ts
index 7fe2b9cc7..af9642a50 100644
--- a/nodejs/test/e2e/harness/sdkTestContext.ts
+++ b/nodejs/test/e2e/harness/sdkTestContext.ts
@@ -14,6 +14,7 @@ import { CapiProxy } from "./CapiProxy";
import { retry, formatError } from "./sdkTestHelper";
export const isCI = process.env.GITHUB_ACTIONS === "true";
+export const DEFAULT_GITHUB_TOKEN = "fake-token-for-e2e-tests";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
@@ -35,12 +36,24 @@ export async function createSdkTestContext({
const openAiEndpoint = new CapiProxy();
const proxyUrl = await openAiEndpoint.start();
+ await openAiEndpoint.setCopilotUserByToken(DEFAULT_GITHUB_TOKEN, {
+ login: "e2e-test-user",
+ copilot_plan: "individual_pro",
+ endpoints: {
+ api: proxyUrl,
+ telemetry: "https://localhost:1/telemetry",
+ },
+ analytics_tracking_id: "e2e-test-tracking-id",
+ });
const env = {
...process.env,
...openAiEndpoint.getProxyEnv(),
COPILOT_API_URL: proxyUrl,
COPILOT_HOME: copilotHomeDir,
+ COPILOT_SDK_AUTH_TOKEN: DEFAULT_GITHUB_TOKEN,
GH_CONFIG_DIR: homeDir,
+ GH_TOKEN: DEFAULT_GITHUB_TOKEN,
+ GITHUB_TOKEN: DEFAULT_GITHUB_TOKEN,
// TODO: I'm not convinced the SDK should default to using whatever config you happen to have in your homedir.
// The SDK config should be independent of the regular CLI app. Likewise it shouldn't mix sessions from the
@@ -48,18 +61,13 @@ export async function createSdkTestContext({
XDG_CONFIG_HOME: homeDir,
XDG_STATE_HOME: homeDir,
};
- if (isCI) {
- env.GH_TOKEN = "fake-token-for-e2e-tests";
- env.GITHUB_TOKEN = "fake-token-for-e2e-tests";
- }
const copilotClient = new CopilotClient({
cwd: workDir,
env,
logLevel: logLevel || "error",
cliPath: process.env.COPILOT_CLI_PATH,
- // Use fake token in CI to allow cached responses without real auth
- gitHubToken: isCI ? "fake-token-for-e2e-tests" : undefined,
+ gitHubToken: DEFAULT_GITHUB_TOKEN,
useStdio: useStdio,
...copilotClientOptions,
});
diff --git a/nodejs/test/e2e/per_session_auth.e2e.test.ts b/nodejs/test/e2e/per_session_auth.e2e.test.ts
index 8ba753069..e2bf6c197 100644
--- a/nodejs/test/e2e/per_session_auth.e2e.test.ts
+++ b/nodejs/test/e2e/per_session_auth.e2e.test.ts
@@ -3,11 +3,11 @@
*--------------------------------------------------------------------------------------------*/
import { describe, expect, it } from "vitest";
-import { approveAll } from "../../src/index.js";
+import { approveAll, CopilotClient } from "../../src/index.js";
import { createSdkTestContext } from "./harness/sdkTestContext.js";
describe("Per-session GitHub auth", async () => {
- const { copilotClient: client, openAiEndpoint, env } = await createSdkTestContext();
+ const { copilotClient: client, openAiEndpoint, env, workDir } = await createSdkTestContext();
// Redirect GitHub API calls (e.g., fetchCopilotUser) to the proxy
// so per-session auth token resolution can be tested
@@ -76,17 +76,32 @@ describe("Per-session GitHub auth", async () => {
});
it("should return unauthenticated when no token is provided", async () => {
- const session = await client.createSession({
- onPermissionRequest: approveAll,
+ const noTokenClient = new CopilotClient({
+ cwd: workDir,
+ env: withoutAuthEnv({
+ ...env,
+ COPILOT_DEBUG_GITHUB_API_URL: env.COPILOT_API_URL,
+ }),
+ logLevel: "error",
+ cliPath: process.env.COPILOT_CLI_PATH,
+ useLoggedInUser: false,
});
- const authStatus = await session.rpc.auth.getStatus();
- // Without a per-session GitHub token, there is no per-session identity.
- // In CI the process-level fake token may still authenticate globally,
- // so we check login rather than isAuthenticated.
- expect(authStatus.login).toBeFalsy();
-
- await session.disconnect();
+ try {
+ const session = await noTokenClient.createSession({
+ onPermissionRequest: approveAll,
+ });
+
+ const authStatus = await session.rpc.auth.getStatus();
+ // Without a per-session GitHub token, there is no per-session identity.
+ // In CI the process-level fake token may still authenticate globally,
+ // so we check login rather than isAuthenticated.
+ expect(authStatus.login).toBeFalsy();
+
+ await session.disconnect();
+ } finally {
+ await noTokenClient.stop();
+ }
});
it("should error when creating session with invalid token", async () => {
@@ -98,3 +113,12 @@ describe("Per-session GitHub auth", async () => {
).rejects.toThrow(/401|Unauthorized/i);
});
});
+
+function withoutAuthEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
+ return {
+ ...env,
+ COPILOT_SDK_AUTH_TOKEN: "",
+ GH_TOKEN: "",
+ GITHUB_TOKEN: "",
+ };
+}
diff --git a/nodejs/test/e2e/session_fs.e2e.test.ts b/nodejs/test/e2e/session_fs.e2e.test.ts
index a28a2713c..4181152aa 100644
--- a/nodejs/test/e2e/session_fs.e2e.test.ts
+++ b/nodejs/test/e2e/session_fs.e2e.test.ts
@@ -269,6 +269,16 @@ describe("Session Fs Adapter", () => {
async rename(src: string, dest: string): Promise {
await provider.rename(src, dest);
},
+ async sqliteQuery(sessionId, query, queryType, params) {
+ return {
+ columns: ["sessionId", "query", "queryType", "answer"],
+ rows: [{ sessionId, query, queryType, answer: params?.answer }],
+ rowsAffected: 0,
+ };
+ },
+ async sqliteExists(sessionId) {
+ return sessionId === "handler-session";
+ },
};
const handler = createSessionFsAdapter(userProvider);
@@ -339,6 +349,25 @@ describe("Session Fs Adapter", () => {
const missing = await handler.stat(params({ path: "/workspace/nested/missing.txt" }));
expect(missing.error?.code).toBe("ENOENT");
+
+ const sqliteQuery = await handler.sqliteQuery({
+ sessionId,
+ query: "select :answer as answer",
+ queryType: "query",
+ params: { answer: 42 },
+ });
+ expect(sqliteQuery.columns).toContain("answer");
+ expect(sqliteQuery.rows[0]).toMatchObject({
+ sessionId,
+ query: "select :answer as answer",
+ queryType: "query",
+ answer: 42,
+ });
+ expect(sqliteQuery.rowsAffected).toBe(0);
+ expect(sqliteQuery.error).toBeUndefined();
+
+ const sqliteExists = await handler.sqliteExists({ sessionId });
+ expect(sqliteExists.exists).toBe(true);
});
it("converts provider exceptions to RPC errors", async () => {
@@ -376,6 +405,12 @@ describe("Session Fs Adapter", () => {
rename: async () => {
throw enoent;
},
+ sqliteQuery: async () => {
+ throw enoent;
+ },
+ sqliteExists: async () => {
+ throw enoent;
+ },
};
const handler = createSessionFsAdapter(throwing);
@@ -410,6 +445,18 @@ describe("Session Fs Adapter", () => {
assertEnoent((await handler.readdirWithTypes({ path: "missing-dir" } as never)).error);
assertEnoent(await handler.rm({ path: "missing.txt" } as never));
assertEnoent(await handler.rename({ src: "missing.txt", dest: "dest.txt" } as never));
+ const sqliteQuery = await handler.sqliteQuery({
+ sessionId: "throw-session",
+ query: "select 1",
+ queryType: "query",
+ });
+ assertEnoent(sqliteQuery.error);
+ expect(sqliteQuery.columns).toEqual([]);
+ expect(sqliteQuery.rows).toEqual([]);
+ expect(sqliteQuery.rowsAffected).toBe(0);
+
+ const sqliteExistsResult = await handler.sqliteExists({ sessionId: "throw-session" });
+ expect(sqliteExistsResult.exists).toBe(false);
// Non-ENOENT errors map to UNKNOWN.
const unknown: SessionFsProvider = {
@@ -508,5 +555,15 @@ function createTestSessionFsHandler(
async rename(src: string, dest: string): Promise {
await provider.rename(sp(src), sp(dest));
},
+ async sqliteQuery() {
+ return {
+ columns: [],
+ rows: [],
+ rowsAffected: 0,
+ };
+ },
+ async sqliteExists(sessionId) {
+ return sessionId === session.sessionId;
+ },
};
}
diff --git a/nodejs/test/session_fs_adapter.test.ts b/nodejs/test/session_fs_adapter.test.ts
index 1c4044c7a..7bed1f8c1 100644
--- a/nodejs/test/session_fs_adapter.test.ts
+++ b/nodejs/test/session_fs_adapter.test.ts
@@ -59,6 +59,18 @@ describe("SessionFsAdapter", () => {
async rename(src, dest) {
await memoryProvider.rename(sp(src), sp(dest));
},
+ async sqliteQuery(actualSessionId, query, queryType, params) {
+ return {
+ columns: ["sessionId", "query", "queryType", "answer"],
+ rows: [
+ { sessionId: actualSessionId, query, queryType, answer: params?.answer },
+ ],
+ rowsAffected: 0,
+ };
+ },
+ async sqliteExists(actualSessionId) {
+ return actualSessionId === sessionId;
+ },
};
const handler = createSessionFsAdapter(provider);
@@ -149,6 +161,25 @@ describe("SessionFsAdapter", () => {
path: "/workspace/nested/missing.txt",
});
expect(missing.error?.code).toBe("ENOENT");
+
+ const sqliteResult = await handler.sqliteQuery({
+ sessionId,
+ query: "select :answer as answer",
+ queryType: "query",
+ params: { answer: 42 },
+ });
+ expect(sqliteResult.columns).toContain("answer");
+ expect(sqliteResult.rows[0]).toMatchObject({
+ sessionId,
+ query: "select :answer as answer",
+ queryType: "query",
+ answer: 42,
+ });
+ expect(sqliteResult.rowsAffected).toBe(0);
+ expect(sqliteResult.error).toBeUndefined();
+
+ const sqliteExists = await handler.sqliteExists({ sessionId });
+ expect(sqliteExists.exists).toBe(true);
});
it("converts provider exceptions to rpc errors", async () => {
@@ -172,6 +203,8 @@ describe("SessionFsAdapter", () => {
readdirWithTypes: () => Promise.reject(error),
rm: () => Promise.reject(error),
rename: () => Promise.reject(error),
+ sqliteQuery: () => Promise.reject(error),
+ sqliteExists: () => Promise.reject(error),
};
}
@@ -202,6 +235,16 @@ describe("SessionFsAdapter", () => {
assertEnoent((await handler.readdirWithTypes({ sessionId, path: "missing-dir" })).error);
assertEnoent(await handler.rm({ sessionId, path: "missing.txt" }));
assertEnoent(await handler.rename({ sessionId, src: "missing.txt", dest: "dest.txt" }));
+ const sqliteQuery = await handler.sqliteQuery({
+ sessionId,
+ query: "select 1",
+ queryType: "query",
+ });
+ assertEnoent(sqliteQuery.error);
+ expect(sqliteQuery.columns).toEqual([]);
+ expect(sqliteQuery.rows).toEqual([]);
+ expect(sqliteQuery.rowsAffected).toBe(0);
+ expect((await handler.sqliteExists({ sessionId })).exists).toBe(false);
const unknownProvider = createSessionFsAdapter(makeThrowingProvider(makeError("bad path")));
const unknownError = await unknownProvider.writeFile({
diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py
index e7c969fd6..7aceb1e3b 100644
--- a/python/copilot/generated/rpc.py
+++ b/python/copilot/generated/rpc.py
@@ -4732,7 +4732,7 @@ class SessionFSSqliteQueryRequest:
session_id: str
"""Target session identifier"""
- params: dict[str, Optional[float | str]] | None = None
+ params: dict[str, float | str | None] | None = None
"""Optional named bind parameters"""
@staticmethod
diff --git a/python/copilot/session_fs_provider.py b/python/copilot/session_fs_provider.py
index 5435d3b56..f3bd89ef1 100644
--- a/python/copilot/session_fs_provider.py
+++ b/python/copilot/session_fs_provider.py
@@ -31,6 +31,9 @@
SessionFSReaddirWithTypesEntry,
SessionFSReaddirWithTypesResult,
SessionFSReadFileResult,
+ SessionFSSqliteExistsResult,
+ SessionFSSqliteQueryResult,
+ SessionFSSqliteQueryType,
SessionFSStatResult,
)
@@ -95,6 +98,20 @@ async def rm(self, path: str, recursive: bool, force: bool) -> None:
async def rename(self, src: str, dest: str) -> None:
"""Rename / move a file or directory."""
+ @abc.abstractmethod
+ async def sqlite_query(
+ self,
+ session_id: str,
+ query: str,
+ query_type: SessionFSSqliteQueryType,
+ params: dict[str, float | str | None] | None = None,
+ ) -> SessionFSSqliteQueryResult:
+ """Execute a SQLite query against the provider's per-session database."""
+
+ @abc.abstractmethod
+ async def sqlite_exists(self, session_id: str) -> bool:
+ """Return whether the provider has a SQLite database for *session_id*."""
+
def create_session_fs_adapter(provider: SessionFsProvider) -> SessionFsHandler:
"""Wrap a :class:`SessionFsProvider` into a :class:`SessionFsHandler`.
@@ -209,6 +226,29 @@ async def rename(self, params: object) -> SessionFSError | None:
except Exception as exc:
return _to_session_fs_error(exc)
+ async def sqlite_query(self, params: object) -> SessionFSSqliteQueryResult:
+ try:
+ return await self._p.sqlite_query( # type: ignore[attr-defined]
+ params.session_id,
+ params.query,
+ params.query_type,
+ getattr(params, "params", None),
+ )
+ except Exception as exc:
+ return SessionFSSqliteQueryResult(
+ columns=[],
+ rows=[],
+ rows_affected=0,
+ error=_to_session_fs_error(exc),
+ )
+
+ async def sqlite_exists(self, params: object) -> SessionFSSqliteExistsResult:
+ try:
+ result = await self._p.sqlite_exists(params.session_id) # type: ignore[attr-defined]
+ return SessionFSSqliteExistsResult.from_dict({"exists": result})
+ except Exception:
+ return SessionFSSqliteExistsResult.from_dict({"exists": False})
+
def _to_session_fs_error(exc: Exception) -> SessionFSError:
code = SessionFSErrorCode.ENOENT if _is_enoent(exc) else SessionFSErrorCode.UNKNOWN
diff --git a/python/e2e/test_per_session_auth_e2e.py b/python/e2e/test_per_session_auth_e2e.py
index 0f07824c1..7bc32bce2 100644
--- a/python/e2e/test_per_session_auth_e2e.py
+++ b/python/e2e/test_per_session_auth_e2e.py
@@ -2,6 +2,7 @@
import pytest
+from copilot.client import CopilotClient, SubprocessConfig
from copilot.session import PermissionHandler
from .testharness import E2ETestContext
@@ -93,18 +94,32 @@ async def test_should_isolate_auth_between_sessions_with_different_tokens(
async def test_should_return_unauthenticated_when_no_token_provided(
self, auth_ctx: E2ETestContext
):
- session = await auth_ctx.client.create_session(
- on_permission_request=PermissionHandler.approve_all,
+ env = without_auth_env(auth_ctx.get_env())
+ env["COPILOT_DEBUG_GITHUB_API_URL"] = auth_ctx.proxy_url
+ no_token_client = CopilotClient(
+ SubprocessConfig(
+ cli_path=auth_ctx.cli_path,
+ cwd=auth_ctx.work_dir,
+ env=env,
+ use_logged_in_user=False,
+ )
)
- auth_status = await session.rpc.auth.get_status()
- # Without a per-session token, there is no per-session identity.
- # In CI the process-level fake token may still authenticate globally,
- # so we check login rather than is_authenticated. On some platforms
- # the absence of a login may surface as None, on others as an empty string.
- assert not auth_status.login
+ try:
+ session = await no_token_client.create_session(
+ on_permission_request=PermissionHandler.approve_all,
+ )
- await session.disconnect()
+ auth_status = await session.rpc.auth.get_status()
+ # Without a per-session token, there is no per-session identity.
+ # In CI the process-level fake token may still authenticate globally,
+ # so we check login rather than is_authenticated. On some platforms
+ # the absence of a login may surface as None, on others as an empty string.
+ assert not auth_status.login
+
+ await session.disconnect()
+ finally:
+ await no_token_client.stop()
async def test_should_error_when_creating_session_with_invalid_token(
self, auth_ctx: E2ETestContext
@@ -114,3 +129,12 @@ async def test_should_error_when_creating_session_with_invalid_token(
on_permission_request=PermissionHandler.approve_all,
github_token="invalid-token-12345",
)
+
+
+def without_auth_env(env: dict[str, str]) -> dict[str, str]:
+ return {
+ **env,
+ "COPILOT_SDK_AUTH_TOKEN": "",
+ "GH_TOKEN": "",
+ "GITHUB_TOKEN": "",
+ }
diff --git a/python/e2e/test_session_fs_e2e.py b/python/e2e/test_session_fs_e2e.py
index e8fd85ca7..328ad9e02 100644
--- a/python/e2e/test_session_fs_e2e.py
+++ b/python/e2e/test_session_fs_e2e.py
@@ -17,12 +17,14 @@
from copilot.generated.rpc import (
SessionFSReaddirWithTypesEntry,
SessionFSReaddirWithTypesEntryType,
+ SessionFSSqliteQueryResult,
+ SessionFSSqliteQueryType,
)
from copilot.generated.session_events import SessionCompactionCompleteData, SessionEvent
from copilot.session import PermissionHandler
from copilot.session_fs_provider import SessionFsFileInfo, SessionFsProvider
-from .testharness import E2ETestContext
+from .testharness import DEFAULT_GITHUB_TOKEN, E2ETestContext
pytestmark = pytest.mark.asyncio(loop_scope="module")
@@ -44,15 +46,12 @@
@pytest_asyncio.fixture(scope="module", loop_scope="module")
async def session_fs_client(ctx: E2ETestContext):
- github_token = (
- "fake-token-for-e2e-tests" if os.environ.get("GITHUB_ACTIONS") == "true" else None
- )
client = CopilotClient(
SubprocessConfig(
cli_path=ctx.cli_path,
cwd=ctx.work_dir,
env=ctx.get_env(),
- github_token=github_token,
+ github_token=DEFAULT_GITHUB_TOKEN,
session_fs=SESSION_FS_CONFIG,
)
)
@@ -119,16 +118,13 @@ async def test_should_load_session_data_from_fs_provider_on_resume(
await session2.disconnect()
async def test_should_reject_setprovider_when_sessions_already_exist(self, ctx: E2ETestContext):
- github_token = (
- "fake-token-for-e2e-tests" if os.environ.get("GITHUB_ACTIONS") == "true" else None
- )
client1 = CopilotClient(
SubprocessConfig(
cli_path=ctx.cli_path,
cwd=ctx.work_dir,
env=ctx.get_env(),
use_stdio=False,
- github_token=github_token,
+ github_token=DEFAULT_GITHUB_TOKEN,
)
)
session = None
@@ -287,6 +283,8 @@ async def test_should_map_all_sessionfs_handler_operations(self, ctx: E2ETestCon
SessionFSReadFileRequest,
SessionFSRenameRequest,
SessionFSRmRequest,
+ SessionFSSqliteExistsRequest,
+ SessionFSSqliteQueryRequest,
SessionFSStatRequest,
SessionFSWriteFileRequest,
)
@@ -397,6 +395,31 @@ async def test_should_map_all_sessionfs_handler_operations(self, ctx: E2ETestCon
from copilot.generated.rpc import SessionFSErrorCode
assert missing.error.code == SessionFSErrorCode.ENOENT
+
+ sqlite_query = await handler.sqlite_query(
+ SessionFSSqliteQueryRequest(
+ session_id=session_id,
+ query="select :answer as answer",
+ query_type=SessionFSSqliteQueryType.QUERY,
+ params={"answer": 42},
+ )
+ )
+ assert "answer" in sqlite_query.columns
+ assert sqlite_query.rows == [
+ {
+ "sessionId": session_id,
+ "query": "select :answer as answer",
+ "queryType": "query",
+ "answer": 42,
+ }
+ ]
+ assert sqlite_query.rows_affected == 0
+ assert sqlite_query.error is None
+
+ sqlite_exists = await handler.sqlite_exists(
+ SessionFSSqliteExistsRequest(session_id=session_id)
+ )
+ assert sqlite_exists.exists is True
finally:
try:
import shutil
@@ -416,6 +439,8 @@ async def test_sessionfsprovider_converts_exceptions_to_rpc_errors(self):
SessionFSReadFileRequest,
SessionFSRenameRequest,
SessionFSRmRequest,
+ SessionFSSqliteExistsRequest,
+ SessionFSSqliteQueryRequest,
SessionFSStatRequest,
SessionFSWriteFileRequest,
)
@@ -455,6 +480,12 @@ async def rm(self, path, recursive, force):
async def rename(self, src, dest):
raise self._exc
+ async def sqlite_query(self, session_id, query, query_type, params=None):
+ raise self._exc
+
+ async def sqlite_exists(self, session_id):
+ raise self._exc
+
def assert_fs_error(error) -> None:
assert error is not None
assert error.code == SessionFSErrorCode.ENOENT
@@ -511,6 +542,17 @@ def assert_fs_error(error) -> None:
SessionFSRenameRequest(session_id=sid, src="missing.txt", dest="dest.txt")
)
)
+ sqlite_query = await handler.sqlite_query(
+ SessionFSSqliteQueryRequest(
+ session_id=sid, query="select 1", query_type=SessionFSSqliteQueryType.QUERY
+ )
+ )
+ assert_fs_error(sqlite_query.error)
+ assert sqlite_query.columns == []
+ assert sqlite_query.rows == []
+ assert sqlite_query.rows_affected == 0
+ sqlite_exists = await handler.sqlite_exists(SessionFSSqliteExistsRequest(session_id=sid))
+ assert sqlite_exists.exists is False
unknown_handler = create_session_fs_adapter(_ThrowingProvider(RuntimeError("bad path")))
unknown_error = await unknown_handler.write_file(
@@ -588,6 +630,29 @@ async def rename(self, src: str, dest: str) -> None:
d.parent.mkdir(parents=True, exist_ok=True)
self._path(src).rename(d)
+ async def sqlite_query(
+ self,
+ session_id: str,
+ query: str,
+ query_type: SessionFSSqliteQueryType,
+ params: dict[str, float | str | None] | None = None,
+ ) -> SessionFSSqliteQueryResult:
+ return SessionFSSqliteQueryResult(
+ columns=["sessionId", "query", "queryType", "answer"],
+ rows=[
+ {
+ "sessionId": session_id,
+ "query": query,
+ "queryType": query_type.value,
+ "answer": params["answer"] if params else None,
+ }
+ ],
+ rows_affected=0,
+ )
+
+ async def sqlite_exists(self, session_id: str) -> bool:
+ return session_id == self._session_id
+
def create_test_session_fs_handler(provider_root: Path):
def create_handler(session):
diff --git a/python/e2e/testharness/__init__.py b/python/e2e/testharness/__init__.py
index 58a36028f..28558d687 100644
--- a/python/e2e/testharness/__init__.py
+++ b/python/e2e/testharness/__init__.py
@@ -1,11 +1,12 @@
"""Test harness for E2E tests."""
-from .context import CLI_PATH, E2ETestContext
+from .context import CLI_PATH, DEFAULT_GITHUB_TOKEN, E2ETestContext
from .helper import get_final_assistant_message, get_next_event_of_type
from .proxy import CapiProxy
__all__ = [
"CLI_PATH",
+ "DEFAULT_GITHUB_TOKEN",
"E2ETestContext",
"CapiProxy",
"get_final_assistant_message",
diff --git a/python/e2e/testharness/context.py b/python/e2e/testharness/context.py
index acebe5f91..dc31cfe92 100644
--- a/python/e2e/testharness/context.py
+++ b/python/e2e/testharness/context.py
@@ -38,6 +38,7 @@ def get_cli_path_for_tests() -> str:
CLI_PATH = get_cli_path_for_tests()
SNAPSHOTS_DIR = Path(__file__).parents[3] / "test" / "snapshots"
+DEFAULT_GITHUB_TOKEN = "fake-token-for-e2e-tests"
class E2ETestContext:
@@ -64,19 +65,27 @@ async def setup(self, cli_args: list[str] | None = None):
self._proxy = CapiProxy()
self.proxy_url = await self._proxy.start()
+ await self._proxy.set_copilot_user_by_token(
+ DEFAULT_GITHUB_TOKEN,
+ {
+ "login": "e2e-test-user",
+ "copilot_plan": "individual_pro",
+ "endpoints": {
+ "api": self.proxy_url,
+ "telemetry": "https://localhost:1/telemetry",
+ },
+ "analytics_tracking_id": "e2e-test-tracking-id",
+ },
+ )
# Create the shared client (like Node.js/Go do)
- # Use fake token in CI to allow cached responses without real auth
- github_token = (
- "fake-token-for-e2e-tests" if os.environ.get("GITHUB_ACTIONS") == "true" else None
- )
self._client = CopilotClient(
SubprocessConfig(
cli_path=self.cli_path,
cli_args=cli_args or [],
cwd=self.work_dir,
env=self.get_env(),
- github_token=github_token,
+ github_token=DEFAULT_GITHUB_TOKEN,
)
)
@@ -140,14 +149,14 @@ def get_env(self) -> dict:
{
"COPILOT_API_URL": self.proxy_url,
"COPILOT_HOME": self.home_dir,
+ "COPILOT_SDK_AUTH_TOKEN": DEFAULT_GITHUB_TOKEN,
"GH_CONFIG_DIR": self.home_dir,
+ "GH_TOKEN": DEFAULT_GITHUB_TOKEN,
"XDG_CONFIG_HOME": self.home_dir,
"XDG_STATE_HOME": self.home_dir,
+ "GITHUB_TOKEN": DEFAULT_GITHUB_TOKEN,
}
)
- if os.environ.get("GITHUB_ACTIONS") == "true":
- env["GH_TOKEN"] = "fake-token-for-e2e-tests"
- env["GITHUB_TOKEN"] = "fake-token-for-e2e-tests"
return env
@property
diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs
index b3857191f..1c7dd03a6 100644
--- a/rust/src/generated/api_types.rs
+++ b/rust/src/generated/api_types.rs
@@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
use super::session_events::{
McpServerSource, McpServerStatus, ReasoningSummary, SessionMode, SkillSource,
};
+
use crate::types::{RequestId, SessionId};
/// JSON-RPC method name constants.
diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs
index f477db536..dac970fd4 100644
--- a/rust/src/generated/rpc.rs
+++ b/rust/src/generated/rpc.rs
@@ -9,6 +9,7 @@
#![allow(clippy::too_many_arguments)]
use super::api_types::{rpc_methods, *};
+use super::session_events::SessionMode;
use crate::session::Session;
use crate::{Client, Error};
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index af30b4191..6585676ec 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -1062,6 +1062,7 @@ impl Client {
if let Some(cfg) = session_fs_config {
let session_fs_start = Instant::now();
let request = crate::generated::api_types::SessionFsSetProviderRequest {
+ capabilities: None,
conventions: cfg.conventions.into_wire(),
initial_cwd: cfg.initial_cwd,
session_state_path: cfg.session_state_path,
diff --git a/rust/src/session_fs.rs b/rust/src/session_fs.rs
index e675760a1..b4d860ee9 100644
--- a/rust/src/session_fs.rs
+++ b/rust/src/session_fs.rs
@@ -9,10 +9,9 @@
//! # Concurrency
//!
//! Each inbound `sessionFs.*` request is dispatched on its own spawned task,
-//! matching Node's behavior. Provider implementations MUST be safe for
-//! concurrent invocation across distinct paths. Use internal synchronization
-//! (e.g. [`tokio::sync::Mutex`] keyed by path) if your backing store needs
-//! ordering.
+//! so provider implementations MUST be safe for concurrent invocation across
+//! distinct paths. Use internal synchronization (e.g. [`tokio::sync::Mutex`]
+//! keyed by path) if your backing store needs ordering.
//!
//! # Errors
//!
@@ -41,6 +40,8 @@
//! }
//! ```
+use std::collections::HashMap;
+
use async_trait::async_trait;
use crate::generated::api_types::{
@@ -48,6 +49,8 @@ use crate::generated::api_types::{
SessionFsReaddirWithTypesEntryType, SessionFsSetProviderConventions, SessionFsStatResult,
};
+pub use crate::generated::api_types::{SessionFsSqliteQueryResult, SessionFsSqliteQueryType};
+
/// Configuration for a custom session filesystem provider.
///
/// When set on [`ClientOptions::session_fs`](crate::ClientOptions::session_fs),
@@ -344,6 +347,23 @@ pub trait SessionFsProvider: Send + Sync + 'static {
let _ = (src, dest);
Err(FsError::Other("rename not supported".to_string()))
}
+
+ /// Execute a SQLite query against the provider's per-session database.
+ async fn sqlite_query(
+ &self,
+ query: &str,
+ query_type: SessionFsSqliteQueryType,
+ params: &HashMap,
+ ) -> Result {
+ let _ = (query, query_type, params);
+ Err(FsError::Other("sqlite_query not supported".to_string()))
+ }
+
+ /// Check whether the provider has a SQLite database for the session.
+ async fn sqlite_exists(&self, session_id: &str) -> Result {
+ let _ = session_id;
+ Err(FsError::Other("sqlite_exists not supported".to_string()))
+ }
}
#[cfg(test)]
diff --git a/rust/src/session_fs_dispatch.rs b/rust/src/session_fs_dispatch.rs
index 7b2ae49fd..15fd0a969 100644
--- a/rust/src/session_fs_dispatch.rs
+++ b/rust/src/session_fs_dispatch.rs
@@ -16,9 +16,11 @@ use crate::generated::api_types::{
SessionFsMkdirRequest, SessionFsReadFileRequest, SessionFsReadFileResult,
SessionFsReaddirRequest, SessionFsReaddirResult, SessionFsReaddirWithTypesRequest,
SessionFsReaddirWithTypesResult, SessionFsRenameRequest, SessionFsRmRequest,
- SessionFsStatRequest, SessionFsStatResult, SessionFsWriteFileRequest,
+ SessionFsSqliteExistsParams, SessionFsSqliteExistsResult, SessionFsSqliteQueryRequest,
+ SessionFsSqliteQueryResult, SessionFsStatRequest, SessionFsStatResult,
+ SessionFsWriteFileRequest,
};
-use crate::session_fs::{FsError, SessionFsProvider};
+use crate::session_fs::SessionFsProvider;
use crate::{Client, JsonRpcRequest, JsonRpcResponse, error_codes};
/// Helper: serialize a typed result, send the response.
@@ -146,7 +148,6 @@ pub(crate) async fn exists(
}
};
let id = request.id;
- // Match Node's `createSessionFsAdapter`: errors collapse to `exists: false`.
let exists_value = provider.exists(¶ms.path).await.unwrap_or(false);
respond(
client,
@@ -302,6 +303,55 @@ pub(crate) async fn rename(
}
}
+pub(crate) async fn sqlite_query(
+ client: &Client,
+ provider: &Arc,
+ request: JsonRpcRequest,
+) {
+ let params: SessionFsSqliteQueryRequest = match parse_params(&request) {
+ Some(p) => p,
+ None => {
+ send_error(client, request.id, "invalid sessionFs.sqliteQuery params").await;
+ return;
+ }
+ };
+ let id = request.id;
+ let result = match provider
+ .sqlite_query(¶ms.query, params.query_type, ¶ms.params)
+ .await
+ {
+ Ok(result) => result,
+ Err(e) => SessionFsSqliteQueryResult {
+ columns: Vec::new(),
+ error: Some(e.into_wire()),
+ last_insert_rowid: None,
+ rows: Vec::new(),
+ rows_affected: 0,
+ },
+ };
+ respond(client, id, result).await;
+}
+
+pub(crate) async fn sqlite_exists(
+ client: &Client,
+ provider: &Arc,
+ request: JsonRpcRequest,
+) {
+ let params: SessionFsSqliteExistsParams = match parse_params(&request) {
+ Some(p) => p,
+ None => {
+ send_error(client, request.id, "invalid sessionFs.sqliteExists params").await;
+ return;
+ }
+ };
+ let id = request.id;
+ let result = match provider.sqlite_exists(params.session_id.as_ref()).await {
+ Ok(exists) => SessionFsSqliteExistsResult { exists },
+ Err(_) => SessionFsSqliteExistsResult { exists: false },
+ };
+ respond(client, id, result).await;
+}
+
/// Dispatch a `sessionFs.*` request to the appropriate handler. Returns
/// `true` if the request was a session-fs method (whether or not a provider
/// was registered), `false` otherwise (caller should continue matching).
@@ -338,6 +388,8 @@ pub(crate) async fn dispatch(
"sessionFs.readdirWithTypes" => readdir_with_types(client, &provider, request).await,
"sessionFs.rm" => rm(client, &provider, request).await,
"sessionFs.rename" => rename(client, &provider, request).await,
+ "sessionFs.sqliteQuery" => sqlite_query(client, &provider, request).await,
+ "sessionFs.sqliteExists" => sqlite_exists(client, &provider, request).await,
_ => {
warn!(method = %method, "unknown sessionFs.* method");
send_error(client, request.id, "unknown sessionFs method").await;
@@ -345,7 +397,3 @@ pub(crate) async fn dispatch(
}
true
}
-
-// FsError is used through `into_wire()` calls above.
-#[allow(dead_code)]
-fn _ensure_fs_error_used(_e: FsError) {}
diff --git a/rust/src/types.rs b/rust/src/types.rs
index e6b49c130..0f242445e 100644
--- a/rust/src/types.rs
+++ b/rust/src/types.rs
@@ -16,7 +16,7 @@ use crate::handler::SessionHandler;
use crate::hooks::SessionHooks;
pub use crate::session_fs::{
DirEntry, DirEntryKind, FileInfo, FsError, SessionFsConfig, SessionFsConventions,
- SessionFsProvider,
+ SessionFsProvider, SessionFsSqliteQueryResult, SessionFsSqliteQueryType,
};
pub use crate::trace_context::{TraceContext, TraceContextProvider};
use crate::transforms::SystemMessageTransform;
diff --git a/rust/tests/e2e/mode_handlers.rs b/rust/tests/e2e/mode_handlers.rs
index 53f7be255..1c997fccf 100644
--- a/rust/tests/e2e/mode_handlers.rs
+++ b/rust/tests/e2e/mode_handlers.rs
@@ -2,10 +2,13 @@ use std::sync::Arc;
use async_trait::async_trait;
use github_copilot_sdk::generated::session_events::{
- AutoModeSwitchCompletedData, AutoModeSwitchRequestedData, ExitPlanModeCompletedData,
- ExitPlanModeRequestedData, SessionEventType, SessionModelChangeData,
+ AutoModeSwitchCompletedData, AutoModeSwitchRequestedData,
+ AutoModeSwitchResponse as EventAutoModeSwitchResponse, ExitPlanModeAction,
+ ExitPlanModeCompletedData, ExitPlanModeRequestedData, SessionEventType, SessionModelChangeData,
+};
+use github_copilot_sdk::handler::{
+ AutoModeSwitchResponse as HandlerAutoModeSwitchResponse, ExitPlanModeResult, SessionHandler,
};
-use github_copilot_sdk::handler::{AutoModeSwitchResponse, ExitPlanModeResult, SessionHandler};
use github_copilot_sdk::{ExitPlanModeData, SessionConfig, SessionId};
use serde_json::json;
use tokio::sync::mpsc;
@@ -53,11 +56,11 @@ impl SessionHandler for AutoModeHandler {
session_id: SessionId,
error_code: Option,
retry_after_seconds: Option,
- ) -> AutoModeSwitchResponse {
+ ) -> HandlerAutoModeSwitchResponse {
let _ = self
.requests
.send((session_id, error_code, retry_after_seconds));
- AutoModeSwitchResponse::Yes
+ HandlerAutoModeSwitchResponse::Yes
}
}
@@ -102,7 +105,8 @@ async fn should_invoke_exit_plan_mode_handler_when_model_uses_tool() {
.typed_data::()
.is_some_and(|data| {
data.approved == Some(true)
- && data.selected_action.as_deref() == Some("interactive")
+ && data.selected_action
+ == Some(ExitPlanModeAction::Interactive)
})
},
));
@@ -144,10 +148,17 @@ async fn should_invoke_exit_plan_mode_handler_when_model_uses_tool() {
.typed_data::()
.expect("typed requested event");
assert_eq!(requested_data.summary, request.summary);
- assert_eq!(requested_data.actions, request.actions);
+ assert_eq!(
+ requested_data.actions,
+ [
+ ExitPlanModeAction::Interactive,
+ ExitPlanModeAction::Autopilot,
+ ExitPlanModeAction::ExitOnly,
+ ]
+ );
assert_eq!(
requested_data.recommended_action,
- request.recommended_action
+ ExitPlanModeAction::Interactive
);
let completed = completed_event.await.expect("completed task");
@@ -156,8 +167,8 @@ async fn should_invoke_exit_plan_mode_handler_when_model_uses_tool() {
.expect("typed completed event");
assert_eq!(completed_data.approved, Some(true));
assert_eq!(
- completed_data.selected_action.as_deref(),
- Some("interactive")
+ completed_data.selected_action,
+ Some(ExitPlanModeAction::Interactive)
);
assert_eq!(
completed_data.feedback.as_deref(),
@@ -215,7 +226,9 @@ async fn should_invoke_auto_mode_switch_handler_when_rate_limited() {
event.parsed_type() == SessionEventType::AutoModeSwitchCompleted
&& event
.typed_data::()
- .is_some_and(|data| data.response == "yes")
+ .is_some_and(|data| {
+ data.response == EventAutoModeSwitchResponse::Yes
+ })
},
));
let model_change_event =
@@ -258,7 +271,7 @@ async fn should_invoke_auto_mode_switch_handler_when_rate_limited() {
let completed_data = completed
.typed_data::()
.expect("typed completed event");
- assert_eq!(completed_data.response, "yes");
+ assert_eq!(completed_data.response, EventAutoModeSwitchResponse::Yes);
let model_change = model_change_event.await.expect("model change task");
let model_change_data = model_change
diff --git a/rust/tests/e2e/rpc_additional_edge_cases.rs b/rust/tests/e2e/rpc_additional_edge_cases.rs
index a85da53f0..c56b39844 100644
--- a/rust/tests/e2e/rpc_additional_edge_cases.rs
+++ b/rust/tests/e2e/rpc_additional_edge_cases.rs
@@ -1,6 +1,7 @@
+use github_copilot_sdk::generated::SessionMode;
use github_copilot_sdk::generated::api_types::{
ModeSetRequest, NameSetRequest, PermissionsSetApproveAllRequest, PlanUpdateRequest,
- SessionMode, ShellExecRequest, WorkspacesCreateFileRequest, WorkspacesReadFileRequest,
+ ShellExecRequest, WorkspacesCreateFileRequest, WorkspacesReadFileRequest,
};
use super::support::{wait_for_condition, with_e2e_context};
diff --git a/rust/tests/e2e/rpc_event_side_effects.rs b/rust/tests/e2e/rpc_event_side_effects.rs
index 1c39dc317..e68939f98 100644
--- a/rust/tests/e2e/rpc_event_side_effects.rs
+++ b/rust/tests/e2e/rpc_event_side_effects.rs
@@ -1,5 +1,6 @@
+use github_copilot_sdk::generated::SessionMode;
use github_copilot_sdk::generated::api_types::{
- HistoryTruncateRequest, ModeSetRequest, NameSetRequest, PlanUpdateRequest, SessionMode,
+ HistoryTruncateRequest, ModeSetRequest, NameSetRequest, PlanUpdateRequest,
WorkspacesCreateFileRequest,
};
use github_copilot_sdk::generated::session_events::{
@@ -30,7 +31,8 @@ async fn should_emit_mode_changed_event_when_mode_set() {
let data = event
.typed_data::()
.expect("mode changed data");
- data.previous_mode == "interactive" && data.new_mode == "plan"
+ data.previous_mode == SessionMode::Interactive
+ && data.new_mode == SessionMode::Plan
});
session
.rpc()
diff --git a/rust/tests/e2e/rpc_session_state.rs b/rust/tests/e2e/rpc_session_state.rs
index 83c527be7..e246e6a03 100644
--- a/rust/tests/e2e/rpc_session_state.rs
+++ b/rust/tests/e2e/rpc_session_state.rs
@@ -1,7 +1,8 @@
+use github_copilot_sdk::generated::SessionMode;
use github_copilot_sdk::generated::api_types::{
HistoryTruncateRequest, McpOauthLoginRequest, ModeSetRequest, ModelSwitchToRequest,
- NameSetRequest, PermissionsSetApproveAllRequest, PlanUpdateRequest, SessionMode,
- SessionsForkRequest, WorkspacesCreateFileRequest, WorkspacesReadFileRequest,
+ NameSetRequest, PermissionsSetApproveAllRequest, PlanUpdateRequest, SessionsForkRequest,
+ WorkspacesCreateFileRequest, WorkspacesReadFileRequest,
};
use github_copilot_sdk::generated::session_events::{
AssistantMessageData, SessionEventType, SessionTitleChangedData,
diff --git a/rust/tests/e2e/session_fs.rs b/rust/tests/e2e/session_fs.rs
index f069f6ffe..36d409c84 100644
--- a/rust/tests/e2e/session_fs.rs
+++ b/rust/tests/e2e/session_fs.rs
@@ -5,7 +5,7 @@ use async_trait::async_trait;
use github_copilot_sdk::generated::api_types::PlanUpdateRequest;
use github_copilot_sdk::{
Client, DirEntry, DirEntryKind, FileInfo, FsError, SessionConfig, SessionFsConfig,
- SessionFsConventions, SessionFsProvider,
+ SessionFsConventions, SessionFsProvider, SessionFsSqliteQueryResult, SessionFsSqliteQueryType,
};
use super::support::{assistant_message_content, wait_for_condition, with_e2e_context};
@@ -206,6 +206,23 @@ async fn should_map_all_sessionfs_handler_operations() {
provider.stat("/workspace/nested/missing.txt").await,
Err(FsError::NotFound(_))
));
+ let sqlite_result = provider
+ .sqlite_query(
+ "select :answer as answer",
+ SessionFsSqliteQueryType::Query,
+ &std::collections::HashMap::from([("answer".to_string(), serde_json::Value::from(42))]),
+ )
+ .await
+ .expect("sqlite query");
+ assert_eq!(sqlite_result.columns[3], "answer");
+ assert_eq!(sqlite_result.rows[0]["answer"], 42);
+ assert_eq!(sqlite_result.rows_affected, 0);
+ assert!(
+ provider
+ .sqlite_exists("handler-session")
+ .await
+ .expect("sqlite exists")
+ );
let _ = std::fs::remove_dir_all(root);
}
@@ -602,6 +619,51 @@ impl SessionFsProvider for TestSessionFsProvider {
}
std::fs::rename(src, dest).map_err(FsError::from)
}
+
+ async fn sqlite_query(
+ &self,
+ query: &str,
+ query_type: SessionFsSqliteQueryType,
+ params: &std::collections::HashMap,
+ ) -> Result {
+ let mut row = std::collections::HashMap::new();
+ row.insert("sessionId".to_string(), self.session_id.clone().into());
+ row.insert("query".to_string(), query.to_string().into());
+ row.insert(
+ "queryType".to_string(),
+ match query_type {
+ SessionFsSqliteQueryType::Exec => "exec",
+ SessionFsSqliteQueryType::Query => "query",
+ SessionFsSqliteQueryType::Run => "run",
+ SessionFsSqliteQueryType::Unknown => "unknown",
+ }
+ .into(),
+ );
+ row.insert(
+ "answer".to_string(),
+ params
+ .get("answer")
+ .cloned()
+ .unwrap_or(serde_json::Value::Null),
+ );
+
+ Ok(SessionFsSqliteQueryResult {
+ columns: vec![
+ "sessionId".to_string(),
+ "query".to_string(),
+ "queryType".to_string(),
+ "answer".to_string(),
+ ],
+ rows: vec![row],
+ rows_affected: 0,
+ last_insert_rowid: None,
+ error: None,
+ })
+ }
+
+ async fn sqlite_exists(&self, session_id: &str) -> Result {
+ Ok(session_id == self.session_id)
+ }
}
#[derive(Clone)]
diff --git a/rust/tests/session_test.rs b/rust/tests/session_test.rs
index 81ddf54f5..31359eca1 100644
--- a/rust/tests/session_test.rs
+++ b/rust/tests/session_test.rs
@@ -2912,6 +2912,7 @@ async fn command_execute_handler_error_propagates_to_ack() {
use github_copilot_sdk::session_fs::{
DirEntry, DirEntryKind, FileInfo, FsError, SessionFsConventions, SessionFsProvider,
+ SessionFsSqliteQueryResult, SessionFsSqliteQueryType,
};
struct RecordingFsProvider {
@@ -2983,6 +2984,53 @@ impl SessionFsProvider for RecordingFsProvider {
}
Ok(())
}
+
+ async fn sqlite_query(
+ &self,
+ query: &str,
+ query_type: SessionFsSqliteQueryType,
+ params: &std::collections::HashMap,
+ ) -> Result {
+ let mut row = std::collections::HashMap::new();
+ row.insert(
+ "query".to_string(),
+ serde_json::Value::String(query.to_string()),
+ );
+ row.insert(
+ "queryType".to_string(),
+ serde_json::Value::String(
+ match query_type {
+ SessionFsSqliteQueryType::Exec => "exec",
+ SessionFsSqliteQueryType::Query => "query",
+ SessionFsSqliteQueryType::Run => "run",
+ SessionFsSqliteQueryType::Unknown => "unknown",
+ }
+ .to_string(),
+ ),
+ );
+ row.insert(
+ "answer".to_string(),
+ params
+ .get("answer")
+ .cloned()
+ .unwrap_or(serde_json::Value::Null),
+ );
+ Ok(SessionFsSqliteQueryResult {
+ columns: vec![
+ "query".to_string(),
+ "queryType".to_string(),
+ "answer".to_string(),
+ ],
+ rows: vec![row],
+ rows_affected: 0,
+ last_insert_rowid: None,
+ error: None,
+ })
+ }
+
+ async fn sqlite_exists(&self, session_id: &str) -> Result {
+ Ok(!session_id.is_empty())
+ }
}
async fn create_session_pair_with_fs_provider(
@@ -3102,6 +3150,116 @@ async fn session_fs_maps_other_to_unknown() {
);
}
+#[tokio::test]
+async fn session_fs_dispatches_sqlite_query_to_provider() {
+ let provider = Arc::new(RecordingFsProvider::new());
+ let (_session, mut server) =
+ create_session_pair_with_fs_provider(Arc::new(NoopHandler), provider).await;
+
+ server
+ .send_request(
+ 9,
+ "sessionFs.sqliteQuery",
+ serde_json::json!({
+ "sessionId": server.session_id,
+ "query": "select :answer as answer",
+ "queryType": "query",
+ "params": { "answer": 42 },
+ }),
+ )
+ .await;
+
+ let response = timeout(TIMEOUT, server.read_response()).await.unwrap();
+ assert_eq!(response["id"], 9);
+ assert_eq!(response["result"]["columns"][2], "answer");
+ assert_eq!(
+ response["result"]["rows"][0]["query"],
+ "select :answer as answer"
+ );
+ assert_eq!(response["result"]["rows"][0]["queryType"], "query");
+ assert_eq!(response["result"]["rows"][0]["answer"], 42);
+ assert_eq!(response["result"]["rowsAffected"], 0);
+ assert!(response["result"].get("error").is_none() || response["result"]["error"].is_null());
+}
+
+#[tokio::test]
+async fn session_fs_dispatches_sqlite_exists_to_provider() {
+ let provider = Arc::new(RecordingFsProvider::new());
+ let (_session, mut server) =
+ create_session_pair_with_fs_provider(Arc::new(NoopHandler), provider).await;
+
+ server
+ .send_request(
+ 13,
+ "sessionFs.sqliteExists",
+ serde_json::json!({ "sessionId": server.session_id }),
+ )
+ .await;
+
+ let response = timeout(TIMEOUT, server.read_response()).await.unwrap();
+ assert_eq!(response["id"], 13);
+ assert_eq!(response["result"]["exists"], true);
+}
+
+#[tokio::test]
+async fn session_fs_maps_sqlite_errors_to_results() {
+ struct AlwaysFails;
+ #[async_trait]
+ impl SessionFsProvider for AlwaysFails {
+ async fn sqlite_query(
+ &self,
+ _query: &str,
+ _query_type: SessionFsSqliteQueryType,
+ _params: &std::collections::HashMap,
+ ) -> Result {
+ Err(FsError::Other("sqlite unavailable".to_string()))
+ }
+
+ async fn sqlite_exists(&self, _session_id: &str) -> Result {
+ Err(FsError::Other("sqlite unavailable".to_string()))
+ }
+ }
+
+ let (_session, mut server) =
+ create_session_pair_with_fs_provider(Arc::new(NoopHandler), Arc::new(AlwaysFails)).await;
+
+ server
+ .send_request(
+ 14,
+ "sessionFs.sqliteQuery",
+ serde_json::json!({
+ "sessionId": server.session_id,
+ "query": "select 1",
+ "queryType": "query",
+ }),
+ )
+ .await;
+ let response = timeout(TIMEOUT, server.read_response()).await.unwrap();
+ assert_eq!(response["id"], 14);
+ assert_eq!(response["result"]["columns"].as_array().unwrap().len(), 0);
+ assert_eq!(response["result"]["rows"].as_array().unwrap().len(), 0);
+ assert_eq!(response["result"]["rowsAffected"], 0);
+ let error = &response["result"]["error"];
+ assert_eq!(error["code"], "UNKNOWN");
+ assert!(
+ error["message"]
+ .as_str()
+ .unwrap()
+ .contains("sqlite unavailable")
+ );
+
+ server
+ .send_request(
+ 15,
+ "sessionFs.sqliteExists",
+ serde_json::json!({ "sessionId": server.session_id }),
+ )
+ .await;
+ let response = timeout(TIMEOUT, server.read_response()).await.unwrap();
+ assert_eq!(response["id"], 15);
+ assert_eq!(response["result"]["exists"], false);
+}
+
#[tokio::test]
async fn session_fs_dispatches_write_file_with_mode() {
let provider = Arc::new(RecordingFsProvider::new());
diff --git a/scripts/codegen/csharp.ts b/scripts/codegen/csharp.ts
index 95d3af21e..5033b7500 100644
--- a/scripts/codegen/csharp.ts
+++ b/scripts/codegen/csharp.ts
@@ -249,7 +249,7 @@ function isNonNullableCSharpValueType(typeName: string): boolean {
"long",
"DateTimeOffset",
"TimeSpan",
- ].includes(typeName) || generatedEnums.has(typeName) || emittedRpcEnumResultTypes.has(typeName);
+ ].includes(typeName) || generatedEnums.has(typeName) || emittedRpcEnumResultTypes.has(typeName) || externalRpcValueTypes.has(typeName);
}
async function formatCSharpFile(filePath: string): Promise {
@@ -1343,6 +1343,7 @@ let emittedRpcEnumResultTypes = new Set();
let experimentalRpcTypes = new Set();
let rpcKnownTypes = new Map();
let rpcEnumOutput: string[] = [];
+let externalRpcValueTypes = new Set();
/** Schema definitions available during RPC generation (for $ref resolution). */
let rpcDefinitions: DefinitionCollections = { definitions: {}, $defs: {} };
@@ -2113,7 +2114,8 @@ function emitClientSessionApiRegistration(clientSchema: Record,
function generateRpcCode(
schema: ApiSchema,
- externalJsonSerializableRefs: Map> = new Map()
+ externalJsonSerializableRefs: Map> = new Map(),
+ externalValueTypes: Set = new Set()
): string {
emittedRpcClassSchemas.clear();
emittedRpcEnumResultTypes.clear();
@@ -2121,6 +2123,7 @@ function generateRpcCode(
rpcKnownTypes.clear();
rpcEnumOutput = [];
generatedEnums.clear(); // Clear shared enum deduplication map
+ externalRpcValueTypes = new Set([...externalValueTypes].map(typeToClassName));
rpcDefinitions = collectDefinitionCollections(schema as Record);
for (const defs of [rpcDefinitions.definitions, rpcDefinitions.$defs]) {
for (const [name, def] of Object.entries(defs ?? {})) {
@@ -2205,6 +2208,7 @@ export async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSO
schema = rewriteSharedDefinitionReferences(schema, sharedDefinitions, "session-events.schema.json");
}
const externalJsonSerializableRefs = new Map>();
+ const externalValueTypes = new Set();
if (sessionEventsSchema) {
const sessionEventsCode = generateSessionEventsCode(sessionEventsSchema);
const externalRefs = collectExternalSchemaRefNames(schema);
@@ -2221,6 +2225,10 @@ export async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSO
if (declarationPattern.test(sessionEventsCode)) {
emittedDefinitions.add(name);
}
+ const valueTypeDeclarationPattern = new RegExp(`\\bpublic\\s+(?:(?:readonly)\\s+)?struct\\s+${typeName}\\b`);
+ if (valueTypeDeclarationPattern.test(sessionEventsCode)) {
+ externalValueTypes.add(name);
+ }
}
externalJsonSerializableRefs.set(
"session-events.schema.json",
@@ -2228,7 +2236,7 @@ export async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSO
);
}
}
- const code = generateRpcCode(schema, externalJsonSerializableRefs);
+ const code = generateRpcCode(schema, externalJsonSerializableRefs, externalValueTypes);
const outPath = await writeGeneratedFile("dotnet/src/Generated/Rpc.cs", code);
console.log(` ✓ ${outPath}`);
await formatCSharpFile(outPath);
diff --git a/scripts/codegen/python.ts b/scripts/codegen/python.ts
index 29c68da0d..8e1314022 100644
--- a/scripts/codegen/python.ts
+++ b/scripts/codegen/python.ts
@@ -2127,6 +2127,7 @@ async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSONSchema
typesCode = collapsePlaceholderPythonDataclasses(typesCode, knownDefNames);
typesCode = postProcessExternalUnionAliasesForPython(typesCode, externalUnionAliases);
typesCode = postProcessExternalRefsForPython(typesCode, externalRefs.placeholderNames);
+ typesCode = modernizePython(typesCode);
// Fix quicktype's Enum-suffix renaming: quicktype sometimes renames "Xyz" to
// "XyzEnum" to avoid internal collisions. Strip the suffix to match our schema
diff --git a/scripts/codegen/rust.ts b/scripts/codegen/rust.ts
index 024305c49..7b4850231 100644
--- a/scripts/codegen/rust.ts
+++ b/scripts/codegen/rust.ts
@@ -1757,6 +1757,43 @@ function generateRpcCode(apiSchema: ApiSchema): string {
out.push("#![allow(clippy::too_many_arguments)]");
out.push("");
out.push("use super::api_types::{rpc_methods, *};");
+ const externalTypeRefs = new Map>();
+ const recordExternalTypeRef = (ref: string | undefined): void => {
+ if (!ref) return;
+ const externalRef = parseExternalSchemaRef(ref);
+ if (!externalRef) return;
+ let typeNames = externalTypeRefs.get(externalRef.schemaFile);
+ if (!typeNames) {
+ typeNames = new Set();
+ externalTypeRefs.set(externalRef.schemaFile, typeNames);
+ }
+ typeNames.add(externalRef.definitionName);
+ };
+ for (const method of [...serverMethods, ...sessionMethods]) {
+ recordExternalTypeRef(method.params?.$ref);
+ recordExternalTypeRef(method.result?.$ref);
+ recordExternalTypeRef(getNullableInner(method.result)?.$ref);
+ }
+ const externalImports = new Map>();
+ for (const [schemaFile, typeNames] of externalTypeRefs) {
+ const defaultModule = EXTERNAL_SCHEMA_RUST_MODULE[schemaFile];
+ const typeModules = EXTERNAL_SCHEMA_RUST_TYPE_MODULE[schemaFile] ?? {};
+ for (const typeName of typeNames) {
+ const module = typeModules[typeName] ?? defaultModule;
+ if (!module) continue;
+ let names = externalImports.get(module);
+ if (!names) {
+ names = new Set();
+ externalImports.set(module, names);
+ }
+ names.add(typeName);
+ }
+ }
+ for (const [module, typeNames] of [...externalImports].sort(([left], [right]) =>
+ left.localeCompare(right),
+ )) {
+ out.push(`use ${module}::{${[...typeNames].sort().join(", ")}};`);
+ }
out.push("use crate::session::Session;");
out.push("use crate::{Client, Error};");
out.push("");
diff --git a/scripts/codegen/typescript.ts b/scripts/codegen/typescript.ts
index 819d8adf9..88d2ba54e 100644
--- a/scripts/codegen/typescript.ts
+++ b/scripts/codegen/typescript.ts
@@ -487,7 +487,8 @@ import type { MessageConnection } from "vscode-jsonrpc/node.js";
for (const method of [...allMethods, ...clientSessionMethods]) {
const resultSchema = getMethodResultSchema(method);
- if (!isVoidSchema(resultSchema) && !getNullableInner(resultSchema)) {
+ const resultExternalRef = method.result?.$ref ? parseExternalSchemaRef(method.result.$ref) : undefined;
+ if (!resultExternalRef && !isVoidSchema(resultSchema) && !getNullableInner(resultSchema)) {
const resultSource = schemaSourceForNamedDefinition(method.result, resultSchema);
combinedSchema.definitions![resultTypeName(method)] = withRootTitle(
resultSource,
@@ -503,6 +504,10 @@ import type { MessageConnection } from "vscode-jsonrpc/node.js";
const resolvedParams = getMethodParamsSchema(method);
if (method.params && hasSchemaPayload(resolvedParams)) {
+ const paramsExternalRef = method.params.$ref ? parseExternalSchemaRef(method.params.$ref) : undefined;
+ if (paramsExternalRef) {
+ continue;
+ }
if (method.rpcMethod.startsWith("session.") && resolvedParams?.properties) {
const filtered: JSONSchema7 = {
...resolvedParams,
From 1cef46edfe1f36cb5d08ef960fdd11168c05a2d4 Mon Sep 17 00:00:00 2001
From: Copilot <223556219+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 22:32:45 -0400
Subject: [PATCH 3/8] Address SDK update review feedback
Tighten C# SessionFS exception handling and make Python SessionFS adapter params type-check cleanly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
dotnet/src/SessionFsProvider.cs | 14 ++++++++++++--
dotnet/test/E2E/ModeHandlersE2ETests.cs | 4 +++-
python/copilot/session_fs_provider.py | 25 +++++++++++++------------
3 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/dotnet/src/SessionFsProvider.cs b/dotnet/src/SessionFsProvider.cs
index df26d6384..a9c627f15 100644
--- a/dotnet/src/SessionFsProvider.cs
+++ b/dotnet/src/SessionFsProvider.cs
@@ -252,7 +252,7 @@ async Task ISessionFsHandler.SqliteQueryAsync(Sessio
{
return await SqliteQueryAsync(request.SessionId, request.Query, request.QueryType, request.Params, cancellationToken).ConfigureAwait(false);
}
- catch (Exception ex)
+ catch (Exception ex) when (!IsCriticalException(ex))
{
return new SessionFsSqliteQueryResult { Error = ToSessionFsError(ex) };
}
@@ -267,12 +267,22 @@ async Task ISessionFsHandler.SqliteExistsAsync(Sess
var exists = await SqliteExistsAsync(request.SessionId, cancellationToken).ConfigureAwait(false);
return new SessionFsSqliteExistsResult { Exists = exists };
}
- catch
+ catch (Exception ex) when (!IsCriticalException(ex))
{
return new SessionFsSqliteExistsResult { Exists = false };
}
}
+ private static bool IsCriticalException(Exception ex) =>
+ ex is OperationCanceledException
+ or OutOfMemoryException
+ or StackOverflowException
+ or AccessViolationException
+ or AppDomainUnloadedException
+ or BadImageFormatException
+ or CannotUnloadAppDomainException
+ or InvalidProgramException;
+
private static SessionFsError ToSessionFsError(Exception ex)
{
var code = ex is FileNotFoundException or DirectoryNotFoundException
diff --git a/dotnet/test/E2E/ModeHandlersE2ETests.cs b/dotnet/test/E2E/ModeHandlersE2ETests.cs
index b68e9c3ed..dffa2142a 100644
--- a/dotnet/test/E2E/ModeHandlersE2ETests.cs
+++ b/dotnet/test/E2E/ModeHandlersE2ETests.cs
@@ -71,7 +71,9 @@ public async Task Should_Invoke_Exit_Plan_Mode_Handler_When_Model_Uses_Tool()
var completedEvent = await completedEventTask;
Assert.True(completedEvent.Data.Approved);
- Assert.Equal("interactive", completedEvent.Data.SelectedAction?.Value);
+ var selectedAction = completedEvent.Data.SelectedAction;
+ Assert.NotNull(selectedAction);
+ Assert.Equal("interactive", selectedAction.Value.Value);
Assert.Equal("Approved by the C# E2E test", completedEvent.Data.Feedback);
Assert.NotNull(response);
diff --git a/python/copilot/session_fs_provider.py b/python/copilot/session_fs_provider.py
index f3bd89ef1..eb8882336 100644
--- a/python/copilot/session_fs_provider.py
+++ b/python/copilot/session_fs_provider.py
@@ -21,6 +21,7 @@
from collections.abc import Sequence
from dataclasses import dataclass
from datetime import UTC, datetime
+from typing import Any
from .generated.rpc import (
SessionFSError,
@@ -128,7 +129,7 @@ class _SessionFsAdapter:
def __init__(self, provider: SessionFsProvider) -> None:
self._p = provider
- async def read_file(self, params: object) -> SessionFSReadFileResult:
+ async def read_file(self, params: Any) -> SessionFSReadFileResult:
try:
content = await self._p.read_file(params.path) # type: ignore[attr-defined]
return SessionFSReadFileResult.from_dict({"content": content})
@@ -136,28 +137,28 @@ async def read_file(self, params: object) -> SessionFSReadFileResult:
err = _to_session_fs_error(exc)
return SessionFSReadFileResult.from_dict({"content": "", "error": err.to_dict()})
- async def write_file(self, params: object) -> SessionFSError | None:
+ async def write_file(self, params: Any) -> SessionFSError | None:
try:
await self._p.write_file(params.path, params.content, getattr(params, "mode", None)) # type: ignore[attr-defined]
return None
except Exception as exc:
return _to_session_fs_error(exc)
- async def append_file(self, params: object) -> SessionFSError | None:
+ async def append_file(self, params: Any) -> SessionFSError | None:
try:
await self._p.append_file(params.path, params.content, getattr(params, "mode", None)) # type: ignore[attr-defined]
return None
except Exception as exc:
return _to_session_fs_error(exc)
- async def exists(self, params: object) -> SessionFSExistsResult:
+ async def exists(self, params: Any) -> SessionFSExistsResult:
try:
result = await self._p.exists(params.path) # type: ignore[attr-defined]
return SessionFSExistsResult.from_dict({"exists": result})
except Exception:
return SessionFSExistsResult.from_dict({"exists": False})
- async def stat(self, params: object) -> SessionFSStatResult:
+ async def stat(self, params: Any) -> SessionFSStatResult:
try:
info = await self._p.stat(params.path) # type: ignore[attr-defined]
return SessionFSStatResult(
@@ -179,7 +180,7 @@ async def stat(self, params: object) -> SessionFSStatResult:
error=err,
)
- async def mkdir(self, params: object) -> SessionFSError | None:
+ async def mkdir(self, params: Any) -> SessionFSError | None:
try:
await self._p.mkdir(
params.path, # type: ignore[attr-defined]
@@ -190,7 +191,7 @@ async def mkdir(self, params: object) -> SessionFSError | None:
except Exception as exc:
return _to_session_fs_error(exc)
- async def readdir(self, params: object) -> SessionFSReaddirResult:
+ async def readdir(self, params: Any) -> SessionFSReaddirResult:
try:
entries = await self._p.readdir(params.path) # type: ignore[attr-defined]
return SessionFSReaddirResult.from_dict({"entries": entries})
@@ -198,7 +199,7 @@ async def readdir(self, params: object) -> SessionFSReaddirResult:
err = _to_session_fs_error(exc)
return SessionFSReaddirResult.from_dict({"entries": [], "error": err.to_dict()})
- async def readdir_with_types(self, params: object) -> SessionFSReaddirWithTypesResult:
+ async def readdir_with_types(self, params: Any) -> SessionFSReaddirWithTypesResult:
try:
entries = await self._p.readdir_with_types(params.path) # type: ignore[attr-defined]
return SessionFSReaddirWithTypesResult(entries=list(entries))
@@ -208,7 +209,7 @@ async def readdir_with_types(self, params: object) -> SessionFSReaddirWithTypesR
{"entries": [], "error": err.to_dict()}
)
- async def rm(self, params: object) -> SessionFSError | None:
+ async def rm(self, params: Any) -> SessionFSError | None:
try:
await self._p.rm(
params.path, # type: ignore[attr-defined]
@@ -219,14 +220,14 @@ async def rm(self, params: object) -> SessionFSError | None:
except Exception as exc:
return _to_session_fs_error(exc)
- async def rename(self, params: object) -> SessionFSError | None:
+ async def rename(self, params: Any) -> SessionFSError | None:
try:
await self._p.rename(params.src, params.dest) # type: ignore[attr-defined]
return None
except Exception as exc:
return _to_session_fs_error(exc)
- async def sqlite_query(self, params: object) -> SessionFSSqliteQueryResult:
+ async def sqlite_query(self, params: Any) -> SessionFSSqliteQueryResult:
try:
return await self._p.sqlite_query( # type: ignore[attr-defined]
params.session_id,
@@ -242,7 +243,7 @@ async def sqlite_query(self, params: object) -> SessionFSSqliteQueryResult:
error=_to_session_fs_error(exc),
)
- async def sqlite_exists(self, params: object) -> SessionFSSqliteExistsResult:
+ async def sqlite_exists(self, params: Any) -> SessionFSSqliteExistsResult:
try:
result = await self._p.sqlite_exists(params.session_id) # type: ignore[attr-defined]
return SessionFSSqliteExistsResult.from_dict({"exists": result})
From 8ee987b354afe3fe623e722da3a20d170ae53024 Mon Sep 17 00:00:00 2001
From: Copilot <223556219+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 22:44:04 -0400
Subject: [PATCH 4/8] Pass Rust SessionFS SQLite session IDs
Teach Rust codegen to prefer richer inline RPC parameter schemas when definitions omit wire fields, and forward the SQLite query session ID through the provider trait.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
rust/src/generated/api_types.rs | 52 ++++++++++++++++-------
rust/src/session_fs.rs | 3 +-
rust/src/session_fs_dispatch.rs | 7 +++-
rust/tests/e2e/session_fs.rs | 4 +-
rust/tests/session_test.rs | 13 +++++-
scripts/codegen/rust.ts | 74 ++++++++++++++++++++++++---------
6 files changed, 115 insertions(+), 38 deletions(-)
diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs
index 1c7dd03a6..cd214830f 100644
--- a/rust/src/generated/api_types.rs
+++ b/rust/src/generated/api_types.rs
@@ -1762,13 +1762,15 @@ pub struct SessionAuthStatus {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsAppendFileRequest {
+ /// Target session identifier
+ pub session_id: SessionId,
+ /// Path using SessionFs conventions
+ pub path: String,
/// Content to append
pub content: String,
/// Optional POSIX-style mode for newly created files
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option,
- /// Path using SessionFs conventions
- pub path: String,
}
/// Describes a filesystem error.
@@ -1786,6 +1788,8 @@ pub struct SessionFsError {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsExistsRequest {
+ /// Target session identifier
+ pub session_id: SessionId,
/// Path using SessionFs conventions
pub path: String,
}
@@ -1802,20 +1806,24 @@ pub struct SessionFsExistsResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsMkdirRequest {
- /// Optional POSIX-style mode for newly created directories
- #[serde(skip_serializing_if = "Option::is_none")]
- pub mode: Option,
+ /// Target session identifier
+ pub session_id: SessionId,
/// Path using SessionFs conventions
pub path: String,
/// Create parent directories as needed
#[serde(skip_serializing_if = "Option::is_none")]
pub recursive: Option,
+ /// Optional POSIX-style mode for newly created directories
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub mode: Option,
}
/// Directory path whose entries should be listed from the client-provided session filesystem.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsReaddirRequest {
+ /// Target session identifier
+ pub session_id: SessionId,
/// Path using SessionFs conventions
pub path: String,
}
@@ -1845,6 +1853,8 @@ pub struct SessionFsReaddirWithTypesEntry {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsReaddirWithTypesRequest {
+ /// Target session identifier
+ pub session_id: SessionId,
/// Path using SessionFs conventions
pub path: String,
}
@@ -1864,6 +1874,8 @@ pub struct SessionFsReaddirWithTypesResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsReadFileRequest {
+ /// Target session identifier
+ pub session_id: SessionId,
/// Path using SessionFs conventions
pub path: String,
}
@@ -1883,24 +1895,28 @@ pub struct SessionFsReadFileResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsRenameRequest {
- /// Destination path using SessionFs conventions
- pub dest: String,
+ /// Target session identifier
+ pub session_id: SessionId,
/// Source path using SessionFs conventions
pub src: String,
+ /// Destination path using SessionFs conventions
+ pub dest: String,
}
/// Path to remove from the client-provided session filesystem, with options for recursive removal and force.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsRmRequest {
- /// Ignore errors if the path does not exist
- #[serde(skip_serializing_if = "Option::is_none")]
- pub force: Option,
+ /// Target session identifier
+ pub session_id: SessionId,
/// Path using SessionFs conventions
pub path: String,
/// Remove directories and their contents recursively
#[serde(skip_serializing_if = "Option::is_none")]
pub recursive: Option,
+ /// Ignore errors if the path does not exist
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub force: Option,
}
/// Optional capabilities declared by the provider
@@ -1947,13 +1963,15 @@ pub struct SessionFsSqliteExistsResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsSqliteQueryRequest {
- /// Optional named bind parameters
- #[serde(default)]
- pub params: HashMap,
+ /// Target session identifier
+ pub session_id: SessionId,
/// SQL query to execute
pub query: String,
/// How to execute the query: 'exec' for DDL/multi-statement (no results), 'query' for SELECT (returns rows), 'run' for INSERT/UPDATE/DELETE (returns rowsAffected)
pub query_type: SessionFsSqliteQueryType,
+ /// Optional named bind parameters
+ #[serde(default)]
+ pub params: HashMap,
}
/// Query results including rows, columns, and rows affected, or a filesystem error if execution failed.
@@ -1978,6 +1996,8 @@ pub struct SessionFsSqliteQueryResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsStatRequest {
+ /// Target session identifier
+ pub session_id: SessionId,
/// Path using SessionFs conventions
pub path: String,
}
@@ -2005,13 +2025,15 @@ pub struct SessionFsStatResult {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionFsWriteFileRequest {
+ /// Target session identifier
+ pub session_id: SessionId,
+ /// Path using SessionFs conventions
+ pub path: String,
/// Content to write
pub content: String,
/// Optional POSIX-style mode for newly created files
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option,
- /// Path using SessionFs conventions
- pub path: String,
}
/// Source session identifier to fork from, optional event-ID boundary, and optional friendly name for the new session.
diff --git a/rust/src/session_fs.rs b/rust/src/session_fs.rs
index b4d860ee9..40562fc1e 100644
--- a/rust/src/session_fs.rs
+++ b/rust/src/session_fs.rs
@@ -351,11 +351,12 @@ pub trait SessionFsProvider: Send + Sync + 'static {
/// Execute a SQLite query against the provider's per-session database.
async fn sqlite_query(
&self,
+ session_id: &str,
query: &str,
query_type: SessionFsSqliteQueryType,
params: &HashMap,
) -> Result {
- let _ = (query, query_type, params);
+ let _ = (session_id, query, query_type, params);
Err(FsError::Other("sqlite_query not supported".to_string()))
}
diff --git a/rust/src/session_fs_dispatch.rs b/rust/src/session_fs_dispatch.rs
index 15fd0a969..b92d4fee8 100644
--- a/rust/src/session_fs_dispatch.rs
+++ b/rust/src/session_fs_dispatch.rs
@@ -317,7 +317,12 @@ pub(crate) async fn sqlite_query(
};
let id = request.id;
let result = match provider
- .sqlite_query(¶ms.query, params.query_type, ¶ms.params)
+ .sqlite_query(
+ params.session_id.as_ref(),
+ ¶ms.query,
+ params.query_type,
+ ¶ms.params,
+ )
.await
{
Ok(result) => result,
diff --git a/rust/tests/e2e/session_fs.rs b/rust/tests/e2e/session_fs.rs
index 36d409c84..ef3926d03 100644
--- a/rust/tests/e2e/session_fs.rs
+++ b/rust/tests/e2e/session_fs.rs
@@ -208,6 +208,7 @@ async fn should_map_all_sessionfs_handler_operations() {
));
let sqlite_result = provider
.sqlite_query(
+ "handler-session",
"select :answer as answer",
SessionFsSqliteQueryType::Query,
&std::collections::HashMap::from([("answer".to_string(), serde_json::Value::from(42))]),
@@ -622,12 +623,13 @@ impl SessionFsProvider for TestSessionFsProvider {
async fn sqlite_query(
&self,
+ session_id: &str,
query: &str,
query_type: SessionFsSqliteQueryType,
params: &std::collections::HashMap,
) -> Result {
let mut row = std::collections::HashMap::new();
- row.insert("sessionId".to_string(), self.session_id.clone().into());
+ row.insert("sessionId".to_string(), session_id.to_string().into());
row.insert("query".to_string(), query.to_string().into());
row.insert(
"queryType".to_string(),
diff --git a/rust/tests/session_test.rs b/rust/tests/session_test.rs
index 31359eca1..ae6d4daea 100644
--- a/rust/tests/session_test.rs
+++ b/rust/tests/session_test.rs
@@ -2987,11 +2987,16 @@ impl SessionFsProvider for RecordingFsProvider {
async fn sqlite_query(
&self,
+ session_id: &str,
query: &str,
query_type: SessionFsSqliteQueryType,
params: &std::collections::HashMap,
) -> Result {
let mut row = std::collections::HashMap::new();
+ row.insert(
+ "sessionId".to_string(),
+ serde_json::Value::String(session_id.to_string()),
+ );
row.insert(
"query".to_string(),
serde_json::Value::String(query.to_string()),
@@ -3017,6 +3022,7 @@ impl SessionFsProvider for RecordingFsProvider {
);
Ok(SessionFsSqliteQueryResult {
columns: vec![
+ "sessionId".to_string(),
"query".to_string(),
"queryType".to_string(),
"answer".to_string(),
@@ -3171,11 +3177,15 @@ async fn session_fs_dispatches_sqlite_query_to_provider() {
let response = timeout(TIMEOUT, server.read_response()).await.unwrap();
assert_eq!(response["id"], 9);
- assert_eq!(response["result"]["columns"][2], "answer");
+ assert_eq!(response["result"]["columns"][3], "answer");
assert_eq!(
response["result"]["rows"][0]["query"],
"select :answer as answer"
);
+ assert_eq!(
+ response["result"]["rows"][0]["sessionId"],
+ server.session_id.to_string()
+ );
assert_eq!(response["result"]["rows"][0]["queryType"], "query");
assert_eq!(response["result"]["rows"][0]["answer"], 42);
assert_eq!(response["result"]["rowsAffected"], 0);
@@ -3208,6 +3218,7 @@ async fn session_fs_maps_sqlite_errors_to_results() {
impl SessionFsProvider for AlwaysFails {
async fn sqlite_query(
&self,
+ _session_id: &str,
_query: &str,
_query_type: SessionFsSqliteQueryType,
_params: &std::collections::HashMap,
diff --git a/scripts/codegen/rust.ts b/scripts/codegen/rust.ts
index 7b4850231..a69d825d6 100644
--- a/scripts/codegen/rust.ts
+++ b/scripts/codegen/rust.ts
@@ -1261,10 +1261,64 @@ function generateApiTypesCode(apiSchema: ApiSchema): string {
);
const ctx = makeCtx(defCollections);
+ const methodEntries: { method: RpcMethod; isSession: boolean }[] = [];
+ for (const { group, isSession } of [
+ { group: apiSchema.server, isSession: false },
+ { group: apiSchema.session, isSession: true },
+ { group: apiSchema.clientSession, isSession: false },
+ ]) {
+ if (group) {
+ methodEntries.push(
+ ...collectRpcMethods(group as Record).map((method) => ({
+ method,
+ isSession,
+ })),
+ );
+ }
+ }
+ const allMethods = methodEntries.map(({ method }) => method);
+ const inlineMethodParamSchemas = new Map();
+ const sortedNames = (names: Iterable | undefined): string[] =>
+ [...(names ?? [])].sort();
+ const schemaPropertyNames = (schema: JSONSchema7): string[] =>
+ sortedNames(Object.keys(schema.properties ?? {}));
+ const shouldPreferMethodParamSchema = (
+ typeName: string,
+ paramsSchema: JSONSchema7,
+ ): boolean => {
+ const definition = definitions[typeName];
+ if (typeof definition !== "object" || definition === null) return false;
+ const definitionSchema = asGeneratedObjectSchema(
+ definition as JSONSchema7,
+ defCollections,
+ );
+ if (!definitionSchema) return false;
+
+ return (
+ JSON.stringify(schemaPropertyNames(paramsSchema)) !==
+ JSON.stringify(schemaPropertyNames(definitionSchema)) ||
+ JSON.stringify(sortedNames(paramsSchema.required)) !==
+ JSON.stringify(sortedNames(definitionSchema.required))
+ );
+ };
+ for (const { method, isSession } of methodEntries) {
+ const params = method.params as (JSONSchema7 & { $ref?: string }) | undefined;
+ if (!params || typeof params.$ref === "string") continue;
+ const paramsSchema = getMethodParamsObjectSchema(
+ method,
+ defCollections,
+ isSession,
+ );
+ const paramsName = rustParamsTypeName(method, defCollections);
+ if (paramsSchema && shouldPreferMethodParamSchema(paramsName, paramsSchema)) {
+ inlineMethodParamSchemas.set(paramsName, paramsSchema);
+ }
+ }
+
// Generate shared definitions (structs & enums)
for (const [name, def] of Object.entries(definitions)) {
if (typeof def !== "object" || def === null) continue;
- const schema = def as JSONSchema7;
+ const schema = inlineMethodParamSchemas.get(name) ?? (def as JSONSchema7);
if (schema.enum && Array.isArray(schema.enum)) {
emitRustStringEnum(
@@ -1294,24 +1348,6 @@ function generateApiTypesCode(apiSchema: ApiSchema): string {
}
}
- // Collect all RPC methods and generate request/response types
- const methodEntries: { method: RpcMethod; isSession: boolean }[] = [];
- for (const { group, isSession } of [
- { group: apiSchema.server, isSession: false },
- { group: apiSchema.session, isSession: true },
- { group: apiSchema.clientSession, isSession: false },
- ]) {
- if (group) {
- methodEntries.push(
- ...collectRpcMethods(group as Record).map((method) => ({
- method,
- isSession,
- })),
- );
- }
- }
- const allMethods = methodEntries.map(({ method }) => method);
-
// RPC method name constants
const methodConstLines: string[] = [];
methodConstLines.push("/// JSON-RPC method name constants.");
From 66ec70e85afc6dea4a41557bae6976157bc6bda9 Mon Sep 17 00:00:00 2001
From: Copilot <223556219+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 22:49:50 -0400
Subject: [PATCH 5/8] Address nullable assertion review feedback
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
dotnet/test/E2E/ModeHandlersE2ETests.cs | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/dotnet/test/E2E/ModeHandlersE2ETests.cs b/dotnet/test/E2E/ModeHandlersE2ETests.cs
index dffa2142a..e059af559 100644
--- a/dotnet/test/E2E/ModeHandlersE2ETests.cs
+++ b/dotnet/test/E2E/ModeHandlersE2ETests.cs
@@ -71,9 +71,13 @@ public async Task Should_Invoke_Exit_Plan_Mode_Handler_When_Model_Uses_Tool()
var completedEvent = await completedEventTask;
Assert.True(completedEvent.Data.Approved);
- var selectedAction = completedEvent.Data.SelectedAction;
- Assert.NotNull(selectedAction);
- Assert.Equal("interactive", selectedAction.Value.Value);
+ if (completedEvent.Data.SelectedAction is not { } selectedAction)
+ {
+ Assert.Fail("Expected a selected action.");
+ return;
+ }
+
+ Assert.Equal("interactive", selectedAction.Value);
Assert.Equal("Approved by the C# E2E test", completedEvent.Data.Feedback);
Assert.NotNull(response);
From 8ba82aecc483d180264ff1b22ddbefed851e3b84 Mon Sep 17 00:00:00 2001
From: Copilot <223556219+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 23:23:01 -0400
Subject: [PATCH 6/8] Fix codegen and Rust SQLite params
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
go/rpc/zrpc.go | 2 +-
python/e2e/test_rpc_mcp_config_e2e.py | 8 ++++----
rust/src/generated/api_types.rs | 3 +--
rust/src/session_fs.rs | 3 +--
rust/src/session_fs_dispatch.rs | 3 ++-
rust/tests/e2e/session_fs.rs | 8 +++++---
rust/tests/session_test.rs | 6 +++---
7 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go
index e8cf96a12..fda585e92 100644
--- a/go/rpc/zrpc.go
+++ b/go/rpc/zrpc.go
@@ -799,7 +799,7 @@ func (McpServerConfigStdio) mcpServerConfig() {}
// Additional authentication configuration for this server.
type McpServerConfigHTTPAuth struct {
// Fixed port for the OAuth redirect callback server.
- RedirectPort *int64 `json:"redirectPort,omitempty"`
+ RedirectPort *int32 `json:"redirectPort,omitempty"`
}
// MCP servers configured for the session, with their connection status.
diff --git a/python/e2e/test_rpc_mcp_config_e2e.py b/python/e2e/test_rpc_mcp_config_e2e.py
index bab0a62a8..d9229adff 100644
--- a/python/e2e/test_rpc_mcp_config_e2e.py
+++ b/python/e2e/test_rpc_mcp_config_e2e.py
@@ -19,7 +19,7 @@
MCPConfigUpdateRequest,
MCPServerConfig,
MCPServerConfigHTTPOauthGrantType,
- MCPServerConfigType,
+ MCPServerConfigHTTPType,
)
from .testharness import E2ETestContext
@@ -71,7 +71,7 @@ async def test_should_round_trip_http_mcp_oauth_config_rpc(self, ctx: E2ETestCon
server_name = f"sdk-http-oauth-{uuid.uuid4().hex}"
config = MCPServerConfig(
- type=MCPServerConfigType.HTTP,
+ type=MCPServerConfigHTTPType.HTTP,
url="https://example.com/mcp",
headers={"Authorization": "Bearer token"},
oauth_client_id="client-id",
@@ -81,7 +81,7 @@ async def test_should_round_trip_http_mcp_oauth_config_rpc(self, ctx: E2ETestCon
timeout=3000,
)
updated_config = MCPServerConfig(
- type=MCPServerConfigType.HTTP,
+ type=MCPServerConfigHTTPType.HTTP,
url="https://example.com/updated-mcp",
oauth_client_id="updated-client-id",
oauth_public_client=True,
@@ -96,7 +96,7 @@ async def test_should_round_trip_http_mcp_oauth_config_rpc(self, ctx: E2ETestCon
)
after_add = await ctx.client.rpc.mcp.config.list()
added = _server_config(after_add.servers, server_name)
- assert added.type == MCPServerConfigType.HTTP
+ assert added.type == MCPServerConfigHTTPType.HTTP
assert added.url == "https://example.com/mcp"
assert added.headers is not None
assert added.headers["Authorization"] == "Bearer token"
diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs
index cd214830f..5bca815e7 100644
--- a/rust/src/generated/api_types.rs
+++ b/rust/src/generated/api_types.rs
@@ -9,7 +9,6 @@ use serde::{Deserialize, Serialize};
use super::session_events::{
McpServerSource, McpServerStatus, ReasoningSummary, SessionMode, SkillSource,
};
-
use crate::types::{RequestId, SessionId};
/// JSON-RPC method name constants.
@@ -969,7 +968,7 @@ pub struct McpServer {
pub struct McpServerConfigHttpAuth {
/// Fixed port for the OAuth redirect callback server.
#[serde(skip_serializing_if = "Option::is_none")]
- pub redirect_port: Option,
+ pub redirect_port: Option,
}
/// Remote MCP server configuration accessed over HTTP or SSE.
diff --git a/rust/src/session_fs.rs b/rust/src/session_fs.rs
index 40562fc1e..8474235c7 100644
--- a/rust/src/session_fs.rs
+++ b/rust/src/session_fs.rs
@@ -48,7 +48,6 @@ use crate::generated::api_types::{
SessionFsError, SessionFsErrorCode, SessionFsReaddirWithTypesEntry,
SessionFsReaddirWithTypesEntryType, SessionFsSetProviderConventions, SessionFsStatResult,
};
-
pub use crate::generated::api_types::{SessionFsSqliteQueryResult, SessionFsSqliteQueryType};
/// Configuration for a custom session filesystem provider.
@@ -354,7 +353,7 @@ pub trait SessionFsProvider: Send + Sync + 'static {
session_id: &str,
query: &str,
query_type: SessionFsSqliteQueryType,
- params: &HashMap,
+ params: Option<&HashMap>,
) -> Result {
let _ = (session_id, query, query_type, params);
Err(FsError::Other("sqlite_query not supported".to_string()))
diff --git a/rust/src/session_fs_dispatch.rs b/rust/src/session_fs_dispatch.rs
index b92d4fee8..3810d978f 100644
--- a/rust/src/session_fs_dispatch.rs
+++ b/rust/src/session_fs_dispatch.rs
@@ -316,12 +316,13 @@ pub(crate) async fn sqlite_query(
}
};
let id = request.id;
+ let sqlite_params = (!params.params.is_empty()).then_some(¶ms.params);
let result = match provider
.sqlite_query(
params.session_id.as_ref(),
¶ms.query,
params.query_type,
- ¶ms.params,
+ sqlite_params,
)
.await
{
diff --git a/rust/tests/e2e/session_fs.rs b/rust/tests/e2e/session_fs.rs
index ef3926d03..217e3e883 100644
--- a/rust/tests/e2e/session_fs.rs
+++ b/rust/tests/e2e/session_fs.rs
@@ -206,12 +206,14 @@ async fn should_map_all_sessionfs_handler_operations() {
provider.stat("/workspace/nested/missing.txt").await,
Err(FsError::NotFound(_))
));
+ let sqlite_params =
+ std::collections::HashMap::from([("answer".to_string(), serde_json::Value::from(42))]);
let sqlite_result = provider
.sqlite_query(
"handler-session",
"select :answer as answer",
SessionFsSqliteQueryType::Query,
- &std::collections::HashMap::from([("answer".to_string(), serde_json::Value::from(42))]),
+ Some(&sqlite_params),
)
.await
.expect("sqlite query");
@@ -626,7 +628,7 @@ impl SessionFsProvider for TestSessionFsProvider {
session_id: &str,
query: &str,
query_type: SessionFsSqliteQueryType,
- params: &std::collections::HashMap,
+ params: Option<&std::collections::HashMap>,
) -> Result {
let mut row = std::collections::HashMap::new();
row.insert("sessionId".to_string(), session_id.to_string().into());
@@ -644,7 +646,7 @@ impl SessionFsProvider for TestSessionFsProvider {
row.insert(
"answer".to_string(),
params
- .get("answer")
+ .and_then(|params| params.get("answer"))
.cloned()
.unwrap_or(serde_json::Value::Null),
);
diff --git a/rust/tests/session_test.rs b/rust/tests/session_test.rs
index ae6d4daea..3a60f4663 100644
--- a/rust/tests/session_test.rs
+++ b/rust/tests/session_test.rs
@@ -2990,7 +2990,7 @@ impl SessionFsProvider for RecordingFsProvider {
session_id: &str,
query: &str,
query_type: SessionFsSqliteQueryType,
- params: &std::collections::HashMap,
+ params: Option<&std::collections::HashMap>,
) -> Result {
let mut row = std::collections::HashMap::new();
row.insert(
@@ -3016,7 +3016,7 @@ impl SessionFsProvider for RecordingFsProvider {
row.insert(
"answer".to_string(),
params
- .get("answer")
+ .and_then(|params| params.get("answer"))
.cloned()
.unwrap_or(serde_json::Value::Null),
);
@@ -3221,7 +3221,7 @@ async fn session_fs_maps_sqlite_errors_to_results() {
_session_id: &str,
_query: &str,
_query_type: SessionFsSqliteQueryType,
- _params: &std::collections::HashMap,
+ _params: Option<&std::collections::HashMap>,
) -> Result {
Err(FsError::Other("sqlite unavailable".to_string()))
}
From ec40f4d64cbd0e789b2756a6626a67921cdd321e Mon Sep 17 00:00:00 2001
From: Copilot <223556219+Copilot@users.noreply.github.com>
Date: Tue, 19 May 2026 00:39:05 -0400
Subject: [PATCH 7/8] Fix Python generated enum refs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
python/copilot/generated/rpc.py | 146 +++++++-----------
python/e2e/test_mode_handlers_e2e.py | 10 +-
python/e2e/test_rpc_event_side_effects_e2e.py | 4 +-
python/e2e/test_skills_e2e.py | 3 +-
scripts/codegen/python.ts | 96 +++++++++---
5 files changed, 145 insertions(+), 114 deletions(-)
diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py
index 7aceb1e3b..b4391942a 100644
--- a/python/copilot/generated/rpc.py
+++ b/python/copilot/generated/rpc.py
@@ -51,9 +51,6 @@ def from_float(x: Any) -> float:
assert isinstance(x, (float, int)) and not isinstance(x, bool)
return float(x)
-def from_datetime(x: Any) -> datetime:
- return dateutil.parser.parse(x)
-
def to_float(x: Any) -> float:
assert isinstance(x, (int, float))
return x
@@ -74,6 +71,9 @@ def to_enum(c: type[EnumT], x: Any) -> EnumT:
assert isinstance(x, c)
return x.value
+def from_datetime(x: Any) -> datetime:
+ return dateutil.parser.parse(x)
+
@dataclass
class AccountGetQuotaRequest:
git_hub_token: str | None = None
@@ -118,7 +118,7 @@ class AccountQuotaSnapshot:
used_requests: int
"""Number of requests used so far this period"""
- reset_date: datetime | None = None
+ reset_date: str | None = None
"""Date when the quota resets (ISO 8601 string)"""
@staticmethod
@@ -131,7 +131,7 @@ def from_dict(obj: Any) -> 'AccountQuotaSnapshot':
remaining_percentage = from_float(obj.get("remainingPercentage"))
usage_allowed_with_exhausted_quota = from_bool(obj.get("usageAllowedWithExhaustedQuota"))
used_requests = from_int(obj.get("usedRequests"))
- reset_date = from_union([from_datetime, from_none], obj.get("resetDate"))
+ reset_date = from_union([from_str, from_none], obj.get("resetDate"))
return AccountQuotaSnapshot(entitlement_requests, is_unlimited_entitlement, overage, overage_allowed_with_exhausted_quota, remaining_percentage, usage_allowed_with_exhausted_quota, used_requests, reset_date)
def to_dict(self) -> dict:
@@ -144,7 +144,7 @@ def to_dict(self) -> dict:
result["usageAllowedWithExhaustedQuota"] = from_bool(self.usage_allowed_with_exhausted_quota)
result["usedRequests"] = from_int(self.used_requests)
if self.reset_date is not None:
- result["resetDate"] = from_union([lambda x: x.isoformat(), from_none], self.reset_date)
+ result["resetDate"] = from_union([from_str, from_none], self.reset_date)
return result
@dataclass
@@ -475,23 +475,6 @@ def to_dict(self) -> dict:
result["modelId"] = from_union([from_str, from_none], self.model_id)
return result
-@dataclass
-class ExternalRefMCPServerSource:
- """Configuration source: user, workspace, plugin, or builtin"""
-
- external_ref_marker_external_ref_mcp_server_source: str
-
- @staticmethod
- def from_dict(obj: Any) -> 'ExternalRefMCPServerSource':
- assert isinstance(obj, dict)
- external_ref_marker_external_ref_mcp_server_source = from_str(obj.get("__externalRefMarker___ExternalRef_McpServerSource"))
- return ExternalRefMCPServerSource(external_ref_marker_external_ref_mcp_server_source)
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["__externalRefMarker___ExternalRef_McpServerSource"] = from_str(self.external_ref_marker_external_ref_mcp_server_source)
- return result
-
class DiscoveredMCPServerType(Enum):
"""Server transport type: stdio, http, sse, or memory"""
@@ -992,20 +975,38 @@ def to_dict(self) -> dict:
return result
@dataclass
-class ExternalRefMCPServerStatus:
+class MCPServer:
+ """Schema for the `McpServer` type."""
+
+ name: str
+ """Server name (config key)"""
+
+ status: McpServerStatus
"""Connection status: connected, failed, needs-auth, pending, disabled, or not_configured"""
- external_ref_marker_external_ref_mcp_server_status: str
+ error: str | None = None
+ """Error message if the server failed to connect"""
+
+ source: McpServerSource | None = None
+ """Configuration source: user, workspace, plugin, or builtin"""
@staticmethod
- def from_dict(obj: Any) -> 'ExternalRefMCPServerStatus':
+ def from_dict(obj: Any) -> 'MCPServer':
assert isinstance(obj, dict)
- external_ref_marker_external_ref_mcp_server_status = from_str(obj.get("__externalRefMarker___ExternalRef_McpServerStatus"))
- return ExternalRefMCPServerStatus(external_ref_marker_external_ref_mcp_server_status)
+ name = from_str(obj.get("name"))
+ status = McpServerStatus(obj.get("status"))
+ error = from_union([from_str, from_none], obj.get("error"))
+ source = from_union([McpServerSource, from_none], obj.get("source"))
+ return MCPServer(name, status, error, source)
def to_dict(self) -> dict:
result: dict = {}
- result["__externalRefMarker___ExternalRef_McpServerStatus"] = from_str(self.external_ref_marker_external_ref_mcp_server_status)
+ result["name"] = from_str(self.name)
+ result["status"] = to_enum(McpServerStatus, self.status)
+ if self.error is not None:
+ result["error"] = from_union([from_str, from_none], self.error)
+ if self.source is not None:
+ result["source"] = from_union([lambda x: to_enum(McpServerSource, x), from_none], self.source)
return result
@dataclass
@@ -1018,12 +1019,12 @@ class ModeSetRequest:
@staticmethod
def from_dict(obj: Any) -> 'ModeSetRequest':
assert isinstance(obj, dict)
- mode = SessionMode.from_dict(obj.get("mode"))
+ mode = SessionMode(obj.get("mode"))
return ModeSetRequest(mode)
def to_dict(self) -> dict:
result: dict = {}
- result["mode"] = to_class(SessionMode, self.mode)
+ result["mode"] = to_enum(SessionMode, self.mode)
return result
@dataclass
@@ -1648,7 +1649,7 @@ def from_dict(obj: Any) -> 'ServerSkill':
description = from_str(obj.get("description"))
enabled = from_bool(obj.get("enabled"))
name = from_str(obj.get("name"))
- source = SkillSource.from_dict(obj.get("source"))
+ source = SkillSource(obj.get("source"))
user_invocable = from_bool(obj.get("userInvocable"))
path = from_union([from_str, from_none], obj.get("path"))
project_path = from_union([from_str, from_none], obj.get("projectPath"))
@@ -1659,7 +1660,7 @@ def to_dict(self) -> dict:
result["description"] = from_str(self.description)
result["enabled"] = from_bool(self.enabled)
result["name"] = from_str(self.name)
- result["source"] = to_class(SkillSource, self.source)
+ result["source"] = to_enum(SkillSource, self.source)
result["userInvocable"] = from_bool(self.user_invocable)
if self.path is not None:
result["path"] = from_union([from_str, from_none], self.path)
@@ -2232,7 +2233,7 @@ def from_dict(obj: Any) -> 'Skill':
description = from_str(obj.get("description"))
enabled = from_bool(obj.get("enabled"))
name = from_str(obj.get("name"))
- source = SkillSource.from_dict(obj.get("source"))
+ source = SkillSource(obj.get("source"))
user_invocable = from_bool(obj.get("userInvocable"))
path = from_union([from_str, from_none], obj.get("path"))
return Skill(description, enabled, name, source, user_invocable, path)
@@ -2242,7 +2243,7 @@ def to_dict(self) -> dict:
result["description"] = from_str(self.description)
result["enabled"] = from_bool(self.enabled)
result["name"] = from_str(self.name)
- result["source"] = to_class(SkillSource, self.source)
+ result["source"] = to_enum(SkillSource, self.source)
result["userInvocable"] = from_bool(self.user_invocable)
if self.path is not None:
result["path"] = from_union([from_str, from_none], self.path)
@@ -3317,7 +3318,7 @@ class DiscoveredMCPServer:
name: str
"""Server name (config key)"""
- source: ExternalRefMCPServerSource
+ source: McpServerSource
"""Configuration source: user, workspace, plugin, or builtin"""
type: DiscoveredMCPServerType | None = None
@@ -3328,7 +3329,7 @@ def from_dict(obj: Any) -> 'DiscoveredMCPServer':
assert isinstance(obj, dict)
enabled = from_bool(obj.get("enabled"))
name = from_str(obj.get("name"))
- source = ExternalRefMCPServerSource.from_dict(obj.get("source"))
+ source = McpServerSource(obj.get("source"))
type = from_union([DiscoveredMCPServerType, from_none], obj.get("type"))
return DiscoveredMCPServer(enabled, name, source, type)
@@ -3336,7 +3337,7 @@ def to_dict(self) -> dict:
result: dict = {}
result["enabled"] = from_bool(self.enabled)
result["name"] = from_str(self.name)
- result["source"] = to_class(ExternalRefMCPServerSource, self.source)
+ result["source"] = to_enum(McpServerSource, self.source)
if self.type is not None:
result["type"] = from_union([lambda x: to_enum(DiscoveredMCPServerType, x), from_none], self.type)
return result
@@ -3951,38 +3952,21 @@ def to_dict(self) -> dict:
return result
@dataclass
-class MCPServer:
- """Schema for the `McpServer` type."""
-
- name: str
- """Server name (config key)"""
-
- status: ExternalRefMCPServerStatus
- """Connection status: connected, failed, needs-auth, pending, disabled, or not_configured"""
-
- error: str | None = None
- """Error message if the server failed to connect"""
+class MCPServerList:
+ """MCP servers configured for the session, with their connection status."""
- source: ExternalRefMCPServerSource | None = None
- """Configuration source: user, workspace, plugin, or builtin"""
+ servers: list[MCPServer]
+ """Configured MCP servers"""
@staticmethod
- def from_dict(obj: Any) -> 'MCPServer':
+ def from_dict(obj: Any) -> 'MCPServerList':
assert isinstance(obj, dict)
- name = from_str(obj.get("name"))
- status = ExternalRefMCPServerStatus.from_dict(obj.get("status"))
- error = from_union([from_str, from_none], obj.get("error"))
- source = from_union([ExternalRefMCPServerSource.from_dict, from_none], obj.get("source"))
- return MCPServer(name, status, error, source)
+ servers = from_list(MCPServer.from_dict, obj.get("servers"))
+ return MCPServerList(servers)
def to_dict(self) -> dict:
result: dict = {}
- result["name"] = from_str(self.name)
- result["status"] = to_class(ExternalRefMCPServerStatus, self.status)
- if self.error is not None:
- result["error"] = from_union([from_str, from_none], self.error)
- if self.source is not None:
- result["source"] = from_union([lambda x: to_class(ExternalRefMCPServerSource, x), from_none], self.source)
+ result["servers"] = from_list(lambda x: to_class(MCPServer, x), self.servers)
return result
@dataclass
@@ -4841,7 +4825,7 @@ def from_dict(obj: Any) -> 'SlashCommandAgentPromptResult':
display_prompt = from_str(obj.get("displayPrompt"))
kind = SlashCommandAgentPromptResultKind(obj.get("kind"))
prompt = from_str(obj.get("prompt"))
- mode = from_union([SessionMode.from_dict, from_none], obj.get("mode"))
+ mode = from_union([SessionMode, from_none], obj.get("mode"))
runtime_settings_changed = from_union([from_bool, from_none], obj.get("runtimeSettingsChanged"))
return SlashCommandAgentPromptResult(display_prompt, kind, prompt, mode, runtime_settings_changed)
@@ -4851,7 +4835,7 @@ def to_dict(self) -> dict:
result["kind"] = to_enum(SlashCommandAgentPromptResultKind, self.kind)
result["prompt"] = from_str(self.prompt)
if self.mode is not None:
- result["mode"] = from_union([lambda x: to_class(SessionMode, x), from_none], self.mode)
+ result["mode"] = from_union([lambda x: to_enum(SessionMode, x), from_none], self.mode)
if self.runtime_settings_changed is not None:
result["runtimeSettingsChanged"] = from_union([from_bool, from_none], self.runtime_settings_changed)
return result
@@ -5829,24 +5813,6 @@ def to_dict(self) -> dict:
result["name"] = from_str(self.name)
return result
-@dataclass
-class MCPServerList:
- """MCP servers configured for the session, with their connection status."""
-
- servers: list[MCPServer]
- """Configured MCP servers"""
-
- @staticmethod
- def from_dict(obj: Any) -> 'MCPServerList':
- assert isinstance(obj, dict)
- servers = from_list(MCPServer.from_dict, obj.get("servers"))
- return MCPServerList(servers)
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["servers"] = from_list(lambda x: to_class(MCPServer, x), self.servers)
- return result
-
@dataclass
class ModelCapabilitiesOverride:
"""Override individual model capabilities resolved by the runtime"""
@@ -6105,7 +6071,7 @@ def from_dict(obj: Any) -> 'SlashCommandInvocationResult':
runtime_settings_changed = from_union([from_bool, from_none], obj.get("runtimeSettingsChanged"))
text = from_union([from_str, from_none], obj.get("text"))
display_prompt = from_union([from_str, from_none], obj.get("displayPrompt"))
- mode = from_union([SessionMode.from_dict, from_none], obj.get("mode"))
+ mode = from_union([SessionMode, from_none], obj.get("mode"))
prompt = from_union([from_str, from_none], obj.get("prompt"))
message = from_union([from_str, from_none], obj.get("message"))
return SlashCommandInvocationResult(kind, markdown, preserve_ansi, runtime_settings_changed, text, display_prompt, mode, prompt, message)
@@ -6124,7 +6090,7 @@ def to_dict(self) -> dict:
if self.display_prompt is not None:
result["displayPrompt"] = from_union([from_str, from_none], self.display_prompt)
if self.mode is not None:
- result["mode"] = from_union([lambda x: to_class(SessionMode, x), from_none], self.mode)
+ result["mode"] = from_union([lambda x: to_enum(SessionMode, x), from_none], self.mode)
if self.prompt is not None:
result["prompt"] = from_union([from_str, from_none], self.prompt)
if self.message is not None:
@@ -7200,7 +7166,7 @@ def from_dict(obj: Any) -> 'ModelSwitchToRequest':
model_id = from_str(obj.get("modelId"))
model_capabilities = from_union([ModelCapabilitiesOverride.from_dict, from_none], obj.get("modelCapabilities"))
reasoning_effort = from_union([from_str, from_none], obj.get("reasoningEffort"))
- reasoning_summary = from_union([ReasoningSummary.from_dict, from_none], obj.get("reasoningSummary"))
+ reasoning_summary = from_union([ReasoningSummary, from_none], obj.get("reasoningSummary"))
return ModelSwitchToRequest(model_id, model_capabilities, reasoning_effort, reasoning_summary)
def to_dict(self) -> dict:
@@ -7211,7 +7177,7 @@ def to_dict(self) -> dict:
if self.reasoning_effort is not None:
result["reasoningEffort"] = from_union([from_str, from_none], self.reasoning_effort)
if self.reasoning_summary is not None:
- result["reasoningSummary"] = from_union([lambda x: to_class(ReasoningSummary, x), from_none], self.reasoning_summary)
+ result["reasoningSummary"] = from_union([lambda x: to_enum(ReasoningSummary, x), from_none], self.reasoning_summary)
return result
@dataclass
@@ -7944,7 +7910,7 @@ def from_dict(obj: Any) -> 'RPC':
session_fs_stat_result = SessionFSStatResult.from_dict(obj.get("SessionFsStatResult"))
session_fs_write_file_request = SessionFSWriteFileRequest.from_dict(obj.get("SessionFsWriteFileRequest"))
session_log_level = SessionLogLevel(obj.get("SessionLogLevel"))
- session_mode = SessionMode.from_dict(obj.get("SessionMode"))
+ session_mode = SessionMode(obj.get("SessionMode"))
sessions_fork_request = SessionsForkRequest.from_dict(obj.get("SessionsForkRequest"))
sessions_fork_result = SessionsForkResult.from_dict(obj.get("SessionsForkResult"))
shell_exec_request = ShellExecRequest.from_dict(obj.get("ShellExecRequest"))
@@ -8207,7 +8173,7 @@ def to_dict(self) -> dict:
result["SessionFsStatResult"] = to_class(SessionFSStatResult, self.session_fs_stat_result)
result["SessionFsWriteFileRequest"] = to_class(SessionFSWriteFileRequest, self.session_fs_write_file_request)
result["SessionLogLevel"] = to_enum(SessionLogLevel, self.session_log_level)
- result["SessionMode"] = to_class(SessionMode, self.session_mode)
+ result["SessionMode"] = to_enum(SessionMode, self.session_mode)
result["SessionsForkRequest"] = to_class(SessionsForkRequest, self.sessions_fork_request)
result["SessionsForkResult"] = to_class(SessionsForkResult, self.sessions_fork_result)
result["ShellExecRequest"] = to_class(ShellExecRequest, self.shell_exec_request)
@@ -8295,6 +8261,8 @@ def rpc_to_dict(x: RPC) -> Any:
ExternalToolResult = ExternalToolTextResultForLlm
FilterMapping = dict
+TaskInfoExecutionMode = TaskExecutionMode
+TaskInfoStatus = TaskStatus
def _timeout_kwargs(timeout: float | None) -> dict:
"""Build keyword arguments for optional timeout forwarding."""
diff --git a/python/e2e/test_mode_handlers_e2e.py b/python/e2e/test_mode_handlers_e2e.py
index 981a9ca8b..c0e19da13 100644
--- a/python/e2e/test_mode_handlers_e2e.py
+++ b/python/e2e/test_mode_handlers_e2e.py
@@ -9,6 +9,8 @@
from copilot.generated.session_events import (
AutoModeSwitchCompletedData,
AutoModeSwitchRequestedData,
+ AutoModeSwitchResponse,
+ ExitPlanModeAction,
ExitPlanModeCompletedData,
ExitPlanModeRequestedData,
SessionIdleData,
@@ -104,7 +106,7 @@ async def on_exit_plan_mode(request, invocation):
lambda event: (
isinstance(event.data, ExitPlanModeCompletedData)
and event.data.approved is True
- and event.data.selected_action == "interactive"
+ and event.data.selected_action == ExitPlanModeAction.INTERACTIVE
),
)
)
@@ -126,7 +128,7 @@ async def on_exit_plan_mode(request, invocation):
completed = await completed_event
assert completed.data.approved is True
- assert completed.data.selected_action == "interactive"
+ assert completed.data.selected_action == ExitPlanModeAction.INTERACTIVE
assert completed.data.feedback == "Approved by the Python E2E test"
assert response is not None
finally:
@@ -164,7 +166,7 @@ async def on_auto_mode_switch(request, invocation):
session,
lambda event: (
isinstance(event.data, AutoModeSwitchCompletedData)
- and event.data.response == "yes"
+ and event.data.response == AutoModeSwitchResponse.YES
),
)
)
@@ -192,7 +194,7 @@ async def on_auto_mode_switch(request, invocation):
assert requested.data.retry_after_seconds == 1
completed = await completed_event
- assert completed.data.response == "yes"
+ assert completed.data.response == AutoModeSwitchResponse.YES
model_change = await model_change_event
assert model_change.data.cause == "rate_limit_auto_switch"
diff --git a/python/e2e/test_rpc_event_side_effects_e2e.py b/python/e2e/test_rpc_event_side_effects_e2e.py
index e31e00fbe..b4a5b2790 100644
--- a/python/e2e/test_rpc_event_side_effects_e2e.py
+++ b/python/e2e/test_rpc_event_side_effects_e2e.py
@@ -69,8 +69,8 @@ def on_event(event):
event = await asyncio.wait_for(changed_future, timeout=15.0)
assert isinstance(event.data, SessionModeChangedData)
- assert event.data.new_mode == SessionMode.PLAN.value
- assert event.data.previous_mode == SessionMode.INTERACTIVE.value
+ assert event.data.new_mode == SessionMode.PLAN
+ assert event.data.previous_mode == SessionMode.INTERACTIVE
finally:
unsubscribe()
finally:
diff --git a/python/e2e/test_skills_e2e.py b/python/e2e/test_skills_e2e.py
index 368b42379..c31632fda 100644
--- a/python/e2e/test_skills_e2e.py
+++ b/python/e2e/test_skills_e2e.py
@@ -7,6 +7,7 @@
import pytest
+from copilot.generated.rpc import SkillSource
from copilot.session import CustomAgentConfig, PermissionHandler
from .testharness import E2ETestContext
@@ -230,6 +231,6 @@ async def test_should_control_ambient_project_skills_with_enableconfigdiscovery(
assert len(discovered) == 1
skill = discovered[0]
assert skill.enabled is True
- assert skill.source == "project"
+ assert skill.source == SkillSource.PROJECT
assert skill.path.endswith(os.path.join(skill_name, "SKILL.md"))
await enabled_session.disconnect()
diff --git a/scripts/codegen/python.ts b/scripts/codegen/python.ts
index 8e1314022..4de9e1d23 100644
--- a/scripts/codegen/python.ts
+++ b/scripts/codegen/python.ts
@@ -124,29 +124,78 @@ function placeholderToQuicktypeIdentifier(placeholder: string): string {
.join("");
}
-function postProcessExternalRefsForPython(code: string, placeholderToReal: Map): string {
+function placeholderToQuicktypeIdentifiers(placeholder: string): string[] {
+ const basic = placeholderToQuicktypeIdentifier(placeholder);
+ return [...new Set([basic, basic.replace(/Mcp/g, "MCP")])];
+}
+
+function postProcessExternalRefsForPython(
+ code: string,
+ placeholderToReal: Map,
+ externalEnumNames: Set = new Set()
+): string {
for (const [placeholder, realName] of placeholderToReal) {
- const quicktypeName = placeholderToQuicktypeIdentifier(placeholder);
- code = code.replace(
- new RegExp(
- `(?:^|\\n)@dataclass\\r?\\nclass ${quicktypeName}\\b[\\s\\S]*?(?=\\n@dataclass\\b|\\nclass\\s+\\w|\\ndef\\s+\\w|$)`,
- "g"
- ),
- "\n"
- );
- code = code.replace(
- new RegExp(
- `(?:^|\\n)class ${quicktypeName}\\w*\\(Enum\\):[\\s\\S]*?(?=\\nclass\\s+\\w|\\n@dataclass\\b|\\ndef\\s+\\w|$)`,
- "g"
- ),
- "\n"
- );
- code = code.replace(new RegExp(`\\b${quicktypeName}\\b`, "g"), realName);
+ for (const quicktypeName of placeholderToQuicktypeIdentifiers(placeholder)) {
+ code = code.replace(
+ new RegExp(
+ `(?:^|\\n)@dataclass\\r?\\nclass ${quicktypeName}\\b[\\s\\S]*?(?=\\n@dataclass\\b|\\nclass\\s+\\w|\\ndef\\s+\\w|$)`,
+ "g"
+ ),
+ "\n"
+ );
+ code = code.replace(
+ new RegExp(
+ `(?:^|\\n)class ${quicktypeName}\\w*\\(Enum\\):[\\s\\S]*?(?=\\nclass\\s+\\w|\\n@dataclass\\b|\\ndef\\s+\\w|$)`,
+ "g"
+ ),
+ "\n"
+ );
+ code = code.replace(new RegExp(`\\b${quicktypeName}\\b`, "g"), realName);
+ }
+ if (externalEnumNames.has(realName)) {
+ code = code.replace(new RegExp(`\\b${realName}\\.from_dict\\b`, "g"), realName);
+ code = code.replace(
+ new RegExp(`to_class\\(${realName},\\s*([^)]+)\\)`, "g"),
+ `to_enum(${realName}, $1)`
+ );
+ }
}
return code.replace(/\n{3,}/g, "\n\n");
}
+function collectPythonExternalEnumNames(
+ schema: JSONSchema7 | undefined,
+ placeholderToReal: Map
+): Set {
+ const enumNames = new Set();
+ if (!schema) return enumNames;
+
+ const definitions = collectDefinitionCollections(schema as Record);
+ for (const realName of placeholderToReal.values()) {
+ const definition = definitions.definitions[realName] ?? definitions.$defs[realName];
+ const resolved = definition ? resolveSchema(definition, definitions) ?? definition : undefined;
+ if (
+ resolved?.enum &&
+ Array.isArray(resolved.enum) &&
+ resolved.enum.every((value) => typeof value === "string")
+ ) {
+ enumNames.add(realName);
+ }
+ }
+
+ return enumNames;
+}
+
+function preservePythonRpcStringDateFields(definitions: Record): void {
+ const quotaSnapshot = definitions.AccountQuotaSnapshot;
+ const resetDate = quotaSnapshot?.properties?.resetDate as JSONSchema7 | undefined;
+ if (resetDate?.type === "string" && resetDate.format === "date-time") {
+ // Keep the existing Python API shape: AccountQuotaSnapshot.reset_date is an ISO string.
+ delete resetDate.format;
+ }
+}
+
function collectExternalUnionAliasesForPython(
definitions: Record,
placeholderToReal: Map
@@ -2081,6 +2130,7 @@ async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSONSchema
}
const allDefinitions = combinedSchema.definitions! as Record;
+ preservePythonRpcStringDateFields(allDefinitions);
const allDefinitionCollections: DefinitionCollections = {
definitions: { ...(combinedSchema.$defs ?? {}), ...allDefinitions },
$defs: { ...allDefinitions, ...(combinedSchema.$defs ?? {}) },
@@ -2099,6 +2149,7 @@ async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSONSchema
required: Object.keys(allDefinitions),
};
const externalRefs = rewriteExternalRefsForPython(singleSchema as JSONSchema7 & { definitions?: Record });
+ const externalEnumNames = collectPythonExternalEnumNames(sessionEventsSchema, externalRefs.placeholderNames);
const externalUnionAliases = collectExternalUnionAliasesForPython(
singleSchema.definitions as Record,
externalRefs.placeholderNames
@@ -2126,7 +2177,7 @@ async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSONSchema
const knownDefNames = new Set(Object.keys(allDefinitions).map((n) => n.toLowerCase()));
typesCode = collapsePlaceholderPythonDataclasses(typesCode, knownDefNames);
typesCode = postProcessExternalUnionAliasesForPython(typesCode, externalUnionAliases);
- typesCode = postProcessExternalRefsForPython(typesCode, externalRefs.placeholderNames);
+ typesCode = postProcessExternalRefsForPython(typesCode, externalRefs.placeholderNames, externalEnumNames);
typesCode = modernizePython(typesCode);
// Fix quicktype's Enum-suffix renaming: quicktype sometimes renames "Xyz" to
@@ -2246,6 +2297,15 @@ async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSONSchema
}
}
}
+ const compatibilityTypeAliases = new Map([
+ ["TaskInfoExecutionMode", "TaskExecutionMode"],
+ ["TaskInfoStatus", "TaskStatus"],
+ ]);
+ for (const [aliasName, targetName] of compatibilityTypeAliases) {
+ if (actualTypeNames.has(targetName.toLowerCase()) && !actualTypeNames.has(aliasName.toLowerCase())) {
+ publicTypeAliases.set(aliasName, actualTypeNames.get(targetName.toLowerCase()) ?? targetName);
+ }
+ }
const resolveType = (name: string): string =>
actualTypeNames.get(name.toLowerCase()) ?? definitionAliases.get(name.toLowerCase()) ?? name;
From 56e315b4f381f34e3092a27be54ed594a27d472a Mon Sep 17 00:00:00 2001
From: Copilot <223556219+Copilot@users.noreply.github.com>
Date: Tue, 19 May 2026 04:25:31 -0400
Subject: [PATCH 8/8] Fix Rust generated import formatting
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
rust/src/generated/api_types.rs | 1 -
scripts/codegen/rust.ts | 3 ---
2 files changed, 4 deletions(-)
diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs
index 05618c28d..6f7e97ad7 100644
--- a/rust/src/generated/api_types.rs
+++ b/rust/src/generated/api_types.rs
@@ -9,7 +9,6 @@ use serde::{Deserialize, Serialize};
use super::session_events::{
McpServerSource, McpServerStatus, ReasoningSummary, SessionMode, SkillSource,
};
-
use crate::types::{RequestId, SessionId};
/// JSON-RPC method name constants.
diff --git a/scripts/codegen/rust.ts b/scripts/codegen/rust.ts
index 8747a6fe3..3898ee7f2 100644
--- a/scripts/codegen/rust.ts
+++ b/scripts/codegen/rust.ts
@@ -1460,9 +1460,6 @@ function generateApiTypesCode(apiSchema: ApiSchema): string {
)) {
out.push(`use ${module}::{${[...typeNames].sort().join(", ")}};`);
}
- if (externalImports.size > 0) {
- out.push("");
- }
out.push("use crate::types::{RequestId, SessionId};");
out.push("");