diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index bf73bdfaf..0f6793107 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -1510,6 +1510,10 @@ public sealed class ServerSkill [Experimental(Diagnostics.Experimental)] public sealed class ServerSkillList { + /// Messages for skills that failed to load (e.g. malformed SKILL.md). Empty when host skills are excluded so host-local paths are not disclosed to multitenant callers. + [JsonPropertyName("errors")] + public IList? Errors { get; set; } + /// All discovered skills across all sources. [JsonPropertyName("skills")] public IList Skills { get => field ??= []; set; } @@ -4083,6 +4087,308 @@ internal sealed class CanvasActionInvokeRequest public string SessionId { get; set; } = string.Empty; } +/// Machine-readable factory run failure. +/// Polymorphic base type discriminated by type. +[Experimental(Diagnostics.Experimental)] +[JsonPolymorphic( + TypeDiscriminatorPropertyName = "type", + UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] +[JsonDerivedType(typeof(FactoryRunFailureFactoryLimitReached), "factory_limit_reached")] +[JsonDerivedType(typeof(FactoryRunFailureFactoryResumeDeclined), "factory_resume_declined")] +public partial class FactoryRunFailure +{ + /// The type discriminator. + [JsonPropertyName("type")] + public virtual string Type { get; set; } = string.Empty; +} + + +/// The factory_limit_reached variant of . +[Experimental(Diagnostics.Experimental)] +public partial class FactoryRunFailureFactoryLimitReached : FactoryRunFailure +{ + /// + [JsonIgnore] + public override string Type => "factory_limit_reached"; + + /// Resource ceiling that stopped the run. + [JsonPropertyName("kind")] + public required FactoryRunFailureKind Kind { get; set; } + + /// Factory run identifier. + [JsonPropertyName("runId")] + public required string RunId { get; set; } + + /// Approved effective ceiling that was reached. + [JsonPropertyName("value")] + public required double Value { get; set; } +} + +/// The factory_resume_declined variant of . +[Experimental(Diagnostics.Experimental)] +public partial class FactoryRunFailureFactoryResumeDeclined : FactoryRunFailure +{ + /// + [JsonIgnore] + public override string Type => "factory_resume_declined"; + + /// Human-readable reason the resume did not proceed. + [JsonPropertyName("reason")] + public required string Reason { get; set; } + + /// Factory run identifier whose changed limits were declined. + [JsonPropertyName("runId")] + public required string RunId { get; set; } +} + +/// Complete current or terminal factory run envelope. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryRunResult +{ + /// Error message for an errored run. + [JsonPropertyName("error")] + public string? Error { get; set; } + + /// Machine-readable failure details for an errored run. + [JsonPropertyName("failure")] + public FactoryRunFailure? Failure { get; set; } + + /// Reason for a halted or cancelled run. + [JsonPropertyName("reason")] + public string? Reason { get; set; } + + /// Completed factory result. + [JsonPropertyName("result")] + public JsonElement? Result { get; set; } + + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Partial journal and progress snapshot for a halted, cancelled, or errored run. + [JsonPropertyName("snapshot")] + public JsonElement? Snapshot { get; set; } + + /// Current or terminal factory run status. + [JsonPropertyName("status")] + public FactoryRunStatus Status { get; set; } +} + +/// Wire-only per-invocation factory resource ceiling overrides. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryRunLimits +{ + /// Maximum number of factory subagents that may run concurrently. + [JsonPropertyName("maxConcurrentSubagents")] + public long? MaxConcurrentSubagents { get; set; } + + /// Maximum total number of factory subagents that may be admitted. + [JsonPropertyName("maxTotalSubagents")] + public long? MaxTotalSubagents { get; set; } + + /// Factory active-run timeout in milliseconds. + [JsonPropertyName("timeout")] + public double? Timeout { get; set; } +} + +/// Options controlling factory invocation. +[Experimental(Diagnostics.Experimental)] +public sealed class RunOptions +{ + /// Per-invocation resource ceiling overrides. + [JsonPropertyName("limits")] + public FactoryRunLimits? Limits { get; set; } + + /// Run identifier whose journal and progress should seed this resumed run. + [JsonPropertyName("resumeFromRunId")] + public string? ResumeFromRunId { get; set; } +} + +/// Parameters for invoking a registered factory. +[Experimental(Diagnostics.Experimental)] +internal sealed class FactoryRunRequest +{ + /// Factory input value. + [JsonPropertyName("args")] + public JsonElement Args { get; set; } + + /// Registered factory name. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Factory invocation options. + [JsonPropertyName("options")] + public RunOptions? Options { get; set; } + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Parameters for retrieving a factory run. +[Experimental(Diagnostics.Experimental)] +internal sealed class FactoryGetRunRequest +{ + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Parameters for cancelling a factory run. +[Experimental(Diagnostics.Experimental)] +internal sealed class FactoryCancelRequest +{ + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Acknowledgement that a factory request was accepted. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryAckResult +{ +} + +/// One ordered factory progress line. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryLogLine +{ + /// Progress line kind. + [JsonPropertyName("kind")] + public FactoryLogLineKind Kind { get; set; } + + /// Monotonic sequence number within the factory run. + [JsonPropertyName("seq")] + public long Seq { get; set; } + + /// Progress text. + [JsonPropertyName("text")] + public string Text { get; set; } = string.Empty; +} + +/// Parameters for recording factory progress. +[Experimental(Diagnostics.Experimental)] +internal sealed class FactoryLogRequest +{ + /// Ordered progress lines to append. + [JsonPropertyName("lines")] + public IList Lines { get => field ??= []; set; } + + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Result of one factory-scoped subagent call. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryAgentResult +{ + /// Agent result, omitted when the agent produced no result. + [JsonPropertyName("result")] + public JsonElement? Result { get; set; } +} + +/// Options for one factory-scoped subagent call. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryAgentOptions +{ + /// Optional label distinguishing otherwise identical memoized agent calls. + [JsonPropertyName("label")] + public string? Label { get; set; } + + /// Optional model identifier for the subagent. + [JsonPropertyName("model")] + public string? Model { get; set; } + + /// Optional JSON Schema for structured agent output. + [JsonPropertyName("schema")] + public JsonElement? Schema { get; set; } +} + +/// Parameters for one factory-scoped subagent call. +[Experimental(Diagnostics.Experimental)] +internal sealed class FactoryAgentRequest +{ + /// Factory run identifier that owns the subagent. + [JsonPropertyName("factoryRunId")] + public string FactoryRunId { get; set; } = string.Empty; + + /// Subagent execution options. + [JsonPropertyName("opts")] + public FactoryAgentOptions Opts { get => field ??= new(); set; } + + /// Prompt to send to the subagent. + [JsonPropertyName("prompt")] + public string Prompt { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Result of reading a factory journal entry. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryJournalGetResult +{ + /// Whether the journal contained the requested key. + [JsonPropertyName("hit")] + public bool Hit { get; set; } + + /// Cached JSON result. The hit field distinguishes a cached JSON null from a miss. + [JsonPropertyName("resultJson")] + public JsonElement? ResultJson { get; set; } +} + +/// Parameters for reading a factory journal entry. +[Experimental(Diagnostics.Experimental)] +internal sealed class FactoryJournalGetRequest +{ + /// Namespaced journal key. + [JsonPropertyName("key")] + public string Key { get; set; } = string.Empty; + + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Parameters for storing a factory journal entry. +[Experimental(Diagnostics.Experimental)] +internal sealed class FactoryJournalPutRequest +{ + /// Namespaced journal key. + [JsonPropertyName("key")] + public string Key { get; set; } = string.Empty; + + /// JSON result to memoize. + [JsonPropertyName("resultJson")] + public JsonElement ResultJson { get; set; } + + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + /// The currently selected model, reasoning effort, and context tier for the session. The context tier reflects `Session.getContextTier()`, restored from the session journal on resume. [Experimental(Diagnostics.Experimental)] public sealed class CurrentModel @@ -7427,6 +7733,14 @@ public sealed class SandboxConfig [JsonPropertyName("enabled")] public bool Enabled { get; set; } + /// Whether to export `GH_TOKEN` so the `gh` CLI authenticates inside the sandbox without the OS keyring the sandbox blocks. Default: false (opt-in). + [JsonPropertyName("ghAuth")] + public bool? GhAuth { get; set; } + + /// Whether to inject the Copilot GitHub token as an `http.<host>.extraheader` so authenticated HTTPS git works inside the sandbox without the shell-based credential helper the sandbox blocks. Default: false (opt-in). + [JsonPropertyName("gitAuth")] + public bool? GitAuth { get; set; } + /// User-managed sandbox policy fragment merged into the auto-discovered base policy. [JsonPropertyName("userPolicy")] public SandboxConfigUserPolicy? UserPolicy { get; set; } @@ -10794,7 +11108,7 @@ internal sealed class MetadataContextHeaviestMessagesRequest public string SessionId { get; set; } = string.Empty; } -/// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). +/// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead. [Experimental(Diagnostics.Experimental)] public sealed class MetadataRecordContextChangeResult { @@ -11660,6 +11974,10 @@ public sealed class UsageMetricsModelMetricUsage [Experimental(Diagnostics.Experimental)] public sealed class UsageMetricsModelMetric { + /// Latest known prompt-cache expiration for this model. A timestamp in the past indicates that the observed cache has expired. + [JsonPropertyName("cacheExpiresAt")] + public DateTimeOffset? CacheExpiresAt { get; set; } + /// Request count and cost metrics for this model. [JsonPropertyName("requests")] public UsageMetricsModelMetricRequests Requests { get => field ??= new(); set; } @@ -11969,6 +12287,49 @@ public sealed class ProviderTokenAcquireRequest public string SessionId { get; set; } = string.Empty; } +/// Result returned by an extension factory closure. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryExecuteResult +{ + /// Factory result value. + [JsonPropertyName("result")] + public JsonElement Result { get; set; } +} + +/// Parameters sent to the owning extension to execute a factory closure. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryExecuteRequest +{ + /// Factory input value. + [JsonPropertyName("args")] + public JsonElement Args { get; set; } + + /// Registered factory name. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// Parameters for cooperatively aborting a factory body. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryAbortRequest +{ + /// Factory run identifier. + [JsonPropertyName("runId")] + public string RunId { get; set; } = string.Empty; + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + /// Describes a filesystem error. [Experimental(Diagnostics.Experimental)] public sealed class SessionFsError @@ -12454,10 +12815,14 @@ public sealed class LlmInferenceHttpRequestStartResult [Experimental(Diagnostics.Experimental)] public sealed class LlmInferenceHttpRequestStartRequest { - /// Stable per-agent-instance id attributing this request to a specific agent trajectory. Present when the request originates from an agent turn; absent for requests issued outside any agent context (e.g. some SDK callers). A request with an `agentId` but no `parentAgentId` is a root-agent request; one carrying both is a subagent request. Sourced from the runtime's per-request agent context and surfaced on the envelope independently of transport, so it is available for both first-party (CAPI) and BYOK/custom-provider requests; on the CAPI transport the runtime derives the upstream `X-Agent-Task-Id` header from this same context. Consumers routing each provider call to a training trajectory should key on this rather than on lifecycle events, since it is available on the request path before sampling. + /// Stable identity of the agent trajectory that issued this request. Present when the request originates from an agent turn; absent for requests outside any agent context. This is the same identity used by lifecycle and bridged session events and remains constant across turns and retries. [JsonPropertyName("agentId")] public string? AgentId { get; set; } + /// Identity of the agent invocation (one agentic loop) that issued this request. It remains fixed across physical retries within the invocation and is distinct from the stable trajectory `agentId`. A caller-supplied invocation id always takes precedence (this covers auxiliary calls that have no model call id). Otherwise, first-party CAPI requests fall back to the runtime's agent task id — the same value the runtime emits as the `X-Agent-Task-Id` header — while custom-provider requests fall back to the model call id. + [JsonPropertyName("agentInvocationId")] + public string? AgentInvocationId { get; set; } + /// Gets or sets the headers value. [JsonPropertyName("headers")] public IDictionary> Headers { get => field ??= new Dictionary>(); set; } @@ -12470,7 +12835,7 @@ public sealed class LlmInferenceHttpRequestStartRequest [JsonPropertyName("method")] public string Method { get; set; } = string.Empty; - /// Id of the parent agent that spawned the agent issuing this request. Present only for subagent requests; absent for root-agent requests and non-agent requests. Combined with `agentId`, this lets consumers attribute a call to a child trajectory versus the root. Like `agentId`, it comes from the runtime's per-request agent context independently of transport; on the CAPI transport the runtime derives the upstream `X-Parent-Agent-Id` header from this same context. + /// Stable identity of the immediate parent trajectory. Present for child trajectories such as subagents and conversation-sampling requests; absent for root-agent and non-agent requests. [JsonPropertyName("parentAgentId")] public string? ParentAgentId { get; set; } @@ -15186,6 +15551,207 @@ public override void Write(Utf8JsonWriter writer, DebugCollectLogsRedaction valu } +/// Cumulative resource ceiling that stopped a factory run. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct FactoryRunFailureKind : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public FactoryRunFailureKind(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// The run admitted the approved maximum total number of subagents. + public static FactoryRunFailureKind MaxTotalSubagents { get; } = new("maxTotalSubagents"); + + /// The run reached the approved timeout deadline. + public static FactoryRunFailureKind Timeout { get; } = new("timeout"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(FactoryRunFailureKind left, FactoryRunFailureKind right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(FactoryRunFailureKind left, FactoryRunFailureKind right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is FactoryRunFailureKind other && Equals(other); + + /// + public bool Equals(FactoryRunFailureKind 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 FactoryRunFailureKind Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, FactoryRunFailureKind value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(FactoryRunFailureKind)); + } + } +} + + +/// Current or terminal state of a factory run. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct FactoryRunStatus : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public FactoryRunStatus(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// The run was minted and is awaiting approval. + public static FactoryRunStatus Pending { get; } = new("pending"); + + /// The run is executing. + public static FactoryRunStatus Running { get; } = new("running"); + + /// The run completed successfully. + public static FactoryRunStatus Completed { get; } = new("completed"); + + /// The run was interrupted while resource budget remained. + public static FactoryRunStatus Halted { get; } = new("halted"); + + /// The run was cancelled before completion. + public static FactoryRunStatus Cancelled { get; } = new("cancelled"); + + /// The factory body failed or reached a cumulative resource ceiling. + public static FactoryRunStatus Error { get; } = new("error"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(FactoryRunStatus left, FactoryRunStatus right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(FactoryRunStatus left, FactoryRunStatus right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is FactoryRunStatus other && Equals(other); + + /// + public bool Equals(FactoryRunStatus 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 FactoryRunStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, FactoryRunStatus value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(FactoryRunStatus)); + } + } +} + + +/// Kind of factory progress line. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct FactoryLogLineKind : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public FactoryLogLineKind(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// A narrator log line. + public static FactoryLogLineKind Log { get; } = new("log"); + + /// A named factory phase marker. + public static FactoryLogLineKind Phase { get; } = new("phase"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(FactoryLogLineKind left, FactoryLogLineKind right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(FactoryLogLineKind left, FactoryLogLineKind right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is FactoryLogLineKind other && Equals(other); + + /// + public bool Equals(FactoryLogLineKind 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 FactoryLogLineKind Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, FactoryLogLineKind value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(FactoryLogLineKind)); + } + } +} + + /// Allowed values for the `WorkspacesWorkspaceDetailsHostType` enumeration. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] @@ -20342,6 +20908,12 @@ internal SessionRpc(CopilotSession session) Interlocked.CompareExchange(ref field, new(_session), null) ?? field; + /// Factory APIs. + public FactoryApi Factory => + field ?? + Interlocked.CompareExchange(ref field, new(_session), null) ?? + field; + /// Model APIs. public ModelApi Model => field ?? @@ -20797,6 +21369,142 @@ public async Task InvokeAsync(string instanceId, strin } } +/// Provides session-scoped Factory APIs. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryApi +{ + private readonly CopilotSession _session; + + internal FactoryApi(CopilotSession session) + { + _session = session; + } + + /// Runs a registered factory by name at the top level. + /// Registered factory name. + /// Factory input value. + /// Factory invocation options. + /// The to monitor for cancellation requests. The default is . + /// Complete current or terminal factory run envelope. + public async Task RunAsync(string name, object args, RunOptions? options = null, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(name); + ArgumentNullException.ThrowIfNull(args); + _session.ThrowIfDisposed(); + + var request = new FactoryRunRequest { SessionId = _session.SessionId, Name = name, Args = CopilotClient.ToJsonElementForWire(args)!.Value, Options = options }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.factory.run", [request], cancellationToken); + } + + /// Gets the current or settled envelope for a factory run. + /// Factory run identifier. + /// The to monitor for cancellation requests. The default is . + /// Complete current or terminal factory run envelope. + public async Task GetRunAsync(string runId, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(runId); + _session.ThrowIfDisposed(); + + var request = new FactoryGetRunRequest { SessionId = _session.SessionId, RunId = runId }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.factory.getRun", [request], cancellationToken); + } + + /// Requests cancellation of a factory run and returns its run envelope. + /// Factory run identifier. + /// The to monitor for cancellation requests. The default is . + /// Complete current or terminal factory run envelope. + public async Task CancelAsync(string runId, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(runId); + _session.ThrowIfDisposed(); + + var request = new FactoryCancelRequest { SessionId = _session.SessionId, RunId = runId }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.factory.cancel", [request], cancellationToken); + } + + /// Records a batch of ordered factory progress lines. + /// Factory run identifier. + /// Ordered progress lines to append. + /// The to monitor for cancellation requests. The default is . + /// Acknowledgement that a factory request was accepted. + public async Task LogAsync(string runId, IList lines, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(runId); + ArgumentNullException.ThrowIfNull(lines); + _session.ThrowIfDisposed(); + + var request = new FactoryLogRequest { SessionId = _session.SessionId, RunId = runId, Lines = lines }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.factory.log", [request], cancellationToken); + } + + /// Runs one factory-scoped subagent and returns its result. + /// Factory run identifier that owns the subagent. + /// Prompt to send to the subagent. + /// Subagent execution options. + /// The to monitor for cancellation requests. The default is . + /// Result of one factory-scoped subagent call. + public async Task AgentAsync(string factoryRunId, string prompt, FactoryAgentOptions opts, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(factoryRunId); + ArgumentNullException.ThrowIfNull(prompt); + ArgumentNullException.ThrowIfNull(opts); + _session.ThrowIfDisposed(); + + var request = new FactoryAgentRequest { SessionId = _session.SessionId, FactoryRunId = factoryRunId, Prompt = prompt, Opts = opts }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.factory.agent", [request], cancellationToken); + } + + /// Journal APIs. + public FactoryJournalApi Journal => + field ?? + Interlocked.CompareExchange(ref field, new(_session), null) ?? + field; +} + +/// Provides session-scoped FactoryJournal APIs. +[Experimental(Diagnostics.Experimental)] +public sealed class FactoryJournalApi +{ + private readonly CopilotSession _session; + + internal FactoryJournalApi(CopilotSession session) + { + _session = session; + } + + /// Reads a memoized factory journal entry. + /// Factory run identifier. + /// Namespaced journal key. + /// The to monitor for cancellation requests. The default is . + /// Result of reading a factory journal entry. + public async Task GetAsync(string runId, string key, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(runId); + ArgumentNullException.ThrowIfNull(key); + _session.ThrowIfDisposed(); + + var request = new FactoryJournalGetRequest { SessionId = _session.SessionId, RunId = runId, Key = key }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.factory.journal.get", [request], cancellationToken); + } + + /// Stores a memoized factory journal entry. + /// Factory run identifier. + /// Namespaced journal key. + /// JSON result to memoize. + /// The to monitor for cancellation requests. The default is . + /// Acknowledgement that a factory request was accepted. + public async Task PutAsync(string runId, string key, object resultJson, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(runId); + ArgumentNullException.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(resultJson); + _session.ThrowIfDisposed(); + + var request = new FactoryJournalPutRequest { SessionId = _session.SessionId, RunId = runId, Key = key, ResultJson = CopilotClient.ToJsonElementForWire(resultJson)!.Value }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.factory.journal.put", [request], cancellationToken); + } +} + /// Provides session-scoped Model APIs. [Experimental(Diagnostics.Experimental)] public sealed class ModelApi @@ -23018,10 +23726,10 @@ public async Task GetContextHeaviestMessa return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.metadata.getContextHeaviestMessages", [request], cancellationToken); } - /// Records a working-directory/git context change and emits a `session.context_changed` event. + /// Records a working-directory/git context change and emits a `session.context_changed` event. For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event): a local session's working directory is authoritative and is moved via `metadata.setWorkingDirectory` (or an SDK `session.resume` that supplies a `workingDirectory`), not by this method. /// Updated working directory and git context. Emitted as the new payload of `session.context_changed`. /// The to monitor for cancellation requests. The default is . - /// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). + /// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead. public async Task RecordContextChangeAsync(SessionWorkingDirectoryContext context, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(context); @@ -23492,6 +24200,22 @@ public interface IProviderTokenHandler Task GetTokenAsync(ProviderTokenAcquireRequest request, CancellationToken cancellationToken = default); } +/// Handles `factory` client session API methods. +[Experimental(Diagnostics.Experimental)] +public interface IFactoryHandler +{ + /// Asks the owning extension connection to execute a registered factory closure. + /// Parameters sent to the owning extension to execute a factory closure. + /// The to monitor for cancellation requests. The default is . + /// Result returned by an extension factory closure. + Task ExecuteAsync(FactoryExecuteRequest request, CancellationToken cancellationToken = default); + /// Asks the owning extension connection to abort a running factory cooperatively. + /// Parameters for cooperatively aborting a factory body. + /// The to monitor for cancellation requests. The default is . + /// Acknowledgement that a factory request was accepted. + Task AbortAsync(FactoryAbortRequest request, CancellationToken cancellationToken = default); +} + /// Handles `sessionFs` client session API methods. [Experimental(Diagnostics.Experimental)] public interface ISessionFsHandler @@ -23584,6 +24308,9 @@ public sealed class ClientSessionApiHandlers /// Optional handler for ProviderToken client session API methods. public IProviderTokenHandler? ProviderToken { get; set; } + /// Optional handler for Factory client session API methods. + public IFactoryHandler? Factory { get; set; } + /// Optional handler for SessionFs client session API methods. public ISessionFsHandler? SessionFs { get; set; } @@ -23607,6 +24334,18 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, Func>)(async (request, cancellationToken) => + { + var handler = getHandlers(request.SessionId).Factory; + if (handler is null) throw new InvalidOperationException($"No factory handler registered for session: {request.SessionId}"); + return await handler.ExecuteAsync(request, cancellationToken); + }), singleObjectParam: true); + rpc.SetLocalRpcMethod("factory.abort", (Func>)(async (request, cancellationToken) => + { + var handler = getHandlers(request.SessionId).Factory; + if (handler is null) throw new InvalidOperationException($"No factory handler registered for session: {request.SessionId}"); + return await handler.AbortAsync(request, cancellationToken); + }), singleObjectParam: true); rpc.SetLocalRpcMethod("sessionFs.readFile", (Func>)(async (request, cancellationToken) => { var handler = getHandlers(request.SessionId).SessionFs; @@ -23802,6 +24541,8 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.AssistantToolCallDeltaEvent), TypeInfoPropertyName = "SessionEventsAssistantToolCallDeltaEvent")] [JsonSerializable(typeof(GitHub.Copilot.AssistantTurnEndData), TypeInfoPropertyName = "SessionEventsAssistantTurnEndData")] [JsonSerializable(typeof(GitHub.Copilot.AssistantTurnEndEvent), TypeInfoPropertyName = "SessionEventsAssistantTurnEndEvent")] +[JsonSerializable(typeof(GitHub.Copilot.AssistantTurnRetryData), TypeInfoPropertyName = "SessionEventsAssistantTurnRetryData")] +[JsonSerializable(typeof(GitHub.Copilot.AssistantTurnRetryEvent), TypeInfoPropertyName = "SessionEventsAssistantTurnRetryEvent")] [JsonSerializable(typeof(GitHub.Copilot.AssistantTurnStartData), TypeInfoPropertyName = "SessionEventsAssistantTurnStartData")] [JsonSerializable(typeof(GitHub.Copilot.AssistantTurnStartEvent), TypeInfoPropertyName = "SessionEventsAssistantTurnStartEvent")] [JsonSerializable(typeof(GitHub.Copilot.AssistantUsageApiEndpoint), TypeInfoPropertyName = "SessionEventsAssistantUsageApiEndpoint")] @@ -23904,6 +24645,8 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.HookProgressEvent), TypeInfoPropertyName = "SessionEventsHookProgressEvent")] [JsonSerializable(typeof(GitHub.Copilot.HookStartData), TypeInfoPropertyName = "SessionEventsHookStartData")] [JsonSerializable(typeof(GitHub.Copilot.HookStartEvent), TypeInfoPropertyName = "SessionEventsHookStartEvent")] +[JsonSerializable(typeof(GitHub.Copilot.ManagedSettingsEnforcedAction), TypeInfoPropertyName = "SessionEventsManagedSettingsEnforcedAction")] +[JsonSerializable(typeof(GitHub.Copilot.ManagedSettingsEnforcedEscalation), TypeInfoPropertyName = "SessionEventsManagedSettingsEnforcedEscalation")] [JsonSerializable(typeof(GitHub.Copilot.ManagedSettingsResolvedSource), TypeInfoPropertyName = "SessionEventsManagedSettingsResolvedSource")] [JsonSerializable(typeof(GitHub.Copilot.McpAppToolCallCompleteData), TypeInfoPropertyName = "SessionEventsMcpAppToolCallCompleteData")] [JsonSerializable(typeof(GitHub.Copilot.McpAppToolCallCompleteError), TypeInfoPropertyName = "SessionEventsMcpAppToolCallCompleteError")] @@ -23935,8 +24678,12 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.ModelCallFailureBadRequestKind), TypeInfoPropertyName = "SessionEventsModelCallFailureBadRequestKind")] [JsonSerializable(typeof(GitHub.Copilot.ModelCallFailureData), TypeInfoPropertyName = "SessionEventsModelCallFailureData")] [JsonSerializable(typeof(GitHub.Copilot.ModelCallFailureEvent), TypeInfoPropertyName = "SessionEventsModelCallFailureEvent")] +[JsonSerializable(typeof(GitHub.Copilot.ModelCallFailureKind), TypeInfoPropertyName = "SessionEventsModelCallFailureKind")] [JsonSerializable(typeof(GitHub.Copilot.ModelCallFailureRequestFingerprint), TypeInfoPropertyName = "SessionEventsModelCallFailureRequestFingerprint")] [JsonSerializable(typeof(GitHub.Copilot.ModelCallFailureSource), TypeInfoPropertyName = "SessionEventsModelCallFailureSource")] +[JsonSerializable(typeof(GitHub.Copilot.ModelCallFailureTransport), TypeInfoPropertyName = "SessionEventsModelCallFailureTransport")] +[JsonSerializable(typeof(GitHub.Copilot.ModelCallStartData), TypeInfoPropertyName = "SessionEventsModelCallStartData")] +[JsonSerializable(typeof(GitHub.Copilot.ModelCallStartEvent), TypeInfoPropertyName = "SessionEventsModelCallStartEvent")] [JsonSerializable(typeof(GitHub.Copilot.OmittedBinaryOmittedReason), TypeInfoPropertyName = "SessionEventsOmittedBinaryOmittedReason")] [JsonSerializable(typeof(GitHub.Copilot.OmittedBinaryResult), TypeInfoPropertyName = "SessionEventsOmittedBinaryResult")] [JsonSerializable(typeof(GitHub.Copilot.OmittedBinaryType), TypeInfoPropertyName = "SessionEventsOmittedBinaryType")] @@ -24070,6 +24817,8 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartToolDescriptionMeta), TypeInfoPropertyName = "SessionEventsToolExecutionStartToolDescriptionMeta")] [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartToolDescriptionMetaUI), TypeInfoPropertyName = "SessionEventsToolExecutionStartToolDescriptionMetaUI")] [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartToolDescriptionMetaUIVisibility), TypeInfoPropertyName = "SessionEventsToolExecutionStartToolDescriptionMetaUIVisibility")] +[JsonSerializable(typeof(GitHub.Copilot.ToolSearchActivatedData), TypeInfoPropertyName = "SessionEventsToolSearchActivatedData")] +[JsonSerializable(typeof(GitHub.Copilot.ToolSearchActivatedEvent), TypeInfoPropertyName = "SessionEventsToolSearchActivatedEvent")] [JsonSerializable(typeof(GitHub.Copilot.ToolUserRequestedData), TypeInfoPropertyName = "SessionEventsToolUserRequestedData")] [JsonSerializable(typeof(GitHub.Copilot.ToolUserRequestedEvent), TypeInfoPropertyName = "SessionEventsToolUserRequestedEvent")] [JsonSerializable(typeof(GitHub.Copilot.UserInputCompletedData), TypeInfoPropertyName = "SessionEventsUserInputCompletedData")] @@ -24185,6 +24934,24 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(ExtensionList))] [JsonSerializable(typeof(ExtensionsDisableRequest))] [JsonSerializable(typeof(ExtensionsEnableRequest))] +[JsonSerializable(typeof(FactoryAbortRequest))] +[JsonSerializable(typeof(FactoryAckResult))] +[JsonSerializable(typeof(FactoryAgentOptions))] +[JsonSerializable(typeof(FactoryAgentRequest))] +[JsonSerializable(typeof(FactoryAgentResult))] +[JsonSerializable(typeof(FactoryCancelRequest))] +[JsonSerializable(typeof(FactoryExecuteRequest))] +[JsonSerializable(typeof(FactoryExecuteResult))] +[JsonSerializable(typeof(FactoryGetRunRequest))] +[JsonSerializable(typeof(FactoryJournalGetRequest))] +[JsonSerializable(typeof(FactoryJournalGetResult))] +[JsonSerializable(typeof(FactoryJournalPutRequest))] +[JsonSerializable(typeof(FactoryLogLine))] +[JsonSerializable(typeof(FactoryLogRequest))] +[JsonSerializable(typeof(FactoryRunFailure))] +[JsonSerializable(typeof(FactoryRunLimits))] +[JsonSerializable(typeof(FactoryRunRequest))] +[JsonSerializable(typeof(FactoryRunResult))] [JsonSerializable(typeof(FleetStartRequest))] [JsonSerializable(typeof(FleetStartResult))] [JsonSerializable(typeof(FolderTrustAddParams))] @@ -24475,6 +25242,7 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(RemoteSessionConnectionResult))] [JsonSerializable(typeof(RemoteSessionMetadataRepository))] [JsonSerializable(typeof(RemoteSessionMetadataValue))] +[JsonSerializable(typeof(RunOptions))] [JsonSerializable(typeof(SandboxConfig))] [JsonSerializable(typeof(SandboxConfigUserPolicy))] [JsonSerializable(typeof(SandboxConfigUserPolicyExperimental))] diff --git a/dotnet/src/Generated/SessionEvents.cs b/dotnet/src/Generated/SessionEvents.cs index 41b87d06f..a8c70df7c 100644 --- a/dotnet/src/Generated/SessionEvents.cs +++ b/dotnet/src/Generated/SessionEvents.cs @@ -36,6 +36,7 @@ namespace GitHub.Copilot; [JsonDerivedType(typeof(AssistantStreamingDeltaEvent), "assistant.streaming_delta")] [JsonDerivedType(typeof(AssistantToolCallDeltaEvent), "assistant.tool_call_delta")] [JsonDerivedType(typeof(AssistantTurnEndEvent), "assistant.turn_end")] +[JsonDerivedType(typeof(AssistantTurnRetryEvent), "assistant.turn_retry")] [JsonDerivedType(typeof(AssistantTurnStartEvent), "assistant.turn_start")] [JsonDerivedType(typeof(AssistantUsageEvent), "assistant.usage")] [JsonDerivedType(typeof(AutoModeSwitchCompletedEvent), "auto_mode_switch.completed")] @@ -63,6 +64,7 @@ namespace GitHub.Copilot; [JsonDerivedType(typeof(McpResourcesListChangedEvent), "mcp.resources.list_changed")] [JsonDerivedType(typeof(McpToolsListChangedEvent), "mcp.tools.list_changed")] [JsonDerivedType(typeof(ModelCallFailureEvent), "model.call_failure")] +[JsonDerivedType(typeof(ModelCallStartEvent), "model.call_start")] [JsonDerivedType(typeof(PendingMessagesModifiedEvent), "pending_messages.modified")] [JsonDerivedType(typeof(PermissionCompletedEvent), "permission.completed")] [JsonDerivedType(typeof(PermissionRequestedEvent), "permission.requested")] @@ -91,6 +93,7 @@ namespace GitHub.Copilot; [JsonDerivedType(typeof(SessionHandoffEvent), "session.handoff")] [JsonDerivedType(typeof(SessionIdleEvent), "session.idle")] [JsonDerivedType(typeof(SessionInfoEvent), "session.info")] +[JsonDerivedType(typeof(SessionManagedSettingsEnforcedEvent), "session.managed_settings_enforced")] [JsonDerivedType(typeof(SessionManagedSettingsResolvedEvent), "session.managed_settings_resolved")] [JsonDerivedType(typeof(SessionMcpServerStatusChangedEvent), "session.mcp_server_status_changed")] [JsonDerivedType(typeof(SessionMcpServersLoadedEvent), "session.mcp_servers_loaded")] @@ -125,6 +128,7 @@ namespace GitHub.Copilot; [JsonDerivedType(typeof(SubagentStartedEvent), "subagent.started")] [JsonDerivedType(typeof(SystemMessageEvent), "system.message")] [JsonDerivedType(typeof(SystemNotificationEvent), "system.notification")] +[JsonDerivedType(typeof(ToolSearchActivatedEvent), "tool_search.activated")] [JsonDerivedType(typeof(ToolExecutionCompleteEvent), "tool.execution_complete")] [JsonDerivedType(typeof(ToolExecutionPartialResultEvent), "tool.execution_partial_result")] [JsonDerivedType(typeof(ToolExecutionProgressEvent), "tool.execution_progress")] @@ -591,6 +595,19 @@ public sealed partial class AssistantTurnStartEvent : SessionEvent public required AssistantTurnStartData Data { get; set; } } +/// Metadata for an additional model inference attempt within an existing assistant turn. +/// Represents the assistant.turn_retry event. +public sealed partial class AssistantTurnRetryEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "assistant.turn_retry"; + + /// The assistant.turn_retry event payload. + [JsonPropertyName("data")] + public required AssistantTurnRetryData Data { get; set; } +} + /// Agent intent description for current activity or plan. /// Represents the assistant.intent event. public sealed partial class AssistantIntentEvent : SessionEvent @@ -760,6 +777,19 @@ public sealed partial class ModelCallFailureEvent : SessionEvent public required ModelCallFailureData Data { get; set; } } +/// Model API dispatch metadata for internal telemetry. +/// Represents the model.call_start event. +public sealed partial class ModelCallStartEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "model.call_start"; + + /// The model.call_start event payload. + [JsonPropertyName("data")] + public required ModelCallStartData Data { get; set; } +} + /// Turn abort information including the reason for termination. /// Represents the abort event. public sealed partial class AbortEvent : SessionEvent @@ -838,6 +868,19 @@ public sealed partial class ToolExecutionCompleteEvent : SessionEvent public required ToolExecutionCompleteData Data { get; set; } } +/// Persisted generic client-side tool activations restored when a session resumes. +/// Represents the tool_search.activated event. +public sealed partial class ToolSearchActivatedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "tool_search.activated"; + + /// The tool_search.activated event payload. + [JsonPropertyName("data")] + public required ToolSearchActivatedData Data { get; set; } +} + /// Skill invocation details including content, allowed tools, and plugin metadata. /// Represents the skill.invoked event. public sealed partial class SkillInvokedEvent : SessionEvent @@ -1309,6 +1352,20 @@ public sealed partial class SessionManagedSettingsResolvedEvent : SessionEvent public required SessionManagedSettingsResolvedData Data { get; set; } } +/// Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes. +/// Represents the session.managed_settings_enforced event. +[Experimental(Diagnostics.Experimental)] +public sealed partial class SessionManagedSettingsEnforcedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "session.managed_settings_enforced"; + + /// The session.managed_settings_enforced event payload. + [JsonPropertyName("data")] + public required SessionManagedSettingsEnforcedData Data { get; set; } +} + /// SDK command registration change notification. /// Represents the commands.changed event. public sealed partial class CommandsChangedEvent : SessionEvent @@ -2231,6 +2288,12 @@ public sealed partial class SessionShutdownData /// Durable session usage checkpoint for reconstructing aggregate accounting on resume. public sealed partial class SessionUsageCheckpointData { + /// Internal per-model prompt-cache state used to restore expiration tracking on resume. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonInclude] + [JsonPropertyName("modelCacheState")] + internal UsageCheckpointModelCacheState[]? ModelCacheState { get; set; } + /// Session-wide accumulated nano-AI units cost at checkpoint time. [JsonPropertyName("totalNanoAiu")] public required double TotalNanoAiu { get; set; } @@ -2533,6 +2596,24 @@ public sealed partial class AssistantTurnStartData public required string TurnId { get; set; } } +/// Metadata for an additional model inference attempt within an existing assistant turn. +public sealed partial class AssistantTurnRetryData +{ + /// Model identifier used for this retry, when known. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("model")] + public string? Model { get; set; } + + /// Provider or runtime classification that caused the retry, when known. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("reason")] + public string? Reason { get; set; } + + /// Identifier of the turn whose model inference is being retried. + [JsonPropertyName("turnId")] + public required string TurnId { get; set; } +} + /// Agent intent description for current activity or plan. public sealed partial class AssistantIntentData { @@ -2782,6 +2863,11 @@ public sealed partial class AssistantUsageData [JsonPropertyName("apiEndpoint")] public AssistantUsageApiEndpoint? ApiEndpoint { get; set; } + /// Updated prompt-cache expiration for this model call. Present only when the call establishes or refreshes known cache state. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("cacheExpiresAt")] + public DateTimeOffset? CacheExpiresAt { get; set; } + /// Number of tokens read from prompt cache. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("cacheReadTokens")] @@ -2894,6 +2980,11 @@ public sealed partial class ModelCallFailureData [JsonPropertyName("apiCallId")] public string? ApiCallId { get; set; } + /// API endpoint used for this model call, matching CAPI supported_endpoints vocabulary. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("apiEndpoint")] + public AssistantUsageApiEndpoint? ApiEndpoint { get; set; } + /// For HTTP 400 failures only: whether the response carried a structured CAPI error envelope (structured_error, a deterministic validation failure) or no error body (bodyless, the transient gateway/proxy signature). Absent for non-400 failures. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("badRequestKind")] @@ -2920,11 +3011,36 @@ public sealed partial class ModelCallFailureData [JsonPropertyName("errorType")] public string? ErrorType { get; set; } + /// Whether the failure originated from an API response or the request transport. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("failureKind")] + public ModelCallFailureKind? FailureKind { get; set; } + /// What initiated this API call (e.g., "sub-agent", "mcp-sampling"); absent for user-initiated calls. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("initiator")] public string? Initiator { get; set; } + /// Whether the session selected Auto mode for the failed call. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("isAuto")] + public bool? IsAuto { get; set; } + + /// Whether the failed call used a bring-your-own-key provider. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("isByok")] + public bool? IsByok { get; set; } + + /// Effective maximum output-token limit for the failed call. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("maxOutputTokens")] + public long? MaxOutputTokens { get; set; } + + /// Effective maximum prompt-token limit for the failed call. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("maxPromptTokens")] + public long? MaxPromptTokens { get; set; } + /// Model identifier used for the failed API call. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("model")] @@ -2941,6 +3057,11 @@ public sealed partial class ModelCallFailureData [JsonPropertyName("quotaSnapshots")] internal IDictionary? QuotaSnapshots { get; set; } + /// Reasoning effort level used for the failed model call, if applicable. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("reasoningEffort")] + public string? ReasoningEffort { get; set; } + /// Content-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("requestFingerprint")] @@ -2959,6 +3080,24 @@ public sealed partial class ModelCallFailureData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("statusCode")] public int? StatusCode { get; set; } + + /// Transport used for the failed model call (http or websocket). + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("transport")] + public ModelCallFailureTransport? Transport { get; set; } +} + +/// Model API dispatch metadata for internal telemetry. +public sealed partial class ModelCallStartData +{ + /// Model identifier used for this API call, when known. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("model")] + public string? Model { get; set; } + + /// Identifier of the assistant turn that initiated the model call. + [JsonPropertyName("turnId")] + public required string TurnId { get; set; } } /// Turn abort information including the reason for termination. @@ -3143,6 +3282,18 @@ public sealed partial class ToolExecutionCompleteData public string? TurnId { get; set; } } +/// Persisted generic client-side tool activations restored when a session resumes. +public sealed partial class ToolSearchActivatedData +{ + /// Tool-search strategy that activated the definitions. + [JsonPropertyName("strategy")] + public required string Strategy { get; set; } + + /// Names of tool definitions activated by this search invocation. + [JsonPropertyName("toolNames")] + public required string[] ToolNames { get; set; } +} + /// Skill invocation details including content, allowed tools, and plugin metadata. public sealed partial class SkillInvokedData { @@ -3934,6 +4085,32 @@ public sealed partial class SessionManagedSettingsResolvedData public required ManagedSettingsResolvedSource Source { get; set; } } +/// Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes. +[Experimental(Diagnostics.Experimental)] +public sealed partial class SessionManagedSettingsEnforcedData +{ + /// The category of runtime action that managed policy governed. + [JsonPropertyName("action")] + public required ManagedSettingsEnforcedAction Action { get; set; } + + /// For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused. Absent for actions without a specific escalation primitive. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("escalation")] + public ManagedSettingsEnforcedEscalation? Escalation { get; set; } + + /// Whether the enforcement was forced by fail-closed handling (managed policy could not be determined) rather than an explicit managed setting. When true, `setting` still names the restriction that was applied. + [JsonPropertyName("failClosed")] + public required bool FailClosed { get; set; } + + /// A human-readable explanation of why the action was governed, suitable for surfacing to the user. + [JsonPropertyName("message")] + public required string Message { get; set; } + + /// The managed setting key responsible for the enforcement (e.g. `permissions.disableBypassPermissionsMode`). + [JsonPropertyName("setting")] + public required string Setting { get; set; } +} + /// SDK command registration change notification. public sealed partial class CommandsChangedData { @@ -4461,6 +4638,24 @@ public sealed partial class ShutdownTokenDetail public required long TokenCount { get; set; } } +/// Internal prompt-cache expiration state for one model. +/// Nested data type for UsageCheckpointModelCacheState. +internal sealed partial class UsageCheckpointModelCacheState +{ + /// Latest known prompt-cache expiration. + [JsonPropertyName("cacheExpiresAt")] + public required DateTimeOffset CacheExpiresAt { get; set; } + + /// Retained cache lifetime in seconds, used to refresh expiration after a cache read. + [JsonInclude] + [JsonPropertyName("cacheTtlSeconds")] + internal required long CacheTtlSeconds { get; set; } + + /// Model identifier associated with this cache state. + [JsonPropertyName("modelId")] + public required string ModelId { get; set; } +} + /// Token usage detail for a single billing category. /// Nested data type for CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail. public sealed partial class CompactionCompleteCompactionTokensUsedCopilotUsageTokenDetail @@ -9234,6 +9429,67 @@ public override void Write(Utf8JsonWriter writer, ModelCallFailureBadRequestKind } } +/// Boundary that produced a model call failure. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct ModelCallFailureKind : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public ModelCallFailureKind(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// The provider returned an API error response. + public static ModelCallFailureKind Api { get; } = new("api"); + + /// The request transport failed before a usable API response completed. + public static ModelCallFailureKind Transport { get; } = new("transport"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(ModelCallFailureKind left, ModelCallFailureKind right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(ModelCallFailureKind left, ModelCallFailureKind right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is ModelCallFailureKind other && Equals(other); + + /// + public bool Equals(ModelCallFailureKind 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 ModelCallFailureKind Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, ModelCallFailureKind value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ModelCallFailureKind)); + } + } +} + /// Where the failed model call originated. [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] @@ -9298,6 +9554,67 @@ public override void Write(Utf8JsonWriter writer, ModelCallFailureSource value, } } +/// Transport used for a failed model call. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct ModelCallFailureTransport : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public ModelCallFailureTransport(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// HTTP transport, including SSE streams. + public static ModelCallFailureTransport Http { get; } = new("http"); + + /// WebSocket transport. + public static ModelCallFailureTransport Websocket { get; } = new("websocket"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(ModelCallFailureTransport left, ModelCallFailureTransport right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(ModelCallFailureTransport left, ModelCallFailureTransport right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is ModelCallFailureTransport other && Equals(other); + + /// + public bool Equals(ModelCallFailureTransport 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 ModelCallFailureTransport Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, ModelCallFailureTransport value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ModelCallFailureTransport)); + } + } +} + /// Finite reason code describing why the current turn was aborted. [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] @@ -10869,6 +11186,134 @@ public override void Write(Utf8JsonWriter writer, ManagedSettingsResolvedSource } } +/// The category of runtime action that enterprise managed settings governed (blocked or capped). +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct ManagedSettingsEnforcedAction : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public ManagedSettingsEnforcedAction(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// An attempt to turn on a bypass-permissions ("yolo") escalation was refused or capped because policy disables bypass-permissions mode. + public static ManagedSettingsEnforcedAction BypassPermissionsBlocked { get; } = new("bypass_permissions_blocked"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(ManagedSettingsEnforcedAction left, ManagedSettingsEnforcedAction right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(ManagedSettingsEnforcedAction left, ManagedSettingsEnforcedAction right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is ManagedSettingsEnforcedAction other && Equals(other); + + /// + public bool Equals(ManagedSettingsEnforcedAction 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 ManagedSettingsEnforcedAction Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, ManagedSettingsEnforcedAction value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ManagedSettingsEnforcedAction)); + } + } +} + +/// For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct ManagedSettingsEnforcedEscalation : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public ManagedSettingsEnforcedEscalation(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Full allow-all ("/allow-all on") permissions — auto-approving tools, paths, and URLs. + public static ManagedSettingsEnforcedEscalation AllowAll { get; } = new("allow_all"); + + /// Auto-approval of all tool permission requests. + public static ManagedSettingsEnforcedEscalation ApproveAll { get; } = new("approve_all"); + + /// Advisory auto-approval ("/allow-all auto") mode — keeps normal prompt paths and adds LLM-advised approval, distinct from full allow-all. + public static ManagedSettingsEnforcedEscalation AutoApproval { get; } = new("auto_approval"); + + /// Unrestricted filesystem access outside the session's allowed directories. + public static ManagedSettingsEnforcedEscalation UnrestrictedPaths { get; } = new("unrestricted_paths"); + + /// Unrestricted URL fetch access. + public static ManagedSettingsEnforcedEscalation UnrestrictedUrls { get; } = new("unrestricted_urls"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(ManagedSettingsEnforcedEscalation left, ManagedSettingsEnforcedEscalation right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(ManagedSettingsEnforcedEscalation left, ManagedSettingsEnforcedEscalation right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is ManagedSettingsEnforcedEscalation other && Equals(other); + + /// + public bool Equals(ManagedSettingsEnforcedEscalation 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 ManagedSettingsEnforcedEscalation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, ManagedSettingsEnforcedEscalation value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ManagedSettingsEnforcedEscalation)); + } + } +} + /// Exit plan mode action. [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] @@ -11384,6 +11829,8 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(AssistantToolCallDeltaEvent))] [JsonSerializable(typeof(AssistantTurnEndData))] [JsonSerializable(typeof(AssistantTurnEndEvent))] +[JsonSerializable(typeof(AssistantTurnRetryData))] +[JsonSerializable(typeof(AssistantTurnRetryEvent))] [JsonSerializable(typeof(AssistantTurnStartData))] [JsonSerializable(typeof(AssistantTurnStartEvent))] [JsonSerializable(typeof(AssistantUsageCopilotUsage))] @@ -11497,6 +11944,8 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(ModelCallFailureData))] [JsonSerializable(typeof(ModelCallFailureEvent))] [JsonSerializable(typeof(ModelCallFailureRequestFingerprint))] +[JsonSerializable(typeof(ModelCallStartData))] +[JsonSerializable(typeof(ModelCallStartEvent))] [JsonSerializable(typeof(OmittedBinaryResult))] [JsonSerializable(typeof(PendingMessagesModifiedData))] [JsonSerializable(typeof(PendingMessagesModifiedEvent))] @@ -11596,6 +12045,8 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(SessionLimitsExhaustedRequestedData))] [JsonSerializable(typeof(SessionLimitsExhaustedRequestedEvent))] [JsonSerializable(typeof(SessionLimitsExhaustedResponse))] +[JsonSerializable(typeof(SessionManagedSettingsEnforcedData))] +[JsonSerializable(typeof(SessionManagedSettingsEnforcedEvent))] [JsonSerializable(typeof(SessionManagedSettingsResolvedData))] [JsonSerializable(typeof(SessionManagedSettingsResolvedEvent))] [JsonSerializable(typeof(SessionMcpServerStatusChangedData))] @@ -11715,8 +12166,11 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(ToolExecutionStartToolDescription))] [JsonSerializable(typeof(ToolExecutionStartToolDescriptionMeta))] [JsonSerializable(typeof(ToolExecutionStartToolDescriptionMetaUI))] +[JsonSerializable(typeof(ToolSearchActivatedData))] +[JsonSerializable(typeof(ToolSearchActivatedEvent))] [JsonSerializable(typeof(ToolUserRequestedData))] [JsonSerializable(typeof(ToolUserRequestedEvent))] +[JsonSerializable(typeof(UsageCheckpointModelCacheState))] [JsonSerializable(typeof(UserInputCompletedData))] [JsonSerializable(typeof(UserInputCompletedEvent))] [JsonSerializable(typeof(UserInputRequestedData))] diff --git a/dotnet/test/E2E/RpcSessionStateE2ETests.cs b/dotnet/test/E2E/RpcSessionStateE2ETests.cs index dfd76fb34..6fbc72cb2 100644 --- a/dotnet/test/E2E/RpcSessionStateE2ETests.cs +++ b/dotnet/test/E2E/RpcSessionStateE2ETests.cs @@ -278,7 +278,6 @@ public async Task Should_Call_Metadata_Snapshot_SetWorkingDirectory_And_RecordCo { var firstDirectory = CreateUniqueDirectory(); var secondDirectory = CreateUniqueDirectory(); - var contextDirectory = CreateUniqueDirectory(); var branch = $"rpc-context-{Guid.NewGuid():N}"; await using var session = await CreateSessionAsync(new SessionConfig { @@ -324,7 +323,7 @@ await TestHelper.WaitForConditionAsync( var context = new SessionWorkingDirectoryContext { - Cwd = contextDirectory, + Cwd = secondDirectory, GitRoot = firstDirectory, Branch = branch, Repository = "github/copilot-sdk-e2e", @@ -338,8 +337,8 @@ await TestHelper.WaitForConditionAsync( Assert.NotNull(recordResult); var contextChanged = await contextChangedTask; - Assert.True(PathEquals(contextDirectory, contextChanged.Data.Cwd), - $"Expected context cwd '{contextDirectory}', actual '{contextChanged.Data.Cwd}'."); + Assert.True(PathEquals(secondDirectory, contextChanged.Data.Cwd), + $"Expected context cwd '{secondDirectory}', actual '{contextChanged.Data.Cwd}'."); Assert.True(PathEquals(firstDirectory, contextChanged.Data.GitRoot), $"Expected context git root '{firstDirectory}', actual '{contextChanged.Data.GitRoot}'."); Assert.Equal(branch, contextChanged.Data.Branch); diff --git a/go/internal/e2e/rpc_session_state_e2e_test.go b/go/internal/e2e/rpc_session_state_e2e_test.go index 07ec4138d..1b7b37aee 100644 --- a/go/internal/e2e/rpc_session_state_e2e_test.go +++ b/go/internal/e2e/rpc_session_state_e2e_test.go @@ -482,7 +482,6 @@ func TestRPCSessionStateE2E(t *testing.T) { t.Run("should call metadata snapshot set working directory and record context change", func(t *testing.T) { firstDirectory := createUniqueRPCWorkDirectory(t, ctx, "rpc-session-state-first") secondDirectory := createUniqueRPCWorkDirectory(t, ctx, "rpc-session-state-second") - contextDirectory := createUniqueRPCWorkDirectory(t, ctx, "rpc-session-state-context") branch := "rpc-context-" + randomHex(t) session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{ @@ -534,7 +533,7 @@ func TestRPCSessionStateE2E(t *testing.T) { headCommit := "1111111111111111111111111111111111111111" if _, err := session.RPC.Metadata.RecordContextChange(t.Context(), &rpc.MetadataRecordContextChangeRequest{ Context: rpc.SessionWorkingDirectoryContext{ - Cwd: contextDirectory, + Cwd: secondDirectory, GitRoot: &firstDirectory, Branch: &branch, Repository: &repo, @@ -548,7 +547,7 @@ func TestRPCSessionStateE2E(t *testing.T) { } contextChanged := awaitEvent(t, awaitContextChanged) data := contextChanged.Data.(*copilot.SessionContextChangedData) - assertRPCPathEqual(t, contextDirectory, data.Cwd) + assertRPCPathEqual(t, secondDirectory, data.Cwd) if data.GitRoot == nil { t.Fatal("Expected context changed git root") } diff --git a/go/internal/e2e/session_e2e_test.go b/go/internal/e2e/session_e2e_test.go index 9e21e82be..13ed75750 100644 --- a/go/internal/e2e/session_e2e_test.go +++ b/go/internal/e2e/session_e2e_test.go @@ -643,11 +643,29 @@ func TestSessionE2E(t *testing.T) { } // We should be able to send another message - answer, err := session.SendAndWait(t.Context(), copilot.MessageOptions{Prompt: "What is 2+2?"}) + answerCh := make(chan *copilot.SessionEvent, 1) + answerErrCh := make(chan error, 1) + go func() { + evt, err := testharness.GetNextEventOfType(session, copilot.SessionEventTypeAssistantMessage, 60*time.Second) + if err != nil { + answerErrCh <- err + } else { + answerCh <- evt + } + }() + + _, err = session.Send(t.Context(), copilot.MessageOptions{Prompt: "What is 2+2?"}) if err != nil { t.Fatalf("Failed to send message after abort: %v", err) } + var answer *copilot.SessionEvent + select { + case answer = <-answerCh: + case err := <-answerErrCh: + t.Fatalf("Failed waiting for assistant message after abort: %v", err) + } + if ad, ok := answer.Data.(*copilot.AssistantMessageData); !ok || !strings.Contains(ad.Content, "4") { t.Errorf("Expected answer to contain '4', got %v", answer.Data) } diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index 30ae6ff27..e2e18dee4 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -2214,6 +2214,233 @@ type ExternalToolTextResultForLlmContentResourceLinkIcon struct { Theme *ExternalToolTextResultForLlmContentResourceLinkIconTheme `json:"theme,omitempty"` } +// Parameters for cooperatively aborting a factory body. +// Experimental: FactoryAbortRequest is part of an experimental API and may change or be +// removed. +type FactoryAbortRequest struct { + // Factory run identifier. + RunID string `json:"runId"` + // Target session identifier + SessionID string `json:"sessionId"` +} + +// Acknowledgement that a factory request was accepted. +// Experimental: FactoryAckResult is part of an experimental API and may change or be +// removed. +type FactoryAckResult struct { +} + +// Options for one factory-scoped subagent call. +// Experimental: FactoryAgentOptions is part of an experimental API and may change or be +// removed. +type FactoryAgentOptions struct { + // Optional label distinguishing otherwise identical memoized agent calls. + Label *string `json:"label,omitempty"` + // Optional model identifier for the subagent. + Model *string `json:"model,omitempty"` + // Optional JSON Schema for structured agent output. + Schema any `json:"schema,omitempty"` +} + +// Parameters for one factory-scoped subagent call. +// Experimental: FactoryAgentRequest is part of an experimental API and may change or be +// removed. +type FactoryAgentRequest struct { + // Factory run identifier that owns the subagent. + FactoryRunID string `json:"factoryRunId"` + // Subagent execution options. + Opts FactoryAgentOptions `json:"opts"` + // Prompt to send to the subagent. + Prompt string `json:"prompt"` +} + +// Result of one factory-scoped subagent call. +// Experimental: FactoryAgentResult is part of an experimental API and may change or be +// removed. +type FactoryAgentResult struct { + // Agent result, omitted when the agent produced no result. + Result any `json:"result,omitempty"` +} + +// Parameters for cancelling a factory run. +// Experimental: FactoryCancelRequest is part of an experimental API and may change or be +// removed. +type FactoryCancelRequest struct { + // Factory run identifier. + RunID string `json:"runId"` +} + +// Parameters sent to the owning extension to execute a factory closure. +// Experimental: FactoryExecuteRequest is part of an experimental API and may change or be +// removed. +type FactoryExecuteRequest struct { + // Factory input value. + Args any `json:"args"` + // Registered factory name. + Name string `json:"name"` + // Factory run identifier. + RunID string `json:"runId"` + // Target session identifier + SessionID string `json:"sessionId"` +} + +// Result returned by an extension factory closure. +// Experimental: FactoryExecuteResult is part of an experimental API and may change or be +// removed. +type FactoryExecuteResult struct { + // Factory result value. + Result any `json:"result"` +} + +// Parameters for retrieving a factory run. +// Experimental: FactoryGetRunRequest is part of an experimental API and may change or be +// removed. +type FactoryGetRunRequest struct { + // Factory run identifier. + RunID string `json:"runId"` +} + +// Parameters for reading a factory journal entry. +// Experimental: FactoryJournalGetRequest is part of an experimental API and may change or +// be removed. +type FactoryJournalGetRequest struct { + // Namespaced journal key. + Key string `json:"key"` + // Factory run identifier. + RunID string `json:"runId"` +} + +// Result of reading a factory journal entry. +// Experimental: FactoryJournalGetResult is part of an experimental API and may change or be +// removed. +type FactoryJournalGetResult struct { + // Whether the journal contained the requested key. + Hit bool `json:"hit"` + // Cached JSON result. The hit field distinguishes a cached JSON null from a miss. + ResultJSON any `json:"resultJson,omitempty"` +} + +// Parameters for storing a factory journal entry. +// Experimental: FactoryJournalPutRequest is part of an experimental API and may change or +// be removed. +type FactoryJournalPutRequest struct { + // Namespaced journal key. + Key string `json:"key"` + // JSON result to memoize. + ResultJSON any `json:"resultJson"` + // Factory run identifier. + RunID string `json:"runId"` +} + +// One ordered factory progress line. +// Experimental: FactoryLogLine is part of an experimental API and may change or be removed. +type FactoryLogLine struct { + // Progress line kind. + Kind FactoryLogLineKind `json:"kind"` + // Monotonic sequence number within the factory run. + Seq int64 `json:"seq"` + // Progress text. + Text string `json:"text"` +} + +// Parameters for recording factory progress. +// Experimental: FactoryLogRequest is part of an experimental API and may change or be +// removed. +type FactoryLogRequest struct { + // Ordered progress lines to append. + Lines []FactoryLogLine `json:"lines"` + // Factory run identifier. + RunID string `json:"runId"` +} + +// Machine-readable factory run failure. +// Experimental: FactoryRunFailure is part of an experimental API and may change or be +// removed. +type FactoryRunFailure interface { + factoryRunFailure() + Type() FactoryRunFailureType +} + +type RawFactoryRunFailureData struct { + Discriminator FactoryRunFailureType + Raw json.RawMessage +} + +func (RawFactoryRunFailureData) factoryRunFailure() {} +func (r RawFactoryRunFailureData) Type() FactoryRunFailureType { + return r.Discriminator +} + +type FactoryRunFailureFactoryLimitReached struct { + // Resource ceiling that stopped the run. + Kind FactoryRunFailureKind `json:"kind"` + // Factory run identifier. + RunID string `json:"runId"` + // Approved effective ceiling that was reached. + Value float64 `json:"value"` +} + +func (FactoryRunFailureFactoryLimitReached) factoryRunFailure() {} +func (FactoryRunFailureFactoryLimitReached) Type() FactoryRunFailureType { + return FactoryRunFailureTypeFactoryLimitReached +} + +type FactoryRunFailureFactoryResumeDeclined struct { + // Human-readable reason the resume did not proceed. + Reason string `json:"reason"` + // Factory run identifier whose changed limits were declined. + RunID string `json:"runId"` +} + +func (FactoryRunFailureFactoryResumeDeclined) factoryRunFailure() {} +func (FactoryRunFailureFactoryResumeDeclined) Type() FactoryRunFailureType { + return FactoryRunFailureTypeFactoryResumeDeclined +} + +// Wire-only per-invocation factory resource ceiling overrides. +// Experimental: FactoryRunLimits is part of an experimental API and may change or be +// removed. +type FactoryRunLimits struct { + // Maximum number of factory subagents that may run concurrently. + MaxConcurrentSubagents *int64 `json:"maxConcurrentSubagents,omitempty"` + // Maximum total number of factory subagents that may be admitted. + MaxTotalSubagents *int64 `json:"maxTotalSubagents,omitempty"` + // Factory active-run timeout in milliseconds. + Timeout *float64 `json:"timeout,omitempty"` +} + +// Parameters for invoking a registered factory. +// Experimental: FactoryRunRequest is part of an experimental API and may change or be +// removed. +type FactoryRunRequest struct { + // Factory input value. + Args any `json:"args"` + // Registered factory name. + Name string `json:"name"` + // Factory invocation options. + Options *RunOptions `json:"options,omitempty"` +} + +// Complete current or terminal factory run envelope. +// Experimental: FactoryRunResult is part of an experimental API and may change or be +// removed. +type FactoryRunResult struct { + // Error message for an errored run. + Error *string `json:"error,omitempty"` + // Machine-readable failure details for an errored run. + Failure FactoryRunFailure `json:"failure,omitempty"` + // Reason for a halted or cancelled run. + Reason *string `json:"reason,omitempty"` + // Completed factory result. + Result any `json:"result,omitempty"` + // Factory run identifier. + RunID string `json:"runId"` + // Partial journal and progress snapshot for a halted, cancelled, or errored run. + Snapshot any `json:"snapshot,omitempty"` + // Current or terminal factory run status. + Status FactoryRunStatus `json:"status"` +} + // Content filtering mode to apply to all tools, or a map of tool name to content filtering // mode. // Experimental: FilterMapping is part of an experimental API and may change or be removed. @@ -2694,18 +2921,19 @@ type LlmInferenceHTTPRequestChunkResult struct { // Experimental: LlmInferenceHTTPRequestStartRequest is part of an experimental API and may // change or be removed. type LlmInferenceHTTPRequestStartRequest struct { - // Stable per-agent-instance id attributing this request to a specific agent trajectory. - // Present when the request originates from an agent turn; absent for requests issued - // outside any agent context (e.g. some SDK callers). A request with an `agentId` but no - // `parentAgentId` is a root-agent request; one carrying both is a subagent request. Sourced - // from the runtime's per-request agent context and surfaced on the envelope independently - // of transport, so it is available for both first-party (CAPI) and BYOK/custom-provider - // requests; on the CAPI transport the runtime derives the upstream `X-Agent-Task-Id` header - // from this same context. Consumers routing each provider call to a training trajectory - // should key on this rather than on lifecycle events, since it is available on the request - // path before sampling. - AgentID *string `json:"agentId,omitempty"` - Headers map[string][]string `json:"headers"` + // Stable identity of the agent trajectory that issued this request. Present when the + // request originates from an agent turn; absent for requests outside any agent context. + // This is the same identity used by lifecycle and bridged session events and remains + // constant across turns and retries. + AgentID *string `json:"agentId,omitempty"` + // Identity of the agent invocation (one agentic loop) that issued this request. It remains + // fixed across physical retries within the invocation and is distinct from the stable + // trajectory `agentId`. A caller-supplied invocation id always takes precedence (this + // covers auxiliary calls that have no model call id). Otherwise, first-party CAPI requests + // fall back to the runtime's agent task id — the same value the runtime emits as the + // `X-Agent-Task-Id` header — while custom-provider requests fall back to the model call id. + AgentInvocationID *string `json:"agentInvocationId,omitempty"` + Headers map[string][]string `json:"headers"` // Coarse classification of the interaction that produced this request. Open string for // forward-compatibility; known values include `conversation-agent`, // `conversation-subagent`, `conversation-sampling`, `conversation-background`, @@ -2716,12 +2944,9 @@ type LlmInferenceHTTPRequestStartRequest struct { InteractionType *string `json:"interactionType,omitempty"` // HTTP method, e.g. GET, POST. Method string `json:"method"` - // Id of the parent agent that spawned the agent issuing this request. Present only for - // subagent requests; absent for root-agent requests and non-agent requests. Combined with - // `agentId`, this lets consumers attribute a call to a child trajectory versus the root. - // Like `agentId`, it comes from the runtime's per-request agent context independently of - // transport; on the CAPI transport the runtime derives the upstream `X-Parent-Agent-Id` - // header from this same context. + // Stable identity of the immediate parent trajectory. Present for child trajectories such + // as subagents and conversation-sampling requests; absent for root-agent and non-agent + // requests. ParentAgentID *string `json:"parentAgentId,omitempty"` // Opaque runtime-minted id, unique per in-flight request. The SDK uses this to correlate // httpRequestChunk frames and to address its httpResponseStart / httpResponseChunk replies @@ -4136,7 +4361,10 @@ type MetadataRecordContextChangeRequest struct { // Notify the session that its working directory context has changed. Emits a // `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline // UI) can react. Use this when the host has detected a cwd/branch/repo change outside the -// session's normal lifecycle (e.g., after a shell command in interactive mode). +// session's normal lifecycle (e.g., after a shell command in interactive mode). For a local +// session, a report whose `cwd` diverges from the session's current working directory is +// ignored (the call still succeeds but records nothing and emits no event); move a local +// session's working directory via `metadata.setWorkingDirectory` instead. // Experimental: MetadataRecordContextChangeResult is part of an experimental API and may // change or be removed. type MetadataRecordContextChangeResult struct { @@ -6934,6 +7162,15 @@ type RemoteSessionRepository struct { Owner string `json:"owner"` } +// Options controlling factory invocation. +// Experimental: RunOptions is part of an experimental API and may change or be removed. +type RunOptions struct { + // Per-invocation resource ceiling overrides. + Limits *FactoryRunLimits `json:"limits,omitempty"` + // Run identifier whose journal and progress should seed this resumed run. + ResumeFromRunID *string `json:"resumeFromRunId,omitempty"` +} + // Experimental: RuntimeShutdownResult is part of an experimental API and may change or be // removed. type RuntimeShutdownResult struct { @@ -6946,6 +7183,13 @@ type SandboxConfig struct { AddCurrentWorkingDirectory *bool `json:"addCurrentWorkingDirectory,omitempty"` // Whether sandboxing is enabled for the session. Enabled bool `json:"enabled"` + // Whether to export `GH_TOKEN` so the `gh` CLI authenticates inside the sandbox without the + // OS keyring the sandbox blocks. Default: false (opt-in). + GhAuth *bool `json:"ghAuth,omitempty"` + // Whether to inject the Copilot GitHub token as an `http..extraheader` so + // authenticated HTTPS git works inside the sandbox without the shell-based credential + // helper the sandbox blocks. Default: false (opt-in). + GitAuth *bool `json:"gitAuth,omitempty"` // User-managed sandbox policy fragment merged into the auto-discovered base policy. UserPolicy *SandboxConfigUserPolicy `json:"userPolicy,omitempty"` } @@ -7255,6 +7499,9 @@ type ServerSkill struct { // Skills discovered across global and project sources. // Experimental: ServerSkillList is part of an experimental API and may change or be removed. type ServerSkillList struct { + // Messages for skills that failed to load (e.g. malformed SKILL.md). Empty when host skills + // are excluded so host-local paths are not disclosed to multitenant callers. + Errors []string `json:"errors,omitzero"` // All discovered skills across all sources Skills []ServerSkill `json:"skills"` } @@ -10445,6 +10692,9 @@ type UsageMetricsCodeChanges struct { // Experimental: UsageMetricsModelMetric is part of an experimental API and may change or be // removed. type UsageMetricsModelMetric struct { + // Latest known prompt-cache expiration for this model. A timestamp in the past indicates + // that the observed cache has expired. + CacheExpiresAt *time.Time `json:"cacheExpiresAt,omitempty"` // Request count and cost metrics for this model Requests UsageMetricsModelMetricRequests `json:"requests"` // Token count details per type @@ -11396,6 +11646,58 @@ const ( ExternalToolTextResultForLlmContentTypeText ExternalToolTextResultForLlmContentType = "text" ) +// Kind of factory progress line. +// Experimental: FactoryLogLineKind is part of an experimental API and may change or be +// removed. +type FactoryLogLineKind string + +const ( + // A narrator log line. + FactoryLogLineKindLog FactoryLogLineKind = "log" + // A named factory phase marker. + FactoryLogLineKindPhase FactoryLogLineKind = "phase" +) + +// Cumulative resource ceiling that stopped a factory run. +// Experimental: FactoryRunFailureKind is part of an experimental API and may change or be +// removed. +type FactoryRunFailureKind string + +const ( + // The run admitted the approved maximum total number of subagents. + FactoryRunFailureKindMaxTotalSubagents FactoryRunFailureKind = "maxTotalSubagents" + // The run reached the approved timeout deadline. + FactoryRunFailureKindTimeout FactoryRunFailureKind = "timeout" +) + +// Type discriminator for FactoryRunFailure. +type FactoryRunFailureType string + +const ( + FactoryRunFailureTypeFactoryLimitReached FactoryRunFailureType = "factory_limit_reached" + FactoryRunFailureTypeFactoryResumeDeclined FactoryRunFailureType = "factory_resume_declined" +) + +// Current or terminal state of a factory run. +// Experimental: FactoryRunStatus is part of an experimental API and may change or be +// removed. +type FactoryRunStatus string + +const ( + // The run was cancelled before completion. + FactoryRunStatusCancelled FactoryRunStatus = "cancelled" + // The run completed successfully. + FactoryRunStatusCompleted FactoryRunStatus = "completed" + // The factory body failed or reached a cumulative resource ceiling. + FactoryRunStatusError FactoryRunStatus = "error" + // The run was interrupted while resource budget remained. + FactoryRunStatusHalted FactoryRunStatus = "halted" + // The run was minted and is awaiting approval. + FactoryRunStatusPending FactoryRunStatus = "pending" + // The run is executing. + FactoryRunStatusRunning FactoryRunStatus = "running" +) + // Authentication host. HMAC auth always targets the public GitHub host. type HMACAuthInfoHost string @@ -11440,6 +11742,9 @@ const ( HookTypeSubagentStop HookType = "subagentStop" // Runs after the user submits a prompt. HookTypeUserPromptSubmitted HookType = "userPromptSubmitted" + // Runs after the runtime transforms the submitted prompt for the model, before it is added + // to session history. + HookTypeUserPromptTransformed HookType = "userPromptTransformed" ) // Constant value. Always "github". @@ -15377,6 +15682,188 @@ func (a *ExtensionsAPI) SendAttachmentsToMessage(ctx context.Context, params *Se return &result, nil } +// Experimental: FactoryAPI contains experimental APIs that may change or be removed. +type FactoryAPI sessionAPI + +// Agent runs one factory-scoped subagent and returns its result. +// +// RPC method: session.factory.agent. +// +// Parameters: Parameters for one factory-scoped subagent call. +// +// Returns: Result of one factory-scoped subagent call. +func (a *FactoryAPI) Agent(ctx context.Context, params *FactoryAgentRequest) (*FactoryAgentResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["factoryRunId"] = params.FactoryRunID + req["opts"] = params.Opts + req["prompt"] = params.Prompt + } + raw, err := a.client.Request(ctx, "session.factory.agent", req) + if err != nil { + return nil, err + } + var result FactoryAgentResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Cancel requests cancellation of a factory run and returns its run envelope. +// +// RPC method: session.factory.cancel. +// +// Parameters: Parameters for cancelling a factory run. +// +// Returns: Complete current or terminal factory run envelope. +func (a *FactoryAPI) Cancel(ctx context.Context, params *FactoryCancelRequest) (*FactoryRunResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["runId"] = params.RunID + } + raw, err := a.client.Request(ctx, "session.factory.cancel", req) + if err != nil { + return nil, err + } + var result FactoryRunResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// GetRun gets the current or settled envelope for a factory run. +// +// RPC method: session.factory.getRun. +// +// Parameters: Parameters for retrieving a factory run. +// +// Returns: Complete current or terminal factory run envelope. +func (a *FactoryAPI) GetRun(ctx context.Context, params *FactoryGetRunRequest) (*FactoryRunResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["runId"] = params.RunID + } + raw, err := a.client.Request(ctx, "session.factory.getRun", req) + if err != nil { + return nil, err + } + var result FactoryRunResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Log records a batch of ordered factory progress lines. +// +// RPC method: session.factory.log. +// +// Parameters: Parameters for recording factory progress. +// +// Returns: Acknowledgement that a factory request was accepted. +func (a *FactoryAPI) Log(ctx context.Context, params *FactoryLogRequest) (*FactoryAckResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["lines"] = params.Lines + req["runId"] = params.RunID + } + raw, err := a.client.Request(ctx, "session.factory.log", req) + if err != nil { + return nil, err + } + var result FactoryAckResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Runs a registered factory by name at the top level. +// +// RPC method: session.factory.run. +// +// Parameters: Parameters for invoking a registered factory. +// +// Returns: Complete current or terminal factory run envelope. +func (a *FactoryAPI) Run(ctx context.Context, params *FactoryRunRequest) (*FactoryRunResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["args"] = params.Args + req["name"] = params.Name + if params.Options != nil { + req["options"] = *params.Options + } + } + raw, err := a.client.Request(ctx, "session.factory.run", req) + if err != nil { + return nil, err + } + var result FactoryRunResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Experimental: FactoryJournalAPI contains experimental APIs that may change or be removed. +type FactoryJournalAPI sessionAPI + +// Get reads a memoized factory journal entry. +// +// RPC method: session.factory.journal.get. +// +// Parameters: Parameters for reading a factory journal entry. +// +// Returns: Result of reading a factory journal entry. +func (a *FactoryJournalAPI) Get(ctx context.Context, params *FactoryJournalGetRequest) (*FactoryJournalGetResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["key"] = params.Key + req["runId"] = params.RunID + } + raw, err := a.client.Request(ctx, "session.factory.journal.get", req) + if err != nil { + return nil, err + } + var result FactoryJournalGetResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Put stores a memoized factory journal entry. +// +// RPC method: session.factory.journal.put. +// +// Parameters: Parameters for storing a factory journal entry. +// +// Returns: Acknowledgement that a factory request was accepted. +func (a *FactoryJournalAPI) Put(ctx context.Context, params *FactoryJournalPutRequest) (*FactoryAckResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["key"] = params.Key + req["resultJson"] = params.ResultJSON + req["runId"] = params.RunID + } + raw, err := a.client.Request(ctx, "session.factory.journal.put", req) + if err != nil { + return nil, err + } + var result FactoryAckResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Experimental: Journal returns experimental APIs that may change or be removed. +func (s *FactoryAPI) Journal() *FactoryJournalAPI { + return (*FactoryJournalAPI)(s) +} + // Experimental: FleetAPI contains experimental APIs that may change or be removed. type FleetAPI sessionAPI @@ -16430,7 +16917,11 @@ func (a *MetadataAPI) RecomputeContextTokens(ctx context.Context, params *Metada } // RecordContextChange records a working-directory/git context change and emits a -// `session.context_changed` event. +// `session.context_changed` event. For a local session, a report whose `cwd` diverges from +// the session's current working directory is ignored (the call still succeeds but records +// nothing and emits no event): a local session's working directory is authoritative and is +// moved via `metadata.setWorkingDirectory` (or an SDK `session.resume` that supplies a +// `workingDirectory`), not by this method. // // RPC method: session.metadata.recordContextChange. // @@ -16439,7 +16930,10 @@ func (a *MetadataAPI) RecomputeContextTokens(ctx context.Context, params *Metada // Returns: Notify the session that its working directory context has changed. Emits a // `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline // UI) can react. Use this when the host has detected a cwd/branch/repo change outside the -// session's normal lifecycle (e.g., after a shell command in interactive mode). +// session's normal lifecycle (e.g., after a shell command in interactive mode). For a local +// session, a report whose `cwd` diverges from the session's current working directory is +// ignored (the call still succeeds but records nothing and emits no event); move a local +// session's working directory via `metadata.setWorkingDirectory` instead. func (a *MetadataAPI) RecordContextChange(ctx context.Context, params *MetadataRecordContextChangeRequest) (*MetadataRecordContextChangeResult, error) { req := map[string]any{"sessionId": a.sessionID} if params != nil { @@ -19050,6 +19544,7 @@ type SessionRPC struct { Debug *DebugAPI EventLog *EventLogAPI Extensions *ExtensionsAPI + Factory *FactoryAPI Fleet *FleetAPI GitHubAuth *GitHubAuthAPI History *HistoryAPI @@ -19316,6 +19811,7 @@ func NewSessionRPC(client *jsonrpc2.Client, sessionID string) *SessionRPC { r.Debug = (*DebugAPI)(&r.common) r.EventLog = (*EventLogAPI)(&r.common) r.Extensions = (*ExtensionsAPI)(&r.common) + r.Factory = (*FactoryAPI)(&r.common) r.Fleet = (*FleetAPI)(&r.common) r.GitHubAuth = (*GitHubAuthAPI)(&r.common) r.History = (*HistoryAPI)(&r.common) @@ -19569,6 +20065,26 @@ type CanvasHandler interface { Open(request *CanvasProviderOpenRequest) (*CanvasProviderOpenResult, error) } +// Experimental: FactoryHandler contains experimental APIs that may change or be removed. +type FactoryHandler interface { + // Abort asks the owning extension connection to abort a running factory cooperatively. + // + // RPC method: factory.abort. + // + // Parameters: Parameters for cooperatively aborting a factory body. + // + // Returns: Acknowledgement that a factory request was accepted. + Abort(request *FactoryAbortRequest) (*FactoryAckResult, error) + // Execute asks the owning extension connection to execute a registered factory closure. + // + // RPC method: factory.execute. + // + // Parameters: Parameters sent to the owning extension to execute a factory closure. + // + // Returns: Result returned by an extension factory closure. + Execute(request *FactoryExecuteRequest) (*FactoryExecuteResult, error) +} + // Experimental: ProviderTokenHandler contains experimental APIs that may change or be // removed. type ProviderTokenHandler interface { @@ -19712,6 +20228,7 @@ type SessionFSHandler interface { // ClientSessionAPIHandlers provides all client session API handler groups for a session. type ClientSessionAPIHandlers struct { Canvas CanvasHandler + Factory FactoryHandler ProviderToken ProviderTokenHandler SessionFS SessionFSHandler } @@ -19787,6 +20304,44 @@ func RegisterClientSessionAPIHandlers(client *jsonrpc2.Client, getHandlers func( } return raw, nil }) + client.SetRequestHandler("factory.abort", func(params json.RawMessage) (json.RawMessage, *jsonrpc2.Error) { + var request FactoryAbortRequest + 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.Factory == nil { + return nil, &jsonrpc2.Error{Code: -32603, Message: fmt.Sprintf("No factory handler registered for session: %s", request.SessionID)} + } + result, err := handlers.Factory.Abort(&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("factory.execute", func(params json.RawMessage) (json.RawMessage, *jsonrpc2.Error) { + var request FactoryExecuteRequest + 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.Factory == nil { + return nil, &jsonrpc2.Error{Code: -32603, Message: fmt.Sprintf("No factory handler registered for session: %s", request.SessionID)} + } + result, err := handlers.Factory.Execute(&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("providerToken.getToken", func(params json.RawMessage) (json.RawMessage, *jsonrpc2.Error) { var request ProviderTokenAcquireRequest if err := json.Unmarshal(params, &request); err != nil { diff --git a/go/rpc/zrpc_encoding.go b/go/rpc/zrpc_encoding.go index 81e693120..82f6e1077 100644 --- a/go/rpc/zrpc_encoding.go +++ b/go/rpc/zrpc_encoding.go @@ -1062,6 +1062,99 @@ func unmarshalExternalToolResult(data []byte) (ExternalToolResult, error) { return nil, errors.New("data did not match any union variant for ExternalToolResult") } +func unmarshalFactoryRunFailure(data []byte) (FactoryRunFailure, error) { + if string(data) == "null" { + return nil, nil + } + type rawUnion struct { + Type FactoryRunFailureType `json:"type"` + } + var raw rawUnion + if err := json.Unmarshal(data, &raw); err != nil { + return nil, err + } + + switch raw.Type { + case FactoryRunFailureTypeFactoryLimitReached: + var d FactoryRunFailureFactoryLimitReached + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case FactoryRunFailureTypeFactoryResumeDeclined: + var d FactoryRunFailureFactoryResumeDeclined + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + default: + return &RawFactoryRunFailureData{Discriminator: raw.Type, Raw: data}, nil + } +} + +func (r RawFactoryRunFailureData) MarshalJSON() ([]byte, error) { + if r.Raw != nil { + return r.Raw, nil + } + return json.Marshal(struct { + Type FactoryRunFailureType `json:"type"` + }{ + Type: r.Discriminator, + }) +} + +func (r FactoryRunFailureFactoryLimitReached) MarshalJSON() ([]byte, error) { + type alias FactoryRunFailureFactoryLimitReached + return json.Marshal(struct { + Type FactoryRunFailureType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r FactoryRunFailureFactoryResumeDeclined) MarshalJSON() ([]byte, error) { + type alias FactoryRunFailureFactoryResumeDeclined + return json.Marshal(struct { + Type FactoryRunFailureType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r *FactoryRunResult) UnmarshalJSON(data []byte) error { + type rawFactoryRunResult struct { + Error *string `json:"error,omitempty"` + Failure json.RawMessage `json:"failure,omitempty"` + Reason *string `json:"reason,omitempty"` + Result any `json:"result,omitempty"` + RunID string `json:"runId"` + Snapshot any `json:"snapshot,omitempty"` + Status FactoryRunStatus `json:"status"` + } + var raw rawFactoryRunResult + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + r.Error = raw.Error + if raw.Failure != nil { + value, err := unmarshalFactoryRunFailure(raw.Failure) + if err != nil { + return err + } + r.Failure = value + } + r.Reason = raw.Reason + r.Result = raw.Result + r.RunID = raw.RunID + r.Snapshot = raw.Snapshot + r.Status = raw.Status + return nil +} + func unmarshalFilterMapping(data []byte) (FilterMapping, error) { if string(data) == "null" { return nil, nil diff --git a/go/rpc/zsession_encoding.go b/go/rpc/zsession_encoding.go index 2bd212d88..fe99126cf 100644 --- a/go/rpc/zsession_encoding.go +++ b/go/rpc/zsession_encoding.go @@ -107,6 +107,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeAssistantTurnRetry: + var d AssistantTurnRetryData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeAssistantTurnStart: var d AssistantTurnStartData if err := json.Unmarshal(raw.Data, &d); err != nil { @@ -269,6 +275,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeModelCallStart: + var d ModelCallStartData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypePendingMessagesModified: var d PendingMessagesModifiedData if err := json.Unmarshal(raw.Data, &d); err != nil { @@ -437,6 +449,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeSessionManagedSettingsEnforced: + var d SessionManagedSettingsEnforcedData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeSessionManagedSettingsResolved: var d SessionManagedSettingsResolvedData if err := json.Unmarshal(raw.Data, &d); err != nil { @@ -665,6 +683,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeToolSearchActivated: + var d ToolSearchActivatedData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeToolUserRequested: var d ToolUserRequestedData if err := json.Unmarshal(raw.Data, &d); err != nil { diff --git a/go/rpc/zsession_events.go b/go/rpc/zsession_events.go index ec211132d..44f49948f 100644 --- a/go/rpc/zsession_events.go +++ b/go/rpc/zsession_events.go @@ -65,6 +65,7 @@ const ( SessionEventTypeAssistantStreamingDelta SessionEventType = "assistant.streaming_delta" SessionEventTypeAssistantToolCallDelta SessionEventType = "assistant.tool_call_delta" SessionEventTypeAssistantTurnEnd SessionEventType = "assistant.turn_end" + SessionEventTypeAssistantTurnRetry SessionEventType = "assistant.turn_retry" SessionEventTypeAssistantTurnStart SessionEventType = "assistant.turn_start" SessionEventTypeAssistantUsage SessionEventType = "assistant.usage" SessionEventTypeAutoModeSwitchCompleted SessionEventType = "auto_mode_switch.completed" @@ -92,6 +93,7 @@ const ( SessionEventTypeMCPResourcesListChanged SessionEventType = "mcp.resources.list_changed" SessionEventTypeMCPToolsListChanged SessionEventType = "mcp.tools.list_changed" SessionEventTypeModelCallFailure SessionEventType = "model.call_failure" + SessionEventTypeModelCallStart SessionEventType = "model.call_start" SessionEventTypePendingMessagesModified SessionEventType = "pending_messages.modified" SessionEventTypePermissionCompleted SessionEventType = "permission.completed" SessionEventTypePermissionRequested SessionEventType = "permission.requested" @@ -136,6 +138,9 @@ const ( SessionEventTypeSessionInfo SessionEventType = "session.info" SessionEventTypeSessionLimitsExhaustedCompleted SessionEventType = "session_limits_exhausted.completed" SessionEventTypeSessionLimitsExhaustedRequested SessionEventType = "session_limits_exhausted.requested" + // Experimental: SessionEventTypeSessionManagedSettingsEnforced identifies an experimental + // event that may change or be removed. + SessionEventTypeSessionManagedSettingsEnforced SessionEventType = "session.managed_settings_enforced" // Experimental: SessionEventTypeSessionManagedSettingsResolved identifies an experimental // event that may change or be removed. SessionEventTypeSessionManagedSettingsResolved SessionEventType = "session.managed_settings_resolved" @@ -176,6 +181,7 @@ const ( SessionEventTypeToolExecutionPartialResult SessionEventType = "tool.execution_partial_result" SessionEventTypeToolExecutionProgress SessionEventType = "tool.execution_progress" SessionEventTypeToolExecutionStart SessionEventType = "tool.execution_start" + SessionEventTypeToolSearchActivated SessionEventType = "tool_search.activated" SessionEventTypeToolUserRequested SessionEventType = "tool.user_requested" SessionEventTypeUserInputCompleted SessionEventType = "user_input.completed" SessionEventTypeUserInputRequested SessionEventType = "user_input.requested" @@ -501,6 +507,9 @@ func (*SessionCanvasRemovedData) Type() SessionEventType { return SessionEventTy // Durable session usage checkpoint for reconstructing aggregate accounting on resume type SessionUsageCheckpointData struct { + // Internal per-model prompt-cache state used to restore expiration tracking on resume + // Internal: ModelCacheState is part of the SDK's internal API surface and is not intended for external use. + ModelCacheState []UsageCheckpointModelCacheState `json:"modelCacheState,omitzero"` // Session-wide accumulated nano-AI units cost at checkpoint time TotalNanoAiu float64 `json:"totalNanoAiu"` // Total number of premium API requests used at checkpoint time @@ -689,6 +698,8 @@ func (*ExternalToolRequestedData) Type() SessionEventType { type ModelCallFailureData struct { // Completion ID from the model provider (e.g., chatcmpl-abc123) APICallID *string `json:"apiCallId,omitempty"` + // API endpoint used for this model call, matching CAPI supported_endpoints vocabulary + APIEndpoint *AssistantUsageAPIEndpoint `json:"apiEndpoint,omitempty"` // For HTTP 400 failures only: whether the response carried a structured CAPI error envelope (structured_error, a deterministic validation failure) or no error body (bodyless, the transient gateway/proxy signature). Absent for non-400 failures. BadRequestKind *ModelCallFailureBadRequestKind `json:"badRequestKind,omitempty"` // Duration of the failed API call in milliseconds @@ -699,8 +710,18 @@ type ModelCallFailureData struct { ErrorMessage *string `json:"errorMessage,omitempty"` // For HTTP 400 failures only: the `type` from the CAPI error envelope (e.g. 'websocket_error'), a coarser companion to errorCode for envelopes that carry no code. Raw server-controlled string, emitted only through restricted telemetry. Absent for bodyless or non-400 failures. ErrorType *string `json:"errorType,omitempty"` + // Whether the failure originated from an API response or the request transport + FailureKind *ModelCallFailureKind `json:"failureKind,omitempty"` // What initiated this API call (e.g., "sub-agent", "mcp-sampling"); absent for user-initiated calls Initiator *string `json:"initiator,omitempty"` + // Whether the session selected Auto mode for the failed call + IsAuto *bool `json:"isAuto,omitempty"` + // Whether the failed call used a bring-your-own-key provider + IsByok *bool `json:"isByok,omitempty"` + // Effective maximum output-token limit for the failed call + MaxOutputTokens *int64 `json:"maxOutputTokens,omitempty"` + // Effective maximum prompt-token limit for the failed call + MaxPromptTokens *int64 `json:"maxPromptTokens,omitempty"` // Model identifier used for the failed API call Model *string `json:"model,omitempty"` // GitHub request tracing ID (x-github-request-id header) for server-side log correlation @@ -708,6 +729,8 @@ type ModelCallFailureData struct { // Per-quota usage snapshots parsed from the failed response's quota headers, keyed by quota identifier. Present when the error response carried quota headers (e.g. a 402 once the additional spend limit is reached) so the UI can refresh the quota display on failure. // Internal: QuotaSnapshots is part of the SDK's internal API surface and is not intended for external use. QuotaSnapshots map[string]AssistantUsageQuotaSnapshot `json:"quotaSnapshots,omitzero"` + // Reasoning effort level used for the failed model call, if applicable + ReasoningEffort *string `json:"reasoningEffort,omitempty"` // Content-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures. RequestFingerprint *ModelCallFailureRequestFingerprint `json:"requestFingerprint,omitempty"` // Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation @@ -716,6 +739,8 @@ type ModelCallFailureData struct { Source ModelCallFailureSource `json:"source"` // HTTP status code from the failed request StatusCode *int32 `json:"statusCode,omitempty"` + // Transport used for the failed model call (http or websocket) + Transport *ModelCallFailureTransport `json:"transport,omitempty"` } func (*ModelCallFailureData) sessionEventData() {} @@ -772,6 +797,8 @@ type AssistantUsageData struct { APICallID *string `json:"apiCallId,omitempty"` // API endpoint used for this model call, matching CAPI supported_endpoints vocabulary APIEndpoint *AssistantUsageAPIEndpoint `json:"apiEndpoint,omitempty"` + // Updated prompt-cache expiration for this model call. Present only when the call establishes or refreshes known cache state. + CacheExpiresAt *time.Time `json:"cacheExpiresAt,omitempty"` // Number of tokens read from prompt cache CacheReadTokens *int64 `json:"cacheReadTokens,omitempty"` // Number of tokens written to prompt cache @@ -882,6 +909,30 @@ func (*MCPHeadersRefreshCompletedData) Type() SessionEventType { return SessionEventTypeMCPHeadersRefreshCompleted } +// Metadata for an additional model inference attempt within an existing assistant turn +type AssistantTurnRetryData struct { + // Model identifier used for this retry, when known + Model *string `json:"model,omitempty"` + // Provider or runtime classification that caused the retry, when known + Reason *string `json:"reason,omitempty"` + // Identifier of the turn whose model inference is being retried + TurnID string `json:"turnId"` +} + +func (*AssistantTurnRetryData) sessionEventData() {} +func (*AssistantTurnRetryData) Type() SessionEventType { return SessionEventTypeAssistantTurnRetry } + +// Model API dispatch metadata for internal telemetry +type ModelCallStartData struct { + // Model identifier used for this API call, when known + Model *string `json:"model,omitempty"` + // Identifier of the assistant turn that initiated the model call + TurnID string `json:"turnId"` +} + +func (*ModelCallStartData) sessionEventData() {} +func (*ModelCallStartData) Type() SessionEventType { return SessionEventTypeModelCallStart } + // Model change details including previous and new model identifiers type SessionModelChangeData struct { // Reason the change happened, when not user-initiated. Currently `"rate_limit_auto_switch"` for changes triggered by the auto-mode-switch rate-limit recovery path. UI clients can use this to render contextual copy. @@ -1220,6 +1271,17 @@ func (*SessionPermissionsChangedData) Type() SessionEventType { return SessionEventTypeSessionPermissionsChanged } +// Persisted generic client-side tool activations restored when a session resumes. +type ToolSearchActivatedData struct { + // Tool-search strategy that activated the definitions. + Strategy string `json:"strategy"` + // Names of tool definitions activated by this search invocation. + ToolNames []string `json:"toolNames"` +} + +func (*ToolSearchActivatedData) sessionEventData() {} +func (*ToolSearchActivatedData) Type() SessionEventType { return SessionEventTypeToolSearchActivated } + // Plan approval request with plan content and available user actions type ExitPlanModeRequestedData struct { // Available actions the user can take @@ -1302,6 +1364,26 @@ type CommandExecuteData struct { func (*CommandExecuteData) sessionEventData() {} func (*CommandExecuteData) Type() SessionEventType { return SessionEventTypeCommandExecute } +// Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes. +// Experimental: SessionManagedSettingsEnforcedData is part of an experimental API and may change or be removed. +type SessionManagedSettingsEnforcedData struct { + // The category of runtime action that managed policy governed. + Action ManagedSettingsEnforcedAction `json:"action"` + // For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused. Absent for actions without a specific escalation primitive. + Escalation *ManagedSettingsEnforcedEscalation `json:"escalation,omitempty"` + // Whether the enforcement was forced by fail-closed handling (managed policy could not be determined) rather than an explicit managed setting. When true, `setting` still names the restriction that was applied. + FailClosed bool `json:"failClosed"` + // A human-readable explanation of why the action was governed, suitable for surfacing to the user. + Message string `json:"message"` + // The managed setting key responsible for the enforcement (e.g. `permissions.disableBypassPermissionsMode`). + Setting string `json:"setting"` +} + +func (*SessionManagedSettingsEnforcedData) sessionEventData() {} +func (*SessionManagedSettingsEnforcedData) Type() SessionEventType { + return SessionEventTypeSessionManagedSettingsEnforced +} + // SDK command registration change notification type CommandsChangedData struct { // Current list of registered SDK commands @@ -3670,6 +3752,18 @@ type ToolExecutionStartToolDescriptionMetaUI struct { Visibility []ToolExecutionStartToolDescriptionMetaUIVisibility `json:"visibility,omitzero"` } +// Internal prompt-cache expiration state for one model +// Internal: UsageCheckpointModelCacheState is an internal SDK API and is not part of the public surface. +type UsageCheckpointModelCacheState struct { + // Latest known prompt-cache expiration + CacheExpiresAt time.Time `json:"cacheExpiresAt"` + // Retained cache lifetime in seconds, used to refresh expiration after a cache read + // Internal: CacheTtlSeconds is part of the SDK's internal API surface and is not intended for external use. + CacheTtlSeconds int64 `json:"cacheTtlSeconds"` + // Model identifier associated with this cache state + ModelID string `json:"modelId"` +} + // Working directory and git context at session start type WorkingDirectoryContext struct { // Base commit of current git branch at session start time @@ -3903,6 +3997,30 @@ const ( HandoffSourceTypeRemote HandoffSourceType = "remote" ) +// The category of runtime action that enterprise managed settings governed (blocked or capped) +type ManagedSettingsEnforcedAction string + +const ( + // An attempt to turn on a bypass-permissions ("yolo") escalation was refused or capped because policy disables bypass-permissions mode. + ManagedSettingsEnforcedActionBypassPermissionsBlocked ManagedSettingsEnforcedAction = "bypass_permissions_blocked" +) + +// For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused +type ManagedSettingsEnforcedEscalation string + +const ( + // Full allow-all ("/allow-all on") permissions — auto-approving tools, paths, and URLs. + ManagedSettingsEnforcedEscalationAllowAll ManagedSettingsEnforcedEscalation = "allow_all" + // Auto-approval of all tool permission requests. + ManagedSettingsEnforcedEscalationApproveAll ManagedSettingsEnforcedEscalation = "approve_all" + // Advisory auto-approval ("/allow-all auto") mode — keeps normal prompt paths and adds LLM-advised approval, distinct from full allow-all. + ManagedSettingsEnforcedEscalationAutoApproval ManagedSettingsEnforcedEscalation = "auto_approval" + // Unrestricted filesystem access outside the session's allowed directories. + ManagedSettingsEnforcedEscalationUnrestrictedPaths ManagedSettingsEnforcedEscalation = "unrestricted_paths" + // Unrestricted URL fetch access. + ManagedSettingsEnforcedEscalationUnrestrictedURLs ManagedSettingsEnforcedEscalation = "unrestricted_urls" +) + // Which channel supplied the effective enterprise managed settings (highest-authority present layer wins wholesale) type ManagedSettingsResolvedSource string @@ -3994,6 +4112,16 @@ const ( ModelCallFailureBadRequestKindStructuredError ModelCallFailureBadRequestKind = "structured_error" ) +// Boundary that produced a model call failure +type ModelCallFailureKind string + +const ( + // The provider returned an API error response. + ModelCallFailureKindAPI ModelCallFailureKind = "api" + // The request transport failed before a usable API response completed. + ModelCallFailureKindTransport ModelCallFailureKind = "transport" +) + // Where the failed model call originated type ModelCallFailureSource string @@ -4006,6 +4134,16 @@ const ( ModelCallFailureSourceTopLevel ModelCallFailureSource = "top_level" ) +// Transport used for a failed model call +type ModelCallFailureTransport string + +const ( + // HTTP transport, including SSE streams. + ModelCallFailureTransportHTTP ModelCallFailureTransport = "http" + // WebSocket transport. + ModelCallFailureTransportWebsocket ModelCallFailureTransport = "websocket" +) + // Binary result type discriminator. Use "image" for images and "resource" for other binary data. type OmittedBinaryType string diff --git a/go/zsession_events.go b/go/zsession_events.go index b3dd66ef7..1d35a0a51 100644 --- a/go/zsession_events.go +++ b/go/zsession_events.go @@ -23,6 +23,7 @@ type ( AssistantStreamingDeltaData = rpc.AssistantStreamingDeltaData AssistantToolCallDeltaData = rpc.AssistantToolCallDeltaData AssistantTurnEndData = rpc.AssistantTurnEndData + AssistantTurnRetryData = rpc.AssistantTurnRetryData AssistantTurnStartData = rpc.AssistantTurnStartData AssistantUsageAPIEndpoint = rpc.AssistantUsageAPIEndpoint AssistantUsageCopilotUsage = rpc.AssistantUsageCopilotUsage @@ -110,6 +111,8 @@ type ( HookEndError = rpc.HookEndError HookProgressData = rpc.HookProgressData HookStartData = rpc.HookStartData + ManagedSettingsEnforcedAction = rpc.ManagedSettingsEnforcedAction + ManagedSettingsEnforcedEscalation = rpc.ManagedSettingsEnforcedEscalation ManagedSettingsResolvedSource = rpc.ManagedSettingsResolvedSource MCPAppToolCallCompleteData = rpc.MCPAppToolCallCompleteData MCPAppToolCallCompleteError = rpc.MCPAppToolCallCompleteError @@ -136,8 +139,11 @@ type ( MCPToolsListChangedData = rpc.MCPToolsListChangedData ModelCallFailureBadRequestKind = rpc.ModelCallFailureBadRequestKind ModelCallFailureData = rpc.ModelCallFailureData + ModelCallFailureKind = rpc.ModelCallFailureKind ModelCallFailureRequestFingerprint = rpc.ModelCallFailureRequestFingerprint ModelCallFailureSource = rpc.ModelCallFailureSource + ModelCallFailureTransport = rpc.ModelCallFailureTransport + ModelCallStartData = rpc.ModelCallStartData OmittedBinaryOmittedReason = rpc.OmittedBinaryOmittedReason OmittedBinaryResult = rpc.OmittedBinaryResult OmittedBinaryType = rpc.OmittedBinaryType @@ -235,6 +241,7 @@ type ( SessionLimitsExhaustedRequestedData = rpc.SessionLimitsExhaustedRequestedData SessionLimitsExhaustedResponse = rpc.SessionLimitsExhaustedResponse SessionLimitsExhaustedResponseAction = rpc.SessionLimitsExhaustedResponseAction + SessionManagedSettingsEnforcedData = rpc.SessionManagedSettingsEnforcedData SessionManagedSettingsResolvedData = rpc.SessionManagedSettingsResolvedData SessionMCPServersLoadedData = rpc.SessionMCPServersLoadedData SessionMCPServerStatusChangedData = rpc.SessionMCPServerStatusChangedData @@ -327,6 +334,7 @@ type ( ToolExecutionStartToolDescriptionMeta = rpc.ToolExecutionStartToolDescriptionMeta ToolExecutionStartToolDescriptionMetaUI = rpc.ToolExecutionStartToolDescriptionMetaUI ToolExecutionStartToolDescriptionMetaUIVisibility = rpc.ToolExecutionStartToolDescriptionMetaUIVisibility + ToolSearchActivatedData = rpc.ToolSearchActivatedData ToolUserRequestedData = rpc.ToolUserRequestedData UserInputCompletedData = rpc.UserInputCompletedData UserInputRequestedData = rpc.UserInputRequestedData @@ -427,6 +435,12 @@ const ( ExtensionsLoadedExtensionStatusStarting = rpc.ExtensionsLoadedExtensionStatusStarting HandoffSourceTypeLocal = rpc.HandoffSourceTypeLocal HandoffSourceTypeRemote = rpc.HandoffSourceTypeRemote + ManagedSettingsEnforcedActionBypassPermissionsBlocked = rpc.ManagedSettingsEnforcedActionBypassPermissionsBlocked + ManagedSettingsEnforcedEscalationAllowAll = rpc.ManagedSettingsEnforcedEscalationAllowAll + ManagedSettingsEnforcedEscalationApproveAll = rpc.ManagedSettingsEnforcedEscalationApproveAll + ManagedSettingsEnforcedEscalationAutoApproval = rpc.ManagedSettingsEnforcedEscalationAutoApproval + ManagedSettingsEnforcedEscalationUnrestrictedPaths = rpc.ManagedSettingsEnforcedEscalationUnrestrictedPaths + ManagedSettingsEnforcedEscalationUnrestrictedURLs = rpc.ManagedSettingsEnforcedEscalationUnrestrictedURLs ManagedSettingsResolvedSourceDevice = rpc.ManagedSettingsResolvedSourceDevice ManagedSettingsResolvedSourceNone = rpc.ManagedSettingsResolvedSourceNone ManagedSettingsResolvedSourceServer = rpc.ManagedSettingsResolvedSourceServer @@ -459,9 +473,13 @@ const ( MCPServerTransportStdio = rpc.MCPServerTransportStdio ModelCallFailureBadRequestKindBodyless = rpc.ModelCallFailureBadRequestKindBodyless ModelCallFailureBadRequestKindStructuredError = rpc.ModelCallFailureBadRequestKindStructuredError + ModelCallFailureKindAPI = rpc.ModelCallFailureKindAPI + ModelCallFailureKindTransport = rpc.ModelCallFailureKindTransport ModelCallFailureSourceMCPSampling = rpc.ModelCallFailureSourceMCPSampling ModelCallFailureSourceSubagent = rpc.ModelCallFailureSourceSubagent ModelCallFailureSourceTopLevel = rpc.ModelCallFailureSourceTopLevel + ModelCallFailureTransportHTTP = rpc.ModelCallFailureTransportHTTP + ModelCallFailureTransportWebsocket = rpc.ModelCallFailureTransportWebsocket OmittedBinaryOmittedReasonAssetUnavailable = rpc.OmittedBinaryOmittedReasonAssetUnavailable OmittedBinaryOmittedReasonTooLarge = rpc.OmittedBinaryOmittedReasonTooLarge OmittedBinaryTypeImage = rpc.OmittedBinaryTypeImage @@ -528,6 +546,7 @@ const ( SessionEventTypeAssistantStreamingDelta = rpc.SessionEventTypeAssistantStreamingDelta SessionEventTypeAssistantToolCallDelta = rpc.SessionEventTypeAssistantToolCallDelta SessionEventTypeAssistantTurnEnd = rpc.SessionEventTypeAssistantTurnEnd + SessionEventTypeAssistantTurnRetry = rpc.SessionEventTypeAssistantTurnRetry SessionEventTypeAssistantTurnStart = rpc.SessionEventTypeAssistantTurnStart SessionEventTypeAssistantUsage = rpc.SessionEventTypeAssistantUsage SessionEventTypeAutoModeSwitchCompleted = rpc.SessionEventTypeAutoModeSwitchCompleted @@ -555,6 +574,7 @@ const ( SessionEventTypeMCPResourcesListChanged = rpc.SessionEventTypeMCPResourcesListChanged SessionEventTypeMCPToolsListChanged = rpc.SessionEventTypeMCPToolsListChanged SessionEventTypeModelCallFailure = rpc.SessionEventTypeModelCallFailure + SessionEventTypeModelCallStart = rpc.SessionEventTypeModelCallStart SessionEventTypePendingMessagesModified = rpc.SessionEventTypePendingMessagesModified SessionEventTypePermissionCompleted = rpc.SessionEventTypePermissionCompleted SessionEventTypePermissionRequested = rpc.SessionEventTypePermissionRequested @@ -583,6 +603,7 @@ const ( SessionEventTypeSessionInfo = rpc.SessionEventTypeSessionInfo SessionEventTypeSessionLimitsExhaustedCompleted = rpc.SessionEventTypeSessionLimitsExhaustedCompleted SessionEventTypeSessionLimitsExhaustedRequested = rpc.SessionEventTypeSessionLimitsExhaustedRequested + SessionEventTypeSessionManagedSettingsEnforced = rpc.SessionEventTypeSessionManagedSettingsEnforced SessionEventTypeSessionManagedSettingsResolved = rpc.SessionEventTypeSessionManagedSettingsResolved SessionEventTypeSessionMCPServersLoaded = rpc.SessionEventTypeSessionMCPServersLoaded SessionEventTypeSessionMCPServerStatusChanged = rpc.SessionEventTypeSessionMCPServerStatusChanged @@ -621,6 +642,7 @@ const ( SessionEventTypeToolExecutionPartialResult = rpc.SessionEventTypeToolExecutionPartialResult SessionEventTypeToolExecutionProgress = rpc.SessionEventTypeToolExecutionProgress SessionEventTypeToolExecutionStart = rpc.SessionEventTypeToolExecutionStart + SessionEventTypeToolSearchActivated = rpc.SessionEventTypeToolSearchActivated SessionEventTypeToolUserRequested = rpc.SessionEventTypeToolUserRequested SessionEventTypeUserInputCompleted = rpc.SessionEventTypeUserInputCompleted SessionEventTypeUserInputRequested = rpc.SessionEventTypeUserInputRequested diff --git a/java/pom.xml b/java/pom.xml index ac95090b8..88b7d470d 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -86,7 +86,7 @@ DO NOT EDIT MANUALLY. Updated by the update-copilot-dependency workflow. --> - ^1.0.71 + ^1.0.72 diff --git a/java/scripts/codegen/package-lock.json b/java/scripts/codegen/package-lock.json index 372e3daab..f9a6aaaa4 100644 --- a/java/scripts/codegen/package-lock.json +++ b/java/scripts/codegen/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "copilot-sdk-java-codegen", "dependencies": { - "@github/copilot": "^1.0.71", + "@github/copilot": "^1.0.72", "json-schema": "^0.4.0", "tsx": "^4.23.1" } @@ -428,9 +428,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.71.tgz", - "integrity": "sha512-F3axBi+sXSLYDJbxCBW36bM6MYKNC2rlyAf3Ivo/MjiHKKJW7j5AmaR1IRYS9Gt8r9mxOwWFM1cJFA+CuLaR8g==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.72.tgz", + "integrity": "sha512-muxp9clYtDTGB+KaaL3B5YJM/UqMoCKOU1vFoxWB63zPzeDrl2vlRIYc/pQwCCEVf6Agf9KAe4rvzVoOsRrPeg==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "detect-libc": "^2.1.2" @@ -439,20 +439,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.71", - "@github/copilot-darwin-x64": "1.0.71", - "@github/copilot-linux-arm64": "1.0.71", - "@github/copilot-linux-x64": "1.0.71", - "@github/copilot-linuxmusl-arm64": "1.0.71", - "@github/copilot-linuxmusl-x64": "1.0.71", - "@github/copilot-win32-arm64": "1.0.71", - "@github/copilot-win32-x64": "1.0.71" + "@github/copilot-darwin-arm64": "1.0.72", + "@github/copilot-darwin-x64": "1.0.72", + "@github/copilot-linux-arm64": "1.0.72", + "@github/copilot-linux-x64": "1.0.72", + "@github/copilot-linuxmusl-arm64": "1.0.72", + "@github/copilot-linuxmusl-x64": "1.0.72", + "@github/copilot-win32-arm64": "1.0.72", + "@github/copilot-win32-x64": "1.0.72" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.71.tgz", - "integrity": "sha512-mEWzyqbqRAWgyU7i2uuSRoVPx/TwaFQX0nZmw0bc30aJ0BnO7cy2kYQyCHw8ykmf/tfxT0xauZ6k0BOFmWizzQ==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.72.tgz", + "integrity": "sha512-hUYF/MwE9dji6XVmZ9DkZ8emV/n1Y/8zuAPI8Yfa4mo7smHcRF3LIUUZMVOwdhl0IZj7rvFJJpjfGjXtP5VGcg==", "cpu": [ "arm64" ], @@ -466,9 +466,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.71.tgz", - "integrity": "sha512-Md9yEg406OBVBx3w4PeEj62TubulVLBcHleqmCoOoUmPgUxPZotUbrqz3rtbzADbXfrrD7JWvVsbd2UiNL194w==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.72.tgz", + "integrity": "sha512-4M5qlL5Tf+DVXBcMEBW8v6fGCQKl2Dnpcj5qhFQbPdARHCZNtkBxg2lHWmbHeNmlMU85tndy2Kzb+iAIALTUAw==", "cpu": [ "x64" ], @@ -482,9 +482,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.71.tgz", - "integrity": "sha512-ykLJYOqBj3jRB5IJCDugLClAqbr7DmtTbUjlNY7+Jdq/n6i+d7xUQGclf1IWL5gnxbGQVAf+zkToD+sRM389Kg==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.72.tgz", + "integrity": "sha512-+3Xzfm6Rb+g/oKlD1ZhYzZnrlRnaLkpMYN/9PBwIvBzj3t+c5sH3TDnCEA17Y5oSJeWhuXEyGr9YhuAIuZPemw==", "cpu": [ "arm64" ], @@ -498,9 +498,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.71.tgz", - "integrity": "sha512-pC0FNHG+BBwZd6yZlM85kkAGN+uJhM6o+THi76N2GnnSxmw7+remb1mvYxdgRVbdCm+LBUIbCKRWJLuMwrfb6A==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.72.tgz", + "integrity": "sha512-PjEJXRoR+SXwFo+GUgogC9DKrl/ZhT+/u1Jd3Sa0SdhWGRRqUjPUBzmNeJN9tcT8Q9VeZ1qSk1beD7JszV57ng==", "cpu": [ "x64" ], @@ -514,9 +514,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.71.tgz", - "integrity": "sha512-hBmDljFTjacxqZTasCEy43H8EIzuXB/hHEBBCMFjhB9J00nIxsO6Dh0woTifKpx7knTYZdpTjjca3D0pAoZlUA==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.72.tgz", + "integrity": "sha512-9gQQkln+qmsmq80eYua9pbaxGOajKVRlYBB+0xYWM+yEUebZB52u/IbUGhWJImvbax8EWqGoTU6ngswrs/nYJA==", "cpu": [ "arm64" ], @@ -530,9 +530,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.71.tgz", - "integrity": "sha512-CfTXU8pa5dxRz22xQzoi3TiG1PJo9+WR8PRDiPSdkIBSyPJ1NvX87DJmfXjTgeAfR+wkjt/p0keDCaBBVhNmUA==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.72.tgz", + "integrity": "sha512-t0mowX6LJSbILBNyJo3jYkSzRrATFTBzks2UUUDvDw1FR0k2VkLNCIq0V6LtdRYfNL/CJRKxzH1TqvdVCFCWcA==", "cpu": [ "x64" ], @@ -546,9 +546,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.71.tgz", - "integrity": "sha512-+HI1DokixXhHUahj06Fw67ZAigBuXKC58BFma4UJOGrQsDgwOSbqeTQHCw6vuymzjKlg3sactfsCUTaefkjscQ==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.72.tgz", + "integrity": "sha512-kbaUKFH7/hZd1Y1WhtuXBRX0gBeIVutUvJ6+SRWD/SkOnRW68nS5RShuRogpXTNM5SmopfFaS3BBaMOu2dFLkg==", "cpu": [ "arm64" ], @@ -562,9 +562,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.71.tgz", - "integrity": "sha512-02kXOBd9CwBbCaztuf71WYWn+uGapCuiaasomN4tcMH3HBVZ4gi3J0ZUoRcgcS80xh81uQyeBHbnUKzb/RE/9A==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.72.tgz", + "integrity": "sha512-5Jhb38Yk3nHnxwxgE/8vXDKg1b34ZmZ36EceWkLAO3ga9XQYi3njpphRI10G8UahyCBCdzLingY18WKQ28XRiA==", "cpu": [ "x64" ], diff --git a/java/scripts/codegen/package.json b/java/scripts/codegen/package.json index 32c609be4..a650f2ccf 100644 --- a/java/scripts/codegen/package.json +++ b/java/scripts/codegen/package.json @@ -7,7 +7,7 @@ "generate:java": "tsx java.ts" }, "dependencies": { - "@github/copilot": "^1.0.71", + "@github/copilot": "^1.0.72", "json-schema": "^0.4.0", "tsx": "^4.23.1" } diff --git a/java/src/generated/java/com/github/copilot/generated/AssistantTurnRetryEvent.java b/java/src/generated/java/com/github/copilot/generated/AssistantTurnRetryEvent.java new file mode 100644 index 000000000..e4c127d42 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/AssistantTurnRetryEvent.java @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Session event "assistant.turn_retry". Metadata for an additional model inference attempt within an existing assistant turn + * @since 1.0.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class AssistantTurnRetryEvent extends SessionEvent { + + @Override + public String getType() { return "assistant.turn_retry"; } + + @JsonProperty("data") + private AssistantTurnRetryEventData data; + + public AssistantTurnRetryEventData getData() { return data; } + public void setData(AssistantTurnRetryEventData data) { this.data = data; } + + /** Data payload for {@link AssistantTurnRetryEvent}. */ + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + public record AssistantTurnRetryEventData( + /** Identifier of the turn whose model inference is being retried */ + @JsonProperty("turnId") String turnId, + /** Model identifier used for this retry, when known */ + @JsonProperty("model") String model, + /** Provider or runtime classification that caused the retry, when known */ + @JsonProperty("reason") String reason + ) { + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/AssistantUsageEvent.java b/java/src/generated/java/com/github/copilot/generated/AssistantUsageEvent.java index 62cf9cfe8..47bfcbb4c 100644 --- a/java/src/generated/java/com/github/copilot/generated/AssistantUsageEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/AssistantUsageEvent.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import java.time.OffsetDateTime; import java.util.Map; import javax.annotation.processing.Generated; @@ -45,6 +46,8 @@ public record AssistantUsageEventData( @JsonProperty("cacheReadTokens") Long cacheReadTokens, /** Number of tokens written to prompt cache */ @JsonProperty("cacheWriteTokens") Long cacheWriteTokens, + /** Updated prompt-cache expiration for this model call. Present only when the call establishes or refreshes known cache state. */ + @JsonProperty("cacheExpiresAt") OffsetDateTime cacheExpiresAt, /** Number of output tokens used for reasoning (e.g., chain-of-thought) */ @JsonProperty("reasoningTokens") Long reasoningTokens, /** Model multiplier cost for billing purposes */ diff --git a/java/src/generated/java/com/github/copilot/generated/ManagedSettingsEnforcedAction.java b/java/src/generated/java/com/github/copilot/generated/ManagedSettingsEnforcedAction.java new file mode 100644 index 000000000..afe1c3db2 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ManagedSettingsEnforcedAction.java @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * The category of runtime action that enterprise managed settings governed (blocked or capped) + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum ManagedSettingsEnforcedAction { + /** The {@code bypass_permissions_blocked} variant. */ + BYPASS_PERMISSIONS_BLOCKED("bypass_permissions_blocked"); + + private final String value; + ManagedSettingsEnforcedAction(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static ManagedSettingsEnforcedAction fromValue(String value) { + for (ManagedSettingsEnforcedAction v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown ManagedSettingsEnforcedAction value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/ManagedSettingsEnforcedEscalation.java b/java/src/generated/java/com/github/copilot/generated/ManagedSettingsEnforcedEscalation.java new file mode 100644 index 000000000..cdeea72b4 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ManagedSettingsEnforcedEscalation.java @@ -0,0 +1,41 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum ManagedSettingsEnforcedEscalation { + /** The {@code allow_all} variant. */ + ALLOW_ALL("allow_all"), + /** The {@code approve_all} variant. */ + APPROVE_ALL("approve_all"), + /** The {@code auto_approval} variant. */ + AUTO_APPROVAL("auto_approval"), + /** The {@code unrestricted_paths} variant. */ + UNRESTRICTED_PATHS("unrestricted_paths"), + /** The {@code unrestricted_urls} variant. */ + UNRESTRICTED_URLS("unrestricted_urls"); + + private final String value; + ManagedSettingsEnforcedEscalation(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static ManagedSettingsEnforcedEscalation fromValue(String value) { + for (ManagedSettingsEnforcedEscalation v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown ManagedSettingsEnforcedEscalation value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java index 8797477d5..25c011fe3 100644 --- a/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java @@ -49,6 +49,22 @@ public record ModelCallFailureEventData( @JsonProperty("statusCode") Long statusCode, /** Duration of the failed API call in milliseconds */ @JsonProperty("durationMs") Long durationMs, + /** API endpoint used for this model call, matching CAPI supported_endpoints vocabulary */ + @JsonProperty("apiEndpoint") AssistantUsageApiEndpoint apiEndpoint, + /** Transport used for the failed model call (http or websocket) */ + @JsonProperty("transport") ModelCallFailureTransport transport, + /** Whether the failure originated from an API response or the request transport */ + @JsonProperty("failureKind") ModelCallFailureKind failureKind, + /** Effective maximum prompt-token limit for the failed call */ + @JsonProperty("maxPromptTokens") Long maxPromptTokens, + /** Effective maximum output-token limit for the failed call */ + @JsonProperty("maxOutputTokens") Long maxOutputTokens, + /** Whether the failed call used a bring-your-own-key provider */ + @JsonProperty("isByok") Boolean isByok, + /** Whether the session selected Auto mode for the failed call */ + @JsonProperty("isAuto") Boolean isAuto, + /** Reasoning effort level used for the failed model call, if applicable */ + @JsonProperty("reasoningEffort") String reasoningEffort, /** Where the failed model call originated */ @JsonProperty("source") ModelCallFailureSource source, /** Raw provider/runtime error message for restricted telemetry */ diff --git a/java/src/generated/java/com/github/copilot/generated/ModelCallFailureKind.java b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureKind.java new file mode 100644 index 000000000..917bc270f --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureKind.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * Boundary that produced a model call failure + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum ModelCallFailureKind { + /** The {@code api} variant. */ + API("api"), + /** The {@code transport} variant. */ + TRANSPORT("transport"); + + private final String value; + ModelCallFailureKind(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static ModelCallFailureKind fromValue(String value) { + for (ModelCallFailureKind v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown ModelCallFailureKind value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/ModelCallFailureTransport.java b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureTransport.java new file mode 100644 index 000000000..6f656f837 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureTransport.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * Transport used for a failed model call + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum ModelCallFailureTransport { + /** The {@code http} variant. */ + HTTP("http"), + /** The {@code websocket} variant. */ + WEBSOCKET("websocket"); + + private final String value; + ModelCallFailureTransport(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static ModelCallFailureTransport fromValue(String value) { + for (ModelCallFailureTransport v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown ModelCallFailureTransport value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/ModelCallStartEvent.java b/java/src/generated/java/com/github/copilot/generated/ModelCallStartEvent.java new file mode 100644 index 000000000..6ab9fa547 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ModelCallStartEvent.java @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Session event "model.call_start". Model API dispatch metadata for internal telemetry + * @since 1.0.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class ModelCallStartEvent extends SessionEvent { + + @Override + public String getType() { return "model.call_start"; } + + @JsonProperty("data") + private ModelCallStartEventData data; + + public ModelCallStartEventData getData() { return data; } + public void setData(ModelCallStartEventData data) { this.data = data; } + + /** Data payload for {@link ModelCallStartEvent}. */ + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + public record ModelCallStartEventData( + /** Identifier of the assistant turn that initiated the model call */ + @JsonProperty("turnId") String turnId, + /** Model identifier used for this API call, when known */ + @JsonProperty("model") String model + ) { + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/SessionEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionEvent.java index d15da0c41..e3b5bbae0 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionEvent.java @@ -57,6 +57,7 @@ @JsonSubTypes.Type(value = UserMessageEvent.class, name = "user.message"), @JsonSubTypes.Type(value = PendingMessagesModifiedEvent.class, name = "pending_messages.modified"), @JsonSubTypes.Type(value = AssistantTurnStartEvent.class, name = "assistant.turn_start"), + @JsonSubTypes.Type(value = AssistantTurnRetryEvent.class, name = "assistant.turn_retry"), @JsonSubTypes.Type(value = AssistantIntentEvent.class, name = "assistant.intent"), @JsonSubTypes.Type(value = AssistantServerToolProgressEvent.class, name = "assistant.server_tool_progress"), @JsonSubTypes.Type(value = AssistantReasoningEvent.class, name = "assistant.reasoning"), @@ -70,12 +71,14 @@ @JsonSubTypes.Type(value = AssistantIdleEvent.class, name = "assistant.idle"), @JsonSubTypes.Type(value = AssistantUsageEvent.class, name = "assistant.usage"), @JsonSubTypes.Type(value = ModelCallFailureEvent.class, name = "model.call_failure"), + @JsonSubTypes.Type(value = ModelCallStartEvent.class, name = "model.call_start"), @JsonSubTypes.Type(value = AbortEvent.class, name = "abort"), @JsonSubTypes.Type(value = ToolUserRequestedEvent.class, name = "tool.user_requested"), @JsonSubTypes.Type(value = ToolExecutionStartEvent.class, name = "tool.execution_start"), @JsonSubTypes.Type(value = ToolExecutionPartialResultEvent.class, name = "tool.execution_partial_result"), @JsonSubTypes.Type(value = ToolExecutionProgressEvent.class, name = "tool.execution_progress"), @JsonSubTypes.Type(value = ToolExecutionCompleteEvent.class, name = "tool.execution_complete"), + @JsonSubTypes.Type(value = ToolSearchActivatedEvent.class, name = "tool_search.activated"), @JsonSubTypes.Type(value = SkillInvokedEvent.class, name = "skill.invoked"), @JsonSubTypes.Type(value = SubagentStartedEvent.class, name = "subagent.started"), @JsonSubTypes.Type(value = SubagentCompletedEvent.class, name = "subagent.completed"), @@ -112,6 +115,7 @@ @JsonSubTypes.Type(value = SessionLimitsExhaustedCompletedEvent.class, name = "session_limits_exhausted.completed"), @JsonSubTypes.Type(value = SessionAutoModeResolvedEvent.class, name = "session.auto_mode_resolved"), @JsonSubTypes.Type(value = SessionManagedSettingsResolvedEvent.class, name = "session.managed_settings_resolved"), + @JsonSubTypes.Type(value = SessionManagedSettingsEnforcedEvent.class, name = "session.managed_settings_enforced"), @JsonSubTypes.Type(value = CommandsChangedEvent.class, name = "commands.changed"), @JsonSubTypes.Type(value = CapabilitiesChangedEvent.class, name = "capabilities.changed"), @JsonSubTypes.Type(value = ExitPlanModeRequestedEvent.class, name = "exit_plan_mode.requested"), @@ -169,6 +173,7 @@ public abstract sealed class SessionEvent permits UserMessageEvent, PendingMessagesModifiedEvent, AssistantTurnStartEvent, + AssistantTurnRetryEvent, AssistantIntentEvent, AssistantServerToolProgressEvent, AssistantReasoningEvent, @@ -182,12 +187,14 @@ public abstract sealed class SessionEvent permits AssistantIdleEvent, AssistantUsageEvent, ModelCallFailureEvent, + ModelCallStartEvent, AbortEvent, ToolUserRequestedEvent, ToolExecutionStartEvent, ToolExecutionPartialResultEvent, ToolExecutionProgressEvent, ToolExecutionCompleteEvent, + ToolSearchActivatedEvent, SkillInvokedEvent, SubagentStartedEvent, SubagentCompletedEvent, @@ -224,6 +231,7 @@ public abstract sealed class SessionEvent permits SessionLimitsExhaustedCompletedEvent, SessionAutoModeResolvedEvent, SessionManagedSettingsResolvedEvent, + SessionManagedSettingsEnforcedEvent, CommandsChangedEvent, CapabilitiesChangedEvent, ExitPlanModeRequestedEvent, diff --git a/java/src/generated/java/com/github/copilot/generated/SessionManagedSettingsEnforcedEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionManagedSettingsEnforcedEvent.java new file mode 100644 index 000000000..c712a220a --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/SessionManagedSettingsEnforcedEvent.java @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Session event "session.managed_settings_enforced". Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes. + * @since 1.0.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class SessionManagedSettingsEnforcedEvent extends SessionEvent { + + @Override + public String getType() { return "session.managed_settings_enforced"; } + + @JsonProperty("data") + private SessionManagedSettingsEnforcedEventData data; + + public SessionManagedSettingsEnforcedEventData getData() { return data; } + public void setData(SessionManagedSettingsEnforcedEventData data) { this.data = data; } + + /** Data payload for {@link SessionManagedSettingsEnforcedEvent}. */ + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + public record SessionManagedSettingsEnforcedEventData( + /** The category of runtime action that managed policy governed. */ + @JsonProperty("action") ManagedSettingsEnforcedAction action, + /** For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused. Absent for actions without a specific escalation primitive. */ + @JsonProperty("escalation") ManagedSettingsEnforcedEscalation escalation, + /** The managed setting key responsible for the enforcement (e.g. `permissions.disableBypassPermissionsMode`). */ + @JsonProperty("setting") String setting, + /** Whether the enforcement was forced by fail-closed handling (managed policy could not be determined) rather than an explicit managed setting. When true, `setting` still names the restriction that was applied. */ + @JsonProperty("failClosed") Boolean failClosed, + /** A human-readable explanation of why the action was governed, suitable for surfacing to the user. */ + @JsonProperty("message") String message + ) { + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/SessionUsageCheckpointEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionUsageCheckpointEvent.java index 312cb196b..1a400c013 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionUsageCheckpointEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionUsageCheckpointEvent.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; import javax.annotation.processing.Generated; /** @@ -37,7 +38,9 @@ public record SessionUsageCheckpointEventData( /** Session-wide accumulated nano-AI units cost at checkpoint time */ @JsonProperty("totalNanoAiu") Double totalNanoAiu, /** Total number of premium API requests used at checkpoint time */ - @JsonProperty("totalPremiumRequests") Double totalPremiumRequests + @JsonProperty("totalPremiumRequests") Double totalPremiumRequests, + /** Internal per-model prompt-cache state used to restore expiration tracking on resume */ + @JsonProperty("modelCacheState") List modelCacheState ) { } } diff --git a/java/src/generated/java/com/github/copilot/generated/ToolSearchActivatedEvent.java b/java/src/generated/java/com/github/copilot/generated/ToolSearchActivatedEvent.java new file mode 100644 index 000000000..9dfca4a95 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ToolSearchActivatedEvent.java @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import javax.annotation.processing.Generated; + +/** + * Session event "tool_search.activated". Persisted generic client-side tool activations restored when a session resumes. + * @since 1.0.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class ToolSearchActivatedEvent extends SessionEvent { + + @Override + public String getType() { return "tool_search.activated"; } + + @JsonProperty("data") + private ToolSearchActivatedEventData data; + + public ToolSearchActivatedEventData getData() { return data; } + public void setData(ToolSearchActivatedEventData data) { this.data = data; } + + /** Data payload for {@link ToolSearchActivatedEvent}. */ + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + public record ToolSearchActivatedEventData( + /** Tool-search strategy that activated the definitions. */ + @JsonProperty("strategy") String strategy, + /** Names of tool definitions activated by this search invocation. */ + @JsonProperty("toolNames") List toolNames + ) { + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/UsageCheckpointModelCacheState.java b/java/src/generated/java/com/github/copilot/generated/UsageCheckpointModelCacheState.java new file mode 100644 index 000000000..802ac5cef --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/UsageCheckpointModelCacheState.java @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.time.OffsetDateTime; +import javax.annotation.processing.Generated; + +/** + * Internal prompt-cache expiration state for one model + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record UsageCheckpointModelCacheState( + /** Model identifier associated with this cache state */ + @JsonProperty("modelId") String modelId, + /** Latest known prompt-cache expiration */ + @JsonProperty("cacheExpiresAt") OffsetDateTime cacheExpiresAt, + /** Retained cache lifetime in seconds, used to refresh expiration after a cache read */ + @JsonProperty("cacheTtlSeconds") Long cacheTtlSeconds +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryAbortParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryAbortParams.java new file mode 100644 index 000000000..35e0f276e --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryAbortParams.java @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters for cooperatively aborting a factory body. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record FactoryAbortParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Factory run identifier. */ + @JsonProperty("runId") String runId +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryAgentOptions.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryAgentOptions.java new file mode 100644 index 000000000..675e715e8 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryAgentOptions.java @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Options for one factory-scoped subagent call. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record FactoryAgentOptions( + /** Optional label distinguishing otherwise identical memoized agent calls. */ + @JsonProperty("label") String label, + /** Optional JSON Schema for structured agent output. */ + @JsonProperty("schema") Object schema, + /** Optional model identifier for the subagent. */ + @JsonProperty("model") String model +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryExecuteParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryExecuteParams.java new file mode 100644 index 000000000..e6f453814 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryExecuteParams.java @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters sent to the owning extension to execute a factory closure. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record FactoryExecuteParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Registered factory name. */ + @JsonProperty("name") String name, + /** Factory run identifier. */ + @JsonProperty("runId") String runId, + /** Factory input value. */ + @JsonProperty("args") Object args +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryExecuteResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryExecuteResult.java new file mode 100644 index 000000000..b47b9fb07 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryExecuteResult.java @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Result returned by an extension factory closure. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record FactoryExecuteResult( + /** Factory result value. */ + @JsonProperty("result") Object result +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryLogLine.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryLogLine.java new file mode 100644 index 000000000..28a969045 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryLogLine.java @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * One ordered factory progress line. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record FactoryLogLine( + /** Monotonic sequence number within the factory run. */ + @JsonProperty("seq") Long seq, + /** Progress line kind. */ + @JsonProperty("kind") FactoryLogLineKind kind, + /** Progress text. */ + @JsonProperty("text") String text +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryLogLineKind.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryLogLineKind.java new file mode 100644 index 000000000..1064f1691 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryLogLineKind.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import javax.annotation.processing.Generated; + +/** + * Kind of factory progress line. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum FactoryLogLineKind { + /** The {@code log} variant. */ + LOG("log"), + /** The {@code phase} variant. */ + PHASE("phase"); + + private final String value; + FactoryLogLineKind(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static FactoryLogLineKind fromValue(String value) { + for (FactoryLogLineKind v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown FactoryLogLineKind value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryRunLimits.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryRunLimits.java new file mode 100644 index 000000000..ede598b80 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryRunLimits.java @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Wire-only per-invocation factory resource ceiling overrides. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record FactoryRunLimits( + /** Maximum number of factory subagents that may run concurrently. */ + @JsonProperty("maxConcurrentSubagents") Long maxConcurrentSubagents, + /** Maximum total number of factory subagents that may be admitted. */ + @JsonProperty("maxTotalSubagents") Long maxTotalSubagents, + /** Factory active-run timeout in milliseconds. */ + @JsonProperty("timeout") Double timeout +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/FactoryRunStatus.java b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryRunStatus.java new file mode 100644 index 000000000..5d2348ec9 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/FactoryRunStatus.java @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import javax.annotation.processing.Generated; + +/** + * Current or terminal state of a factory run. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum FactoryRunStatus { + /** The {@code pending} variant. */ + PENDING("pending"), + /** The {@code running} variant. */ + RUNNING("running"), + /** The {@code completed} variant. */ + COMPLETED("completed"), + /** The {@code halted} variant. */ + HALTED("halted"), + /** The {@code cancelled} variant. */ + CANCELLED("cancelled"), + /** The {@code error} variant. */ + ERROR("error"); + + private final String value; + FactoryRunStatus(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static FactoryRunStatus fromValue(String value) { + for (FactoryRunStatus v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown FactoryRunStatus value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/HookType.java b/java/src/generated/java/com/github/copilot/generated/rpc/HookType.java index 006f8a7c1..8d7cd913c 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/HookType.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/HookType.java @@ -26,6 +26,8 @@ public enum HookType { POSTTOOLUSEFAILURE("postToolUseFailure"), /** The {@code userPromptSubmitted} variant. */ USERPROMPTSUBMITTED("userPromptSubmitted"), + /** The {@code userPromptTransformed} variant. */ + USERPROMPTTRANSFORMED("userPromptTransformed"), /** The {@code sessionStart} variant. */ SESSIONSTART("sessionStart"), /** The {@code sessionEnd} variant. */ diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/LlmInferenceHttpRequestStartRequest.java b/java/src/generated/java/com/github/copilot/generated/rpc/LlmInferenceHttpRequestStartRequest.java index a625e4253..b846fcf37 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/LlmInferenceHttpRequestStartRequest.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/LlmInferenceHttpRequestStartRequest.java @@ -34,10 +34,12 @@ public record LlmInferenceHttpRequestStartRequest( @JsonProperty("headers") Map> headers, /** Transport the runtime would otherwise use for this request. `http` (the default when absent) covers plain HTTP and SSE responses; `websocket` indicates a full-duplex message channel where each body chunk maps to one WebSocket message and the `binary` flag distinguishes text from binary frames. The SDK consumer uses this to decide whether to service the request with an HTTP client or a WebSocket client. It is the one piece of request metadata the consumer cannot reliably infer from the URL or headers alone. */ @JsonProperty("transport") LlmInferenceHttpRequestStartTransport transport, - /** Stable per-agent-instance id attributing this request to a specific agent trajectory. Present when the request originates from an agent turn; absent for requests issued outside any agent context (e.g. some SDK callers). A request with an `agentId` but no `parentAgentId` is a root-agent request; one carrying both is a subagent request. Sourced from the runtime's per-request agent context and surfaced on the envelope independently of transport, so it is available for both first-party (CAPI) and BYOK/custom-provider requests; on the CAPI transport the runtime derives the upstream `X-Agent-Task-Id` header from this same context. Consumers routing each provider call to a training trajectory should key on this rather than on lifecycle events, since it is available on the request path before sampling. */ + /** Stable identity of the agent trajectory that issued this request. Present when the request originates from an agent turn; absent for requests outside any agent context. This is the same identity used by lifecycle and bridged session events and remains constant across turns and retries. */ @JsonProperty("agentId") String agentId, - /** Id of the parent agent that spawned the agent issuing this request. Present only for subagent requests; absent for root-agent requests and non-agent requests. Combined with `agentId`, this lets consumers attribute a call to a child trajectory versus the root. Like `agentId`, it comes from the runtime's per-request agent context independently of transport; on the CAPI transport the runtime derives the upstream `X-Parent-Agent-Id` header from this same context. */ + /** Stable identity of the immediate parent trajectory. Present for child trajectories such as subagents and conversation-sampling requests; absent for root-agent and non-agent requests. */ @JsonProperty("parentAgentId") String parentAgentId, + /** Identity of the agent invocation (one agentic loop) that issued this request. It remains fixed across physical retries within the invocation and is distinct from the stable trajectory `agentId`. A caller-supplied invocation id always takes precedence (this covers auxiliary calls that have no model call id). Otherwise, first-party CAPI requests fall back to the runtime's agent task id — the same value the runtime emits as the `X-Agent-Task-Id` header — while custom-provider requests fall back to the model call id. */ + @JsonProperty("agentInvocationId") String agentInvocationId, /** Coarse classification of the interaction that produced this request. Open string for forward-compatibility; known values include `conversation-agent`, `conversation-subagent`, `conversation-sampling`, `conversation-background`, `conversation-compaction`, and `conversation-user`. Absent when the runtime did not classify the request. Comes from the runtime's per-request agent context independently of transport; on the CAPI transport the runtime derives the upstream `X-Interaction-Type` header from this same context. */ @JsonProperty("interactionType") String interactionType ) { diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/RunOptions.java b/java/src/generated/java/com/github/copilot/generated/rpc/RunOptions.java new file mode 100644 index 000000000..92e4c401f --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/RunOptions.java @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Options controlling factory invocation. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record RunOptions( + /** Per-invocation resource ceiling overrides. */ + @JsonProperty("limits") FactoryRunLimits limits, + /** Run identifier whose journal and progress should seed this resumed run. */ + @JsonProperty("resumeFromRunId") String resumeFromRunId +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SandboxConfig.java b/java/src/generated/java/com/github/copilot/generated/rpc/SandboxConfig.java index b2a4d74d1..3460560b2 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SandboxConfig.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SandboxConfig.java @@ -26,6 +26,10 @@ public record SandboxConfig( /** User-managed sandbox policy fragment merged into the auto-discovered base policy. */ @JsonProperty("userPolicy") SandboxConfigUserPolicy userPolicy, /** Whether to auto-add the current working directory to readwritePaths. Default: true. */ - @JsonProperty("addCurrentWorkingDirectory") Boolean addCurrentWorkingDirectory + @JsonProperty("addCurrentWorkingDirectory") Boolean addCurrentWorkingDirectory, + /** Whether to inject the Copilot GitHub token as an `http..extraheader` so authenticated HTTPS git works inside the sandbox without the shell-based credential helper the sandbox blocks. Default: false (opt-in). */ + @JsonProperty("gitAuth") Boolean gitAuth, + /** Whether to export `GH_TOKEN` so the `gh` CLI authenticates inside the sandbox without the OS keyring the sandbox blocks. Default: false (opt-in). */ + @JsonProperty("ghAuth") Boolean ghAuth ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryAgentParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryAgentParams.java new file mode 100644 index 000000000..7f31066fc --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryAgentParams.java @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters for one factory-scoped subagent call. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryAgentParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Factory run identifier that owns the subagent. */ + @JsonProperty("factoryRunId") String factoryRunId, + /** Prompt to send to the subagent. */ + @JsonProperty("prompt") String prompt, + /** Subagent execution options. */ + @JsonProperty("opts") FactoryAgentOptions opts +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryAgentResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryAgentResult.java new file mode 100644 index 000000000..dcd31fd34 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryAgentResult.java @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Result of one factory-scoped subagent call. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryAgentResult( + /** Agent result, omitted when the agent produced no result. */ + @JsonProperty("result") Object result +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryApi.java new file mode 100644 index 000000000..703a2e711 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryApi.java @@ -0,0 +1,117 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.github.copilot.CopilotExperimental; +import java.util.concurrent.CompletableFuture; +import javax.annotation.processing.Generated; + +/** + * API methods for the {@code factory} namespace. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class SessionFactoryApi { + + private static final com.fasterxml.jackson.databind.ObjectMapper MAPPER = RpcMapper.INSTANCE; + + private final RpcCaller caller; + private final String sessionId; + + /** API methods for the {@code factory.journal} sub-namespace. */ + public final SessionFactoryJournalApi journal; + + /** @param caller the RPC transport function */ + SessionFactoryApi(RpcCaller caller, String sessionId) { + this.caller = caller; + this.sessionId = sessionId; + this.journal = new SessionFactoryJournalApi(caller, sessionId); + } + + /** + * Parameters for invoking a registered factory. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture run(SessionFactoryRunParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.factory.run", _p, SessionFactoryRunResult.class); + } + + /** + * Parameters for retrieving a factory run. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture getRun(SessionFactoryGetRunParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.factory.getRun", _p, SessionFactoryGetRunResult.class); + } + + /** + * Parameters for cancelling a factory run. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture cancel(SessionFactoryCancelParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.factory.cancel", _p, SessionFactoryCancelResult.class); + } + + /** + * Parameters for recording factory progress. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture log(SessionFactoryLogParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.factory.log", _p, Void.class); + } + + /** + * Parameters for one factory-scoped subagent call. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture agent(SessionFactoryAgentParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.factory.agent", _p, SessionFactoryAgentResult.class); + } + +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryCancelParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryCancelParams.java new file mode 100644 index 000000000..8ed7e4aa3 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryCancelParams.java @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters for cancelling a factory run. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryCancelParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Factory run identifier. */ + @JsonProperty("runId") String runId +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryCancelResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryCancelResult.java new file mode 100644 index 000000000..0cb66280c --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryCancelResult.java @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Complete current or terminal factory run envelope. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryCancelResult( + /** Factory run identifier. */ + @JsonProperty("runId") String runId, + /** Current or terminal factory run status. */ + @JsonProperty("status") FactoryRunStatus status, + /** Completed factory result. */ + @JsonProperty("result") Object result, + /** Error message for an errored run. */ + @JsonProperty("error") String error, + /** Machine-readable failure details for an errored run. */ + @JsonProperty("failure") Object failure, + /** Reason for a halted or cancelled run. */ + @JsonProperty("reason") String reason, + /** Partial journal and progress snapshot for a halted, cancelled, or errored run. */ + @JsonProperty("snapshot") Object snapshot +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryGetRunParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryGetRunParams.java new file mode 100644 index 000000000..f98e1f0d7 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryGetRunParams.java @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters for retrieving a factory run. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryGetRunParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Factory run identifier. */ + @JsonProperty("runId") String runId +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryGetRunResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryGetRunResult.java new file mode 100644 index 000000000..6742faf03 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryGetRunResult.java @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Complete current or terminal factory run envelope. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryGetRunResult( + /** Factory run identifier. */ + @JsonProperty("runId") String runId, + /** Current or terminal factory run status. */ + @JsonProperty("status") FactoryRunStatus status, + /** Completed factory result. */ + @JsonProperty("result") Object result, + /** Error message for an errored run. */ + @JsonProperty("error") String error, + /** Machine-readable failure details for an errored run. */ + @JsonProperty("failure") Object failure, + /** Reason for a halted or cancelled run. */ + @JsonProperty("reason") String reason, + /** Partial journal and progress snapshot for a halted, cancelled, or errored run. */ + @JsonProperty("snapshot") Object snapshot +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalApi.java new file mode 100644 index 000000000..e5bfb4e66 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalApi.java @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.github.copilot.CopilotExperimental; +import java.util.concurrent.CompletableFuture; +import javax.annotation.processing.Generated; + +/** + * API methods for the {@code factory.journal} namespace. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class SessionFactoryJournalApi { + + private static final com.fasterxml.jackson.databind.ObjectMapper MAPPER = RpcMapper.INSTANCE; + + private final RpcCaller caller; + private final String sessionId; + + /** @param caller the RPC transport function */ + SessionFactoryJournalApi(RpcCaller caller, String sessionId) { + this.caller = caller; + this.sessionId = sessionId; + } + + /** + * Parameters for reading a factory journal entry. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture get(SessionFactoryJournalGetParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.factory.journal.get", _p, SessionFactoryJournalGetResult.class); + } + + /** + * Parameters for storing a factory journal entry. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture put(SessionFactoryJournalPutParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.factory.journal.put", _p, Void.class); + } + +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalGetParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalGetParams.java new file mode 100644 index 000000000..a9b0acc7c --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalGetParams.java @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters for reading a factory journal entry. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryJournalGetParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Factory run identifier. */ + @JsonProperty("runId") String runId, + /** Namespaced journal key. */ + @JsonProperty("key") String key +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalGetResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalGetResult.java new file mode 100644 index 000000000..4b97e1029 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalGetResult.java @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Result of reading a factory journal entry. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryJournalGetResult( + /** Whether the journal contained the requested key. */ + @JsonProperty("hit") Boolean hit, + /** Cached JSON result. The hit field distinguishes a cached JSON null from a miss. */ + @JsonProperty("resultJson") Object resultJson +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalPutParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalPutParams.java new file mode 100644 index 000000000..84478dbb7 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryJournalPutParams.java @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters for storing a factory journal entry. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryJournalPutParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Factory run identifier. */ + @JsonProperty("runId") String runId, + /** Namespaced journal key. */ + @JsonProperty("key") String key, + /** JSON result to memoize. */ + @JsonProperty("resultJson") Object resultJson +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryLogParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryLogParams.java new file mode 100644 index 000000000..7618869e3 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryLogParams.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import java.util.List; +import javax.annotation.processing.Generated; + +/** + * Parameters for recording factory progress. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryLogParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Factory run identifier. */ + @JsonProperty("runId") String runId, + /** Ordered progress lines to append. */ + @JsonProperty("lines") List lines +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryRunParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryRunParams.java new file mode 100644 index 000000000..fd60b9643 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryRunParams.java @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Parameters for invoking a registered factory. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryRunParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Registered factory name. */ + @JsonProperty("name") String name, + /** Factory input value. */ + @JsonProperty("args") Object args, + /** Factory invocation options. */ + @JsonProperty("options") RunOptions options +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryRunResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryRunResult.java new file mode 100644 index 000000000..46083f228 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionFactoryRunResult.java @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Complete current or terminal factory run envelope. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionFactoryRunResult( + /** Factory run identifier. */ + @JsonProperty("runId") String runId, + /** Current or terminal factory run status. */ + @JsonProperty("status") FactoryRunStatus status, + /** Completed factory result. */ + @JsonProperty("result") Object result, + /** Error message for an errored run. */ + @JsonProperty("error") String error, + /** Machine-readable failure details for an errored run. */ + @JsonProperty("failure") Object failure, + /** Reason for a halted or cancelled run. */ + @JsonProperty("reason") String reason, + /** Partial journal and progress snapshot for a halted, cancelled, or errored run. */ + @JsonProperty("snapshot") Object snapshot +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java index c150b7567..3ec3464d0 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java @@ -35,6 +35,8 @@ public final class SessionRpc { public final SessionDebugApi debug; /** API methods for the {@code canvas} namespace. */ public final SessionCanvasApi canvas; + /** API methods for the {@code factory} namespace. */ + public final SessionFactoryApi factory; /** API methods for the {@code model} namespace. */ public final SessionModelApi model; /** API methods for the {@code mode} namespace. */ @@ -112,6 +114,7 @@ public SessionRpc(RpcCaller caller, String sessionId) { this.gitHubAuth = new SessionGitHubAuthApi(caller, sessionId); this.debug = new SessionDebugApi(caller, sessionId); this.canvas = new SessionCanvasApi(caller, sessionId); + this.factory = new SessionFactoryApi(caller, sessionId); this.model = new SessionModelApi(caller, sessionId); this.mode = new SessionModeApi(caller, sessionId); this.name = new SessionNameApi(caller, sessionId); diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SkillsDiscoverResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SkillsDiscoverResult.java index 588e9760c..78b1f1eb9 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SkillsDiscoverResult.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SkillsDiscoverResult.java @@ -26,6 +26,8 @@ @JsonIgnoreProperties(ignoreUnknown = true) public record SkillsDiscoverResult( /** All discovered skills across all sources */ - @JsonProperty("skills") List skills + @JsonProperty("skills") List skills, + /** Messages for skills that failed to load (e.g. malformed SKILL.md). Empty when host skills are excluded so host-local paths are not disclosed to multitenant callers. */ + @JsonProperty("errors") List errors ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/UsageMetricsModelMetric.java b/java/src/generated/java/com/github/copilot/generated/rpc/UsageMetricsModelMetric.java index 1b66120cf..ed5f09305 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/UsageMetricsModelMetric.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/UsageMetricsModelMetric.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import java.time.OffsetDateTime; import java.util.Map; import javax.annotation.processing.Generated; @@ -26,6 +27,8 @@ public record UsageMetricsModelMetric( @JsonProperty("requests") UsageMetricsModelMetricRequests requests, /** Token usage metrics for this model */ @JsonProperty("usage") UsageMetricsModelMetricUsage usage, + /** Latest known prompt-cache expiration for this model. A timestamp in the past indicates that the observed cache has expired. */ + @JsonProperty("cacheExpiresAt") OffsetDateTime cacheExpiresAt, /** Accumulated nano-AI units cost for this model */ @JsonProperty("totalNanoAiu") Double totalNanoAiu, /** Token count details per type */ diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json index 799053c0f..2173662ff 100644 --- a/nodejs/package-lock.json +++ b/nodejs/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0-dev", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.71", + "@github/copilot": "^1.0.72", "koffi": "^3.1.0", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" @@ -700,9 +700,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.71.tgz", - "integrity": "sha512-F3axBi+sXSLYDJbxCBW36bM6MYKNC2rlyAf3Ivo/MjiHKKJW7j5AmaR1IRYS9Gt8r9mxOwWFM1cJFA+CuLaR8g==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.72.tgz", + "integrity": "sha512-muxp9clYtDTGB+KaaL3B5YJM/UqMoCKOU1vFoxWB63zPzeDrl2vlRIYc/pQwCCEVf6Agf9KAe4rvzVoOsRrPeg==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "detect-libc": "^2.1.2" @@ -711,20 +711,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.71", - "@github/copilot-darwin-x64": "1.0.71", - "@github/copilot-linux-arm64": "1.0.71", - "@github/copilot-linux-x64": "1.0.71", - "@github/copilot-linuxmusl-arm64": "1.0.71", - "@github/copilot-linuxmusl-x64": "1.0.71", - "@github/copilot-win32-arm64": "1.0.71", - "@github/copilot-win32-x64": "1.0.71" + "@github/copilot-darwin-arm64": "1.0.72", + "@github/copilot-darwin-x64": "1.0.72", + "@github/copilot-linux-arm64": "1.0.72", + "@github/copilot-linux-x64": "1.0.72", + "@github/copilot-linuxmusl-arm64": "1.0.72", + "@github/copilot-linuxmusl-x64": "1.0.72", + "@github/copilot-win32-arm64": "1.0.72", + "@github/copilot-win32-x64": "1.0.72" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.71.tgz", - "integrity": "sha512-mEWzyqbqRAWgyU7i2uuSRoVPx/TwaFQX0nZmw0bc30aJ0BnO7cy2kYQyCHw8ykmf/tfxT0xauZ6k0BOFmWizzQ==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.72.tgz", + "integrity": "sha512-hUYF/MwE9dji6XVmZ9DkZ8emV/n1Y/8zuAPI8Yfa4mo7smHcRF3LIUUZMVOwdhl0IZj7rvFJJpjfGjXtP5VGcg==", "cpu": [ "arm64" ], @@ -738,9 +738,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.71.tgz", - "integrity": "sha512-Md9yEg406OBVBx3w4PeEj62TubulVLBcHleqmCoOoUmPgUxPZotUbrqz3rtbzADbXfrrD7JWvVsbd2UiNL194w==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.72.tgz", + "integrity": "sha512-4M5qlL5Tf+DVXBcMEBW8v6fGCQKl2Dnpcj5qhFQbPdARHCZNtkBxg2lHWmbHeNmlMU85tndy2Kzb+iAIALTUAw==", "cpu": [ "x64" ], @@ -754,9 +754,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.71.tgz", - "integrity": "sha512-ykLJYOqBj3jRB5IJCDugLClAqbr7DmtTbUjlNY7+Jdq/n6i+d7xUQGclf1IWL5gnxbGQVAf+zkToD+sRM389Kg==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.72.tgz", + "integrity": "sha512-+3Xzfm6Rb+g/oKlD1ZhYzZnrlRnaLkpMYN/9PBwIvBzj3t+c5sH3TDnCEA17Y5oSJeWhuXEyGr9YhuAIuZPemw==", "cpu": [ "arm64" ], @@ -770,9 +770,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.71.tgz", - "integrity": "sha512-pC0FNHG+BBwZd6yZlM85kkAGN+uJhM6o+THi76N2GnnSxmw7+remb1mvYxdgRVbdCm+LBUIbCKRWJLuMwrfb6A==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.72.tgz", + "integrity": "sha512-PjEJXRoR+SXwFo+GUgogC9DKrl/ZhT+/u1Jd3Sa0SdhWGRRqUjPUBzmNeJN9tcT8Q9VeZ1qSk1beD7JszV57ng==", "cpu": [ "x64" ], @@ -786,9 +786,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.71.tgz", - "integrity": "sha512-hBmDljFTjacxqZTasCEy43H8EIzuXB/hHEBBCMFjhB9J00nIxsO6Dh0woTifKpx7knTYZdpTjjca3D0pAoZlUA==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.72.tgz", + "integrity": "sha512-9gQQkln+qmsmq80eYua9pbaxGOajKVRlYBB+0xYWM+yEUebZB52u/IbUGhWJImvbax8EWqGoTU6ngswrs/nYJA==", "cpu": [ "arm64" ], @@ -802,9 +802,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.71.tgz", - "integrity": "sha512-CfTXU8pa5dxRz22xQzoi3TiG1PJo9+WR8PRDiPSdkIBSyPJ1NvX87DJmfXjTgeAfR+wkjt/p0keDCaBBVhNmUA==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.72.tgz", + "integrity": "sha512-t0mowX6LJSbILBNyJo3jYkSzRrATFTBzks2UUUDvDw1FR0k2VkLNCIq0V6LtdRYfNL/CJRKxzH1TqvdVCFCWcA==", "cpu": [ "x64" ], @@ -818,9 +818,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.71.tgz", - "integrity": "sha512-+HI1DokixXhHUahj06Fw67ZAigBuXKC58BFma4UJOGrQsDgwOSbqeTQHCw6vuymzjKlg3sactfsCUTaefkjscQ==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.72.tgz", + "integrity": "sha512-kbaUKFH7/hZd1Y1WhtuXBRX0gBeIVutUvJ6+SRWD/SkOnRW68nS5RShuRogpXTNM5SmopfFaS3BBaMOu2dFLkg==", "cpu": [ "arm64" ], @@ -834,9 +834,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.71.tgz", - "integrity": "sha512-02kXOBd9CwBbCaztuf71WYWn+uGapCuiaasomN4tcMH3HBVZ4gi3J0ZUoRcgcS80xh81uQyeBHbnUKzb/RE/9A==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.72.tgz", + "integrity": "sha512-5Jhb38Yk3nHnxwxgE/8vXDKg1b34ZmZ36EceWkLAO3ga9XQYi3njpphRI10G8UahyCBCdzLingY18WKQ28XRiA==", "cpu": [ "x64" ], diff --git a/nodejs/package.json b/nodejs/package.json index 4f588640a..6ab6d5382 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -56,7 +56,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.71", + "@github/copilot": "^1.0.72", "koffi": "^3.1.0", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json index 89c74c153..ff19a3016 100644 --- a/nodejs/samples/package-lock.json +++ b/nodejs/samples/package-lock.json @@ -18,7 +18,7 @@ "version": "0.0.0-dev", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.71", + "@github/copilot": "^1.0.72", "koffi": "^3.1.0", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index 255a769d5..b554e893e 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -509,6 +509,81 @@ export type ExternalToolTextResultForLlmContentResourceLinkIconTheme = export type ExternalToolTextResultForLlmContentResourceDetails = | EmbeddedTextResourceContents | EmbeddedBlobResourceContents; +/** + * Kind of factory progress line. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryLogLineKind". + */ +/** @experimental */ +export type FactoryLogLineKind = + /** A narrator log line. */ + | "log" + /** A named factory phase marker. */ + | "phase"; +/** + * Machine-readable factory run failure. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryRunFailure". + */ +/** @experimental */ +export type FactoryRunFailure = + | { + kind: FactoryRunFailureKind; + /** + * Approved effective ceiling that was reached. + */ + value: number; + /** + * Factory run identifier. + */ + runId: string; + type: "factory_limit_reached"; + } + | { + /** + * Factory run identifier whose changed limits were declined. + */ + runId: string; + /** + * Human-readable reason the resume did not proceed. + */ + reason: string; + type: "factory_resume_declined"; + }; +/** + * Cumulative resource ceiling that stopped a factory run. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryRunFailureKind". + */ +/** @experimental */ +export type FactoryRunFailureKind = + /** The run admitted the approved maximum total number of subagents. */ + | "maxTotalSubagents" + /** The run reached the approved timeout deadline. */ + | "timeout"; +/** + * Current or terminal state of a factory run. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryRunStatus". + */ +/** @experimental */ +export type FactoryRunStatus = + /** The run was minted and is awaiting approval. */ + | "pending" + /** The run is executing. */ + | "running" + /** The run completed successfully. */ + | "completed" + /** The run was interrupted while resource budget remained. */ + | "halted" + /** The run was cancelled before completion. */ + | "cancelled" + /** The factory body failed or reached a cumulative resource ceiling. */ + | "error"; /** * Content filtering mode to apply to all tools, or a map of tool name to content filtering mode. * @@ -540,6 +615,8 @@ export type HookType = | "postToolUseFailure" /** Runs after the user submits a prompt. */ | "userPromptSubmitted" + /** Runs after the runtime transforms the submitted prompt for the model, before it is added to session history. */ + | "userPromptTransformed" /** Runs when a session starts. */ | "sessionStart" /** Runs when a session ends. */ @@ -4831,6 +4908,339 @@ export interface ExternalToolTextResultForLlmContentResource { type: "resource"; resource: ExternalToolTextResultForLlmContentResourceDetails; } +/** + * Parameters for cooperatively aborting a factory body. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryAbortRequest". + */ +/** @experimental */ +export interface FactoryAbortRequest { + /** + * Target session identifier + */ + sessionId: string; + /** + * Factory run identifier. + */ + runId: string; +} +/** + * Acknowledgement that a factory request was accepted. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryAckResult". + */ +/** @experimental */ +export interface FactoryAckResult {} +/** + * Options for one factory-scoped subagent call. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryAgentOptions". + */ +/** @experimental */ +export interface FactoryAgentOptions { + /** + * Optional label distinguishing otherwise identical memoized agent calls. + */ + label?: string; + /** + * Optional JSON Schema for structured agent output. + */ + schema?: { + [k: string]: unknown | undefined; + }; + /** + * Optional model identifier for the subagent. + */ + model?: string; +} +/** + * Parameters for one factory-scoped subagent call. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryAgentRequest". + */ +/** @experimental */ +export interface FactoryAgentRequest { + /** + * Factory run identifier that owns the subagent. + */ + factoryRunId: string; + /** + * Prompt to send to the subagent. + */ + prompt: string; + opts: FactoryAgentOptions; +} +/** + * Result of one factory-scoped subagent call. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryAgentResult". + */ +/** @experimental */ +export interface FactoryAgentResult { + /** + * Agent result, omitted when the agent produced no result. + */ + result?: { + [k: string]: unknown | undefined; + }; +} +/** + * Parameters for cancelling a factory run. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryCancelRequest". + */ +/** @experimental */ +export interface FactoryCancelRequest { + /** + * Factory run identifier. + */ + runId: string; +} +/** + * Parameters sent to the owning extension to execute a factory closure. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryExecuteRequest". + */ +/** @experimental */ +export interface FactoryExecuteRequest { + /** + * Target session identifier + */ + sessionId: string; + /** + * Registered factory name. + */ + name: string; + /** + * Factory run identifier. + */ + runId: string; + /** + * Factory input value. + */ + args: { + [k: string]: unknown | undefined; + }; +} +/** + * Result returned by an extension factory closure. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryExecuteResult". + */ +/** @experimental */ +export interface FactoryExecuteResult { + /** + * Factory result value. + */ + result: { + [k: string]: unknown | undefined; + }; +} +/** + * Parameters for retrieving a factory run. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryGetRunRequest". + */ +/** @experimental */ +export interface FactoryGetRunRequest { + /** + * Factory run identifier. + */ + runId: string; +} +/** + * Parameters for reading a factory journal entry. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryJournalGetRequest". + */ +/** @experimental */ +export interface FactoryJournalGetRequest { + /** + * Factory run identifier. + */ + runId: string; + /** + * Namespaced journal key. + */ + key: string; +} +/** + * Result of reading a factory journal entry. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryJournalGetResult". + */ +/** @experimental */ +export interface FactoryJournalGetResult { + /** + * Whether the journal contained the requested key. + */ + hit: boolean; + /** + * Cached JSON result. The hit field distinguishes a cached JSON null from a miss. + */ + resultJson?: { + [k: string]: unknown | undefined; + }; +} +/** + * Parameters for storing a factory journal entry. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryJournalPutRequest". + */ +/** @experimental */ +export interface FactoryJournalPutRequest { + /** + * Factory run identifier. + */ + runId: string; + /** + * Namespaced journal key. + */ + key: string; + /** + * JSON result to memoize. + */ + resultJson: { + [k: string]: unknown | undefined; + }; +} +/** + * One ordered factory progress line. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryLogLine". + */ +/** @experimental */ +export interface FactoryLogLine { + /** + * Monotonic sequence number within the factory run. + */ + seq: number; + kind: FactoryLogLineKind; + /** + * Progress text. + */ + text: string; +} +/** + * Parameters for recording factory progress. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryLogRequest". + */ +/** @experimental */ +export interface FactoryLogRequest { + /** + * Factory run identifier. + */ + runId: string; + /** + * Ordered progress lines to append. + */ + lines: FactoryLogLine[]; +} +/** + * Wire-only per-invocation factory resource ceiling overrides. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryRunLimits". + */ +/** @experimental */ +export interface FactoryRunLimits { + /** + * Maximum number of factory subagents that may run concurrently. + */ + maxConcurrentSubagents?: number; + /** + * Maximum total number of factory subagents that may be admitted. + */ + maxTotalSubagents?: number; + /** + * Factory active-run timeout in milliseconds. + */ + timeout?: number; +} +/** + * Parameters for invoking a registered factory. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryRunRequest". + */ +/** @experimental */ +export interface FactoryRunRequest { + /** + * Registered factory name. + */ + name: string; + /** + * Factory input value. + */ + args: { + [k: string]: unknown | undefined; + }; + options?: RunOptions; +} +/** + * Options controlling factory invocation. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "RunOptions". + */ +/** @experimental */ +export interface RunOptions { + limits?: FactoryRunLimits; + /** + * Run identifier whose journal and progress should seed this resumed run. + */ + resumeFromRunId?: string; +} +/** + * Complete current or terminal factory run envelope. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "FactoryRunResult". + */ +/** @experimental */ +export interface FactoryRunResult { + /** + * Factory run identifier. + */ + runId: string; + status: FactoryRunStatus; + /** + * Completed factory result. + */ + result?: { + [k: string]: unknown | undefined; + }; + /** + * Error message for an errored run. + */ + error?: string; + failure?: FactoryRunFailure; + /** + * Reason for a halted or cancelled run. + */ + reason?: string; + /** + * Partial journal and progress snapshot for a halted, cancelled, or errored run. + */ + snapshot?: { + [k: string]: unknown | undefined; + }; +} /** * Optional user prompt to combine with the fleet orchestration instructions. * @@ -5520,13 +5930,17 @@ export interface LlmInferenceHttpRequestStartRequest { headers: LlmInferenceHeaders; transport?: LlmInferenceHttpRequestStartTransport; /** - * Stable per-agent-instance id attributing this request to a specific agent trajectory. Present when the request originates from an agent turn; absent for requests issued outside any agent context (e.g. some SDK callers). A request with an `agentId` but no `parentAgentId` is a root-agent request; one carrying both is a subagent request. Sourced from the runtime's per-request agent context and surfaced on the envelope independently of transport, so it is available for both first-party (CAPI) and BYOK/custom-provider requests; on the CAPI transport the runtime derives the upstream `X-Agent-Task-Id` header from this same context. Consumers routing each provider call to a training trajectory should key on this rather than on lifecycle events, since it is available on the request path before sampling. + * Stable identity of the agent trajectory that issued this request. Present when the request originates from an agent turn; absent for requests outside any agent context. This is the same identity used by lifecycle and bridged session events and remains constant across turns and retries. */ agentId?: string; /** - * Id of the parent agent that spawned the agent issuing this request. Present only for subagent requests; absent for root-agent requests and non-agent requests. Combined with `agentId`, this lets consumers attribute a call to a child trajectory versus the root. Like `agentId`, it comes from the runtime's per-request agent context independently of transport; on the CAPI transport the runtime derives the upstream `X-Parent-Agent-Id` header from this same context. + * Stable identity of the immediate parent trajectory. Present for child trajectories such as subagents and conversation-sampling requests; absent for root-agent and non-agent requests. */ parentAgentId?: string; + /** + * Identity of the agent invocation (one agentic loop) that issued this request. It remains fixed across physical retries within the invocation and is distinct from the stable trajectory `agentId`. A caller-supplied invocation id always takes precedence (this covers auxiliary calls that have no model call id). Otherwise, first-party CAPI requests fall back to the runtime's agent task id — the same value the runtime emits as the `X-Agent-Task-Id` header — while custom-provider requests fall back to the model call id. + */ + agentInvocationId?: string; /** * Coarse classification of the interaction that produced this request. Open string for forward-compatibility; known values include `conversation-agent`, `conversation-subagent`, `conversation-sampling`, `conversation-background`, `conversation-compaction`, and `conversation-user`. Absent when the runtime did not classify the request. Comes from the runtime's per-request agent context independently of transport; on the CAPI transport the runtime derives the upstream `X-Interaction-Type` header from this same context. */ @@ -7503,7 +7917,7 @@ export interface SessionWorkingDirectoryContext { baseCommit?: string; } /** - * Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). + * Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema * via the `definition` "MetadataRecordContextChangeResult". @@ -11061,6 +11475,14 @@ export interface SandboxConfig { * Whether to auto-add the current working directory to readwritePaths. Default: true. */ addCurrentWorkingDirectory?: boolean; + /** + * Whether to inject the Copilot GitHub token as an `http..extraheader` so authenticated HTTPS git works inside the sandbox without the shell-based credential helper the sandbox blocks. Default: false (opt-in). + */ + gitAuth?: boolean; + /** + * Whether to export `GH_TOKEN` so the `gh` CLI authenticates inside the sandbox without the OS keyring the sandbox blocks. Default: false (opt-in). + */ + ghAuth?: boolean; } /** * User-managed sandbox policy fragment merged into the auto-discovered base policy. @@ -11516,6 +11938,10 @@ export interface ServerSkillList { * All discovered skills across all sources */ skills: ServerSkill[]; + /** + * Messages for skills that failed to load (e.g. malformed SKILL.md). Empty when host skills are excluded so host-local paths are not disclosed to multitenant callers. + */ + errors?: string[]; } /** * Current activity flags for the session. @@ -15346,6 +15772,10 @@ export interface UsageMetricsCodeChanges { export interface UsageMetricsModelMetric { requests: UsageMetricsModelMetricRequests; usage: UsageMetricsModelMetricUsage; + /** + * Latest known prompt-cache expiration for this model. A timestamp in the past indicates that the observed cache has expired. + */ + cacheExpiresAt?: string; /** * Accumulated nano-AI units cost for this model */ @@ -16669,6 +17099,75 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin }, }, /** @experimental */ + factory: { + /** + * Runs a registered factory by name at the top level. + * + * @param params Parameters for invoking a registered factory. + * + * @returns Complete current or terminal factory run envelope. + */ + run: async (params: FactoryRunRequest): Promise => + connection.sendRequest("session.factory.run", { sessionId, ...params }), + /** + * Gets the current or settled envelope for a factory run. + * + * @param params Parameters for retrieving a factory run. + * + * @returns Complete current or terminal factory run envelope. + */ + getRun: async (params: FactoryGetRunRequest): Promise => + connection.sendRequest("session.factory.getRun", { sessionId, ...params }), + /** + * Requests cancellation of a factory run and returns its run envelope. + * + * @param params Parameters for cancelling a factory run. + * + * @returns Complete current or terminal factory run envelope. + */ + cancel: async (params: FactoryCancelRequest): Promise => + connection.sendRequest("session.factory.cancel", { sessionId, ...params }), + /** + * Records a batch of ordered factory progress lines. + * + * @param params Parameters for recording factory progress. + * + * @returns Acknowledgement that a factory request was accepted. + */ + log: async (params: FactoryLogRequest): Promise => + connection.sendRequest("session.factory.log", { sessionId, ...params }), + /** + * Runs one factory-scoped subagent and returns its result. + * + * @param params Parameters for one factory-scoped subagent call. + * + * @returns Result of one factory-scoped subagent call. + */ + agent: async (params: FactoryAgentRequest): Promise => + connection.sendRequest("session.factory.agent", { sessionId, ...params }), + /** @experimental */ + journal: { + /** + * Reads a memoized factory journal entry. + * + * @param params Parameters for reading a factory journal entry. + * + * @returns Result of reading a factory journal entry. + */ + get: async (params: FactoryJournalGetRequest): Promise => + connection.sendRequest("session.factory.journal.get", { sessionId, ...params }), + /** + * Stores a memoized factory journal entry. + * + * @param params Parameters for storing a factory journal entry. + * + * @returns Acknowledgement that a factory request was accepted. + */ + put: async (params: FactoryJournalPutRequest): Promise => + connection.sendRequest("session.factory.journal.put", { sessionId, ...params }), + }, + }, + /** @experimental */ model: { /** * Gets the currently selected model for the session. @@ -17835,11 +18334,11 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin getContextHeaviestMessages: async (params: MetadataContextHeaviestMessagesRequest): Promise => connection.sendRequest("session.metadata.getContextHeaviestMessages", { sessionId, ...params }), /** - * Records a working-directory/git context change and emits a `session.context_changed` event. + * Records a working-directory/git context change and emits a `session.context_changed` event. For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event): a local session's working directory is authoritative and is moved via `metadata.setWorkingDirectory` (or an SDK `session.resume` that supplies a `workingDirectory`), not by this method. * * @param params Updated working-directory/git context to record on the session. * - * @returns Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). + * @returns Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead. */ recordContextChange: async (params: MetadataRecordContextChangeRequest): Promise => connection.sendRequest("session.metadata.recordContextChange", { sessionId, ...params }), @@ -18156,6 +18655,27 @@ export interface ProviderTokenHandler { getToken(params: ProviderTokenAcquireRequest): Promise; } +/** Handler for `factory` client session API methods. */ +/** @experimental */ +export interface FactoryHandler { + /** + * Asks the owning extension connection to execute a registered factory closure. + * + * @param params Parameters sent to the owning extension to execute a factory closure. + * + * @returns Result returned by an extension factory closure. + */ + execute(params: FactoryExecuteRequest): Promise; + /** + * Asks the owning extension connection to abort a running factory cooperatively. + * + * @param params Parameters for cooperatively aborting a factory body. + * + * @returns Acknowledgement that a factory request was accepted. + */ + abort(params: FactoryAbortRequest): Promise; +} + /** Handler for `sessionFs` client session API methods. */ /** @experimental */ export interface SessionFsHandler { @@ -18287,6 +18807,7 @@ export interface CanvasHandler { /** All client session API handler groups. */ export interface ClientSessionApiHandlers { providerToken?: ProviderTokenHandler; + factory?: FactoryHandler; sessionFs?: SessionFsHandler; canvas?: CanvasHandler; } @@ -18306,6 +18827,16 @@ export function registerClientSessionApiHandlers( if (!handler) throw new Error(`No providerToken handler registered for session: ${params.sessionId}`); return handler.getToken(params); }); + connection.onRequest("factory.execute", async (params: FactoryExecuteRequest) => { + const handler = getHandlers(params.sessionId).factory; + if (!handler) throw new Error(`No factory handler registered for session: ${params.sessionId}`); + return handler.execute(params); + }); + connection.onRequest("factory.abort", async (params: FactoryAbortRequest) => { + const handler = getHandlers(params.sessionId).factory; + if (!handler) throw new Error(`No factory handler registered for session: ${params.sessionId}`); + return handler.abort(params); + }); connection.onRequest("sessionFs.readFile", async (params: SessionFsReadFileRequest) => { const handler = getHandlers(params.sessionId).sessionFs; if (!handler) throw new Error(`No sessionFs handler registered for session: ${params.sessionId}`); diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts index 7581545a8..b9c9612b8 100644 --- a/nodejs/src/generated/session-events.ts +++ b/nodejs/src/generated/session-events.ts @@ -39,6 +39,7 @@ export type SessionEvent = | UserMessageEvent | PendingMessagesModifiedEvent | AssistantTurnStartEvent + | AssistantTurnRetryEvent | AssistantIntentEvent | AssistantServerToolProgressEvent | AssistantReasoningEvent @@ -52,12 +53,14 @@ export type SessionEvent = | AssistantIdleEvent | AssistantUsageEvent | ModelCallFailureEvent + | ModelCallStartEvent | AbortEvent | ToolUserRequestedEvent | ToolExecutionStartEvent | ToolExecutionPartialResultEvent | ToolExecutionProgressEvent | ToolExecutionCompleteEvent + | ToolSearchActivatedEvent | SkillInvokedEvent | SubagentStartedEvent | SubagentCompletedEvent @@ -94,6 +97,7 @@ export type SessionEvent = | SessionLimitsExhaustedCompletedEvent | AutoModeResolvedEvent | ManagedSettingsResolvedEvent + | ManagedSettingsEnforcedEvent | CommandsChangedEvent | CapabilitiesChangedEvent | ExitPlanModeRequestedEvent @@ -332,6 +336,14 @@ export type ModelCallFailureBadRequestKind = | "bodyless" /** The 400 response carried a structured CAPI error envelope (deterministic validation failure). */ | "structured_error"; +/** + * Boundary that produced a model call failure + */ +export type ModelCallFailureKind = + /** The provider returned an API error response. */ + | "api" + /** The request transport failed before a usable API response completed. */ + | "transport"; /** * Where the failed model call originated */ @@ -342,6 +354,14 @@ export type ModelCallFailureSource = | "subagent" /** Model call from MCP sampling. */ | "mcp_sampling"; +/** + * Transport used for a failed model call + */ +export type ModelCallFailureTransport = + /** HTTP transport, including SSE streams. */ + | "http" + /** WebSocket transport. */ + | "websocket"; /** * Finite reason code describing why the current turn was aborted */ @@ -657,6 +677,26 @@ export type ManagedSettingsResolvedSource = | "device" /** No managed policy is in force (no layer contributed). */ | "none"; +/** + * The category of runtime action that enterprise managed settings governed (blocked or capped) + */ +export type ManagedSettingsEnforcedAction = + /** An attempt to turn on a bypass-permissions ("yolo") escalation was refused or capped because policy disables bypass-permissions mode. */ + "bypass_permissions_blocked"; +/** + * For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused + */ +export type ManagedSettingsEnforcedEscalation = + /** Full allow-all ("/allow-all on") permissions — auto-approving tools, paths, and URLs. */ + | "allow_all" + /** Auto-approval of all tool permission requests. */ + | "approve_all" + /** Advisory auto-approval ("/allow-all auto") mode — keeps normal prompt paths and adds LLM-advised approval, distinct from full allow-all. */ + | "auto_approval" + /** Unrestricted filesystem access outside the session's allowed directories. */ + | "unrestricted_paths" + /** Unrestricted URL fetch access. */ + | "unrestricted_urls"; /** * Exit plan mode action */ @@ -2155,6 +2195,12 @@ export interface UsageCheckpointEvent { * Durable session usage checkpoint for reconstructing aggregate accounting on resume */ export interface UsageCheckpointData { + /** + * Internal per-model prompt-cache state used to restore expiration tracking on resume + * + * @internal + */ + modelCacheState?: UsageCheckpointModelCacheState[]; /** * Session-wide accumulated nano-AI units cost at checkpoint time */ @@ -2166,6 +2212,26 @@ export interface UsageCheckpointData { */ totalPremiumRequests?: number; } +/** + * Internal prompt-cache expiration state for one model + */ +/** @internal */ +export interface UsageCheckpointModelCacheState { + /** + * Latest known prompt-cache expiration + */ + cacheExpiresAt: string; + /** + * Retained cache lifetime in seconds, used to refresh expiration after a cache read + * + * @internal + */ + cacheTtlSeconds: number; + /** + * Model identifier associated with this cache state + */ + modelId: string; +} /** * Session event "session.context_changed". Updated working directory and git context after the change */ @@ -3123,6 +3189,54 @@ export interface AssistantTurnStartData { */ turnId: string; } +/** + * Session event "assistant.turn_retry". Metadata for an additional model inference attempt within an existing assistant turn + */ +/** @internal */ +export interface AssistantTurnRetryEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: AssistantTurnRetryData; + /** + * Always true for events that are transient and not persisted to the session event log on disk. + */ + ephemeral: true; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "assistant.turn_retry". + */ + type: "assistant.turn_retry"; +} +/** + * Metadata for an additional model inference attempt within an existing assistant turn + */ +export interface AssistantTurnRetryData { + /** + * Model identifier used for this retry, when known + */ + model?: string; + /** + * Provider or runtime classification that caused the retry, when known + */ + reason?: string; + /** + * Identifier of the turn whose model inference is being retried + */ + turnId: string; +} /** * Session event "assistant.intent". Agent intent description for current activity or plan */ @@ -3884,6 +3998,10 @@ export interface AssistantUsageData { */ apiCallId?: string; apiEndpoint?: AssistantUsageApiEndpoint; + /** + * Updated prompt-cache expiration for this model call. Present only when the call establishes or refreshes known cache state. + */ + cacheExpiresAt?: string; /** * Number of tokens read from prompt cache */ @@ -4111,6 +4229,7 @@ export interface ModelCallFailureData { * Completion ID from the model provider (e.g., chatcmpl-abc123) */ apiCallId?: string; + apiEndpoint?: AssistantUsageApiEndpoint; badRequestKind?: ModelCallFailureBadRequestKind; /** * Duration of the failed API call in milliseconds @@ -4128,10 +4247,27 @@ export interface ModelCallFailureData { * For HTTP 400 failures only: the `type` from the CAPI error envelope (e.g. 'websocket_error'), a coarser companion to errorCode for envelopes that carry no code. Raw server-controlled string, emitted only through restricted telemetry. Absent for bodyless or non-400 failures. */ errorType?: string; + failureKind?: ModelCallFailureKind; /** * What initiated this API call (e.g., "sub-agent", "mcp-sampling"); absent for user-initiated calls */ initiator?: string; + /** + * Whether the session selected Auto mode for the failed call + */ + isAuto?: boolean; + /** + * Whether the failed call used a bring-your-own-key provider + */ + isByok?: boolean; + /** + * Effective maximum output-token limit for the failed call + */ + maxOutputTokens?: number; + /** + * Effective maximum prompt-token limit for the failed call + */ + maxPromptTokens?: number; /** * Model identifier used for the failed API call */ @@ -4148,6 +4284,10 @@ export interface ModelCallFailureData { quotaSnapshots?: { [k: string]: AssistantUsageQuotaSnapshot | undefined; }; + /** + * Reasoning effort level used for the failed model call, if applicable + */ + reasoningEffort?: string; requestFingerprint?: ModelCallFailureRequestFingerprint; /** * Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation @@ -4158,6 +4298,7 @@ export interface ModelCallFailureData { * HTTP status code from the failed request */ statusCode?: number; + transport?: ModelCallFailureTransport; } /** * Content-free structural summary of the failing request for diagnosing malformed 4xx calls @@ -4192,6 +4333,50 @@ export interface ModelCallFailureRequestFingerprint { */ toolResultMessageCount: number; } +/** + * Session event "model.call_start". Model API dispatch metadata for internal telemetry + */ +/** @internal */ +export interface ModelCallStartEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: ModelCallStartData; + /** + * Always true for events that are transient and not persisted to the session event log on disk. + */ + ephemeral: true; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "model.call_start". + */ + type: "model.call_start"; +} +/** + * Model API dispatch metadata for internal telemetry + */ +export interface ModelCallStartData { + /** + * Model identifier used for this API call, when known + */ + model?: string; + /** + * Identifier of the assistant turn that initiated the model call + */ + turnId: string; +} /** * Session event "abort". Turn abort information including the reason for termination */ @@ -5033,6 +5218,49 @@ export interface ToolExecutionCompleteToolDescriptionMetaUI { */ visibility?: ToolExecutionCompleteToolDescriptionMetaUIVisibility[]; } +/** + * Session event "tool_search.activated". Persisted generic client-side tool activations restored when a session resumes. + */ +export interface ToolSearchActivatedEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: ToolSearchActivatedData; + /** + * When true, the event is transient and not persisted to the session event log on disk + */ + ephemeral?: boolean; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "tool_search.activated". + */ + type: "tool_search.activated"; +} +/** + * Persisted generic client-side tool activations restored when a session resumes. + */ +export interface ToolSearchActivatedData { + /** + * Tool-search strategy that activated the definitions. + */ + strategy: string; + /** + * Names of tool definitions activated by this search invocation. + */ + toolNames: string[]; +} /** * Session event "skill.invoked". Skill invocation details including content, allowed tools, and plugin metadata */ @@ -8037,6 +8265,57 @@ export interface ManagedSettingsResolvedData { }; source: ManagedSettingsResolvedSource; } +/** + * Session event "session.managed_settings_enforced". Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes. + */ +/** @experimental */ +export interface ManagedSettingsEnforcedEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: ManagedSettingsEnforcedData; + /** + * Always true for events that are transient and not persisted to the session event log on disk. + */ + ephemeral: true; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "session.managed_settings_enforced". + */ + type: "session.managed_settings_enforced"; +} +/** + * Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes. + */ +/** @experimental */ +export interface ManagedSettingsEnforcedData { + action: ManagedSettingsEnforcedAction; + escalation?: ManagedSettingsEnforcedEscalation; + /** + * Whether the enforcement was forced by fail-closed handling (managed policy could not be determined) rather than an explicit managed setting. When true, `setting` still names the restriction that was applied. + */ + failClosed: boolean; + /** + * A human-readable explanation of why the action was governed, suitable for surfacing to the user. + */ + message: string; + /** + * The managed setting key responsible for the enforcement (e.g. `permissions.disableBypassPermissionsMode`). + */ + setting: string; +} /** * Session event "commands.changed". SDK command registration change notification */ diff --git a/nodejs/test/e2e/mcp_oauth.e2e.test.ts b/nodejs/test/e2e/mcp_oauth.e2e.test.ts index 0556e857f..5a00526b6 100644 --- a/nodejs/test/e2e/mcp_oauth.e2e.test.ts +++ b/nodejs/test/e2e/mcp_oauth.e2e.test.ts @@ -240,12 +240,15 @@ describe("MCP OAuth host auth", async () => { async () => { const oauthServer = await startOAuthMcpServer(); const serverName = "oauth-cancelled-mcp"; - let authRequest: McpAuthRequest | undefined; + let resolveAuthRequest!: (request: McpAuthRequest) => void; + const authRequest = new Promise((resolve) => { + resolveAuthRequest = resolve; + }); const session = await client.createSession({ onPermissionRequest: approveAll, onMcpAuthRequest: async (request) => { - authRequest = request; + resolveAuthRequest(request); return { kind: "cancelled" }; }, mcpServers: { @@ -262,7 +265,7 @@ describe("MCP OAuth host auth", async () => { await waitForMcpServerStatus(session, serverName, "needs-auth"); - expect(authRequest).toMatchObject({ + expect(await authRequest).toMatchObject({ serverName, reason: "initial", }); diff --git a/nodejs/test/e2e/permissions.e2e.test.ts b/nodejs/test/e2e/permissions.e2e.test.ts index 5ef9206d1..e7c26a293 100644 --- a/nodejs/test/e2e/permissions.e2e.test.ts +++ b/nodejs/test/e2e/permissions.e2e.test.ts @@ -13,7 +13,7 @@ import type { ToolResultObject, } from "../../src/index.js"; import { approveAll, defineTool } from "../../src/index.js"; -import { createSdkTestContext } from "./harness/sdkTestContext.js"; +import { createSdkTestContext, isInProcessTransport } from "./harness/sdkTestContext.js"; import { getFinalAssistantMessage, getNextEventOfType } from "./harness/sdkTestHelper.js"; describe("Permission callbacks", async () => { @@ -408,7 +408,7 @@ describe("Permission callbacks", async () => { await session.disconnect(); }); - it("should deny permission with noresult kind", async () => { + it.skipIf(isInProcessTransport)("should deny permission with noresult kind", async () => { // With no-result, the TypeScript SDK does not send any response to the CLI's permission // request, leaving the tool execution pending. We verify the permission handler fires. let resolvePermissionCalled!: () => void; diff --git a/nodejs/test/e2e/rpc_session_state.e2e.test.ts b/nodejs/test/e2e/rpc_session_state.e2e.test.ts index 7c33d55d6..b137d7a47 100644 --- a/nodejs/test/e2e/rpc_session_state.e2e.test.ts +++ b/nodejs/test/e2e/rpc_session_state.e2e.test.ts @@ -312,7 +312,6 @@ describe("Session-scoped RPC", async () => { it("should call metadata snapshot, setWorkingDirectory, and recordContextChange", async () => { const firstDirectory = createUniqueDirectory(workDir, "rpc-session-state-first"); const secondDirectory = createUniqueDirectory(workDir, "rpc-session-state-second"); - const contextDirectory = createUniqueDirectory(workDir, "rpc-session-state-context"); const branch = `rpc-context-${randomUUID()}`; const session = await client.createSession({ onPermissionRequest: approveAll, @@ -354,7 +353,7 @@ describe("Session-scoped RPC", async () => { ); const context = { - cwd: contextDirectory, + cwd: secondDirectory, gitRoot: firstDirectory, branch, repository: "github/copilot-sdk-e2e", @@ -366,7 +365,7 @@ describe("Session-scoped RPC", async () => { await session.rpc.metadata.recordContextChange({ context }); const event = await contextChanged; - expect(pathsEqual(event.data.cwd, contextDirectory)).toBe(true); + expect(pathsEqual(event.data.cwd, secondDirectory)).toBe(true); expect(pathsEqual(event.data.gitRoot ?? "", firstDirectory)).toBe(true); expect(event.data.branch).toBe(branch); expect(event.data.repository).toBe("github/copilot-sdk-e2e"); diff --git a/nodejs/test/e2e/session.e2e.test.ts b/nodejs/test/e2e/session.e2e.test.ts index 2cb88917e..88fdf4c29 100644 --- a/nodejs/test/e2e/session.e2e.test.ts +++ b/nodejs/test/e2e/session.e2e.test.ts @@ -503,8 +503,10 @@ describe("Sessions", () => { expect(messages.some((m) => m.type === "abort")).toBe(true); // We should be able to send another message - const answer = await session.sendAndWait({ prompt: "What is 2+2?" }); - expect(answer?.data.content).toContain("4"); + const nextAssistantMessage = getNextEventOfType(session, "assistant.message"); + await session.send({ prompt: "What is 2+2?" }); + const answer = await nextAssistantMessage; + expect(answer.data.content).toContain("4"); }); it("should receive session events", async () => { diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index 828eaa3ce..da44a6437 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -2086,6 +2086,335 @@ class ExternalToolTextResultForLlmContentTerminalType(Enum): class KindEnum(Enum): TEXT = "text" +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryAbortRequest: + """Parameters for cooperatively aborting a factory body.""" + + run_id: str + """Factory run identifier.""" + + session_id: str + """Target session identifier""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryAbortRequest': + assert isinstance(obj, dict) + run_id = from_str(obj.get("runId")) + session_id = from_str(obj.get("sessionId")) + return FactoryAbortRequest(run_id, session_id) + + def to_dict(self) -> dict: + result: dict = {} + result["runId"] = from_str(self.run_id) + result["sessionId"] = from_str(self.session_id) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryACKResult: + """Acknowledgement that a factory request was accepted.""" + @staticmethod + def from_dict(obj: Any) -> 'FactoryACKResult': + assert isinstance(obj, dict) + return FactoryACKResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryAgentOptions: + """Options for one factory-scoped subagent call. + + Subagent execution options. + """ + label: str | None = None + """Optional label distinguishing otherwise identical memoized agent calls.""" + + model: str | None = None + """Optional model identifier for the subagent.""" + + schema: Any = None + """Optional JSON Schema for structured agent output.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryAgentOptions': + assert isinstance(obj, dict) + label = from_union([from_str, from_none], obj.get("label")) + model = from_union([from_str, from_none], obj.get("model")) + schema = obj.get("schema") + return FactoryAgentOptions(label, model, schema) + + def to_dict(self) -> dict: + result: dict = {} + if self.label is not None: + result["label"] = from_union([from_str, from_none], self.label) + if self.model is not None: + result["model"] = from_union([from_str, from_none], self.model) + if self.schema is not None: + result["schema"] = self.schema + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryAgentResult: + """Result of one factory-scoped subagent call.""" + + result: Any = None + """Agent result, omitted when the agent produced no result.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryAgentResult': + assert isinstance(obj, dict) + result = obj.get("result") + return FactoryAgentResult(result) + + def to_dict(self) -> dict: + result: dict = {} + if self.result is not None: + result["result"] = self.result + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryCancelRequest: + """Parameters for cancelling a factory run.""" + + run_id: str + """Factory run identifier.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryCancelRequest': + assert isinstance(obj, dict) + run_id = from_str(obj.get("runId")) + return FactoryCancelRequest(run_id) + + def to_dict(self) -> dict: + result: dict = {} + result["runId"] = from_str(self.run_id) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryExecuteRequest: + """Parameters sent to the owning extension to execute a factory closure.""" + + args: Any + """Factory input value.""" + + name: str + """Registered factory name.""" + + run_id: str + """Factory run identifier.""" + + session_id: str + """Target session identifier""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryExecuteRequest': + assert isinstance(obj, dict) + args = obj.get("args") + name = from_str(obj.get("name")) + run_id = from_str(obj.get("runId")) + session_id = from_str(obj.get("sessionId")) + return FactoryExecuteRequest(args, name, run_id, session_id) + + def to_dict(self) -> dict: + result: dict = {} + result["args"] = self.args + result["name"] = from_str(self.name) + result["runId"] = from_str(self.run_id) + result["sessionId"] = from_str(self.session_id) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryExecuteResult: + """Result returned by an extension factory closure.""" + + result: Any + """Factory result value.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryExecuteResult': + assert isinstance(obj, dict) + result = obj.get("result") + return FactoryExecuteResult(result) + + def to_dict(self) -> dict: + result: dict = {} + result["result"] = self.result + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryGetRunRequest: + """Parameters for retrieving a factory run.""" + + run_id: str + """Factory run identifier.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryGetRunRequest': + assert isinstance(obj, dict) + run_id = from_str(obj.get("runId")) + return FactoryGetRunRequest(run_id) + + def to_dict(self) -> dict: + result: dict = {} + result["runId"] = from_str(self.run_id) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryJournalGetRequest: + """Parameters for reading a factory journal entry.""" + + key: str + """Namespaced journal key.""" + + run_id: str + """Factory run identifier.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryJournalGetRequest': + assert isinstance(obj, dict) + key = from_str(obj.get("key")) + run_id = from_str(obj.get("runId")) + return FactoryJournalGetRequest(key, run_id) + + def to_dict(self) -> dict: + result: dict = {} + result["key"] = from_str(self.key) + result["runId"] = from_str(self.run_id) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryJournalGetResult: + """Result of reading a factory journal entry.""" + + hit: bool + """Whether the journal contained the requested key.""" + + result_json: Any = None + """Cached JSON result. The hit field distinguishes a cached JSON null from a miss.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryJournalGetResult': + assert isinstance(obj, dict) + hit = from_bool(obj.get("hit")) + result_json = obj.get("resultJson") + return FactoryJournalGetResult(hit, result_json) + + def to_dict(self) -> dict: + result: dict = {} + result["hit"] = from_bool(self.hit) + if self.result_json is not None: + result["resultJson"] = self.result_json + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryJournalPutRequest: + """Parameters for storing a factory journal entry.""" + + key: str + """Namespaced journal key.""" + + result_json: Any + """JSON result to memoize.""" + + run_id: str + """Factory run identifier.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryJournalPutRequest': + assert isinstance(obj, dict) + key = from_str(obj.get("key")) + result_json = obj.get("resultJson") + run_id = from_str(obj.get("runId")) + return FactoryJournalPutRequest(key, result_json, run_id) + + def to_dict(self) -> dict: + result: dict = {} + result["key"] = from_str(self.key) + result["resultJson"] = self.result_json + result["runId"] = from_str(self.run_id) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +class FactoryLogLineKind(Enum): + """Progress line kind. + + Kind of factory progress line. + """ + LOG = "log" + PHASE = "phase" + +# Experimental: this type is part of an experimental API and may change or be removed. +class FactoryRunFailureKind(Enum): + """Resource ceiling that stopped the run. + + Cumulative resource ceiling that stopped a factory run. + """ + MAX_TOTAL_SUBAGENTS = "maxTotalSubagents" + TIMEOUT = "timeout" + +class FactoryRunFailureType(Enum): + FACTORY_LIMIT_REACHED = "factory_limit_reached" + FACTORY_RESUME_DECLINED = "factory_resume_declined" + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryRunLimits: + """Wire-only per-invocation factory resource ceiling overrides. + + Per-invocation resource ceiling overrides. + """ + max_concurrent_subagents: int | None = None + """Maximum number of factory subagents that may run concurrently.""" + + max_total_subagents: int | None = None + """Maximum total number of factory subagents that may be admitted.""" + + timeout: float | None = None + """Factory active-run timeout in milliseconds.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryRunLimits': + assert isinstance(obj, dict) + max_concurrent_subagents = from_union([from_int, from_none], obj.get("maxConcurrentSubagents")) + max_total_subagents = from_union([from_int, from_none], obj.get("maxTotalSubagents")) + timeout = from_union([from_float, from_none], obj.get("timeout")) + return FactoryRunLimits(max_concurrent_subagents, max_total_subagents, timeout) + + def to_dict(self) -> dict: + result: dict = {} + if self.max_concurrent_subagents is not None: + result["maxConcurrentSubagents"] = from_union([from_int, from_none], self.max_concurrent_subagents) + if self.max_total_subagents is not None: + result["maxTotalSubagents"] = from_union([from_int, from_none], self.max_total_subagents) + if self.timeout is not None: + result["timeout"] = from_union([to_float, from_none], self.timeout) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +class FactoryRunStatus(Enum): + """Current or terminal factory run status. + + Current or terminal state of a factory run. + """ + CANCELLED = "cancelled" + COMPLETED = "completed" + ERROR = "error" + HALTED = "halted" + PENDING = "pending" + RUNNING = "running" + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class FleetStartRequest: @@ -2466,6 +2795,7 @@ class _HookType(Enum): SUBAGENT_START = "subagentStart" SUBAGENT_STOP = "subagentStop" USER_PROMPT_SUBMITTED = "userPromptSubmitted" + USER_PROMPT_TRANSFORMED = "userPromptTransformed" # Internal: this type is an internal SDK API and is not part of the public surface. @dataclass @@ -4153,7 +4483,10 @@ class MetadataRecordContextChangeResult: """Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the - session's normal lifecycle (e.g., after a shell command in interactive mode). + session's normal lifecycle (e.g., after a shell command in interactive mode). For a local + session, a report whose `cwd` diverges from the session's current working directory is + ignored (the call still succeeds but records nothing and emits no event); move a local + session's working directory via `metadata.setWorkingDirectory` instead. """ @staticmethod def from_dict(obj: Any) -> 'MetadataRecordContextChangeResult': @@ -11603,6 +11936,136 @@ def to_dict(self) -> dict: result["runtimeSettingsChanged"] = from_union([from_bool, from_none], self.runtime_settings_changed) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryAgentRequest: + """Parameters for one factory-scoped subagent call.""" + + factory_run_id: str + """Factory run identifier that owns the subagent.""" + + opts: FactoryAgentOptions + """Subagent execution options.""" + + prompt: str + """Prompt to send to the subagent.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryAgentRequest': + assert isinstance(obj, dict) + factory_run_id = from_str(obj.get("factoryRunId")) + opts = FactoryAgentOptions.from_dict(obj.get("opts")) + prompt = from_str(obj.get("prompt")) + return FactoryAgentRequest(factory_run_id, opts, prompt) + + def to_dict(self) -> dict: + result: dict = {} + result["factoryRunId"] = from_str(self.factory_run_id) + result["opts"] = to_class(FactoryAgentOptions, self.opts) + result["prompt"] = from_str(self.prompt) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryLogLine: + """One ordered factory progress line.""" + + kind: FactoryLogLineKind + """Progress line kind.""" + + seq: int + """Monotonic sequence number within the factory run.""" + + text: str + """Progress text.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryLogLine': + assert isinstance(obj, dict) + kind = FactoryLogLineKind(obj.get("kind")) + seq = from_int(obj.get("seq")) + text = from_str(obj.get("text")) + return FactoryLogLine(kind, seq, text) + + def to_dict(self) -> dict: + result: dict = {} + result["kind"] = to_enum(FactoryLogLineKind, self.kind) + result["seq"] = from_int(self.seq) + result["text"] = from_str(self.text) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryRunFailure: + """Machine-readable factory run failure. + + Machine-readable failure details for an errored run. + """ + run_id: str + """Factory run identifier. + + Factory run identifier whose changed limits were declined. + """ + type: FactoryRunFailureType + kind: FactoryRunFailureKind | None = None + """Resource ceiling that stopped the run.""" + + value: float | None = None + """Approved effective ceiling that was reached.""" + + reason: str | None = None + """Human-readable reason the resume did not proceed.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryRunFailure': + assert isinstance(obj, dict) + run_id = from_str(obj.get("runId")) + type = FactoryRunFailureType(obj.get("type")) + kind = from_union([FactoryRunFailureKind, from_none], obj.get("kind")) + value = from_union([from_float, from_none], obj.get("value")) + reason = from_union([from_str, from_none], obj.get("reason")) + return FactoryRunFailure(run_id, type, kind, value, reason) + + def to_dict(self) -> dict: + result: dict = {} + result["runId"] = from_str(self.run_id) + result["type"] = to_enum(FactoryRunFailureType, self.type) + if self.kind is not None: + result["kind"] = from_union([lambda x: to_enum(FactoryRunFailureKind, x), from_none], self.kind) + if self.value is not None: + result["value"] = from_union([to_float, from_none], self.value) + if self.reason is not None: + result["reason"] = from_union([from_str, from_none], self.reason) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class RunOptions: + """Factory invocation options. + + Options controlling factory invocation. + """ + limits: FactoryRunLimits | None = None + """Per-invocation resource ceiling overrides.""" + + resume_from_run_id: str | None = None + """Run identifier whose journal and progress should seed this resumed run.""" + + @staticmethod + def from_dict(obj: Any) -> 'RunOptions': + assert isinstance(obj, dict) + limits = from_union([FactoryRunLimits.from_dict, from_none], obj.get("limits")) + resume_from_run_id = from_union([from_str, from_none], obj.get("resumeFromRunId")) + return RunOptions(limits, resume_from_run_id) + + def to_dict(self) -> dict: + result: dict = {} + if self.limits is not None: + result["limits"] = from_union([lambda x: to_class(FactoryRunLimits, x), from_none], self.limits) + if self.resume_from_run_id is not None: + result["resumeFromRunId"] = from_union([from_str, from_none], self.resume_from_run_id) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class HistoryCompactResult: @@ -12026,16 +12489,18 @@ class LlmInferenceHTTPRequestStartRequest: """Absolute request URL.""" agent_id: str | None = None - """Stable per-agent-instance id attributing this request to a specific agent trajectory. - Present when the request originates from an agent turn; absent for requests issued - outside any agent context (e.g. some SDK callers). A request with an `agentId` but no - `parentAgentId` is a root-agent request; one carrying both is a subagent request. Sourced - from the runtime's per-request agent context and surfaced on the envelope independently - of transport, so it is available for both first-party (CAPI) and BYOK/custom-provider - requests; on the CAPI transport the runtime derives the upstream `X-Agent-Task-Id` header - from this same context. Consumers routing each provider call to a training trajectory - should key on this rather than on lifecycle events, since it is available on the request - path before sampling. + """Stable identity of the agent trajectory that issued this request. Present when the + request originates from an agent turn; absent for requests outside any agent context. + This is the same identity used by lifecycle and bridged session events and remains + constant across turns and retries. + """ + agent_invocation_id: str | None = None + """Identity of the agent invocation (one agentic loop) that issued this request. It remains + fixed across physical retries within the invocation and is distinct from the stable + trajectory `agentId`. A caller-supplied invocation id always takes precedence (this + covers auxiliary calls that have no model call id). Otherwise, first-party CAPI requests + fall back to the runtime's agent task id — the same value the runtime emits as the + `X-Agent-Task-Id` header — while custom-provider requests fall back to the model call id. """ interaction_type: str | None = None """Coarse classification of the interaction that produced this request. Open string for @@ -12047,12 +12512,9 @@ class LlmInferenceHTTPRequestStartRequest: header from this same context. """ parent_agent_id: str | None = None - """Id of the parent agent that spawned the agent issuing this request. Present only for - subagent requests; absent for root-agent requests and non-agent requests. Combined with - `agentId`, this lets consumers attribute a call to a child trajectory versus the root. - Like `agentId`, it comes from the runtime's per-request agent context independently of - transport; on the CAPI transport the runtime derives the upstream `X-Parent-Agent-Id` - header from this same context. + """Stable identity of the immediate parent trajectory. Present for child trajectories such + as subagents and conversation-sampling requests; absent for root-agent and non-agent + requests. """ session_id: str | None = None """Id of the runtime session that triggered this request, when one is in scope. Absent for @@ -12077,11 +12539,12 @@ def from_dict(obj: Any) -> 'LlmInferenceHTTPRequestStartRequest': request_id = from_str(obj.get("requestId")) url = from_str(obj.get("url")) agent_id = from_union([from_str, from_none], obj.get("agentId")) + agent_invocation_id = from_union([from_str, from_none], obj.get("agentInvocationId")) interaction_type = from_union([from_str, from_none], obj.get("interactionType")) parent_agent_id = from_union([from_str, from_none], obj.get("parentAgentId")) session_id = from_union([from_str, from_none], obj.get("sessionId")) transport = from_union([LlmInferenceHTTPRequestStartTransport, from_none], obj.get("transport")) - return LlmInferenceHTTPRequestStartRequest(headers, method, request_id, url, agent_id, interaction_type, parent_agent_id, session_id, transport) + return LlmInferenceHTTPRequestStartRequest(headers, method, request_id, url, agent_id, agent_invocation_id, interaction_type, parent_agent_id, session_id, transport) def to_dict(self) -> dict: result: dict = {} @@ -12091,6 +12554,8 @@ def to_dict(self) -> dict: result["url"] = from_str(self.url) if self.agent_id is not None: result["agentId"] = from_union([from_str, from_none], self.agent_id) + if self.agent_invocation_id is not None: + result["agentInvocationId"] = from_union([from_str, from_none], self.agent_invocation_id) if self.interaction_type is not None: result["interactionType"] = from_union([from_str, from_none], self.interaction_type) if self.parent_agent_id is not None: @@ -16280,15 +16745,23 @@ class ServerSkillList: skills: list[ServerSkill] """All discovered skills across all sources""" + errors: list[str] | None = None + """Messages for skills that failed to load (e.g. malformed SKILL.md). Empty when host skills + are excluded so host-local paths are not disclosed to multitenant callers. + """ + @staticmethod def from_dict(obj: Any) -> 'ServerSkillList': assert isinstance(obj, dict) skills = from_list(ServerSkill.from_dict, obj.get("skills")) - return ServerSkillList(skills) + errors = from_union([lambda x: from_list(from_str, x), from_none], obj.get("errors")) + return ServerSkillList(skills, errors) def to_dict(self) -> dict: result: dict = {} result["skills"] = from_list(lambda x: to_class(ServerSkill, x), self.skills) + if self.errors is not None: + result["errors"] = from_union([lambda x: from_list(from_str, x), from_none], self.errors) return result # Experimental: this type is part of an experimental API and may change or be removed. @@ -17953,6 +18426,10 @@ class UsageMetricsModelMetric: usage: UsageMetricsModelMetricUsage """Token usage metrics for this model""" + cache_expires_at: datetime | None = None + """Latest known prompt-cache expiration for this model. A timestamp in the past indicates + that the observed cache has expired. + """ token_details: dict[str, UsageMetricsModelMetricTokenDetail] | None = None """Token count details per type""" @@ -17964,14 +18441,17 @@ def from_dict(obj: Any) -> 'UsageMetricsModelMetric': assert isinstance(obj, dict) requests = UsageMetricsModelMetricRequests.from_dict(obj.get("requests")) usage = UsageMetricsModelMetricUsage.from_dict(obj.get("usage")) + cache_expires_at = from_union([from_datetime, from_none], obj.get("cacheExpiresAt")) token_details = from_union([lambda x: from_dict(UsageMetricsModelMetricTokenDetail.from_dict, x), from_none], obj.get("tokenDetails")) total_nano_aiu = from_union([from_float, from_none], obj.get("totalNanoAiu")) - return UsageMetricsModelMetric(requests, usage, token_details, total_nano_aiu) + return UsageMetricsModelMetric(requests, usage, cache_expires_at, token_details, total_nano_aiu) def to_dict(self) -> dict: result: dict = {} result["requests"] = to_class(UsageMetricsModelMetricRequests, self.requests) result["usage"] = to_class(UsageMetricsModelMetricUsage, self.usage) + if self.cache_expires_at is not None: + result["cacheExpiresAt"] = from_union([lambda x: x.isoformat(), from_none], self.cache_expires_at) if self.token_details is not None: result["tokenDetails"] = from_union([lambda x: from_dict(lambda x: to_class(UsageMetricsModelMetricTokenDetail, x), x), from_none], self.token_details) if self.total_nano_aiu is not None: @@ -18652,6 +19132,114 @@ def to_dict(self) -> dict: result["title"] = from_union([from_str, from_none], self.title) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryLogRequest: + """Parameters for recording factory progress.""" + + lines: list[FactoryLogLine] + """Ordered progress lines to append.""" + + run_id: str + """Factory run identifier.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryLogRequest': + assert isinstance(obj, dict) + lines = from_list(FactoryLogLine.from_dict, obj.get("lines")) + run_id = from_str(obj.get("runId")) + return FactoryLogRequest(lines, run_id) + + def to_dict(self) -> dict: + result: dict = {} + result["lines"] = from_list(lambda x: to_class(FactoryLogLine, x), self.lines) + result["runId"] = from_str(self.run_id) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryRunResult: + """Complete current or terminal factory run envelope.""" + + run_id: str + """Factory run identifier.""" + + status: FactoryRunStatus + """Current or terminal factory run status.""" + + error: str | None = None + """Error message for an errored run.""" + + failure: FactoryRunFailure | None = None + """Machine-readable failure details for an errored run.""" + + reason: str | None = None + """Reason for a halted or cancelled run.""" + + result: Any = None + """Completed factory result.""" + + snapshot: Any = None + """Partial journal and progress snapshot for a halted, cancelled, or errored run.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryRunResult': + assert isinstance(obj, dict) + run_id = from_str(obj.get("runId")) + status = FactoryRunStatus(obj.get("status")) + error = from_union([from_str, from_none], obj.get("error")) + failure = from_union([FactoryRunFailure.from_dict, from_none], obj.get("failure")) + reason = from_union([from_str, from_none], obj.get("reason")) + result = obj.get("result") + snapshot = obj.get("snapshot") + return FactoryRunResult(run_id, status, error, failure, reason, result, snapshot) + + def to_dict(self) -> dict: + result: dict = {} + result["runId"] = from_str(self.run_id) + result["status"] = to_enum(FactoryRunStatus, self.status) + if self.error is not None: + result["error"] = from_union([from_str, from_none], self.error) + if self.failure is not None: + result["failure"] = from_union([lambda x: to_class(FactoryRunFailure, x), from_none], self.failure) + if self.reason is not None: + result["reason"] = from_union([from_str, from_none], self.reason) + if self.result is not None: + result["result"] = self.result + if self.snapshot is not None: + result["snapshot"] = self.snapshot + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class FactoryRunRequest: + """Parameters for invoking a registered factory.""" + + args: Any + """Factory input value.""" + + name: str + """Registered factory name.""" + + options: RunOptions | None = None + """Factory invocation options.""" + + @staticmethod + def from_dict(obj: Any) -> 'FactoryRunRequest': + assert isinstance(obj, dict) + args = obj.get("args") + name = from_str(obj.get("name")) + options = from_union([RunOptions.from_dict, from_none], obj.get("options")) + return FactoryRunRequest(args, name, options) + + def to_dict(self) -> dict: + result: dict = {} + result["args"] = self.args + result["name"] = from_str(self.name) + if self.options is not None: + result["options"] = from_union([lambda x: to_class(RunOptions, x), from_none], self.options) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class InstalledPlugin: @@ -21548,6 +22136,15 @@ class SandboxConfig: add_current_working_directory: bool | None = None """Whether to auto-add the current working directory to readwritePaths. Default: true.""" + gh_auth: bool | None = None + """Whether to export `GH_TOKEN` so the `gh` CLI authenticates inside the sandbox without the + OS keyring the sandbox blocks. Default: false (opt-in). + """ + git_auth: bool | None = None + """Whether to inject the Copilot GitHub token as an `http..extraheader` so + authenticated HTTPS git works inside the sandbox without the shell-based credential + helper the sandbox blocks. Default: false (opt-in). + """ user_policy: SandboxConfigUserPolicy | None = None """User-managed sandbox policy fragment merged into the auto-discovered base policy.""" @@ -21556,14 +22153,20 @@ def from_dict(obj: Any) -> 'SandboxConfig': assert isinstance(obj, dict) enabled = from_bool(obj.get("enabled")) add_current_working_directory = from_union([from_bool, from_none], obj.get("addCurrentWorkingDirectory")) + gh_auth = from_union([from_bool, from_none], obj.get("ghAuth")) + git_auth = from_union([from_bool, from_none], obj.get("gitAuth")) user_policy = from_union([SandboxConfigUserPolicy.from_dict, from_none], obj.get("userPolicy")) - return SandboxConfig(enabled, add_current_working_directory, user_policy) + return SandboxConfig(enabled, add_current_working_directory, gh_auth, git_auth, user_policy) def to_dict(self) -> dict: result: dict = {} result["enabled"] = from_bool(self.enabled) if self.add_current_working_directory is not None: result["addCurrentWorkingDirectory"] = from_union([from_bool, from_none], self.add_current_working_directory) + if self.gh_auth is not None: + result["ghAuth"] = from_union([from_bool, from_none], self.gh_auth) + if self.git_auth is not None: + result["gitAuth"] = from_union([from_bool, from_none], self.git_auth) if self.user_policy is not None: result["userPolicy"] = from_union([lambda x: to_class(SandboxConfigUserPolicy, x), from_none], self.user_policy) return result @@ -24489,6 +25092,27 @@ class RPC: external_tool_text_result_for_llm_content_shell_exit: ExternalToolTextResultForLlmContentShellExit external_tool_text_result_for_llm_content_terminal: ExternalToolTextResultForLlmContentTerminal external_tool_text_result_for_llm_content_text: ExternalToolTextResultForLlmContentText + factory_abort_request: FactoryAbortRequest + factory_ack_result: FactoryACKResult + factory_agent_options: FactoryAgentOptions + factory_agent_request: FactoryAgentRequest + factory_agent_result: FactoryAgentResult + factory_cancel_request: FactoryCancelRequest + factory_execute_request: FactoryExecuteRequest + factory_execute_result: FactoryExecuteResult + factory_get_run_request: FactoryGetRunRequest + factory_journal_get_request: FactoryJournalGetRequest + factory_journal_get_result: FactoryJournalGetResult + factory_journal_put_request: FactoryJournalPutRequest + factory_log_line: FactoryLogLine + factory_log_line_kind: FactoryLogLineKind + factory_log_request: FactoryLogRequest + factory_run_failure: FactoryRunFailure + factory_run_failure_kind: FactoryRunFailureKind + factory_run_limits: FactoryRunLimits + factory_run_request: FactoryRunRequest + factory_run_result: FactoryRunResult + factory_run_status: FactoryRunStatus filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode fleet_start_request: FleetStartRequest fleet_start_result: FleetStartResult @@ -24895,6 +25519,7 @@ class RPC: remote_session_metadata_value: RemoteSessionMetadataValue remote_session_mode: RemoteSessionMode remote_session_repository: RemoteSessionRepository + run_options: RunOptions sandbox_config: SandboxConfig sandbox_config_user_policy: SandboxConfigUserPolicy sandbox_config_user_policy_experimental: SandboxConfigUserPolicyExperimental @@ -25340,6 +25965,27 @@ def from_dict(obj: Any) -> 'RPC': external_tool_text_result_for_llm_content_shell_exit = ExternalToolTextResultForLlmContentShellExit.from_dict(obj.get("ExternalToolTextResultForLlmContentShellExit")) 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")) + factory_abort_request = FactoryAbortRequest.from_dict(obj.get("FactoryAbortRequest")) + factory_ack_result = FactoryACKResult.from_dict(obj.get("FactoryAckResult")) + factory_agent_options = FactoryAgentOptions.from_dict(obj.get("FactoryAgentOptions")) + factory_agent_request = FactoryAgentRequest.from_dict(obj.get("FactoryAgentRequest")) + factory_agent_result = FactoryAgentResult.from_dict(obj.get("FactoryAgentResult")) + factory_cancel_request = FactoryCancelRequest.from_dict(obj.get("FactoryCancelRequest")) + factory_execute_request = FactoryExecuteRequest.from_dict(obj.get("FactoryExecuteRequest")) + factory_execute_result = FactoryExecuteResult.from_dict(obj.get("FactoryExecuteResult")) + factory_get_run_request = FactoryGetRunRequest.from_dict(obj.get("FactoryGetRunRequest")) + factory_journal_get_request = FactoryJournalGetRequest.from_dict(obj.get("FactoryJournalGetRequest")) + factory_journal_get_result = FactoryJournalGetResult.from_dict(obj.get("FactoryJournalGetResult")) + factory_journal_put_request = FactoryJournalPutRequest.from_dict(obj.get("FactoryJournalPutRequest")) + factory_log_line = FactoryLogLine.from_dict(obj.get("FactoryLogLine")) + factory_log_line_kind = FactoryLogLineKind(obj.get("FactoryLogLineKind")) + factory_log_request = FactoryLogRequest.from_dict(obj.get("FactoryLogRequest")) + factory_run_failure = FactoryRunFailure.from_dict(obj.get("FactoryRunFailure")) + factory_run_failure_kind = FactoryRunFailureKind(obj.get("FactoryRunFailureKind")) + factory_run_limits = FactoryRunLimits.from_dict(obj.get("FactoryRunLimits")) + factory_run_request = FactoryRunRequest.from_dict(obj.get("FactoryRunRequest")) + factory_run_result = FactoryRunResult.from_dict(obj.get("FactoryRunResult")) + factory_run_status = FactoryRunStatus(obj.get("FactoryRunStatus")) 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")) @@ -25746,6 +26392,7 @@ def from_dict(obj: Any) -> 'RPC': remote_session_metadata_value = RemoteSessionMetadataValue.from_dict(obj.get("RemoteSessionMetadataValue")) remote_session_mode = RemoteSessionMode(obj.get("RemoteSessionMode")) remote_session_repository = RemoteSessionRepository.from_dict(obj.get("RemoteSessionRepository")) + run_options = RunOptions.from_dict(obj.get("RunOptions")) sandbox_config = SandboxConfig.from_dict(obj.get("SandboxConfig")) sandbox_config_user_policy = SandboxConfigUserPolicy.from_dict(obj.get("SandboxConfigUserPolicy")) sandbox_config_user_policy_experimental = SandboxConfigUserPolicyExperimental.from_dict(obj.get("SandboxConfigUserPolicyExperimental")) @@ -26048,7 +26695,7 @@ def from_dict(obj: Any) -> 'RPC': subagent_settings = from_union([SubagentSettings.from_dict, from_none], obj.get("SubagentSettings")) task_progress = from_union([TaskProgress.from_dict, from_none], obj.get("TaskProgress")) workspace_summary = from_union([WorkspaceSummary.from_dict, from_none], obj.get("WorkspaceSummary")) - return RPC(abort_request, abort_result, account_all_users, account_get_all_users_result, account_get_current_auth_result, account_get_quota_request, account_get_quota_result, account_login_request, account_login_result, account_logout_request, account_logout_result, account_quota_snapshot, adaptive_thinking_support, agent_discovery_path, agent_discovery_path_list, agent_discovery_path_scope, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_registry_live_target_entry, agent_registry_live_target_entry_attention_kind, agent_registry_live_target_entry_kind, agent_registry_live_target_entry_last_terminal_event, agent_registry_live_target_entry_status, agent_registry_log_capture, agent_registry_log_capture_open_error_reason, agent_registry_spawn_error, agent_registry_spawn_permission_mode, agent_registry_spawn_registry_timeout, agent_registry_spawn_request, agent_registry_spawn_result, agent_registry_spawn_spawned, agent_registry_spawn_validation_error, agent_registry_spawn_validation_error_field, agent_registry_spawn_validation_error_reason, agent_reload_result, agents_discover_request, agent_select_request, agent_select_result, agents_get_discovery_paths_request, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, cancel_user_requested_shell_command_result, canvas_action, canvas_action_invoke_request, canvas_action_invoke_result, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, canvas_session_context, capi_session_options, 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, completions_get_trigger_characters_result, completions_request_request, completions_request_result, configure_session_extensions_params, 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, context_heaviest_message, copilot_api_token_auth_info, copilot_user_response, copilot_user_response_endpoints, copilot_user_response_quota_snapshots, copilot_user_response_quota_snapshots_chat, copilot_user_response_quota_snapshots_completions, copilot_user_response_quota_snapshots_premium_interactions, current_model, current_tool_metadata, debug_collect_logs_collected_entry, debug_collect_logs_destination, debug_collect_logs_entry, debug_collect_logs_entry_kind, debug_collect_logs_include, debug_collect_logs_redaction, debug_collect_logs_request, debug_collect_logs_result, debug_collect_logs_result_kind, debug_collect_logs_skipped_entry, debug_collect_logs_source, discovered_canvas, discovered_mcp_server, discovered_mcp_server_type, enqueue_command_params, enqueue_command_result, env_auth_info, event_log_read_request, event_log_release_interest_result, event_log_tail_result, event_log_types, events_agent_scope, events_cursor_status, events_read_result, execute_command_params, execute_command_result, extension, extension_context_push_input, 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_shell_exit, external_tool_text_result_for_llm_content_terminal, external_tool_text_result_for_llm_content_text, filter_mapping, fleet_start_request, fleet_start_result, folder_trust_add_params, folder_trust_check_params, folder_trust_check_result, gh_cli_auth_info, git_hub_telemetry_client_info, git_hub_telemetry_event, git_hub_telemetry_notification, handle_pending_tool_call_request, handle_pending_tool_call_result, history_abort_manual_compaction_result, history_cancel_background_compaction_result, history_compact_context_window, history_compact_request, history_compact_result, history_summarize_for_handoff_result, history_truncate_request, history_truncate_result, hmac_auth_info, hook_invoke_request, hook_invoke_response, hook_type, installed_plugin, installed_plugin_info, installed_plugin_source, installed_plugin_source_git_hub, installed_plugin_source_local, installed_plugin_source_url, instruction_discovery_path, instruction_discovery_path_kind, instruction_discovery_path_list, instruction_discovery_path_location, instructions_discover_request, instructions_get_discovery_paths_request, instructions_get_sources_result, instruction_source, instruction_source_location, instruction_source_type, llm_inference_headers, llm_inference_http_request_chunk_request, llm_inference_http_request_chunk_result, llm_inference_http_request_start_request, llm_inference_http_request_start_result, llm_inference_http_request_start_transport, llm_inference_http_response_chunk_error, llm_inference_http_response_chunk_request, llm_inference_http_response_chunk_result, llm_inference_http_response_start_request, llm_inference_http_response_start_result, llm_inference_set_provider_result, local_session_metadata_value, log_request, log_result, lsp_initialize_request, marketplace_add_result, marketplace_browse_result, marketplace_info, marketplace_list_result, marketplace_plugin_info, marketplace_refresh_entry, marketplace_refresh_result, marketplace_remove_result, mcp_allowed_server, mcp_apps_call_tool_request, mcp_apps_diagnose_capability, mcp_apps_diagnose_request, mcp_apps_diagnose_result, mcp_apps_diagnose_server, mcp_apps_host_context, mcp_apps_host_context_details, mcp_apps_host_context_details_available_display_mode, mcp_apps_host_context_details_display_mode, mcp_apps_host_context_details_platform, mcp_apps_host_context_details_theme, mcp_apps_list_tools_request, mcp_apps_list_tools_result, mcp_apps_read_resource_request, mcp_apps_read_resource_result, mcp_apps_resource_content, mcp_apps_set_host_context_details, mcp_apps_set_host_context_details_available_display_mode, mcp_apps_set_host_context_details_display_mode, mcp_apps_set_host_context_details_platform, mcp_apps_set_host_context_details_theme, mcp_apps_set_host_context_request, mcp_cancel_sampling_execution_params, mcp_cancel_sampling_execution_result, mcp_config_add_request, mcp_config_disable_request, mcp_config_enable_request, mcp_config_list, mcp_config_remove_request, mcp_config_update_request, mcp_configure_git_hub_request, mcp_configure_git_hub_result, mcp_disable_request, mcp_discover_request, mcp_discover_result, mcp_enable_request, mcp_execute_sampling_params, mcp_execute_sampling_request, mcp_execute_sampling_result, mcp_filtered_server, mcp_headers_handle_pending_headers_refresh_request, mcp_headers_handle_pending_headers_refresh_request_request, mcp_headers_handle_pending_headers_refresh_request_result, mcp_host_state, mcp_is_server_running_request, mcp_is_server_running_result, mcp_list_tools_request, mcp_list_tools_result, mcp_oauth_handle_pending_request, mcp_oauth_handle_pending_result, mcp_oauth_login_grant_type, mcp_oauth_login_request, mcp_oauth_login_result, mcp_oauth_pending_request_response, mcp_register_external_client_request, mcp_reload_with_config_request, mcp_remove_git_hub_result, mcp_resource, mcp_resource_annotations, mcp_resource_content, mcp_resource_icon, mcp_resources_list_request, mcp_resources_list_result, mcp_resources_list_templates_request, mcp_resources_list_templates_result, mcp_resources_read_request, mcp_resources_read_result, mcp_resource_template, mcp_restart_server_request, mcp_sampling_execution_action, mcp_sampling_execution_result, mcp_server, mcp_server_auth_config, mcp_server_auth_config_redirect_port, mcp_server_config, mcp_server_config_defer_tools, mcp_server_config_http, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_failure_info, mcp_server_list, mcp_server_needs_auth_info, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, mcp_start_server_request, mcp_start_servers_result, mcp_stop_server_request, mcp_tools, mcp_tool_ui, mcp_tool_ui_visibility, mcp_unregister_external_client_request, memory_configuration, metadata_context_attribution_result, metadata_context_heaviest_messages_request, metadata_context_heaviest_messages_result, metadata_context_info_request, metadata_context_info_result, metadata_is_processing_result, metadata_recompute_context_tokens_request, metadata_recompute_context_tokens_result, metadata_record_context_change_request, metadata_record_context_change_result, metadata_set_working_directory_request, metadata_set_working_directory_result, metadata_snapshot_current_mode, metadata_snapshot_remote_metadata, metadata_snapshot_remote_metadata_repository, metadata_snapshot_remote_metadata_task_type, model, model_billing, model_billing_promo, model_billing_token_prices, model_billing_token_prices_long_context, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_list_request, model_picker_category, model_picker_price_category, model_policy, model_policy_state, model_set_reasoning_effort_request, model_set_reasoning_effort_result, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, named_provider_config, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_additional_content_exclusion_policy, options_update_additional_content_exclusion_policy_rule, options_update_additional_content_exclusion_policy_rule_source, options_update_additional_content_exclusion_policy_scope, options_update_context_tier, options_update_env_value_mode, options_update_reasoning_summary, options_update_tool_filter_precedence, pending_permission_request, pending_permission_request_list, permission_decision, permission_decision_approved, permission_decision_approved_for_location, permission_decision_approved_for_session, permission_decision_approve_for_location, permission_decision_approve_for_location_approval, permission_decision_approve_for_location_approval_commands, permission_decision_approve_for_location_approval_custom_tool, permission_decision_approve_for_location_approval_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_cancelled, permission_decision_denied_by_content_exclusion_policy, permission_decision_denied_by_permission_request_hook, permission_decision_denied_by_rules, permission_decision_denied_interactively_by_user, permission_decision_denied_no_approval_rule_and_could_not_request_from_user, permission_decision_reject, permission_decision_request, permission_decision_user_not_available, permission_location_add_tool_approval_params, permission_location_apply_params, permission_location_apply_result, permission_location_resolve_params, permission_location_resolve_result, permission_location_type, permission_paths_add_params, permission_paths_allowed_check_params, permission_paths_allowed_check_result, permission_paths_config, permission_paths_list, permission_paths_update_primary_params, permission_paths_workspace_check_params, permission_paths_workspace_check_result, permission_prompt_shown_notification, permission_request_result, permission_rules_set, permissions_allow_all_mode, permissions_configure_additional_content_exclusion_policy, permissions_configure_additional_content_exclusion_policy_rule, permissions_configure_additional_content_exclusion_policy_rule_source, permissions_configure_additional_content_exclusion_policy_scope, permissions_configure_params, permissions_configure_result, permissions_folder_trust_add_trusted_result, permissions_get_allow_all_request, permissions_locations_add_tool_approval_details, permissions_locations_add_tool_approval_details_commands, permissions_locations_add_tool_approval_details_custom_tool, permissions_locations_add_tool_approval_details_extension_management, permissions_locations_add_tool_approval_details_extension_permission_access, permissions_locations_add_tool_approval_details_mcp, permissions_locations_add_tool_approval_details_mcp_sampling, permissions_locations_add_tool_approval_details_memory, permissions_locations_add_tool_approval_details_read, permissions_locations_add_tool_approval_details_write, permissions_locations_add_tool_approval_result, permissions_modify_rules_params, permissions_modify_rules_result, permissions_modify_rules_scope, permissions_notify_prompt_shown_result, permissions_paths_add_result, permissions_paths_list_request, permissions_paths_update_primary_result, permissions_pending_requests_request, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_allow_all_request, permissions_set_allow_all_source, permissions_set_approve_all_request, permissions_set_approve_all_result, permissions_set_approve_all_source, permissions_set_required_request, permissions_set_required_result, permissions_urls_set_unrestricted_mode_result, permission_urls_config, permission_urls_set_unrestricted_mode_params, ping_request, ping_result, plan_read_result, plan_read_sql_todos_result, plan_read_sql_todos_with_dependencies_result, plan_sql_todo_dependency, plan_sql_todos_row, plan_update_request, plugin, plugin_install_result, plugin_list, plugin_list_result, plugins_disable_request, plugins_enable_request, plugins_install_request, plugins_marketplaces_add_request, plugins_marketplaces_browse_request, plugins_marketplaces_refresh_request, plugins_marketplaces_remove_request, plugins_reload_request, plugins_uninstall_request, plugins_update_request, plugin_update_all_entry, plugin_update_all_result, plugin_update_result, provider_add_request, provider_add_result, provider_config, provider_config_azure, provider_config_transport, provider_config_type, provider_config_wire_api, provider_endpoint, provider_endpoint_transport, provider_endpoint_type, provider_endpoint_wire_api, provider_get_endpoint_request, provider_model_config, provider_session_token, provider_token_acquire_request, provider_token_acquire_result, push_attachment, push_attachment_blob, push_attachment_directory, push_attachment_file, push_attachment_file_line_range, push_attachment_git_hub_actions_job, push_attachment_git_hub_commit, push_attachment_git_hub_file, push_attachment_git_hub_file_diff, push_attachment_git_hub_file_diff_side, push_attachment_git_hub_reference, push_attachment_git_hub_reference_type, push_attachment_git_hub_release, push_attachment_git_hub_repository, push_attachment_git_hub_snippet, push_attachment_git_hub_tree_comparison, push_attachment_git_hub_tree_comparison_side, push_attachment_git_hub_url, push_attachment_selection, push_attachment_selection_details, push_attachment_selection_details_end, push_attachment_selection_details_start, push_git_hub_repo_ref, queued_command_handled, queued_command_not_handled, queued_command_result, queue_pending_items, queue_pending_items_kind, queue_pending_items_result, queue_remove_most_recent_result, register_event_interest_params, register_event_interest_result, register_extension_tools_params, register_extension_tools_result, release_event_interest_params, remote_control_config, remote_control_config_existing_mc_session, remote_control_status, remote_control_status_active, remote_control_status_connecting, remote_control_status_error, remote_control_status_off, remote_control_status_result, remote_control_stop_result, remote_control_transfer_result, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_metadata_repository, remote_session_metadata_task_type, remote_session_metadata_value, remote_session_mode, remote_session_repository, sandbox_config, sandbox_config_user_policy, sandbox_config_user_policy_experimental, sandbox_config_user_policy_experimental_seatbelt, sandbox_config_user_policy_filesystem, sandbox_config_user_policy_network, sandbox_config_user_policy_seatbelt, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachments_to_message_params, send_message_item, send_messages_request, send_messages_result, send_mode, send_request, send_result, server_agent_list, server_instruction_source_list, server_skill, server_skill_list, session_activity, session_auth_status, session_bulk_delete_result, session_capability, session_completion_item, session_context, session_context_host_type, session_enrich_metadata_result, session_fs_append_file_request, session_fs_error, session_fs_error_code, session_fs_exists_request, session_fs_exists_result, session_fs_mkdir_request, session_fs_readdir_request, session_fs_readdir_result, session_fs_readdir_with_types_entry, session_fs_readdir_with_types_entry_type, session_fs_readdir_with_types_request, session_fs_readdir_with_types_result, session_fs_read_file_request, session_fs_read_file_result, session_fs_rename_request, session_fs_rm_request, session_fs_set_provider_capabilities, session_fs_set_provider_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_sqlite_exists_request, session_fs_sqlite_exists_result, session_fs_sqlite_query_request, session_fs_sqlite_query_result, session_fs_sqlite_query_type, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_installed_plugin, session_installed_plugin_source, session_installed_plugin_source_git_hub, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_entry, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata_snapshot, session_mode, session_model_list, session_model_price_category, session_open_options, session_open_options_additional_content_exclusion_policy, session_open_options_additional_content_exclusion_policy_rule, session_open_options_additional_content_exclusion_policy_rule_source, session_open_options_additional_content_exclusion_policy_scope, session_open_options_env_value_mode, session_open_options_reasoning_summary, session_open_params, session_open_result, session_prune_result, sessions_bulk_delete_request, sessions_check_in_use_request, sessions_check_in_use_result, sessions_close_request, sessions_close_result, sessions_enrich_metadata_request, session_set_credentials_params, session_set_credentials_result, session_settings_built_in_tool_availability_snapshot, session_settings_evaluate_predicate_request, session_settings_evaluate_predicate_result, session_settings_job_snapshot, session_settings_model_snapshot, session_settings_online_evaluation_snapshot, session_settings_predicate_name, session_settings_repo_snapshot, session_settings_snapshot, session_settings_validation_snapshot, sessions_find_by_prefix_request, sessions_find_by_prefix_result, sessions_find_by_task_id_request, sessions_find_by_task_id_result, sessions_fork_request, sessions_fork_result, sessions_get_board_entry_count_request, sessions_get_board_entry_count_result, sessions_get_event_file_path_request, sessions_get_event_file_path_result, sessions_get_last_for_context_request, sessions_get_last_for_context_result, sessions_get_persisted_remote_steerable_request, sessions_get_persisted_remote_steerable_result, session_sizes, sessions_list_request, sessions_load_deferred_repo_hooks_request, sessions_open_attach, sessions_open_cloud, sessions_open_create, sessions_open_handoff, sessions_open_handoff_task_type, sessions_open_progress, sessions_open_progress_status, sessions_open_progress_step, sessions_open_remote, sessions_open_resume, sessions_open_resume_last, sessions_open_status, session_source, sessions_prune_old_request, sessions_register_extension_tools_on_session_options, sessions_release_lock_request, sessions_release_lock_result, sessions_reload_plugin_hooks_request, sessions_reload_plugin_hooks_result, sessions_save_request, sessions_save_result, sessions_set_additional_plugins_request, sessions_set_additional_plugins_result, sessions_set_remote_control_steering_request, sessions_start_remote_control_request, sessions_stop_remote_control_request, sessions_transfer_remote_control_request, session_telemetry_engagement, session_update_options_params, session_update_options_result, session_visibility_status, session_working_directory_context, session_working_directory_context_host_type, shell_cancel_user_requested_request, shell_exec_request, shell_exec_result, shell_execute_user_requested_request, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_discovery_path, skill_discovery_path_list, skill_discovery_scope, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_discovery_paths_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_choice, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, subagent_settings_entry, subagent_settings_entry_context_tier, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_get_current_metadata_result, tools_initialize_and_validate_result, tools_list_request, tools_update_subagent_settings_result, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_ephemeral_query_request, ui_ephemeral_query_result, ui_exit_plan_mode_action, ui_exit_plan_mode_response, ui_handle_pending_auto_mode_switch_request, ui_handle_pending_elicitation_request, ui_handle_pending_exit_plan_mode_request, ui_handle_pending_result, ui_handle_pending_sampling_request, ui_handle_pending_sampling_response, ui_handle_pending_session_limits_exhausted_request, ui_handle_pending_user_input_request, ui_register_direct_auto_mode_switch_handler_result, ui_session_limits_exhausted_response, ui_session_limits_exhausted_response_action, ui_unregister_direct_auto_mode_switch_handler_request, ui_unregister_direct_auto_mode_switch_handler_result, ui_user_input_response, update_subagent_settings_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, user_auth_info, user_requested_shell_command_result, user_setting_metadata, user_settings_get_result, user_settings_set_request, user_settings_set_result, visibility_get_result, visibility_set_request, visibility_set_result, workspace_diff_file_change, workspace_diff_file_change_type, workspace_diff_mode, workspace_diff_result, workspaces_checkpoints, workspaces_create_file_request, workspaces_diff_request, workspaces_get_workspace_result, workspaces_list_checkpoints_result, workspaces_list_files_result, workspaces_read_checkpoint_request, workspaces_read_checkpoint_result, workspaces_read_file_request, workspaces_read_file_result, workspaces_save_large_paste_request, workspaces_save_large_paste_result, workspace_summary_host_type, workspaces_workspace_details_host_type, session_context_attribution, session_context_info, subagent_settings, task_progress, workspace_summary) + return RPC(abort_request, abort_result, account_all_users, account_get_all_users_result, account_get_current_auth_result, account_get_quota_request, account_get_quota_result, account_login_request, account_login_result, account_logout_request, account_logout_result, account_quota_snapshot, adaptive_thinking_support, agent_discovery_path, agent_discovery_path_list, agent_discovery_path_scope, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_registry_live_target_entry, agent_registry_live_target_entry_attention_kind, agent_registry_live_target_entry_kind, agent_registry_live_target_entry_last_terminal_event, agent_registry_live_target_entry_status, agent_registry_log_capture, agent_registry_log_capture_open_error_reason, agent_registry_spawn_error, agent_registry_spawn_permission_mode, agent_registry_spawn_registry_timeout, agent_registry_spawn_request, agent_registry_spawn_result, agent_registry_spawn_spawned, agent_registry_spawn_validation_error, agent_registry_spawn_validation_error_field, agent_registry_spawn_validation_error_reason, agent_reload_result, agents_discover_request, agent_select_request, agent_select_result, agents_get_discovery_paths_request, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, cancel_user_requested_shell_command_result, canvas_action, canvas_action_invoke_request, canvas_action_invoke_result, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, canvas_session_context, capi_session_options, 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, completions_get_trigger_characters_result, completions_request_request, completions_request_result, configure_session_extensions_params, 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, context_heaviest_message, copilot_api_token_auth_info, copilot_user_response, copilot_user_response_endpoints, copilot_user_response_quota_snapshots, copilot_user_response_quota_snapshots_chat, copilot_user_response_quota_snapshots_completions, copilot_user_response_quota_snapshots_premium_interactions, current_model, current_tool_metadata, debug_collect_logs_collected_entry, debug_collect_logs_destination, debug_collect_logs_entry, debug_collect_logs_entry_kind, debug_collect_logs_include, debug_collect_logs_redaction, debug_collect_logs_request, debug_collect_logs_result, debug_collect_logs_result_kind, debug_collect_logs_skipped_entry, debug_collect_logs_source, discovered_canvas, discovered_mcp_server, discovered_mcp_server_type, enqueue_command_params, enqueue_command_result, env_auth_info, event_log_read_request, event_log_release_interest_result, event_log_tail_result, event_log_types, events_agent_scope, events_cursor_status, events_read_result, execute_command_params, execute_command_result, extension, extension_context_push_input, 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_shell_exit, external_tool_text_result_for_llm_content_terminal, external_tool_text_result_for_llm_content_text, factory_abort_request, factory_ack_result, factory_agent_options, factory_agent_request, factory_agent_result, factory_cancel_request, factory_execute_request, factory_execute_result, factory_get_run_request, factory_journal_get_request, factory_journal_get_result, factory_journal_put_request, factory_log_line, factory_log_line_kind, factory_log_request, factory_run_failure, factory_run_failure_kind, factory_run_limits, factory_run_request, factory_run_result, factory_run_status, filter_mapping, fleet_start_request, fleet_start_result, folder_trust_add_params, folder_trust_check_params, folder_trust_check_result, gh_cli_auth_info, git_hub_telemetry_client_info, git_hub_telemetry_event, git_hub_telemetry_notification, handle_pending_tool_call_request, handle_pending_tool_call_result, history_abort_manual_compaction_result, history_cancel_background_compaction_result, history_compact_context_window, history_compact_request, history_compact_result, history_summarize_for_handoff_result, history_truncate_request, history_truncate_result, hmac_auth_info, hook_invoke_request, hook_invoke_response, hook_type, installed_plugin, installed_plugin_info, installed_plugin_source, installed_plugin_source_git_hub, installed_plugin_source_local, installed_plugin_source_url, instruction_discovery_path, instruction_discovery_path_kind, instruction_discovery_path_list, instruction_discovery_path_location, instructions_discover_request, instructions_get_discovery_paths_request, instructions_get_sources_result, instruction_source, instruction_source_location, instruction_source_type, llm_inference_headers, llm_inference_http_request_chunk_request, llm_inference_http_request_chunk_result, llm_inference_http_request_start_request, llm_inference_http_request_start_result, llm_inference_http_request_start_transport, llm_inference_http_response_chunk_error, llm_inference_http_response_chunk_request, llm_inference_http_response_chunk_result, llm_inference_http_response_start_request, llm_inference_http_response_start_result, llm_inference_set_provider_result, local_session_metadata_value, log_request, log_result, lsp_initialize_request, marketplace_add_result, marketplace_browse_result, marketplace_info, marketplace_list_result, marketplace_plugin_info, marketplace_refresh_entry, marketplace_refresh_result, marketplace_remove_result, mcp_allowed_server, mcp_apps_call_tool_request, mcp_apps_diagnose_capability, mcp_apps_diagnose_request, mcp_apps_diagnose_result, mcp_apps_diagnose_server, mcp_apps_host_context, mcp_apps_host_context_details, mcp_apps_host_context_details_available_display_mode, mcp_apps_host_context_details_display_mode, mcp_apps_host_context_details_platform, mcp_apps_host_context_details_theme, mcp_apps_list_tools_request, mcp_apps_list_tools_result, mcp_apps_read_resource_request, mcp_apps_read_resource_result, mcp_apps_resource_content, mcp_apps_set_host_context_details, mcp_apps_set_host_context_details_available_display_mode, mcp_apps_set_host_context_details_display_mode, mcp_apps_set_host_context_details_platform, mcp_apps_set_host_context_details_theme, mcp_apps_set_host_context_request, mcp_cancel_sampling_execution_params, mcp_cancel_sampling_execution_result, mcp_config_add_request, mcp_config_disable_request, mcp_config_enable_request, mcp_config_list, mcp_config_remove_request, mcp_config_update_request, mcp_configure_git_hub_request, mcp_configure_git_hub_result, mcp_disable_request, mcp_discover_request, mcp_discover_result, mcp_enable_request, mcp_execute_sampling_params, mcp_execute_sampling_request, mcp_execute_sampling_result, mcp_filtered_server, mcp_headers_handle_pending_headers_refresh_request, mcp_headers_handle_pending_headers_refresh_request_request, mcp_headers_handle_pending_headers_refresh_request_result, mcp_host_state, mcp_is_server_running_request, mcp_is_server_running_result, mcp_list_tools_request, mcp_list_tools_result, mcp_oauth_handle_pending_request, mcp_oauth_handle_pending_result, mcp_oauth_login_grant_type, mcp_oauth_login_request, mcp_oauth_login_result, mcp_oauth_pending_request_response, mcp_register_external_client_request, mcp_reload_with_config_request, mcp_remove_git_hub_result, mcp_resource, mcp_resource_annotations, mcp_resource_content, mcp_resource_icon, mcp_resources_list_request, mcp_resources_list_result, mcp_resources_list_templates_request, mcp_resources_list_templates_result, mcp_resources_read_request, mcp_resources_read_result, mcp_resource_template, mcp_restart_server_request, mcp_sampling_execution_action, mcp_sampling_execution_result, mcp_server, mcp_server_auth_config, mcp_server_auth_config_redirect_port, mcp_server_config, mcp_server_config_defer_tools, mcp_server_config_http, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_failure_info, mcp_server_list, mcp_server_needs_auth_info, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, mcp_start_server_request, mcp_start_servers_result, mcp_stop_server_request, mcp_tools, mcp_tool_ui, mcp_tool_ui_visibility, mcp_unregister_external_client_request, memory_configuration, metadata_context_attribution_result, metadata_context_heaviest_messages_request, metadata_context_heaviest_messages_result, metadata_context_info_request, metadata_context_info_result, metadata_is_processing_result, metadata_recompute_context_tokens_request, metadata_recompute_context_tokens_result, metadata_record_context_change_request, metadata_record_context_change_result, metadata_set_working_directory_request, metadata_set_working_directory_result, metadata_snapshot_current_mode, metadata_snapshot_remote_metadata, metadata_snapshot_remote_metadata_repository, metadata_snapshot_remote_metadata_task_type, model, model_billing, model_billing_promo, model_billing_token_prices, model_billing_token_prices_long_context, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_list_request, model_picker_category, model_picker_price_category, model_policy, model_policy_state, model_set_reasoning_effort_request, model_set_reasoning_effort_result, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, named_provider_config, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_additional_content_exclusion_policy, options_update_additional_content_exclusion_policy_rule, options_update_additional_content_exclusion_policy_rule_source, options_update_additional_content_exclusion_policy_scope, options_update_context_tier, options_update_env_value_mode, options_update_reasoning_summary, options_update_tool_filter_precedence, pending_permission_request, pending_permission_request_list, permission_decision, permission_decision_approved, permission_decision_approved_for_location, permission_decision_approved_for_session, permission_decision_approve_for_location, permission_decision_approve_for_location_approval, permission_decision_approve_for_location_approval_commands, permission_decision_approve_for_location_approval_custom_tool, permission_decision_approve_for_location_approval_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_cancelled, permission_decision_denied_by_content_exclusion_policy, permission_decision_denied_by_permission_request_hook, permission_decision_denied_by_rules, permission_decision_denied_interactively_by_user, permission_decision_denied_no_approval_rule_and_could_not_request_from_user, permission_decision_reject, permission_decision_request, permission_decision_user_not_available, permission_location_add_tool_approval_params, permission_location_apply_params, permission_location_apply_result, permission_location_resolve_params, permission_location_resolve_result, permission_location_type, permission_paths_add_params, permission_paths_allowed_check_params, permission_paths_allowed_check_result, permission_paths_config, permission_paths_list, permission_paths_update_primary_params, permission_paths_workspace_check_params, permission_paths_workspace_check_result, permission_prompt_shown_notification, permission_request_result, permission_rules_set, permissions_allow_all_mode, permissions_configure_additional_content_exclusion_policy, permissions_configure_additional_content_exclusion_policy_rule, permissions_configure_additional_content_exclusion_policy_rule_source, permissions_configure_additional_content_exclusion_policy_scope, permissions_configure_params, permissions_configure_result, permissions_folder_trust_add_trusted_result, permissions_get_allow_all_request, permissions_locations_add_tool_approval_details, permissions_locations_add_tool_approval_details_commands, permissions_locations_add_tool_approval_details_custom_tool, permissions_locations_add_tool_approval_details_extension_management, permissions_locations_add_tool_approval_details_extension_permission_access, permissions_locations_add_tool_approval_details_mcp, permissions_locations_add_tool_approval_details_mcp_sampling, permissions_locations_add_tool_approval_details_memory, permissions_locations_add_tool_approval_details_read, permissions_locations_add_tool_approval_details_write, permissions_locations_add_tool_approval_result, permissions_modify_rules_params, permissions_modify_rules_result, permissions_modify_rules_scope, permissions_notify_prompt_shown_result, permissions_paths_add_result, permissions_paths_list_request, permissions_paths_update_primary_result, permissions_pending_requests_request, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_allow_all_request, permissions_set_allow_all_source, permissions_set_approve_all_request, permissions_set_approve_all_result, permissions_set_approve_all_source, permissions_set_required_request, permissions_set_required_result, permissions_urls_set_unrestricted_mode_result, permission_urls_config, permission_urls_set_unrestricted_mode_params, ping_request, ping_result, plan_read_result, plan_read_sql_todos_result, plan_read_sql_todos_with_dependencies_result, plan_sql_todo_dependency, plan_sql_todos_row, plan_update_request, plugin, plugin_install_result, plugin_list, plugin_list_result, plugins_disable_request, plugins_enable_request, plugins_install_request, plugins_marketplaces_add_request, plugins_marketplaces_browse_request, plugins_marketplaces_refresh_request, plugins_marketplaces_remove_request, plugins_reload_request, plugins_uninstall_request, plugins_update_request, plugin_update_all_entry, plugin_update_all_result, plugin_update_result, provider_add_request, provider_add_result, provider_config, provider_config_azure, provider_config_transport, provider_config_type, provider_config_wire_api, provider_endpoint, provider_endpoint_transport, provider_endpoint_type, provider_endpoint_wire_api, provider_get_endpoint_request, provider_model_config, provider_session_token, provider_token_acquire_request, provider_token_acquire_result, push_attachment, push_attachment_blob, push_attachment_directory, push_attachment_file, push_attachment_file_line_range, push_attachment_git_hub_actions_job, push_attachment_git_hub_commit, push_attachment_git_hub_file, push_attachment_git_hub_file_diff, push_attachment_git_hub_file_diff_side, push_attachment_git_hub_reference, push_attachment_git_hub_reference_type, push_attachment_git_hub_release, push_attachment_git_hub_repository, push_attachment_git_hub_snippet, push_attachment_git_hub_tree_comparison, push_attachment_git_hub_tree_comparison_side, push_attachment_git_hub_url, push_attachment_selection, push_attachment_selection_details, push_attachment_selection_details_end, push_attachment_selection_details_start, push_git_hub_repo_ref, queued_command_handled, queued_command_not_handled, queued_command_result, queue_pending_items, queue_pending_items_kind, queue_pending_items_result, queue_remove_most_recent_result, register_event_interest_params, register_event_interest_result, register_extension_tools_params, register_extension_tools_result, release_event_interest_params, remote_control_config, remote_control_config_existing_mc_session, remote_control_status, remote_control_status_active, remote_control_status_connecting, remote_control_status_error, remote_control_status_off, remote_control_status_result, remote_control_stop_result, remote_control_transfer_result, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_metadata_repository, remote_session_metadata_task_type, remote_session_metadata_value, remote_session_mode, remote_session_repository, run_options, sandbox_config, sandbox_config_user_policy, sandbox_config_user_policy_experimental, sandbox_config_user_policy_experimental_seatbelt, sandbox_config_user_policy_filesystem, sandbox_config_user_policy_network, sandbox_config_user_policy_seatbelt, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachments_to_message_params, send_message_item, send_messages_request, send_messages_result, send_mode, send_request, send_result, server_agent_list, server_instruction_source_list, server_skill, server_skill_list, session_activity, session_auth_status, session_bulk_delete_result, session_capability, session_completion_item, session_context, session_context_host_type, session_enrich_metadata_result, session_fs_append_file_request, session_fs_error, session_fs_error_code, session_fs_exists_request, session_fs_exists_result, session_fs_mkdir_request, session_fs_readdir_request, session_fs_readdir_result, session_fs_readdir_with_types_entry, session_fs_readdir_with_types_entry_type, session_fs_readdir_with_types_request, session_fs_readdir_with_types_result, session_fs_read_file_request, session_fs_read_file_result, session_fs_rename_request, session_fs_rm_request, session_fs_set_provider_capabilities, session_fs_set_provider_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_sqlite_exists_request, session_fs_sqlite_exists_result, session_fs_sqlite_query_request, session_fs_sqlite_query_result, session_fs_sqlite_query_type, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_installed_plugin, session_installed_plugin_source, session_installed_plugin_source_git_hub, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_entry, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata_snapshot, session_mode, session_model_list, session_model_price_category, session_open_options, session_open_options_additional_content_exclusion_policy, session_open_options_additional_content_exclusion_policy_rule, session_open_options_additional_content_exclusion_policy_rule_source, session_open_options_additional_content_exclusion_policy_scope, session_open_options_env_value_mode, session_open_options_reasoning_summary, session_open_params, session_open_result, session_prune_result, sessions_bulk_delete_request, sessions_check_in_use_request, sessions_check_in_use_result, sessions_close_request, sessions_close_result, sessions_enrich_metadata_request, session_set_credentials_params, session_set_credentials_result, session_settings_built_in_tool_availability_snapshot, session_settings_evaluate_predicate_request, session_settings_evaluate_predicate_result, session_settings_job_snapshot, session_settings_model_snapshot, session_settings_online_evaluation_snapshot, session_settings_predicate_name, session_settings_repo_snapshot, session_settings_snapshot, session_settings_validation_snapshot, sessions_find_by_prefix_request, sessions_find_by_prefix_result, sessions_find_by_task_id_request, sessions_find_by_task_id_result, sessions_fork_request, sessions_fork_result, sessions_get_board_entry_count_request, sessions_get_board_entry_count_result, sessions_get_event_file_path_request, sessions_get_event_file_path_result, sessions_get_last_for_context_request, sessions_get_last_for_context_result, sessions_get_persisted_remote_steerable_request, sessions_get_persisted_remote_steerable_result, session_sizes, sessions_list_request, sessions_load_deferred_repo_hooks_request, sessions_open_attach, sessions_open_cloud, sessions_open_create, sessions_open_handoff, sessions_open_handoff_task_type, sessions_open_progress, sessions_open_progress_status, sessions_open_progress_step, sessions_open_remote, sessions_open_resume, sessions_open_resume_last, sessions_open_status, session_source, sessions_prune_old_request, sessions_register_extension_tools_on_session_options, sessions_release_lock_request, sessions_release_lock_result, sessions_reload_plugin_hooks_request, sessions_reload_plugin_hooks_result, sessions_save_request, sessions_save_result, sessions_set_additional_plugins_request, sessions_set_additional_plugins_result, sessions_set_remote_control_steering_request, sessions_start_remote_control_request, sessions_stop_remote_control_request, sessions_transfer_remote_control_request, session_telemetry_engagement, session_update_options_params, session_update_options_result, session_visibility_status, session_working_directory_context, session_working_directory_context_host_type, shell_cancel_user_requested_request, shell_exec_request, shell_exec_result, shell_execute_user_requested_request, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_discovery_path, skill_discovery_path_list, skill_discovery_scope, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_discovery_paths_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_choice, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, subagent_settings_entry, subagent_settings_entry_context_tier, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_get_current_metadata_result, tools_initialize_and_validate_result, tools_list_request, tools_update_subagent_settings_result, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_ephemeral_query_request, ui_ephemeral_query_result, ui_exit_plan_mode_action, ui_exit_plan_mode_response, ui_handle_pending_auto_mode_switch_request, ui_handle_pending_elicitation_request, ui_handle_pending_exit_plan_mode_request, ui_handle_pending_result, ui_handle_pending_sampling_request, ui_handle_pending_sampling_response, ui_handle_pending_session_limits_exhausted_request, ui_handle_pending_user_input_request, ui_register_direct_auto_mode_switch_handler_result, ui_session_limits_exhausted_response, ui_session_limits_exhausted_response_action, ui_unregister_direct_auto_mode_switch_handler_request, ui_unregister_direct_auto_mode_switch_handler_result, ui_user_input_response, update_subagent_settings_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, user_auth_info, user_requested_shell_command_result, user_setting_metadata, user_settings_get_result, user_settings_set_request, user_settings_set_result, visibility_get_result, visibility_set_request, visibility_set_result, workspace_diff_file_change, workspace_diff_file_change_type, workspace_diff_mode, workspace_diff_result, workspaces_checkpoints, workspaces_create_file_request, workspaces_diff_request, workspaces_get_workspace_result, workspaces_list_checkpoints_result, workspaces_list_files_result, workspaces_read_checkpoint_request, workspaces_read_checkpoint_result, workspaces_read_file_request, workspaces_read_file_result, workspaces_save_large_paste_request, workspaces_save_large_paste_result, workspace_summary_host_type, workspaces_workspace_details_host_type, session_context_attribution, session_context_info, subagent_settings, task_progress, workspace_summary) def to_dict(self) -> dict: result: dict = {} @@ -26191,6 +26838,27 @@ def to_dict(self) -> dict: result["ExternalToolTextResultForLlmContentShellExit"] = to_class(ExternalToolTextResultForLlmContentShellExit, self.external_tool_text_result_for_llm_content_shell_exit) 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["FactoryAbortRequest"] = to_class(FactoryAbortRequest, self.factory_abort_request) + result["FactoryAckResult"] = to_class(FactoryACKResult, self.factory_ack_result) + result["FactoryAgentOptions"] = to_class(FactoryAgentOptions, self.factory_agent_options) + result["FactoryAgentRequest"] = to_class(FactoryAgentRequest, self.factory_agent_request) + result["FactoryAgentResult"] = to_class(FactoryAgentResult, self.factory_agent_result) + result["FactoryCancelRequest"] = to_class(FactoryCancelRequest, self.factory_cancel_request) + result["FactoryExecuteRequest"] = to_class(FactoryExecuteRequest, self.factory_execute_request) + result["FactoryExecuteResult"] = to_class(FactoryExecuteResult, self.factory_execute_result) + result["FactoryGetRunRequest"] = to_class(FactoryGetRunRequest, self.factory_get_run_request) + result["FactoryJournalGetRequest"] = to_class(FactoryJournalGetRequest, self.factory_journal_get_request) + result["FactoryJournalGetResult"] = to_class(FactoryJournalGetResult, self.factory_journal_get_result) + result["FactoryJournalPutRequest"] = to_class(FactoryJournalPutRequest, self.factory_journal_put_request) + result["FactoryLogLine"] = to_class(FactoryLogLine, self.factory_log_line) + result["FactoryLogLineKind"] = to_enum(FactoryLogLineKind, self.factory_log_line_kind) + result["FactoryLogRequest"] = to_class(FactoryLogRequest, self.factory_log_request) + result["FactoryRunFailure"] = to_class(FactoryRunFailure, self.factory_run_failure) + result["FactoryRunFailureKind"] = to_enum(FactoryRunFailureKind, self.factory_run_failure_kind) + result["FactoryRunLimits"] = to_class(FactoryRunLimits, self.factory_run_limits) + result["FactoryRunRequest"] = to_class(FactoryRunRequest, self.factory_run_request) + result["FactoryRunResult"] = to_class(FactoryRunResult, self.factory_run_result) + result["FactoryRunStatus"] = to_enum(FactoryRunStatus, self.factory_run_status) 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) @@ -26597,6 +27265,7 @@ def to_dict(self) -> dict: result["RemoteSessionMetadataValue"] = to_class(RemoteSessionMetadataValue, self.remote_session_metadata_value) result["RemoteSessionMode"] = to_enum(RemoteSessionMode, self.remote_session_mode) result["RemoteSessionRepository"] = to_class(RemoteSessionRepository, self.remote_session_repository) + result["RunOptions"] = to_class(RunOptions, self.run_options) result["SandboxConfig"] = to_class(SandboxConfig, self.sandbox_config) result["SandboxConfigUserPolicy"] = to_class(SandboxConfigUserPolicy, self.sandbox_config_user_policy) result["SandboxConfigUserPolicyExperimental"] = to_class(SandboxConfigUserPolicyExperimental, self.sandbox_config_user_policy_experimental) @@ -27798,6 +28467,63 @@ async def close(self, params: CanvasCloseRequest, *, timeout: float | None = Non await self._client.request("session.canvas.close", params_dict, **_timeout_kwargs(timeout)) +# Experimental: this API group is experimental and may change or be removed. +class FactoryJournalApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + + async def get(self, params: FactoryJournalGetRequest, *, timeout: float | None = None) -> FactoryJournalGetResult: + "Reads a memoized factory journal entry.\n\nArgs:\n params: Parameters for reading a factory journal entry.\n\nReturns:\n Result of reading a factory journal entry." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return FactoryJournalGetResult.from_dict(await self._client.request("session.factory.journal.get", params_dict, **_timeout_kwargs(timeout))) + + async def put(self, params: FactoryJournalPutRequest, *, timeout: float | None = None) -> FactoryACKResult: + "Stores a memoized factory journal entry.\n\nArgs:\n params: Parameters for storing a factory journal entry.\n\nReturns:\n Acknowledgement that a factory request was accepted." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return FactoryACKResult.from_dict(await self._client.request("session.factory.journal.put", params_dict, **_timeout_kwargs(timeout))) + + +# Experimental: this API group is experimental and may change or be removed. +class FactoryApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + self.journal = FactoryJournalApi(client, session_id) + + async def run(self, params: FactoryRunRequest, *, timeout: float | None = None) -> FactoryRunResult: + "Runs a registered factory by name at the top level.\n\nArgs:\n params: Parameters for invoking a registered factory.\n\nReturns:\n Complete current or terminal factory run envelope." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return FactoryRunResult.from_dict(await self._client.request("session.factory.run", params_dict, **_timeout_kwargs(timeout))) + + async def get_run(self, params: FactoryGetRunRequest, *, timeout: float | None = None) -> FactoryRunResult: + "Gets the current or settled envelope for a factory run.\n\nArgs:\n params: Parameters for retrieving a factory run.\n\nReturns:\n Complete current or terminal factory run envelope." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return FactoryRunResult.from_dict(await self._client.request("session.factory.getRun", params_dict, **_timeout_kwargs(timeout))) + + async def cancel(self, params: FactoryCancelRequest, *, timeout: float | None = None) -> FactoryRunResult: + "Requests cancellation of a factory run and returns its run envelope.\n\nArgs:\n params: Parameters for cancelling a factory run.\n\nReturns:\n Complete current or terminal factory run envelope." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return FactoryRunResult.from_dict(await self._client.request("session.factory.cancel", params_dict, **_timeout_kwargs(timeout))) + + async def log(self, params: FactoryLogRequest, *, timeout: float | None = None) -> FactoryACKResult: + "Records a batch of ordered factory progress lines.\n\nArgs:\n params: Parameters for recording factory progress.\n\nReturns:\n Acknowledgement that a factory request was accepted." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return FactoryACKResult.from_dict(await self._client.request("session.factory.log", params_dict, **_timeout_kwargs(timeout))) + + async def agent(self, params: FactoryAgentRequest, *, timeout: float | None = None) -> FactoryAgentResult: + "Runs one factory-scoped subagent and returns its result.\n\nArgs:\n params: Parameters for one factory-scoped subagent call.\n\nReturns:\n Result of one factory-scoped subagent call." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return FactoryAgentResult.from_dict(await self._client.request("session.factory.agent", params_dict, **_timeout_kwargs(timeout))) + + # Experimental: this API group is experimental and may change or be removed. class ModelApi: def __init__(self, client: "JsonRpcClient", session_id: str): @@ -28733,7 +29459,7 @@ async def get_context_heaviest_messages(self, params: MetadataContextHeaviestMes return MetadataContextHeaviestMessagesResult.from_dict(await self._client.request("session.metadata.getContextHeaviestMessages", params_dict, **_timeout_kwargs(timeout))) async def record_context_change(self, params: MetadataRecordContextChangeRequest, *, timeout: float | None = None) -> MetadataRecordContextChangeResult: - "Records a working-directory/git context change and emits a `session.context_changed` event.\n\nArgs:\n params: Updated working-directory/git context to record on the session.\n\nReturns:\n Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode)." + "Records a working-directory/git context change and emits a `session.context_changed` event. For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event): a local session's working directory is authoritative and is moved via `metadata.setWorkingDirectory` (or an SDK `session.resume` that supplies a `workingDirectory`), not by this method.\n\nArgs:\n params: Updated working-directory/git context to record on the session.\n\nReturns:\n Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead." params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} params_dict["sessionId"] = self._session_id return MetadataRecordContextChangeResult.from_dict(await self._client.request("session.metadata.recordContextChange", params_dict, **_timeout_kwargs(timeout))) @@ -28937,6 +29663,7 @@ def __init__(self, client: "JsonRpcClient", session_id: str): self.git_hub_auth = GitHubAuthApi(client, session_id) self.debug = DebugApi(client, session_id) self.canvas = CanvasApi(client, session_id) + self.factory = FactoryApi(client, session_id) self.model = ModelApi(client, session_id) self.mode = ModeApi(client, session_id) self.name = NameApi(client, session_id) @@ -29067,6 +29794,15 @@ async def get_token(self, params: ProviderTokenAcquireRequest) -> ProviderTokenA "Asks the SDK client to get a bearer token for a BYOK provider whose config set `hasBearerTokenProvider: true`. Session-scoped: the runtime calls it back on the connection that most recently supplied that provider's config for the session (the creating connection, or a resuming connection if the session was resumed — distinct providers may be owned by different connections), passing the provider name, and uses the returned token as the Authorization header for the outbound model request. The runtime does no caching — it calls this once per outbound request; the SDK consumer owns token acquisition, caching, and refresh.\n\nArgs:\n params: Asks the SDK client to acquire a bearer token for a BYOK provider whose config set `hasBearerTokenProvider: true`. Issued by the runtime before each outbound model request; the runtime does no caching, so this is sent once per request.\n\nReturns:\n A bearer token supplied by the SDK client for a BYOK provider. The runtime sets it as `Authorization: Bearer ` on the outbound request and does no caching; the SDK consumer owns token caching and refresh." pass +# Experimental: this API group is experimental and may change or be removed. +class FactoryHandler(Protocol): + async def execute(self, params: FactoryExecuteRequest) -> FactoryExecuteResult: + "Asks the owning extension connection to execute a registered factory closure.\n\nArgs:\n params: Parameters sent to the owning extension to execute a factory closure.\n\nReturns:\n Result returned by an extension factory closure." + pass + async def abort(self, params: FactoryAbortRequest) -> FactoryACKResult: + "Asks the owning extension connection to abort a running factory cooperatively.\n\nArgs:\n params: Parameters for cooperatively aborting a factory body.\n\nReturns:\n Acknowledgement that a factory request was accepted." + pass + # Experimental: this API group is experimental and may change or be removed. class SessionFsHandler(Protocol): async def read_file(self, params: SessionFSReadFileRequest) -> SessionFSReadFileResult: @@ -29121,6 +29857,7 @@ async def invoke(self, params: CanvasProviderInvokeActionRequest) -> Any: @dataclass class ClientSessionApiHandlers: provider_token: ProviderTokenHandler | None = None + factory: FactoryHandler | None = None session_fs: SessionFsHandler | None = None canvas: CanvasHandler | None = None @@ -29136,6 +29873,20 @@ async def handle_provider_token_get_token(params: dict) -> dict | None: result = await handler.get_token(request) return result.to_dict() client.set_request_handler("providerToken.getToken", handle_provider_token_get_token) + async def handle_factory_execute(params: dict) -> dict | None: + request = FactoryExecuteRequest.from_dict(params) + handler = get_handlers(request.session_id).factory + if handler is None: raise RuntimeError(f"No factory handler registered for session: {request.session_id}") + result = await handler.execute(request) + return result.to_dict() + client.set_request_handler("factory.execute", handle_factory_execute) + async def handle_factory_abort(params: dict) -> dict | None: + request = FactoryAbortRequest.from_dict(params) + handler = get_handlers(request.session_id).factory + if handler is None: raise RuntimeError(f"No factory handler registered for session: {request.session_id}") + result = await handler.abort(request) + return result.to_dict() + client.set_request_handler("factory.abort", handle_factory_abort) async def handle_session_fs_read_file(params: dict) -> dict | None: request = SessionFSReadFileRequest.from_dict(params) handler = get_handlers(request.session_id).session_fs @@ -29476,6 +30227,31 @@ async def handle_git_hub_telemetry_event(params: dict) -> None: "ExternalToolTextResultForLlmContentTerminalType", "ExternalToolTextResultForLlmContentText", "ExternalToolTextResultForLlmContentType", + "FactoryACKResult", + "FactoryAbortRequest", + "FactoryAgentOptions", + "FactoryAgentRequest", + "FactoryAgentResult", + "FactoryApi", + "FactoryCancelRequest", + "FactoryExecuteRequest", + "FactoryExecuteResult", + "FactoryGetRunRequest", + "FactoryHandler", + "FactoryJournalApi", + "FactoryJournalGetRequest", + "FactoryJournalGetResult", + "FactoryJournalPutRequest", + "FactoryLogLine", + "FactoryLogLineKind", + "FactoryLogRequest", + "FactoryRunFailure", + "FactoryRunFailureKind", + "FactoryRunFailureType", + "FactoryRunLimits", + "FactoryRunRequest", + "FactoryRunResult", + "FactoryRunStatus", "FilterMapping", "FleetApi", "FleetStartRequest", @@ -29969,6 +30745,7 @@ async def handle_git_hub_telemetry_event(params: dict) -> None: "RemoteSessionMetadataValue", "RemoteSessionMode", "RemoteSessionRepository", + "RunOptions", "SandboxConfig", "SandboxConfigUserPolicy", "SandboxConfigUserPolicyExperimental", diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py index a7c990e16..fecd5839e 100644 --- a/python/copilot/generated/session_events.py +++ b/python/copilot/generated/session_events.py @@ -154,6 +154,7 @@ class SessionEventType(Enum): USER_MESSAGE = "user.message" PENDING_MESSAGES_MODIFIED = "pending_messages.modified" ASSISTANT_TURN_START = "assistant.turn_start" + ASSISTANT_TURN_RETRY = "assistant.turn_retry" ASSISTANT_INTENT = "assistant.intent" ASSISTANT_SERVER_TOOL_PROGRESS = "assistant.server_tool_progress" ASSISTANT_REASONING = "assistant.reasoning" @@ -167,12 +168,14 @@ class SessionEventType(Enum): ASSISTANT_IDLE = "assistant.idle" ASSISTANT_USAGE = "assistant.usage" MODEL_CALL_FAILURE = "model.call_failure" + MODEL_CALL_START = "model.call_start" ABORT = "abort" TOOL_USER_REQUESTED = "tool.user_requested" TOOL_EXECUTION_START = "tool.execution_start" TOOL_EXECUTION_PARTIAL_RESULT = "tool.execution_partial_result" TOOL_EXECUTION_PROGRESS = "tool.execution_progress" TOOL_EXECUTION_COMPLETE = "tool.execution_complete" + TOOL_SEARCH_ACTIVATED = "tool_search.activated" SKILL_INVOKED = "skill.invoked" SUBAGENT_STARTED = "subagent.started" SUBAGENT_COMPLETED = "subagent.completed" @@ -212,6 +215,8 @@ class SessionEventType(Enum): SESSION_AUTO_MODE_RESOLVED = "session.auto_mode_resolved" # Experimental: this event is part of an experimental API and may change or be removed. SESSION_MANAGED_SETTINGS_RESOLVED = "session.managed_settings_resolved" + # Experimental: this event is part of an experimental API and may change or be removed. + SESSION_MANAGED_SETTINGS_ENFORCED = "session.managed_settings_enforced" COMMANDS_CHANGED = "commands.changed" CAPABILITIES_CHANGED = "capabilities.changed" EXIT_PLAN_MODE_REQUESTED = "exit_plan_mode.requested" @@ -1081,6 +1086,43 @@ def to_dict(self) -> dict: return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class SessionManagedSettingsEnforcedData: + "Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes." + action: ManagedSettingsEnforcedAction + fail_closed: bool + message: str + setting: str + escalation: ManagedSettingsEnforcedEscalation | None = None + + @staticmethod + def from_dict(obj: Any) -> "SessionManagedSettingsEnforcedData": + assert isinstance(obj, dict) + action = parse_enum(ManagedSettingsEnforcedAction, obj.get("action")) + fail_closed = from_bool(obj.get("failClosed")) + message = from_str(obj.get("message")) + setting = from_str(obj.get("setting")) + escalation = from_union([from_none, lambda x: parse_enum(ManagedSettingsEnforcedEscalation, x)], obj.get("escalation")) + return SessionManagedSettingsEnforcedData( + action=action, + fail_closed=fail_closed, + message=message, + setting=setting, + escalation=escalation, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["action"] = to_enum(ManagedSettingsEnforcedAction, self.action) + result["failClosed"] = from_bool(self.fail_closed) + result["message"] = from_str(self.message) + result["setting"] = from_str(self.setting) + if self.escalation is not None: + result["escalation"] = from_union([from_none, lambda x: to_enum(ManagedSettingsEnforcedEscalation, x)], self.escalation) + return result + + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class SessionManagedSettingsResolvedData: @@ -1549,6 +1591,35 @@ def to_dict(self) -> dict: return result +@dataclass +class AssistantTurnRetryData: + "Metadata for an additional model inference attempt within an existing assistant turn" + turn_id: str + model: str | None = None + reason: str | None = None + + @staticmethod + def from_dict(obj: Any) -> "AssistantTurnRetryData": + assert isinstance(obj, dict) + turn_id = from_str(obj.get("turnId")) + model = from_union([from_none, from_str], obj.get("model")) + reason = from_union([from_none, from_str], obj.get("reason")) + return AssistantTurnRetryData( + turn_id=turn_id, + model=model, + reason=reason, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["turnId"] = from_str(self.turn_id) + if self.model is not None: + result["model"] = from_union([from_none, from_str], self.model) + if self.reason is not None: + result["reason"] = from_union([from_none, from_str], self.reason) + return result + + @dataclass class AssistantTurnStartData: "Turn initialization metadata including identifier and interaction tracking" @@ -1640,6 +1711,7 @@ class AssistantUsageData: model: str api_call_id: str | None = None api_endpoint: AssistantUsageApiEndpoint | None = None + cache_expires_at: datetime | None = None cache_read_tokens: int | None = None cache_write_tokens: int | None = None content_filter_triggered: bool | None = None @@ -1668,6 +1740,7 @@ def from_dict(obj: Any) -> "AssistantUsageData": model = from_str(obj.get("model")) api_call_id = from_union([from_none, from_str], obj.get("apiCallId")) api_endpoint = from_union([from_none, lambda x: parse_enum(AssistantUsageApiEndpoint, x)], obj.get("apiEndpoint")) + cache_expires_at = from_union([from_none, from_datetime], obj.get("cacheExpiresAt")) cache_read_tokens = from_union([from_none, from_int], obj.get("cacheReadTokens")) cache_write_tokens = from_union([from_none, from_int], obj.get("cacheWriteTokens")) content_filter_triggered = from_union([from_none, from_bool], obj.get("contentFilterTriggered")) @@ -1690,6 +1763,7 @@ def from_dict(obj: Any) -> "AssistantUsageData": model=model, api_call_id=api_call_id, api_endpoint=api_endpoint, + cache_expires_at=cache_expires_at, cache_read_tokens=cache_read_tokens, cache_write_tokens=cache_write_tokens, content_filter_triggered=content_filter_triggered, @@ -1717,6 +1791,8 @@ def to_dict(self) -> dict: result["apiCallId"] = from_union([from_none, from_str], self.api_call_id) if self.api_endpoint is not None: result["apiEndpoint"] = from_union([from_none, lambda x: to_enum(AssistantUsageApiEndpoint, x)], self.api_endpoint) + if self.cache_expires_at is not None: + result["cacheExpiresAt"] = from_union([from_none, to_datetime], self.cache_expires_at) if self.cache_read_tokens is not None: result["cacheReadTokens"] = from_union([from_none, to_int], self.cache_read_tokens) if self.cache_write_tokens is not None: @@ -3862,52 +3938,76 @@ class ModelCallFailureData: "Failed LLM API call metadata for telemetry" source: ModelCallFailureSource api_call_id: str | None = None + api_endpoint: AssistantUsageApiEndpoint | None = None bad_request_kind: ModelCallFailureBadRequestKind | None = None duration: timedelta | None = None error_code: str | None = None error_message: str | None = None error_type: str | None = None + failure_kind: ModelCallFailureKind | None = None initiator: str | None = None + is_auto: bool | None = None + is_byok: bool | None = None + max_output_tokens: int | None = None + max_prompt_tokens: int | None = None model: str | None = None provider_call_id: str | None = None # Internal: this field is an internal SDK API and is not part of the public surface. _quota_snapshots: dict[str, _AssistantUsageQuotaSnapshot] | None = None + reasoning_effort: str | None = None request_fingerprint: ModelCallFailureRequestFingerprint | None = None service_request_id: str | None = None status_code: int | None = None + transport: ModelCallFailureTransport | None = None @staticmethod 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")) + api_endpoint = from_union([from_none, lambda x: parse_enum(AssistantUsageApiEndpoint, x)], obj.get("apiEndpoint")) bad_request_kind = from_union([from_none, lambda x: parse_enum(ModelCallFailureBadRequestKind, x)], obj.get("badRequestKind")) duration = from_union([from_none, from_timedelta], obj.get("durationMs")) error_code = from_union([from_none, from_str], obj.get("errorCode")) error_message = from_union([from_none, from_str], obj.get("errorMessage")) error_type = from_union([from_none, from_str], obj.get("errorType")) + failure_kind = from_union([from_none, lambda x: parse_enum(ModelCallFailureKind, x)], obj.get("failureKind")) initiator = from_union([from_none, from_str], obj.get("initiator")) + is_auto = from_union([from_none, from_bool], obj.get("isAuto")) + is_byok = from_union([from_none, from_bool], obj.get("isByok")) + max_output_tokens = from_union([from_none, from_int], obj.get("maxOutputTokens")) + max_prompt_tokens = from_union([from_none, from_int], obj.get("maxPromptTokens")) model = from_union([from_none, from_str], obj.get("model")) 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")) request_fingerprint = from_union([from_none, ModelCallFailureRequestFingerprint.from_dict], obj.get("requestFingerprint")) service_request_id = from_union([from_none, from_str], obj.get("serviceRequestId")) status_code = from_union([from_none, from_int], obj.get("statusCode")) + transport = from_union([from_none, lambda x: parse_enum(ModelCallFailureTransport, x)], obj.get("transport")) return ModelCallFailureData( source=source, api_call_id=api_call_id, + api_endpoint=api_endpoint, bad_request_kind=bad_request_kind, duration=duration, error_code=error_code, error_message=error_message, error_type=error_type, + failure_kind=failure_kind, initiator=initiator, + is_auto=is_auto, + is_byok=is_byok, + max_output_tokens=max_output_tokens, + max_prompt_tokens=max_prompt_tokens, model=model, provider_call_id=provider_call_id, _quota_snapshots=_quota_snapshots, + reasoning_effort=reasoning_effort, request_fingerprint=request_fingerprint, service_request_id=service_request_id, status_code=status_code, + transport=transport, ) def to_dict(self) -> dict: @@ -3915,6 +4015,8 @@ def to_dict(self) -> dict: result["source"] = to_enum(ModelCallFailureSource, self.source) if self.api_call_id is not None: result["apiCallId"] = from_union([from_none, from_str], self.api_call_id) + if self.api_endpoint is not None: + result["apiEndpoint"] = from_union([from_none, lambda x: to_enum(AssistantUsageApiEndpoint, x)], self.api_endpoint) if self.bad_request_kind is not None: result["badRequestKind"] = from_union([from_none, lambda x: to_enum(ModelCallFailureBadRequestKind, x)], self.bad_request_kind) if self.duration is not None: @@ -3925,20 +4027,34 @@ def to_dict(self) -> dict: result["errorMessage"] = from_union([from_none, from_str], self.error_message) if self.error_type is not None: result["errorType"] = from_union([from_none, from_str], self.error_type) + if self.failure_kind is not None: + result["failureKind"] = from_union([from_none, lambda x: to_enum(ModelCallFailureKind, x)], self.failure_kind) if self.initiator is not None: result["initiator"] = from_union([from_none, from_str], self.initiator) + if self.is_auto is not None: + result["isAuto"] = from_union([from_none, from_bool], self.is_auto) + if self.is_byok is not None: + result["isByok"] = from_union([from_none, from_bool], self.is_byok) + if self.max_output_tokens is not None: + result["maxOutputTokens"] = from_union([from_none, to_int], self.max_output_tokens) + if self.max_prompt_tokens is not None: + result["maxPromptTokens"] = from_union([from_none, to_int], self.max_prompt_tokens) if self.model is not None: result["model"] = from_union([from_none, from_str], self.model) if self.provider_call_id is not None: result["providerCallId"] = from_union([from_none, from_str], self.provider_call_id) if self._quota_snapshots is not None: result["quotaSnapshots"] = from_union([from_none, lambda x: from_dict(lambda x: to_class(_AssistantUsageQuotaSnapshot, x), x)], self._quota_snapshots) + if self.reasoning_effort is not None: + result["reasoningEffort"] = from_union([from_none, from_str], self.reasoning_effort) if self.request_fingerprint is not None: result["requestFingerprint"] = from_union([from_none, lambda x: to_class(ModelCallFailureRequestFingerprint, x)], self.request_fingerprint) if self.service_request_id is not None: result["serviceRequestId"] = from_union([from_none, from_str], self.service_request_id) if self.status_code is not None: result["statusCode"] = from_union([from_none, to_int], self.status_code) + if self.transport is not None: + result["transport"] = from_union([from_none, lambda x: to_enum(ModelCallFailureTransport, x)], self.transport) return result @@ -3986,6 +4102,30 @@ def to_dict(self) -> dict: return result +@dataclass +class ModelCallStartData: + "Model API dispatch metadata for internal telemetry" + turn_id: str + model: str | None = None + + @staticmethod + def from_dict(obj: Any) -> "ModelCallStartData": + assert isinstance(obj, dict) + turn_id = from_str(obj.get("turnId")) + model = from_union([from_none, from_str], obj.get("model")) + return ModelCallStartData( + turn_id=turn_id, + model=model, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["turnId"] = from_str(self.turn_id) + if self.model is not None: + result["model"] = from_union([from_none, from_str], self.model) + return result + + @dataclass class PendingMessagesModifiedData: "Empty payload; the event signals that the pending message queue has changed" @@ -6696,21 +6836,27 @@ class SessionUsageCheckpointData: "Durable session usage checkpoint for reconstructing aggregate accounting on resume" total_nano_aiu: float # Internal: this field is an internal SDK API and is not part of the public surface. + _model_cache_state: list[_UsageCheckpointModelCacheState] | None = None + # Internal: this field is an internal SDK API and is not part of the public surface. _total_premium_requests: float | None = None @staticmethod def from_dict(obj: Any) -> "SessionUsageCheckpointData": assert isinstance(obj, dict) total_nano_aiu = from_float(obj.get("totalNanoAiu")) + _model_cache_state = from_union([from_none, lambda x: from_list(_UsageCheckpointModelCacheState.from_dict, x)], obj.get("modelCacheState")) _total_premium_requests = from_union([from_none, from_float], obj.get("totalPremiumRequests")) return SessionUsageCheckpointData( total_nano_aiu=total_nano_aiu, + _model_cache_state=_model_cache_state, _total_premium_requests=_total_premium_requests, ) def to_dict(self) -> dict: result: dict = {} result["totalNanoAiu"] = to_float(self.total_nano_aiu) + if self._model_cache_state is not None: + result["modelCacheState"] = from_union([from_none, lambda x: from_list(lambda x: to_class(_UsageCheckpointModelCacheState, x), x)], self._model_cache_state) if self._total_premium_requests is not None: result["totalPremiumRequests"] = from_union([from_none, to_float], self._total_premium_requests) return result @@ -8404,6 +8550,29 @@ def to_dict(self) -> dict: return result +@dataclass +class ToolSearchActivatedData: + "Persisted generic client-side tool activations restored when a session resumes." + strategy: str + tool_names: list[str] + + @staticmethod + def from_dict(obj: Any) -> "ToolSearchActivatedData": + assert isinstance(obj, dict) + strategy = from_str(obj.get("strategy")) + tool_names = from_list(from_str, obj.get("toolNames")) + return ToolSearchActivatedData( + strategy=strategy, + tool_names=tool_names, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["strategy"] = from_str(self.strategy) + result["toolNames"] = from_list(from_str, self.tool_names) + return result + + @dataclass class ToolUserRequestedData: "User-initiated tool invocation request with tool name and arguments" @@ -8432,6 +8601,34 @@ def to_dict(self) -> dict: return result +@dataclass +class _UsageCheckpointModelCacheState: + "Internal prompt-cache expiration state for one model" + cache_expires_at: datetime + # Internal: this field is an internal SDK API and is not part of the public surface. + _cache_ttl_seconds: int + model_id: str + + @staticmethod + def from_dict(obj: Any) -> "_UsageCheckpointModelCacheState": + assert isinstance(obj, dict) + cache_expires_at = from_datetime(obj.get("cacheExpiresAt")) + _cache_ttl_seconds = from_int(obj.get("cacheTtlSeconds")) + model_id = from_str(obj.get("modelId")) + return _UsageCheckpointModelCacheState( + cache_expires_at=cache_expires_at, + _cache_ttl_seconds=_cache_ttl_seconds, + model_id=model_id, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["cacheExpiresAt"] = to_datetime(self.cache_expires_at) + result["cacheTtlSeconds"] = to_int(self._cache_ttl_seconds) + result["modelId"] = from_str(self.model_id) + return result + + @dataclass class UserInputCompletedData: "User input request completion with the user's response" @@ -9151,6 +9348,26 @@ class HandoffSourceType(Enum): LOCAL = "local" +class ManagedSettingsEnforcedAction(Enum): + "The category of runtime action that enterprise managed settings governed (blocked or capped)" + # An attempt to turn on a bypass-permissions ("yolo") escalation was refused or capped because policy disables bypass-permissions mode. + BYPASS_PERMISSIONS_BLOCKED = "bypass_permissions_blocked" + + +class ManagedSettingsEnforcedEscalation(Enum): + "For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused" + # Full allow-all ("/allow-all on") permissions — auto-approving tools, paths, and URLs. + ALLOW_ALL = "allow_all" + # Auto-approval of all tool permission requests. + APPROVE_ALL = "approve_all" + # Advisory auto-approval ("/allow-all auto") mode — keeps normal prompt paths and adds LLM-advised approval, distinct from full allow-all. + AUTO_APPROVAL = "auto_approval" + # Unrestricted filesystem access outside the session's allowed directories. + UNRESTRICTED_PATHS = "unrestricted_paths" + # Unrestricted URL fetch access. + UNRESTRICTED_URLS = "unrestricted_urls" + + class ManagedSettingsResolvedSource(Enum): "Which channel supplied the effective enterprise managed settings (highest-authority present layer wins wholesale)" # Account/org policy self-fetched from the GitHub managed-settings endpoint (higher authority). @@ -9249,6 +9466,14 @@ class ModelCallFailureBadRequestKind(Enum): STRUCTURED_ERROR = "structured_error" +class ModelCallFailureKind(Enum): + "Boundary that produced a model call failure" + # The provider returned an API error response. + API = "api" + # The request transport failed before a usable API response completed. + TRANSPORT = "transport" + + class ModelCallFailureSource(Enum): "Where the failed model call originated" # Model call from the top-level agent. @@ -9259,6 +9484,14 @@ class ModelCallFailureSource(Enum): MCP_SAMPLING = "mcp_sampling" +class ModelCallFailureTransport(Enum): + "Transport used for a failed model call" + # HTTP transport, including SSE streams. + HTTP = "http" + # WebSocket transport. + WEBSOCKET = "websocket" + + class OmittedBinaryOmittedReason(Enum): "Why the binary data is absent: it exceeded the inline size limit, or its asset was unavailable" # Bytes exceeded the session's inline size limit. @@ -9475,7 +9708,7 @@ class WorkspaceFileChangedOperation(Enum): UPDATE = "update" -SessionEventData = SessionStartData | SessionResumeData | SessionRemoteSteerableChangedData | SessionErrorData | SessionIdleData | SessionTitleChangedData | SessionScheduleCreatedData | SessionScheduleCancelledData | SessionScheduleRearmedData | SessionAutopilotObjectiveChangedData | SessionInfoData | SessionWarningData | SessionModelChangeData | SessionModeChangedData | SessionSessionLimitsChangedData | SessionPermissionsChangedData | SessionPlanChangedData | SessionTodosChangedData | SessionWorkspaceFileChangedData | SessionHandoffData | SessionTruncationData | SessionSnapshotRewindData | SessionShutdownData | SessionUsageCheckpointData | SessionContextChangedData | SessionUsageInfoData | SessionCompactionStartData | SessionCompactionCompleteData | SessionTaskCompleteData | UserMessageData | PendingMessagesModifiedData | AssistantTurnStartData | AssistantIntentData | AssistantServerToolProgressData | AssistantReasoningData | AssistantReasoningDeltaData | AssistantToolCallDeltaData | AssistantStreamingDeltaData | AssistantMessageData | AssistantMessageStartData | AssistantMessageDeltaData | AssistantTurnEndData | AssistantIdleData | AssistantUsageData | ModelCallFailureData | AbortData | ToolUserRequestedData | ToolExecutionStartData | ToolExecutionPartialResultData | ToolExecutionProgressData | ToolExecutionCompleteData | SkillInvokedData | SubagentStartedData | SubagentCompletedData | SubagentFailedData | SubagentSelectedData | SubagentDeselectedData | HookStartData | HookEndData | HookProgressData | SessionBinaryAssetData | SystemMessageData | SystemNotificationData | PermissionRequestedData | PermissionCompletedData | UserInputRequestedData | UserInputCompletedData | ElicitationRequestedData | ElicitationCompletedData | SamplingRequestedData | SamplingCompletedData | McpOauthRequiredData | McpOauthCompletedData | McpHeadersRefreshRequiredData | McpHeadersRefreshCompletedData | SessionCustomNotificationData | ExternalToolRequestedData | ExternalToolCompletedData | CommandQueuedData | CommandExecuteData | CommandCompletedData | AutoModeSwitchRequestedData | AutoModeSwitchCompletedData | SessionLimitsExhaustedRequestedData | SessionLimitsExhaustedCompletedData | SessionAutoModeResolvedData | SessionManagedSettingsResolvedData | CommandsChangedData | CapabilitiesChangedData | ExitPlanModeRequestedData | ExitPlanModeCompletedData | SessionToolsUpdatedData | SessionBackgroundTasksChangedData | SessionSkillsLoadedData | SessionCustomAgentsUpdatedData | SessionMcpServersLoadedData | SessionMcpServerStatusChangedData | McpToolsListChangedData | McpResourcesListChangedData | McpPromptsListChangedData | SessionExtensionsLoadedData | SessionCanvasOpenedData | SessionCanvasRegistryChangedData | SessionCanvasClosedData | SessionCanvasUnavailableData | SessionCanvasRecordedData | SessionCanvasRemovedData | SessionExtensionsAttachmentsPushedData | McpAppToolCallCompleteData | RawSessionEventData | Data +SessionEventData = SessionStartData | SessionResumeData | SessionRemoteSteerableChangedData | SessionErrorData | SessionIdleData | SessionTitleChangedData | SessionScheduleCreatedData | SessionScheduleCancelledData | SessionScheduleRearmedData | SessionAutopilotObjectiveChangedData | SessionInfoData | SessionWarningData | SessionModelChangeData | SessionModeChangedData | SessionSessionLimitsChangedData | SessionPermissionsChangedData | SessionPlanChangedData | SessionTodosChangedData | SessionWorkspaceFileChangedData | SessionHandoffData | SessionTruncationData | SessionSnapshotRewindData | SessionShutdownData | SessionUsageCheckpointData | SessionContextChangedData | SessionUsageInfoData | SessionCompactionStartData | SessionCompactionCompleteData | SessionTaskCompleteData | UserMessageData | PendingMessagesModifiedData | AssistantTurnStartData | AssistantTurnRetryData | AssistantIntentData | AssistantServerToolProgressData | AssistantReasoningData | AssistantReasoningDeltaData | AssistantToolCallDeltaData | AssistantStreamingDeltaData | AssistantMessageData | AssistantMessageStartData | AssistantMessageDeltaData | AssistantTurnEndData | AssistantIdleData | AssistantUsageData | ModelCallFailureData | ModelCallStartData | AbortData | ToolUserRequestedData | ToolExecutionStartData | ToolExecutionPartialResultData | ToolExecutionProgressData | ToolExecutionCompleteData | ToolSearchActivatedData | SkillInvokedData | SubagentStartedData | SubagentCompletedData | SubagentFailedData | SubagentSelectedData | SubagentDeselectedData | HookStartData | HookEndData | HookProgressData | SessionBinaryAssetData | SystemMessageData | SystemNotificationData | PermissionRequestedData | PermissionCompletedData | UserInputRequestedData | UserInputCompletedData | ElicitationRequestedData | ElicitationCompletedData | SamplingRequestedData | SamplingCompletedData | McpOauthRequiredData | McpOauthCompletedData | McpHeadersRefreshRequiredData | McpHeadersRefreshCompletedData | SessionCustomNotificationData | ExternalToolRequestedData | ExternalToolCompletedData | CommandQueuedData | CommandExecuteData | CommandCompletedData | AutoModeSwitchRequestedData | AutoModeSwitchCompletedData | SessionLimitsExhaustedRequestedData | SessionLimitsExhaustedCompletedData | SessionAutoModeResolvedData | SessionManagedSettingsResolvedData | SessionManagedSettingsEnforcedData | CommandsChangedData | CapabilitiesChangedData | ExitPlanModeRequestedData | ExitPlanModeCompletedData | SessionToolsUpdatedData | SessionBackgroundTasksChangedData | SessionSkillsLoadedData | SessionCustomAgentsUpdatedData | SessionMcpServersLoadedData | SessionMcpServerStatusChangedData | McpToolsListChangedData | McpResourcesListChangedData | McpPromptsListChangedData | SessionExtensionsLoadedData | SessionCanvasOpenedData | SessionCanvasRegistryChangedData | SessionCanvasClosedData | SessionCanvasUnavailableData | SessionCanvasRecordedData | SessionCanvasRemovedData | SessionExtensionsAttachmentsPushedData | McpAppToolCallCompleteData | RawSessionEventData | Data @dataclass @@ -9533,6 +9766,7 @@ def from_dict(obj: Any) -> "SessionEvent": case SessionEventType.USER_MESSAGE: data = UserMessageData.from_dict(data_obj) case SessionEventType.PENDING_MESSAGES_MODIFIED: data = PendingMessagesModifiedData.from_dict(data_obj) case SessionEventType.ASSISTANT_TURN_START: data = AssistantTurnStartData.from_dict(data_obj) + case SessionEventType.ASSISTANT_TURN_RETRY: data = AssistantTurnRetryData.from_dict(data_obj) case SessionEventType.ASSISTANT_INTENT: data = AssistantIntentData.from_dict(data_obj) case SessionEventType.ASSISTANT_SERVER_TOOL_PROGRESS: data = AssistantServerToolProgressData.from_dict(data_obj) case SessionEventType.ASSISTANT_REASONING: data = AssistantReasoningData.from_dict(data_obj) @@ -9546,12 +9780,14 @@ def from_dict(obj: Any) -> "SessionEvent": case SessionEventType.ASSISTANT_IDLE: data = AssistantIdleData.from_dict(data_obj) case SessionEventType.ASSISTANT_USAGE: data = AssistantUsageData.from_dict(data_obj) case SessionEventType.MODEL_CALL_FAILURE: data = ModelCallFailureData.from_dict(data_obj) + case SessionEventType.MODEL_CALL_START: data = ModelCallStartData.from_dict(data_obj) case SessionEventType.ABORT: data = AbortData.from_dict(data_obj) case SessionEventType.TOOL_USER_REQUESTED: data = ToolUserRequestedData.from_dict(data_obj) case SessionEventType.TOOL_EXECUTION_START: data = ToolExecutionStartData.from_dict(data_obj) case SessionEventType.TOOL_EXECUTION_PARTIAL_RESULT: data = ToolExecutionPartialResultData.from_dict(data_obj) case SessionEventType.TOOL_EXECUTION_PROGRESS: data = ToolExecutionProgressData.from_dict(data_obj) case SessionEventType.TOOL_EXECUTION_COMPLETE: data = ToolExecutionCompleteData.from_dict(data_obj) + case SessionEventType.TOOL_SEARCH_ACTIVATED: data = ToolSearchActivatedData.from_dict(data_obj) case SessionEventType.SKILL_INVOKED: data = SkillInvokedData.from_dict(data_obj) case SessionEventType.SUBAGENT_STARTED: data = SubagentStartedData.from_dict(data_obj) case SessionEventType.SUBAGENT_COMPLETED: data = SubagentCompletedData.from_dict(data_obj) @@ -9588,6 +9824,7 @@ def from_dict(obj: Any) -> "SessionEvent": case SessionEventType.SESSION_LIMITS_EXHAUSTED_COMPLETED: data = SessionLimitsExhaustedCompletedData.from_dict(data_obj) case SessionEventType.SESSION_AUTO_MODE_RESOLVED: data = SessionAutoModeResolvedData.from_dict(data_obj) case SessionEventType.SESSION_MANAGED_SETTINGS_RESOLVED: data = SessionManagedSettingsResolvedData.from_dict(data_obj) + case SessionEventType.SESSION_MANAGED_SETTINGS_ENFORCED: data = SessionManagedSettingsEnforcedData.from_dict(data_obj) case SessionEventType.COMMANDS_CHANGED: data = CommandsChangedData.from_dict(data_obj) case SessionEventType.CAPABILITIES_CHANGED: data = CapabilitiesChangedData.from_dict(data_obj) case SessionEventType.EXIT_PLAN_MODE_REQUESTED: data = ExitPlanModeRequestedData.from_dict(data_obj) @@ -9660,6 +9897,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "AssistantStreamingDeltaData", "AssistantToolCallDeltaData", "AssistantTurnEndData", + "AssistantTurnRetryData", "AssistantTurnStartData", "AssistantUsageApiEndpoint", "AssistantUsageCopilotUsage", @@ -9745,6 +9983,8 @@ def session_event_to_dict(x: SessionEvent) -> Any: "HookEndError", "HookProgressData", "HookStartData", + "ManagedSettingsEnforcedAction", + "ManagedSettingsEnforcedEscalation", "ManagedSettingsResolvedSource", "McpAppToolCallCompleteData", "McpAppToolCallCompleteError", @@ -9770,8 +10010,11 @@ def session_event_to_dict(x: SessionEvent) -> Any: "McpToolsListChangedData", "ModelCallFailureBadRequestKind", "ModelCallFailureData", + "ModelCallFailureKind", "ModelCallFailureRequestFingerprint", "ModelCallFailureSource", + "ModelCallFailureTransport", + "ModelCallStartData", "OmittedBinaryOmittedReason", "OmittedBinaryResult", "OmittedBinaryType", @@ -9856,6 +10099,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "SessionLimitsExhaustedRequestedData", "SessionLimitsExhaustedResponse", "SessionLimitsExhaustedResponseAction", + "SessionManagedSettingsEnforcedData", "SessionManagedSettingsResolvedData", "SessionMcpServerStatusChangedData", "SessionMcpServersLoadedData", @@ -9946,6 +10190,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "ToolExecutionStartToolDescriptionMeta", "ToolExecutionStartToolDescriptionMetaUI", "ToolExecutionStartToolDescriptionMetaUIVisibility", + "ToolSearchActivatedData", "ToolUserRequestedData", "UserInputCompletedData", "UserInputRequestedData", diff --git a/python/e2e/test_rpc_session_state_e2e.py b/python/e2e/test_rpc_session_state_e2e.py index 12688f280..914cde03c 100644 --- a/python/e2e/test_rpc_session_state_e2e.py +++ b/python/e2e/test_rpc_session_state_e2e.py @@ -259,7 +259,6 @@ async def test_should_call_metadata_snapshot_set_working_directory_and_record_co ): first_dir = _create_unique_directory(ctx, "metadata-first") second_dir = _create_unique_directory(ctx, "metadata-second") - context_dir = _create_unique_directory(ctx, "metadata-context") branch = f"rpc-context-{uuid.uuid4().hex}" session = await ctx.client.create_session( @@ -307,7 +306,7 @@ def on_event(event): result = await session.rpc.metadata.record_context_change( MetadataRecordContextChangeRequest( context=SessionWorkingDirectoryContext( - cwd=context_dir, + cwd=second_dir, git_root=first_dir, branch=branch, repository="github/copilot-sdk-e2e", @@ -321,7 +320,7 @@ def on_event(event): assert result is not None event = await asyncio.wait_for(context_future, timeout=15.0) - assert _path_equals(context_dir, event.data.cwd) + assert _path_equals(second_dir, event.data.cwd) assert _path_equals(first_dir, event.data.git_root) assert event.data.branch == branch assert event.data.repository == "github/copilot-sdk-e2e" diff --git a/python/e2e/test_session_e2e.py b/python/e2e/test_session_e2e.py index 22f99e403..aed1340f5 100644 --- a/python/e2e/test_session_e2e.py +++ b/python/e2e/test_session_e2e.py @@ -552,7 +552,11 @@ async def test_should_abort_a_session(self, ctx: E2ETestContext): assert len(abort_events) > 0, "Expected an abort event in messages" # We should be able to send another message - answer = await session.send_and_wait("What is 2+2?") + wait_for_answer = asyncio.create_task( + get_next_event_of_type(session, "assistant.message", timeout=60.0) + ) + await session.send("What is 2+2?") + answer = await wait_for_answer assert "4" in answer.data.content async def test_should_receive_session_events(self, ctx: E2ETestContext): diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index e243ec1dc..e6f488e6e 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -195,6 +195,20 @@ pub mod rpc_methods { pub const SESSION_CANVAS_CLOSE: &str = "session.canvas.close"; /// `session.canvas.action.invoke` pub const SESSION_CANVAS_ACTION_INVOKE: &str = "session.canvas.action.invoke"; + /// `session.factory.run` + pub const SESSION_FACTORY_RUN: &str = "session.factory.run"; + /// `session.factory.getRun` + pub const SESSION_FACTORY_GETRUN: &str = "session.factory.getRun"; + /// `session.factory.cancel` + pub const SESSION_FACTORY_CANCEL: &str = "session.factory.cancel"; + /// `session.factory.log` + pub const SESSION_FACTORY_LOG: &str = "session.factory.log"; + /// `session.factory.agent` + pub const SESSION_FACTORY_AGENT: &str = "session.factory.agent"; + /// `session.factory.journal.get` + pub const SESSION_FACTORY_JOURNAL_GET: &str = "session.factory.journal.get"; + /// `session.factory.journal.put` + pub const SESSION_FACTORY_JOURNAL_PUT: &str = "session.factory.journal.put"; /// `session.model.getCurrent` pub const SESSION_MODEL_GETCURRENT: &str = "session.model.getCurrent"; /// `session.model.switchTo` @@ -555,6 +569,10 @@ pub mod rpc_methods { pub const SESSION_SCHEDULE_STOP: &str = "session.schedule.stop"; /// `providerToken.getToken` pub const PROVIDERTOKEN_GETTOKEN: &str = "providerToken.getToken"; + /// `factory.execute` + pub const FACTORY_EXECUTE: &str = "factory.execute"; + /// `factory.abort` + pub const FACTORY_ABORT: &str = "factory.abort"; /// `sessionFs.readFile` pub const SESSIONFS_READFILE: &str = "sessionFs.readFile"; /// `sessionFs.writeFile` @@ -3644,6 +3662,341 @@ pub struct ExternalToolTextResultForLlmContentText { pub r#type: ExternalToolTextResultForLlmContentTextType, } +/// Parameters for cooperatively aborting a factory body. +/// +///

+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryAbortRequest { + /// Target session identifier + pub session_id: SessionId, + /// Factory run identifier. + pub run_id: String, +} + +/// Acknowledgement that a factory request was accepted. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryAckResult {} + +/// Options for one factory-scoped subagent call. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryAgentOptions { + /// Optional label distinguishing otherwise identical memoized agent calls. + #[serde(skip_serializing_if = "Option::is_none")] + pub label: Option, + /// Optional model identifier for the subagent. + #[serde(skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Optional JSON Schema for structured agent output. + #[serde(skip_serializing_if = "Option::is_none")] + pub schema: Option, +} + +/// Parameters for one factory-scoped subagent call. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryAgentRequest { + /// Factory run identifier that owns the subagent. + pub factory_run_id: String, + /// Subagent execution options. + pub opts: FactoryAgentOptions, + /// Prompt to send to the subagent. + pub prompt: String, +} + +/// Result of one factory-scoped subagent call. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryAgentResult { + /// Agent result, omitted when the agent produced no result. + #[serde(skip_serializing_if = "Option::is_none")] + pub result: Option, +} + +/// Parameters for cancelling a factory run. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryCancelRequest { + /// Factory run identifier. + pub run_id: String, +} + +/// Parameters sent to the owning extension to execute a factory closure. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryExecuteRequest { + /// Target session identifier + pub session_id: SessionId, + /// Registered factory name. + pub name: String, + /// Factory run identifier. + pub run_id: String, + /// Factory input value. + pub args: serde_json::Value, +} + +/// Result returned by an extension factory closure. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryExecuteResult { + /// Factory result value. + pub result: serde_json::Value, +} + +/// Parameters for retrieving a factory run. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryGetRunRequest { + /// Factory run identifier. + pub run_id: String, +} + +/// Parameters for reading a factory journal entry. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryJournalGetRequest { + /// Namespaced journal key. + pub key: String, + /// Factory run identifier. + pub run_id: String, +} + +/// Result of reading a factory journal entry. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryJournalGetResult { + /// Whether the journal contained the requested key. + pub hit: bool, + /// Cached JSON result. The hit field distinguishes a cached JSON null from a miss. + #[serde(skip_serializing_if = "Option::is_none")] + pub result_json: Option, +} + +/// Parameters for storing a factory journal entry. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryJournalPutRequest { + /// Namespaced journal key. + pub key: String, + /// JSON result to memoize. + pub result_json: serde_json::Value, + /// Factory run identifier. + pub run_id: String, +} + +/// One ordered factory progress line. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryLogLine { + /// Progress line kind. + pub kind: FactoryLogLineKind, + /// Monotonic sequence number within the factory run. + pub seq: i64, + /// Progress text. + pub text: String, +} + +/// Parameters for recording factory progress. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryLogRequest { + /// Ordered progress lines to append. + pub lines: Vec, + /// Factory run identifier. + pub run_id: String, +} + +/// Wire-only per-invocation factory resource ceiling overrides. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryRunLimits { + /// Maximum number of factory subagents that may run concurrently. + #[serde(skip_serializing_if = "Option::is_none")] + pub max_concurrent_subagents: Option, + /// Maximum total number of factory subagents that may be admitted. + #[serde(skip_serializing_if = "Option::is_none")] + pub max_total_subagents: Option, + /// Factory active-run timeout in milliseconds. + #[serde(skip_serializing_if = "Option::is_none")] + pub timeout: Option, +} + +/// Options controlling factory invocation. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RunOptions { + /// Per-invocation resource ceiling overrides. + #[serde(skip_serializing_if = "Option::is_none")] + pub limits: Option, + /// Run identifier whose journal and progress should seed this resumed run. + #[serde(skip_serializing_if = "Option::is_none")] + pub resume_from_run_id: Option, +} + +/// Parameters for invoking a registered factory. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryRunRequest { + /// Factory input value. + pub args: serde_json::Value, + /// Registered factory name. + pub name: String, + /// Factory invocation options. + #[serde(skip_serializing_if = "Option::is_none")] + pub options: Option, +} + +/// Complete current or terminal factory run envelope. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryRunResult { + /// Error message for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub error: Option, + /// Machine-readable failure details for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub failure: Option, + /// Reason for a halted or cancelled run. + #[serde(skip_serializing_if = "Option::is_none")] + pub reason: Option, + /// Completed factory result. + #[serde(skip_serializing_if = "Option::is_none")] + pub result: Option, + /// Factory run identifier. + pub run_id: String, + /// Partial journal and progress snapshot for a halted, cancelled, or errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub snapshot: Option, + /// Current or terminal factory run status. + pub status: FactoryRunStatus, +} + /// Optional user prompt to combine with the fleet orchestration instructions. /// ///
@@ -4345,16 +4698,19 @@ pub struct LlmInferenceHttpRequestChunkResult {} #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct LlmInferenceHttpRequestStartRequest { - /// Stable per-agent-instance id attributing this request to a specific agent trajectory. Present when the request originates from an agent turn; absent for requests issued outside any agent context (e.g. some SDK callers). A request with an `agentId` but no `parentAgentId` is a root-agent request; one carrying both is a subagent request. Sourced from the runtime's per-request agent context and surfaced on the envelope independently of transport, so it is available for both first-party (CAPI) and BYOK/custom-provider requests; on the CAPI transport the runtime derives the upstream `X-Agent-Task-Id` header from this same context. Consumers routing each provider call to a training trajectory should key on this rather than on lifecycle events, since it is available on the request path before sampling. + /// Stable identity of the agent trajectory that issued this request. Present when the request originates from an agent turn; absent for requests outside any agent context. This is the same identity used by lifecycle and bridged session events and remains constant across turns and retries. #[serde(skip_serializing_if = "Option::is_none")] pub agent_id: Option, + /// Identity of the agent invocation (one agentic loop) that issued this request. It remains fixed across physical retries within the invocation and is distinct from the stable trajectory `agentId`. A caller-supplied invocation id always takes precedence (this covers auxiliary calls that have no model call id). Otherwise, first-party CAPI requests fall back to the runtime's agent task id — the same value the runtime emits as the `X-Agent-Task-Id` header — while custom-provider requests fall back to the model call id. + #[serde(skip_serializing_if = "Option::is_none")] + pub agent_invocation_id: Option, pub headers: HashMap>, /// Coarse classification of the interaction that produced this request. Open string for forward-compatibility; known values include `conversation-agent`, `conversation-subagent`, `conversation-sampling`, `conversation-background`, `conversation-compaction`, and `conversation-user`. Absent when the runtime did not classify the request. Comes from the runtime's per-request agent context independently of transport; on the CAPI transport the runtime derives the upstream `X-Interaction-Type` header from this same context. #[serde(skip_serializing_if = "Option::is_none")] pub interaction_type: Option, /// HTTP method, e.g. GET, POST. pub method: String, - /// Id of the parent agent that spawned the agent issuing this request. Present only for subagent requests; absent for root-agent requests and non-agent requests. Combined with `agentId`, this lets consumers attribute a call to a child trajectory versus the root. Like `agentId`, it comes from the runtime's per-request agent context independently of transport; on the CAPI transport the runtime derives the upstream `X-Parent-Agent-Id` header from this same context. + /// Stable identity of the immediate parent trajectory. Present for child trajectories such as subagents and conversation-sampling requests; absent for root-agent and non-agent requests. #[serde(skip_serializing_if = "Option::is_none")] pub parent_agent_id: Option, /// Opaque runtime-minted id, unique per in-flight request. The SDK uses this to correlate httpRequestChunk frames and to address its httpResponseStart / httpResponseChunk replies back to the runtime. @@ -6508,7 +6864,7 @@ pub struct MetadataRecordContextChangeRequest { pub context: SessionWorkingDirectoryContext, } -/// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). +/// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead. /// ///
/// @@ -10510,6 +10866,12 @@ pub struct SandboxConfig { pub add_current_working_directory: Option, /// Whether sandboxing is enabled for the session. pub enabled: bool, + /// Whether to export `GH_TOKEN` so the `gh` CLI authenticates inside the sandbox without the OS keyring the sandbox blocks. Default: false (opt-in). + #[serde(skip_serializing_if = "Option::is_none")] + pub gh_auth: Option, + /// Whether to inject the Copilot GitHub token as an `http..extraheader` so authenticated HTTPS git works inside the sandbox without the shell-based credential helper the sandbox blocks. Default: false (opt-in). + #[serde(skip_serializing_if = "Option::is_none")] + pub git_auth: Option, /// User-managed sandbox policy fragment merged into the auto-discovered base policy. #[serde(skip_serializing_if = "Option::is_none")] pub user_policy: Option, @@ -10871,6 +11233,9 @@ pub struct ServerSkill { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ServerSkillList { + /// Messages for skills that failed to load (e.g. malformed SKILL.md). Empty when host skills are excluded so host-local paths are not disclosed to multitenant callers. + #[serde(skip_serializing_if = "Option::is_none")] + pub errors: Option>, /// All discovered skills across all sources pub skills: Vec, } @@ -15100,6 +15465,9 @@ pub struct UsageMetricsModelMetricUsage { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct UsageMetricsModelMetric { + /// Latest known prompt-cache expiration for this model. A timestamp in the past indicates that the observed cache has expired. + #[serde(skip_serializing_if = "Option::is_none")] + pub cache_expires_at: Option, /// Request count and cost metrics for this model pub requests: UsageMetricsModelMetricRequests, /// Token count details per type @@ -15877,6 +16245,9 @@ pub struct PluginsMarketplacesRefreshResult { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SkillsDiscoverResult { + /// Messages for skills that failed to load (e.g. malformed SKILL.md). Empty when host skills are excluded so host-local paths are not disclosed to multitenant callers. + #[serde(skip_serializing_if = "Option::is_none")] + pub errors: Option>, /// All discovered skills across all sources pub skills: Vec, } @@ -16494,6 +16865,160 @@ pub struct SessionCanvasActionInvokeResult { pub result: Option, } +/// Complete current or terminal factory run envelope. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionFactoryRunResult { + /// Error message for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub error: Option, + /// Machine-readable failure details for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub failure: Option, + /// Reason for a halted or cancelled run. + #[serde(skip_serializing_if = "Option::is_none")] + pub reason: Option, + /// Completed factory result. + #[serde(skip_serializing_if = "Option::is_none")] + pub result: Option, + /// Factory run identifier. + pub run_id: String, + /// Partial journal and progress snapshot for a halted, cancelled, or errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub snapshot: Option, + /// Current or terminal factory run status. + pub status: FactoryRunStatus, +} + +/// Complete current or terminal factory run envelope. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionFactoryGetRunResult { + /// Error message for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub error: Option, + /// Machine-readable failure details for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub failure: Option, + /// Reason for a halted or cancelled run. + #[serde(skip_serializing_if = "Option::is_none")] + pub reason: Option, + /// Completed factory result. + #[serde(skip_serializing_if = "Option::is_none")] + pub result: Option, + /// Factory run identifier. + pub run_id: String, + /// Partial journal and progress snapshot for a halted, cancelled, or errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub snapshot: Option, + /// Current or terminal factory run status. + pub status: FactoryRunStatus, +} + +/// Complete current or terminal factory run envelope. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionFactoryCancelResult { + /// Error message for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub error: Option, + /// Machine-readable failure details for an errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub failure: Option, + /// Reason for a halted or cancelled run. + #[serde(skip_serializing_if = "Option::is_none")] + pub reason: Option, + /// Completed factory result. + #[serde(skip_serializing_if = "Option::is_none")] + pub result: Option, + /// Factory run identifier. + pub run_id: String, + /// Partial journal and progress snapshot for a halted, cancelled, or errored run. + #[serde(skip_serializing_if = "Option::is_none")] + pub snapshot: Option, + /// Current or terminal factory run status. + pub status: FactoryRunStatus, +} + +/// Acknowledgement that a factory request was accepted. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionFactoryLogResult {} + +/// Result of one factory-scoped subagent call. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionFactoryAgentResult { + /// Agent result, omitted when the agent produced no result. + #[serde(skip_serializing_if = "Option::is_none")] + pub result: Option, +} + +/// Result of reading a factory journal entry. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionFactoryJournalGetResult { + /// Whether the journal contained the requested key. + pub hit: bool, + /// Cached JSON result. The hit field distinguishes a cached JSON null from a miss. + #[serde(skip_serializing_if = "Option::is_none")] + pub result_json: Option, +} + +/// Acknowledgement that a factory request was accepted. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionFactoryJournalPutResult {} + /// Identifies the target session. /// ///
@@ -19028,7 +19553,7 @@ pub struct SessionMetadataGetContextHeaviestMessagesResult { pub total_tokens: i64, } -/// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). +/// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead. /// ///
/// @@ -19689,6 +20214,18 @@ pub struct ProviderTokenGetTokenResult { pub token: String, } +/// Acknowledgement that a factory request was accepted. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FactoryAbortResult {} + /// Identifies the target session. /// ///
@@ -20824,6 +21361,84 @@ pub enum ExternalToolTextResultForLlmContentTextType { Text, } +/// Kind of factory progress line. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum FactoryLogLineKind { + /// A narrator log line. + #[serde(rename = "log")] + Log, + /// A named factory phase marker. + #[serde(rename = "phase")] + Phase, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Cumulative resource ceiling that stopped a factory run. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum FactoryRunFailureKind { + /// The run admitted the approved maximum total number of subagents. + #[serde(rename = "maxTotalSubagents")] + MaxTotalSubagents, + /// The run reached the approved timeout deadline. + #[serde(rename = "timeout")] + Timeout, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// Current or terminal state of a factory run. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum FactoryRunStatus { + /// The run was minted and is awaiting approval. + #[serde(rename = "pending")] + Pending, + /// The run is executing. + #[serde(rename = "running")] + Running, + /// The run completed successfully. + #[serde(rename = "completed")] + Completed, + /// The run was interrupted while resource budget remained. + #[serde(rename = "halted")] + Halted, + /// The run was cancelled before completion. + #[serde(rename = "cancelled")] + Cancelled, + /// The factory body failed or reached a cumulative resource ceiling. + #[serde(rename = "error")] + Error, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// Authentication via the `gh` CLI's saved credentials. #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum GhCliAuthInfoType { @@ -20866,6 +21481,9 @@ pub enum HookType { /// Runs after the user submits a prompt. #[serde(rename = "userPromptSubmitted")] UserPromptSubmitted, + /// Runs after the runtime transforms the submitted prompt for the model, before it is added to session history. + #[serde(rename = "userPromptTransformed")] + UserPromptTransformed, /// Runs when a session starts. #[serde(rename = "sessionStart")] SessionStart, diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs index 403933a27..431ffa3ae 100644 --- a/rust/src/generated/rpc.rs +++ b/rust/src/generated/rpc.rs @@ -2640,6 +2640,13 @@ impl<'a> SessionRpc<'a> { } } + /// `session.factory.*` sub-namespace. + pub fn factory(&self) -> SessionRpcFactory<'a> { + SessionRpcFactory { + session: self.session, + } + } + /// `session.fleet.*` sub-namespace. pub fn fleet(&self) -> SessionRpcFleet<'a> { SessionRpcFleet { @@ -3925,6 +3932,242 @@ impl<'a> SessionRpcExtensions<'a> { } } +/// `session.factory.*` RPCs. +#[derive(Clone, Copy)] +pub struct SessionRpcFactory<'a> { + pub(crate) session: &'a Session, +} + +impl<'a> SessionRpcFactory<'a> { + /// `session.factory.journal.*` sub-namespace. + pub fn journal(&self) -> SessionRpcFactoryJournal<'a> { + SessionRpcFactoryJournal { + session: self.session, + } + } + + /// Runs a registered factory by name at the top level. + /// + /// Wire method: `session.factory.run`. + /// + /// # Parameters + /// + /// * `params` - Parameters for invoking a registered factory. + /// + /// # Returns + /// + /// Complete current or terminal factory run envelope. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn run(&self, params: FactoryRunRequest) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_FACTORY_RUN, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Gets the current or settled envelope for a factory run. + /// + /// Wire method: `session.factory.getRun`. + /// + /// # Parameters + /// + /// * `params` - Parameters for retrieving a factory run. + /// + /// # Returns + /// + /// Complete current or terminal factory run envelope. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn get_run(&self, params: FactoryGetRunRequest) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_FACTORY_GETRUN, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Requests cancellation of a factory run and returns its run envelope. + /// + /// Wire method: `session.factory.cancel`. + /// + /// # Parameters + /// + /// * `params` - Parameters for cancelling a factory run. + /// + /// # Returns + /// + /// Complete current or terminal factory run envelope. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn cancel(&self, params: FactoryCancelRequest) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_FACTORY_CANCEL, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Records a batch of ordered factory progress lines. + /// + /// Wire method: `session.factory.log`. + /// + /// # Parameters + /// + /// * `params` - Parameters for recording factory progress. + /// + /// # Returns + /// + /// Acknowledgement that a factory request was accepted. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn log(&self, params: FactoryLogRequest) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_FACTORY_LOG, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Runs one factory-scoped subagent and returns its result. + /// + /// Wire method: `session.factory.agent`. + /// + /// # Parameters + /// + /// * `params` - Parameters for one factory-scoped subagent call. + /// + /// # Returns + /// + /// Result of one factory-scoped subagent call. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn agent(&self, params: FactoryAgentRequest) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_FACTORY_AGENT, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } +} + +/// `session.factory.journal.*` RPCs. +#[derive(Clone, Copy)] +pub struct SessionRpcFactoryJournal<'a> { + pub(crate) session: &'a Session, +} + +impl<'a> SessionRpcFactoryJournal<'a> { + /// Reads a memoized factory journal entry. + /// + /// Wire method: `session.factory.journal.get`. + /// + /// # Parameters + /// + /// * `params` - Parameters for reading a factory journal entry. + /// + /// # Returns + /// + /// Result of reading a factory journal entry. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn get( + &self, + params: FactoryJournalGetRequest, + ) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_FACTORY_JOURNAL_GET, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Stores a memoized factory journal entry. + /// + /// Wire method: `session.factory.journal.put`. + /// + /// # Parameters + /// + /// * `params` - Parameters for storing a factory journal entry. + /// + /// # Returns + /// + /// Acknowledgement that a factory request was accepted. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn put(&self, params: FactoryJournalPutRequest) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_FACTORY_JOURNAL_PUT, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } +} + /// `session.fleet.*` RPCs. #[derive(Clone, Copy)] pub struct SessionRpcFleet<'a> { @@ -5437,7 +5680,7 @@ impl<'a> SessionRpcMetadata<'a> { Ok(serde_json::from_value(_value)?) } - /// Records a working-directory/git context change and emits a `session.context_changed` event. + /// Records a working-directory/git context change and emits a `session.context_changed` event. For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event): a local session's working directory is authoritative and is moved via `metadata.setWorkingDirectory` (or an SDK `session.resume` that supplies a `workingDirectory`), not by this method. /// /// Wire method: `session.metadata.recordContextChange`. /// @@ -5447,7 +5690,7 @@ impl<'a> SessionRpcMetadata<'a> { /// /// # Returns /// - /// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). + /// Notify the session that its working directory context has changed. Emits a `session.context_changed` event so consumers (telemetry, OTel tracker, ACP, the timeline UI) can react. Use this when the host has detected a cwd/branch/repo change outside the session's normal lifecycle (e.g., after a shell command in interactive mode). For a local session, a report whose `cwd` diverges from the session's current working directory is ignored (the call still succeeds but records nothing and emits no event); move a local session's working directory via `metadata.setWorkingDirectory` instead. /// ///
/// diff --git a/rust/src/generated/session_events.rs b/rust/src/generated/session_events.rs index cf670c485..abc7dca62 100644 --- a/rust/src/generated/session_events.rs +++ b/rust/src/generated/session_events.rs @@ -75,6 +75,8 @@ pub enum SessionEventType { PendingMessagesModified, #[serde(rename = "assistant.turn_start")] AssistantTurnStart, + #[serde(rename = "assistant.turn_retry")] + AssistantTurnRetry, #[serde(rename = "assistant.intent")] AssistantIntent, #[serde(rename = "assistant.server_tool_progress")] @@ -101,6 +103,8 @@ pub enum SessionEventType { AssistantUsage, #[serde(rename = "model.call_failure")] ModelCallFailure, + #[serde(rename = "model.call_start")] + ModelCallStart, #[serde(rename = "abort")] Abort, #[serde(rename = "tool.user_requested")] @@ -113,6 +117,8 @@ pub enum SessionEventType { ToolExecutionProgress, #[serde(rename = "tool.execution_complete")] ToolExecutionComplete, + #[serde(rename = "tool_search.activated")] + ToolSearchActivated, #[serde(rename = "skill.invoked")] SkillInvoked, #[serde(rename = "subagent.started")] @@ -206,6 +212,15 @@ pub enum SessionEventType { ///
#[serde(rename = "session.managed_settings_resolved")] SessionManagedSettingsResolved, + /// + ///
+ /// + /// **Experimental.** This type is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. + /// + ///
+ #[serde(rename = "session.managed_settings_enforced")] + SessionManagedSettingsEnforced, #[serde(rename = "commands.changed")] CommandsChanged, #[serde(rename = "capabilities.changed")] @@ -368,6 +383,8 @@ pub enum SessionEventData { PendingMessagesModified(PendingMessagesModifiedData), #[serde(rename = "assistant.turn_start")] AssistantTurnStart(AssistantTurnStartData), + #[serde(rename = "assistant.turn_retry")] + AssistantTurnRetry(AssistantTurnRetryData), #[serde(rename = "assistant.intent")] AssistantIntent(AssistantIntentData), #[serde(rename = "assistant.server_tool_progress")] @@ -394,6 +411,8 @@ pub enum SessionEventData { AssistantUsage(AssistantUsageData), #[serde(rename = "model.call_failure")] ModelCallFailure(ModelCallFailureData), + #[serde(rename = "model.call_start")] + ModelCallStart(ModelCallStartData), #[serde(rename = "abort")] Abort(AbortData), #[serde(rename = "tool.user_requested")] @@ -406,6 +425,8 @@ pub enum SessionEventData { ToolExecutionProgress(ToolExecutionProgressData), #[serde(rename = "tool.execution_complete")] ToolExecutionComplete(ToolExecutionCompleteData), + #[serde(rename = "tool_search.activated")] + ToolSearchActivated(ToolSearchActivatedData), #[serde(rename = "skill.invoked")] SkillInvoked(SkillInvokedData), #[serde(rename = "subagent.started")] @@ -492,6 +513,15 @@ pub enum SessionEventData { ///
#[serde(rename = "session.managed_settings_resolved")] SessionManagedSettingsResolved(SessionManagedSettingsResolvedData), + /// + ///
+ /// + /// **Experimental.** This type is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. + /// + ///
+ #[serde(rename = "session.managed_settings_enforced")] + SessionManagedSettingsEnforced(SessionManagedSettingsEnforcedData), #[serde(rename = "commands.changed")] CommandsChanged(CommandsChangedData), #[serde(rename = "capabilities.changed")] @@ -1209,10 +1239,27 @@ pub struct SessionShutdownData { pub(crate) total_premium_requests: Option, } +/// Internal prompt-cache expiration state for one model +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct UsageCheckpointModelCacheState { + /// Latest known prompt-cache expiration + pub cache_expires_at: String, + /// Retained cache lifetime in seconds, used to refresh expiration after a cache read + #[doc(hidden)] + pub(crate) cache_ttl_seconds: i64, + /// Model identifier associated with this cache state + pub model_id: String, +} + /// Session event "session.usage_checkpoint". Durable session usage checkpoint for reconstructing aggregate accounting on resume #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SessionUsageCheckpointData { + /// Internal per-model prompt-cache state used to restore expiration tracking on resume + #[doc(hidden)] + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) model_cache_state: Option>, /// Session-wide accumulated nano-AI units cost at checkpoint time pub total_nano_aiu: f64, /// Total number of premium API requests used at checkpoint time @@ -1475,6 +1522,20 @@ pub struct AssistantTurnStartData { pub turn_id: String, } +/// Session event "assistant.turn_retry". Metadata for an additional model inference attempt within an existing assistant turn +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AssistantTurnRetryData { + /// Model identifier used for this retry, when known + #[serde(skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Provider or runtime classification that caused the retry, when known + #[serde(skip_serializing_if = "Option::is_none")] + pub reason: Option, + /// Identifier of the turn whose model inference is being retried + pub turn_id: String, +} + /// Session event "assistant.intent". Agent intent description for current activity or plan #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -1870,6 +1931,9 @@ pub struct AssistantUsageData { /// API endpoint used for this model call, matching CAPI supported_endpoints vocabulary #[serde(skip_serializing_if = "Option::is_none")] pub api_endpoint: Option, + /// Updated prompt-cache expiration for this model call. Present only when the call establishes or refreshes known cache state. + #[serde(skip_serializing_if = "Option::is_none")] + pub cache_expires_at: Option, /// Number of tokens read from prompt cache #[serde(skip_serializing_if = "Option::is_none")] pub cache_read_tokens: Option, @@ -1966,6 +2030,9 @@ pub struct ModelCallFailureData { /// Completion ID from the model provider (e.g., chatcmpl-abc123) #[serde(skip_serializing_if = "Option::is_none")] pub api_call_id: Option, + /// API endpoint used for this model call, matching CAPI supported_endpoints vocabulary + #[serde(skip_serializing_if = "Option::is_none")] + pub api_endpoint: Option, /// For HTTP 400 failures only: whether the response carried a structured CAPI error envelope (structured_error, a deterministic validation failure) or no error body (bodyless, the transient gateway/proxy signature). Absent for non-400 failures. #[serde(skip_serializing_if = "Option::is_none")] pub bad_request_kind: Option, @@ -1981,9 +2048,24 @@ pub struct ModelCallFailureData { /// For HTTP 400 failures only: the `type` from the CAPI error envelope (e.g. 'websocket_error'), a coarser companion to errorCode for envelopes that carry no code. Raw server-controlled string, emitted only through restricted telemetry. Absent for bodyless or non-400 failures. #[serde(skip_serializing_if = "Option::is_none")] pub error_type: Option, + /// Whether the failure originated from an API response or the request transport + #[serde(skip_serializing_if = "Option::is_none")] + pub failure_kind: Option, /// What initiated this API call (e.g., "sub-agent", "mcp-sampling"); absent for user-initiated calls #[serde(skip_serializing_if = "Option::is_none")] pub initiator: Option, + /// Whether the session selected Auto mode for the failed call + #[serde(skip_serializing_if = "Option::is_none")] + pub is_auto: Option, + /// Whether the failed call used a bring-your-own-key provider + #[serde(skip_serializing_if = "Option::is_none")] + pub is_byok: Option, + /// Effective maximum output-token limit for the failed call + #[serde(skip_serializing_if = "Option::is_none")] + pub max_output_tokens: Option, + /// Effective maximum prompt-token limit for the failed call + #[serde(skip_serializing_if = "Option::is_none")] + pub max_prompt_tokens: Option, /// Model identifier used for the failed API call #[serde(skip_serializing_if = "Option::is_none")] pub model: Option, @@ -1994,6 +2076,9 @@ pub struct ModelCallFailureData { #[doc(hidden)] #[serde(skip_serializing_if = "Option::is_none")] pub(crate) quota_snapshots: Option>, + /// Reasoning effort level used for the failed model call, if applicable + #[serde(skip_serializing_if = "Option::is_none")] + pub reasoning_effort: Option, /// Content-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures. #[serde(skip_serializing_if = "Option::is_none")] pub request_fingerprint: Option, @@ -2005,6 +2090,20 @@ pub struct ModelCallFailureData { /// HTTP status code from the failed request #[serde(skip_serializing_if = "Option::is_none")] pub status_code: Option, + /// Transport used for the failed model call (http or websocket) + #[serde(skip_serializing_if = "Option::is_none")] + pub transport: Option, +} + +/// Session event "model.call_start". Model API dispatch metadata for internal telemetry +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ModelCallStartData { + /// Model identifier used for this API call, when known + #[serde(skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Identifier of the assistant turn that initiated the model call + pub turn_id: String, } /// Session event "abort". Turn abort information including the reason for termination @@ -2555,6 +2654,16 @@ pub struct ToolExecutionCompleteData { pub turn_id: Option, } +/// Session event "tool_search.activated". Persisted generic client-side tool activations restored when a session resumes. +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ToolSearchActivatedData { + /// Tool-search strategy that activated the definitions. + pub strategy: String, + /// Names of tool definitions activated by this search invocation. + pub tool_names: Vec, +} + /// Session event "skill.invoked". Skill invocation details including content, allowed tools, and plugin metadata #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -4004,6 +4113,30 @@ pub struct SessionManagedSettingsResolvedData { pub source: ManagedSettingsResolvedSource, } +/// Session event "session.managed_settings_enforced". Runtime enforcement of enterprise managed settings: fires when the session blocks or caps a runtime action because enterprise policy governs it, so SDK clients can explain *why* an action was governed. Unlike `session.managed_settings_resolved` (which reports *what* is managed), this reports a concrete governed action — e.g. a user or host tried to turn on a bypass-permissions escalation while policy disables it. Emitted live (not persisted to the session event log) on user/host-initiated attempts only, never for silent policy application. Marked experimental while the managed-settings surface stabilizes. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionManagedSettingsEnforcedData { + /// The category of runtime action that managed policy governed. + pub action: ManagedSettingsEnforcedAction, + /// For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused. Absent for actions without a specific escalation primitive. + #[serde(skip_serializing_if = "Option::is_none")] + pub escalation: Option, + /// Whether the enforcement was forced by fail-closed handling (managed policy could not be determined) rather than an explicit managed setting. When true, `setting` still names the restriction that was applied. + pub fail_closed: bool, + /// A human-readable explanation of why the action was governed, suitable for surfacing to the user. + pub message: String, + /// The managed setting key responsible for the enforcement (e.g. `permissions.disableBypassPermissionsMode`). + pub setting: String, +} + /// A single slash command available in the session, as listed by the `commands.changed` event. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -4830,6 +4963,21 @@ pub enum ModelCallFailureBadRequestKind { Unknown, } +/// Boundary that produced a model call failure +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum ModelCallFailureKind { + /// The provider returned an API error response. + #[serde(rename = "api")] + Api, + /// The request transport failed before a usable API response completed. + #[serde(rename = "transport")] + Transport, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// Where the failed model call originated #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum ModelCallFailureSource { @@ -4848,6 +4996,21 @@ pub enum ModelCallFailureSource { Unknown, } +/// Transport used for a failed model call +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum ModelCallFailureTransport { + /// HTTP transport, including SSE streams. + #[serde(rename = "http")] + Http, + /// WebSocket transport. + #[serde(rename = "websocket")] + Websocket, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// Finite reason code describing why the current turn was aborted #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum AbortReason { @@ -5676,6 +5839,42 @@ pub enum ManagedSettingsResolvedSource { Unknown, } +/// The category of runtime action that enterprise managed settings governed (blocked or capped) +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum ManagedSettingsEnforcedAction { + /// An attempt to turn on a bypass-permissions ("yolo") escalation was refused or capped because policy disables bypass-permissions mode. + #[serde(rename = "bypass_permissions_blocked")] + BypassPermissionsBlocked, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// For a `bypass_permissions_blocked` action, which permission-escalation primitive was refused +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum ManagedSettingsEnforcedEscalation { + /// Full allow-all ("/allow-all on") permissions — auto-approving tools, paths, and URLs. + #[serde(rename = "allow_all")] + AllowAll, + /// Auto-approval of all tool permission requests. + #[serde(rename = "approve_all")] + ApproveAll, + /// Advisory auto-approval ("/allow-all auto") mode — keeps normal prompt paths and adds LLM-advised approval, distinct from full allow-all. + #[serde(rename = "auto_approval")] + AutoApproval, + /// Unrestricted filesystem access outside the session's allowed directories. + #[serde(rename = "unrestricted_paths")] + UnrestrictedPaths, + /// Unrestricted URL fetch access. + #[serde(rename = "unrestricted_urls")] + UnrestrictedUrls, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// Exit plan mode action #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum ExitPlanModeAction { diff --git a/rust/tests/e2e/session.rs b/rust/tests/e2e/session.rs index 744708db7..45932ffdd 100644 --- a/rust/tests/e2e/session.rs +++ b/rust/tests/e2e/session.rs @@ -457,11 +457,17 @@ async fn should_abort_a_session() { assert!(messages .iter() .any(|event| event.parsed_type() == SessionEventType::Abort)); - let answer = session - .send_and_wait("What is 2+2?") + let answer_events = session.subscribe(); + session + .send("What is 2+2?") .await - .expect("send after abort") - .expect("assistant message"); + .expect("send after abort"); + let answer = wait_for_event( + answer_events, + "assistant message after abort", + |event| event.parsed_type() == SessionEventType::AssistantMessage, + ) + .await; assert!(assistant_message_content(&answer).contains('4')); session.disconnect().await.expect("disconnect session"); diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json index 1a8462d66..271270edd 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.71", + "@github/copilot": "^1.0.72", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14", @@ -501,9 +501,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.71.tgz", - "integrity": "sha512-F3axBi+sXSLYDJbxCBW36bM6MYKNC2rlyAf3Ivo/MjiHKKJW7j5AmaR1IRYS9Gt8r9mxOwWFM1cJFA+CuLaR8g==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.72.tgz", + "integrity": "sha512-muxp9clYtDTGB+KaaL3B5YJM/UqMoCKOU1vFoxWB63zPzeDrl2vlRIYc/pQwCCEVf6Agf9KAe4rvzVoOsRrPeg==", "dev": true, "license": "SEE LICENSE IN LICENSE.md", "dependencies": { @@ -513,20 +513,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.71", - "@github/copilot-darwin-x64": "1.0.71", - "@github/copilot-linux-arm64": "1.0.71", - "@github/copilot-linux-x64": "1.0.71", - "@github/copilot-linuxmusl-arm64": "1.0.71", - "@github/copilot-linuxmusl-x64": "1.0.71", - "@github/copilot-win32-arm64": "1.0.71", - "@github/copilot-win32-x64": "1.0.71" + "@github/copilot-darwin-arm64": "1.0.72", + "@github/copilot-darwin-x64": "1.0.72", + "@github/copilot-linux-arm64": "1.0.72", + "@github/copilot-linux-x64": "1.0.72", + "@github/copilot-linuxmusl-arm64": "1.0.72", + "@github/copilot-linuxmusl-x64": "1.0.72", + "@github/copilot-win32-arm64": "1.0.72", + "@github/copilot-win32-x64": "1.0.72" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.71.tgz", - "integrity": "sha512-mEWzyqbqRAWgyU7i2uuSRoVPx/TwaFQX0nZmw0bc30aJ0BnO7cy2kYQyCHw8ykmf/tfxT0xauZ6k0BOFmWizzQ==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.72.tgz", + "integrity": "sha512-hUYF/MwE9dji6XVmZ9DkZ8emV/n1Y/8zuAPI8Yfa4mo7smHcRF3LIUUZMVOwdhl0IZj7rvFJJpjfGjXtP5VGcg==", "cpu": [ "arm64" ], @@ -541,9 +541,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.71.tgz", - "integrity": "sha512-Md9yEg406OBVBx3w4PeEj62TubulVLBcHleqmCoOoUmPgUxPZotUbrqz3rtbzADbXfrrD7JWvVsbd2UiNL194w==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.72.tgz", + "integrity": "sha512-4M5qlL5Tf+DVXBcMEBW8v6fGCQKl2Dnpcj5qhFQbPdARHCZNtkBxg2lHWmbHeNmlMU85tndy2Kzb+iAIALTUAw==", "cpu": [ "x64" ], @@ -558,9 +558,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.71.tgz", - "integrity": "sha512-ykLJYOqBj3jRB5IJCDugLClAqbr7DmtTbUjlNY7+Jdq/n6i+d7xUQGclf1IWL5gnxbGQVAf+zkToD+sRM389Kg==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.72.tgz", + "integrity": "sha512-+3Xzfm6Rb+g/oKlD1ZhYzZnrlRnaLkpMYN/9PBwIvBzj3t+c5sH3TDnCEA17Y5oSJeWhuXEyGr9YhuAIuZPemw==", "cpu": [ "arm64" ], @@ -575,9 +575,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.71.tgz", - "integrity": "sha512-pC0FNHG+BBwZd6yZlM85kkAGN+uJhM6o+THi76N2GnnSxmw7+remb1mvYxdgRVbdCm+LBUIbCKRWJLuMwrfb6A==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.72.tgz", + "integrity": "sha512-PjEJXRoR+SXwFo+GUgogC9DKrl/ZhT+/u1Jd3Sa0SdhWGRRqUjPUBzmNeJN9tcT8Q9VeZ1qSk1beD7JszV57ng==", "cpu": [ "x64" ], @@ -592,9 +592,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.71.tgz", - "integrity": "sha512-hBmDljFTjacxqZTasCEy43H8EIzuXB/hHEBBCMFjhB9J00nIxsO6Dh0woTifKpx7knTYZdpTjjca3D0pAoZlUA==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.72.tgz", + "integrity": "sha512-9gQQkln+qmsmq80eYua9pbaxGOajKVRlYBB+0xYWM+yEUebZB52u/IbUGhWJImvbax8EWqGoTU6ngswrs/nYJA==", "cpu": [ "arm64" ], @@ -609,9 +609,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.71.tgz", - "integrity": "sha512-CfTXU8pa5dxRz22xQzoi3TiG1PJo9+WR8PRDiPSdkIBSyPJ1NvX87DJmfXjTgeAfR+wkjt/p0keDCaBBVhNmUA==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.72.tgz", + "integrity": "sha512-t0mowX6LJSbILBNyJo3jYkSzRrATFTBzks2UUUDvDw1FR0k2VkLNCIq0V6LtdRYfNL/CJRKxzH1TqvdVCFCWcA==", "cpu": [ "x64" ], @@ -626,9 +626,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.71.tgz", - "integrity": "sha512-+HI1DokixXhHUahj06Fw67ZAigBuXKC58BFma4UJOGrQsDgwOSbqeTQHCw6vuymzjKlg3sactfsCUTaefkjscQ==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.72.tgz", + "integrity": "sha512-kbaUKFH7/hZd1Y1WhtuXBRX0gBeIVutUvJ6+SRWD/SkOnRW68nS5RShuRogpXTNM5SmopfFaS3BBaMOu2dFLkg==", "cpu": [ "arm64" ], @@ -643,9 +643,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.71", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.71.tgz", - "integrity": "sha512-02kXOBd9CwBbCaztuf71WYWn+uGapCuiaasomN4tcMH3HBVZ4gi3J0ZUoRcgcS80xh81uQyeBHbnUKzb/RE/9A==", + "version": "1.0.72", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.72.tgz", + "integrity": "sha512-5Jhb38Yk3nHnxwxgE/8vXDKg1b34ZmZ36EceWkLAO3ga9XQYi3njpphRI10G8UahyCBCdzLingY18WKQ28XRiA==", "cpu": [ "x64" ], diff --git a/test/harness/package.json b/test/harness/package.json index 18b19e21a..b9168d30f 100644 --- a/test/harness/package.json +++ b/test/harness/package.json @@ -14,7 +14,7 @@ "node": "^20.19.0 || >=22.12.0" }, "devDependencies": { - "@github/copilot": "^1.0.71", + "@github/copilot": "^1.0.72", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14", diff --git a/test/harness/replayingCapiProxy.test.ts b/test/harness/replayingCapiProxy.test.ts index 009a1e40a..c5747a306 100644 --- a/test/harness/replayingCapiProxy.test.ts +++ b/test/harness/replayingCapiProxy.test.ts @@ -348,9 +348,9 @@ describe("ReplayingCapiProxy", () => { }); test("normalizes task completion notification wording", async () => { - const unreadNotification = [ + const idleNotification = [ "", - 'Agent "sdk-background-agent" (general-purpose) has completed successfully. Use read_agent with agent_id "sdk-background-agent" to retrieve unread results.', + 'Agent "sdk-background-agent" (general-purpose) has finished processing and is now idle. Use read_agent with agent_id "sdk-background-agent" to read the results, or write_agent to send follow-up messages.', "", ].join("\n"); const fullNotification = [ @@ -363,7 +363,7 @@ describe("ReplayingCapiProxy", () => { messages: [ { role: "user", - content: unreadNotification, + content: idleNotification, }, ], }); @@ -509,7 +509,7 @@ Always include PINEAPPLE_COCONUT_42. expect(toolMessages[1].content).toBe("[beta result]"); }); - test("collapses the available-tools list to a stable placeholder", async () => { + test("removes the runtime-specific available-tools list", async () => { const requestBody = JSON.stringify({ messages: [ { role: "user", content: "Help me" }, @@ -543,14 +543,48 @@ Always include PINEAPPLE_COCONUT_42. const toolMessage = result.conversations[0].messages.find( (m) => m.role === "tool", ); - // The whole enumeration collapses so snapshots stay stable as the built-in - // tool set evolves (e.g. write_agent being added). - expect(toolMessage?.content).toBe( - "Tool 'report_intent' does not exist. Available tools that can be called are ${available_tools}.", + expect(toolMessage?.content).toBe("Tool 'report_intent' does not exist."); + }); + + test("removes runtime advisories from background agent start results", async () => { + const stableResult = + "Agent started in background with agent_id: read-file. You'll be notified when it completes. Tell the user you're waiting and end your response, or continue unrelated work until notified."; + const requestBody = JSON.stringify({ + messages: [ + { role: "user", content: "Help me" }, + { + role: "assistant", + tool_calls: [ + { + id: "tc1", + type: "function", + function: { name: "task", arguments: "{}" }, + }, + ], + }, + { + role: "tool", + tool_call_id: "tc1", + content: `${stableResult} The agent supports multi-turn conversations.`, + }, + ], + }); + const responseBody = JSON.stringify({ + choices: [{ message: { role: "assistant", content: "Done" } }], + }); + + const outputPath = await createProxy([ + { url: "/chat/completions", requestBody, responseBody }, + ]); + + const result = await readYamlOutput(outputPath); + const toolMessage = result.conversations[0].messages.find( + (m) => m.role === "tool", ); + expect(toolMessage?.content).toBe(stableResult); }); - test("normalizes read_agent timing metadata", async () => { + test("normalizes read_agent result metadata", async () => { const requestBody = JSON.stringify({ messages: [ { role: "user", content: "Help me" }, @@ -571,7 +605,7 @@ Always include PINEAPPLE_COCONUT_42. role: "tool", tool_call_id: "tc1", content: - "Agent completed. agent_id: read-file, agent_type: explore, status: completed, description: Reading subagent-test.txt, elapsed: 1.25s, total_turns: 0, duration: 2s\n\nDone.", + "Agent is idle (waiting for messages). agent_id: read-file, agent_type: explore, status: idle, description: Reading subagent-test.txt, elapsed: 1.25s, total_turns: 1\n\n[Turn 0]\nDone.", }, ], }); @@ -1075,6 +1109,11 @@ Always include PINEAPPLE_COCONUT_42. 'Agent "read-file" (explore) has completed successfully. Use read_agent with agent_id "read-file" to retrieve unread results.', "", ].join("\n"); + const idleNotification = [ + "", + 'Agent "read-file" (explore) has finished processing and is now idle. Use read_agent with agent_id "read-file" to read the results, or write_agent to send follow-up messages.', + "", + ].join("\n"); const cacheContent = yaml.stringify({ models: ["test-model"], @@ -1107,7 +1146,7 @@ Always include PINEAPPLE_COCONUT_42. { role: "system", content: "Be helpful" }, { role: "user", content: "Hello" }, { role: "assistant", content: "Hi!" }, - { role: "user", content: unreadNotification }, + { role: "user", content: idleNotification }, ], }, }); diff --git a/test/harness/replayingCapiProxy.ts b/test/harness/replayingCapiProxy.ts index 1c29fb755..5e07449f7 100644 --- a/test/harness/replayingCapiProxy.ts +++ b/test/harness/replayingCapiProxy.ts @@ -127,7 +127,8 @@ export class ReplayingCapiProxy extends CapturingHttpProxy { { toolName: "${shell}", normalizer: normalizeShellExitMarkers }, { toolName: "*", normalizer: normalizeGhAuthMessages }, { toolName: "*", normalizer: normalizeAvailableToolNames }, - { toolName: "read_agent", normalizer: normalizeReadAgentTimings }, + { toolName: "*", normalizer: normalizeBackgroundAgentStartMessage }, + { toolName: "read_agent", normalizer: normalizeReadAgentResult }, ]; /** @@ -1223,7 +1224,10 @@ function transformOpenAIRequestMessage( function normalizeUserMessage(content: string): string { return normalizeSkillContextFrontmatter(content) - .replace(taskCompletionNotificationPattern, taskCompletionNotificationReplacement) + .replace( + taskCompletionNotificationPattern, + taskCompletionNotificationReplacement, + ) .replace(/.*?<\/current_datetime>/g, "") .replace(/[\s\S]*?<\/reminder>/g, "") .replace(/[\s\S]*?<\/system_reminder>/g, "") @@ -1237,9 +1241,9 @@ function normalizeUserMessage(content: string): string { } const taskCompletionNotificationPattern = - /Use read_agent with agent_id "([^"]+)" to retrieve unread results\./g; + /Agent "([^"]+)" \(([^)]+)\) (?:has completed successfully|has finished processing and is now idle)\. Use read_agent with agent_id "[^"]+" to (?:retrieve (?:unread results|the full results)|read the results, or write_agent to send follow-up messages)\./g; const taskCompletionNotificationReplacement = - 'Use read_agent with agent_id "$1" to retrieve the full results.'; + 'Agent "$1" ($2) has completed successfully. Use read_agent with agent_id "$1" to retrieve the full results.'; function normalizeStoredUserMessages(conversations: NormalizedConversation[]) { for (const conversation of conversations) { @@ -1299,17 +1303,15 @@ function coalesceMessages( return result; } -// Re-normalizes the built-in tool enumeration in stored tool results at load -// time. Snapshots recorded before normalizeAvailableToolNames collapsed the -// whole list (or recorded against an older tool set) still contain the literal -// enumeration on disk; the result normalizers only run against live requests, -// so without this the stored side would keep the stale list and never match a -// request whose tool set has since changed. +// Apply runtime-dependent tool result normalization to snapshots recorded by +// older CLI versions as well as to live requests. function normalizeStoredToolMessages(conversations: NormalizedConversation[]) { for (const conversation of conversations) { for (const message of conversation.messages) { if (message.role === "tool" && typeof message.content === "string") { message.content = normalizeAvailableToolNames(message.content); + message.content = normalizeBackgroundAgentStartMessage(message.content); + message.content = normalizeReadAgentResult(message.content); } } } @@ -1399,27 +1401,41 @@ function normalizeGh401AuthMessages(result: string): string { return changed ? normalizedLines.join("\n") : result; } -function normalizeReadAgentTimings(result: string): string { - return result +function normalizeReadAgentResult(result: string): string { + const normalized = result + .replace( + /^Agent is idle \(waiting for messages\)\./, + "Agent completed.", + ) + .replace(/^Agent completed\. (.*), status: idle,/, "Agent completed. $1, status: completed,") + .replace( + /, total_turns: \d+(?=\r?\n|$)/, + ", total_turns: 0, duration: 0s", + ) + .replace(/\r?\n\r?\n\[Turn \d+\]\r?\n/, "\n\n"); + + return normalized .replace(/\belapsed: \d+(?:\.\d+)?s\b/g, "elapsed: 0s") .replace(/\bduration: \d+(?:\.\d+)?s\b/g, "duration: 0s"); } -// Stable placeholder for the built-in tool enumeration the runtime emits when a -// nonexistent tool is called (see normalizeAvailableToolNames). -export const availableToolsPlaceholder = "${available_tools}"; - // When a model calls a tool that doesn't exist (e.g., the removed report_intent // tool), the runtime replies with "Available tools that can be called are ." // That enumeration is both platform-specific (shell tool family names differ // across OSes) and runtime-version-specific (built-in tools such as write_agent -// are added or removed over time), so any test that trips this path would break -// whenever the tool set changes. Collapse the whole list to a stable placeholder -// so snapshots keep matching as the built-in tool set evolves. +// are added or removed over time). Some runtime builds omit the enumeration +// entirely, so remove the optional suffix and retain only the stable error. function normalizeAvailableToolNames(result: string): string { return result.replace( - /(Available tools that can be called are )[^.]*/g, - (_full, prefix: string) => prefix + availableToolsPlaceholder, + /(Tool '[^']+' does not exist\.) Available tools that can be called are [^.]*\./g, + "$1", + ); +} + +function normalizeBackgroundAgentStartMessage(result: string): string { + return result.replace( + /^(Agent started in background with agent_id: .*?\. You'll be notified when it completes\. Tell the user you're waiting and end your response, or continue unrelated work until notified\.).*$/s, + "$1", ); }