From bbaed70daa6e519427d64899c69a82d6cd3b15ae Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 4 Mar 2026 10:03:20 -0500 Subject: [PATCH] Register sessions before RPC and add SessionConfig.OnEvent Register sessions in the client's sessions map before issuing the session.create and session.resume RPC calls, so that events emitted by the CLI during the RPC (e.g. session.start, permission requests, tool calls) are not dropped. Previously, sessions were registered only after the RPC completed, creating a window where notifications for the session had no target. The session ID is now generated client-side (via UUID) rather than extracted from the server response. On RPC failure, the session is cleaned up from the map. Add a new OnEvent property to each SDK's session configuration (SessionConfig / ResumeSessionConfig) that registers an event handler on the session before the create/resume RPC is issued. This guarantees that early events emitted by the CLI during session creation (e.g. session.start) are delivered to the handler, unlike calling On() after createSession() returns. Changes across all four SDKs (Node.js, Python, Go, .NET): - Generate sessionId client-side before the RPC - Create and register the session in the sessions map before the RPC - Set workspacePath from the RPC response after it completes - Remove the session from the map if the RPC fails - Add OnEvent/on_event config property wired up before the RPC Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/src/Client.cs | 151 +++++++++------- dotnet/src/Session.cs | 2 +- dotnet/src/Types.cs | 20 +++ dotnet/test/SessionTests.cs | 12 +- go/client.go | 78 +++++--- go/go.mod | 2 + go/go.sum | 2 + go/internal/e2e/session_test.go | 26 ++- go/types.go | 13 +- nodejs/src/client.ts | 169 ++++++++++-------- nodejs/src/session.ts | 2 +- nodejs/src/types.ts | 12 ++ nodejs/test/e2e/session.test.ts | 14 +- python/copilot/client.py | 44 +++-- python/copilot/types.py | 9 +- python/e2e/test_session.py | 16 +- test/scenarios/auth/byok-anthropic/go/go.mod | 5 +- test/scenarios/auth/byok-anthropic/go/go.sum | 2 + test/scenarios/auth/byok-azure/go/go.mod | 5 +- test/scenarios/auth/byok-azure/go/go.sum | 2 + test/scenarios/auth/byok-ollama/go/go.mod | 5 +- test/scenarios/auth/byok-ollama/go/go.sum | 2 + test/scenarios/auth/byok-openai/go/go.mod | 5 +- test/scenarios/auth/byok-openai/go/go.sum | 2 + test/scenarios/auth/gh-app/go/go.mod | 5 +- test/scenarios/auth/gh-app/go/go.sum | 2 + .../bundling/app-backend-to-server/go/go.mod | 5 +- .../bundling/app-backend-to-server/go/go.sum | 2 + .../bundling/app-direct-server/go/go.mod | 5 +- .../bundling/app-direct-server/go/go.sum | 2 + .../bundling/container-proxy/go/go.mod | 5 +- .../bundling/container-proxy/go/go.sum | 2 + .../bundling/fully-bundled/go/go.mod | 5 +- .../bundling/fully-bundled/go/go.sum | 2 + test/scenarios/callbacks/hooks/go/go.mod | 5 +- test/scenarios/callbacks/hooks/go/go.sum | 2 + .../scenarios/callbacks/permissions/go/go.mod | 5 +- .../scenarios/callbacks/permissions/go/go.sum | 2 + test/scenarios/callbacks/user-input/go/go.mod | 5 +- test/scenarios/callbacks/user-input/go/go.sum | 2 + test/scenarios/modes/default/go/go.mod | 5 +- test/scenarios/modes/default/go/go.sum | 2 + test/scenarios/modes/minimal/go/go.mod | 5 +- test/scenarios/modes/minimal/go/go.sum | 2 + test/scenarios/prompts/attachments/go/go.mod | 5 +- test/scenarios/prompts/attachments/go/go.sum | 2 + .../prompts/reasoning-effort/go/go.mod | 5 +- .../prompts/reasoning-effort/go/go.sum | 2 + .../prompts/system-message/go/go.mod | 5 +- .../prompts/system-message/go/go.sum | 2 + .../sessions/concurrent-sessions/go/go.mod | 5 +- .../sessions/concurrent-sessions/go/go.sum | 2 + .../sessions/infinite-sessions/go/go.mod | 5 +- .../sessions/infinite-sessions/go/go.sum | 2 + .../sessions/session-resume/go/go.mod | 5 +- .../sessions/session-resume/go/go.sum | 2 + test/scenarios/sessions/streaming/go/go.mod | 5 +- test/scenarios/sessions/streaming/go/go.sum | 2 + test/scenarios/tools/custom-agents/go/go.mod | 5 +- test/scenarios/tools/custom-agents/go/go.sum | 2 + test/scenarios/tools/mcp-servers/go/go.mod | 5 +- test/scenarios/tools/mcp-servers/go/go.sum | 2 + test/scenarios/tools/no-tools/go/go.mod | 5 +- test/scenarios/tools/no-tools/go/go.sum | 2 + test/scenarios/tools/skills/go/go.mod | 5 +- test/scenarios/tools/skills/go/go.sum | 2 + test/scenarios/tools/tool-filtering/go/go.mod | 5 +- test/scenarios/tools/tool-filtering/go/go.sum | 2 + test/scenarios/tools/tool-overrides/go/go.mod | 5 +- test/scenarios/tools/tool-overrides/go/go.sum | 2 + .../tools/virtual-filesystem/go/go.mod | 5 +- .../tools/virtual-filesystem/go/go.sum | 2 + test/scenarios/transport/reconnect/go/go.mod | 5 +- test/scenarios/transport/reconnect/go/go.sum | 2 + test/scenarios/transport/stdio/go/go.mod | 5 +- test/scenarios/transport/stdio/go/go.sum | 2 + test/scenarios/transport/tcp/go/go.mod | 5 +- test/scenarios/transport/tcp/go/go.sum | 2 + 78 files changed, 580 insertions(+), 209 deletions(-) diff --git a/dotnet/src/Client.cs b/dotnet/src/Client.cs index 1b4da2ff..5b7474a6 100644 --- a/dotnet/src/Client.cs +++ b/dotnet/src/Client.cs @@ -403,34 +403,11 @@ public async Task CreateSessionAsync(SessionConfig config, Cance config.Hooks.OnSessionEnd != null || config.Hooks.OnErrorOccurred != null); - var request = new CreateSessionRequest( - config.Model, - config.SessionId, - config.ClientName, - config.ReasoningEffort, - config.Tools?.Select(ToolDefinition.FromAIFunction).ToList(), - config.SystemMessage, - config.AvailableTools, - config.ExcludedTools, - config.Provider, - (bool?)true, - config.OnUserInputRequest != null ? true : null, - hasHooks ? true : null, - config.WorkingDirectory, - config.Streaming is true ? true : null, - config.McpServers, - "direct", - config.CustomAgents, - config.Agent, - config.ConfigDir, - config.SkillDirectories, - config.DisabledSkills, - config.InfiniteSessions); - - var response = await InvokeRpcAsync( - connection.Rpc, "session.create", [request], cancellationToken); - - var session = new CopilotSession(response.SessionId, connection.Rpc, response.WorkspacePath); + var sessionId = config.SessionId ?? Guid.NewGuid().ToString(); + + // Create and register the session before issuing the RPC so that + // events emitted by the CLI (e.g. session.start) are not dropped. + var session = new CopilotSession(sessionId, connection.Rpc); session.RegisterTools(config.Tools ?? []); session.RegisterPermissionHandler(config.OnPermissionRequest); if (config.OnUserInputRequest != null) @@ -441,10 +418,47 @@ public async Task CreateSessionAsync(SessionConfig config, Cance { session.RegisterHooks(config.Hooks); } + if (config.OnEvent != null) + { + session.On(config.OnEvent); + } + _sessions[sessionId] = session; - if (!_sessions.TryAdd(response.SessionId, session)) + try { - throw new InvalidOperationException($"Session {response.SessionId} already exists"); + var request = new CreateSessionRequest( + config.Model, + sessionId, + config.ClientName, + config.ReasoningEffort, + config.Tools?.Select(ToolDefinition.FromAIFunction).ToList(), + config.SystemMessage, + config.AvailableTools, + config.ExcludedTools, + config.Provider, + (bool?)true, + config.OnUserInputRequest != null ? true : null, + hasHooks ? true : null, + config.WorkingDirectory, + config.Streaming is true ? true : null, + config.McpServers, + "direct", + config.CustomAgents, + config.Agent, + config.ConfigDir, + config.SkillDirectories, + config.DisabledSkills, + config.InfiniteSessions); + + var response = await InvokeRpcAsync( + connection.Rpc, "session.create", [request], cancellationToken); + + session.WorkspacePath = response.WorkspacePath; + } + catch + { + _sessions.TryRemove(sessionId, out _); + throw; } return session; @@ -495,35 +509,9 @@ public async Task ResumeSessionAsync(string sessionId, ResumeSes config.Hooks.OnSessionEnd != null || config.Hooks.OnErrorOccurred != null); - var request = new ResumeSessionRequest( - sessionId, - config.ClientName, - config.Model, - config.ReasoningEffort, - config.Tools?.Select(ToolDefinition.FromAIFunction).ToList(), - config.SystemMessage, - config.AvailableTools, - config.ExcludedTools, - config.Provider, - (bool?)true, - config.OnUserInputRequest != null ? true : null, - hasHooks ? true : null, - config.WorkingDirectory, - config.ConfigDir, - config.DisableResume is true ? true : null, - config.Streaming is true ? true : null, - config.McpServers, - "direct", - config.CustomAgents, - config.Agent, - config.SkillDirectories, - config.DisabledSkills, - config.InfiniteSessions); - - var response = await InvokeRpcAsync( - connection.Rpc, "session.resume", [request], cancellationToken); - - var session = new CopilotSession(response.SessionId, connection.Rpc, response.WorkspacePath); + // Create and register the session before issuing the RPC so that + // events emitted by the CLI (e.g. session.start) are not dropped. + var session = new CopilotSession(sessionId, connection.Rpc); session.RegisterTools(config.Tools ?? []); session.RegisterPermissionHandler(config.OnPermissionRequest); if (config.OnUserInputRequest != null) @@ -534,9 +522,50 @@ public async Task ResumeSessionAsync(string sessionId, ResumeSes { session.RegisterHooks(config.Hooks); } + if (config.OnEvent != null) + { + session.On(config.OnEvent); + } + _sessions[sessionId] = session; + + try + { + var request = new ResumeSessionRequest( + sessionId, + config.ClientName, + config.Model, + config.ReasoningEffort, + config.Tools?.Select(ToolDefinition.FromAIFunction).ToList(), + config.SystemMessage, + config.AvailableTools, + config.ExcludedTools, + config.Provider, + (bool?)true, + config.OnUserInputRequest != null ? true : null, + hasHooks ? true : null, + config.WorkingDirectory, + config.ConfigDir, + config.DisableResume is true ? true : null, + config.Streaming is true ? true : null, + config.McpServers, + "direct", + config.CustomAgents, + config.Agent, + config.SkillDirectories, + config.DisabledSkills, + config.InfiniteSessions); + + var response = await InvokeRpcAsync( + connection.Rpc, "session.resume", [request], cancellationToken); + + session.WorkspacePath = response.WorkspacePath; + } + catch + { + _sessions.TryRemove(sessionId, out _); + throw; + } - // Replace any existing session entry to ensure new config (like permission handler) is used - _sessions[response.SessionId] = session; return session; } diff --git a/dotnet/src/Session.cs b/dotnet/src/Session.cs index b9d70a2a..324b3df6 100644 --- a/dotnet/src/Session.cs +++ b/dotnet/src/Session.cs @@ -86,7 +86,7 @@ public sealed partial class CopilotSession : IAsyncDisposable /// The path to the workspace containing checkpoints/, plan.md, and files/ subdirectories, /// or null if infinite sessions are disabled. /// - public string? WorkspacePath { get; } + public string? WorkspacePath { get; internal set; } /// /// Initializes a new instance of the class. diff --git a/dotnet/src/Types.cs b/dotnet/src/Types.cs index 4d268434..633a9765 100644 --- a/dotnet/src/Types.cs +++ b/dotnet/src/Types.cs @@ -1183,6 +1183,7 @@ protected SessionConfig(SessionConfig? other) ? new Dictionary(other.McpServers, other.McpServers.Comparer) : null; Model = other.Model; + OnEvent = other.OnEvent; OnPermissionRequest = other.OnPermissionRequest; OnUserInputRequest = other.OnUserInputRequest; Provider = other.Provider; @@ -1307,6 +1308,18 @@ protected SessionConfig(SessionConfig? other) /// public InfiniteSessionConfig? InfiniteSessions { get; set; } + /// + /// Optional event handler that is registered on the session before the + /// session.create RPC is issued. + /// + /// + /// Equivalent to calling immediately + /// after creation, but executes earlier in the lifecycle so no events are missed. + /// Using this property rather than guarantees that early events emitted + /// by the CLI during session creation (e.g. session.start) are delivered to the handler. + /// + public SessionEventHandler? OnEvent { get; set; } + /// /// Creates a shallow clone of this instance. /// @@ -1355,6 +1368,7 @@ protected ResumeSessionConfig(ResumeSessionConfig? other) ? new Dictionary(other.McpServers, other.McpServers.Comparer) : null; Model = other.Model; + OnEvent = other.OnEvent; OnPermissionRequest = other.OnPermissionRequest; OnUserInputRequest = other.OnUserInputRequest; Provider = other.Provider; @@ -1482,6 +1496,12 @@ protected ResumeSessionConfig(ResumeSessionConfig? other) /// public InfiniteSessionConfig? InfiniteSessions { get; set; } + /// + /// Optional event handler registered before the session.resume RPC is issued, + /// ensuring early events are delivered. See . + /// + public SessionEventHandler? OnEvent { get; set; } + /// /// Creates a shallow clone of this instance. /// diff --git a/dotnet/test/SessionTests.cs b/dotnet/test/SessionTests.cs index 20d6f3ac..80043958 100644 --- a/dotnet/test/SessionTests.cs +++ b/dotnet/test/SessionTests.cs @@ -245,7 +245,17 @@ await session.SendAsync(new MessageOptions [Fact] public async Task Should_Receive_Session_Events() { - var session = await CreateSessionAsync(); + // Use OnEvent to capture events dispatched during session creation. + // session.start is emitted during the session.create RPC; if the session + // weren't registered in the sessions map before the RPC, it would be dropped. + var earlyEvents = new List(); + var session = await CreateSessionAsync(new SessionConfig + { + OnEvent = evt => earlyEvents.Add(evt), + }); + + Assert.Contains(earlyEvents, evt => evt is SessionStartEvent); + var receivedEvents = new List(); var idleReceived = new TaskCompletionSource(); diff --git a/go/client.go b/go/client.go index d440b49b..021de2b1 100644 --- a/go/client.go +++ b/go/client.go @@ -44,6 +44,8 @@ import ( "sync/atomic" "time" + "github.com/google/uuid" + "github.com/github/copilot-sdk/go/internal/embeddedcli" "github.com/github/copilot-sdk/go/internal/jsonrpc2" "github.com/github/copilot-sdk/go/rpc" @@ -493,7 +495,6 @@ func (c *Client) CreateSession(ctx context.Context, config *SessionConfig) (*Ses req := createSessionRequest{} req.Model = config.Model - req.SessionID = config.SessionID req.ClientName = config.ClientName req.ReasoningEffort = config.ReasoningEffort req.ConfigDir = config.ConfigDir @@ -527,17 +528,15 @@ func (c *Client) CreateSession(ctx context.Context, config *SessionConfig) (*Ses } req.RequestPermission = Bool(true) - result, err := c.client.Request("session.create", req) - if err != nil { - return nil, fmt.Errorf("failed to create session: %w", err) - } - - var response createSessionResponse - if err := json.Unmarshal(result, &response); err != nil { - return nil, fmt.Errorf("failed to unmarshal response: %w", err) + sessionID := config.SessionID + if sessionID == "" { + sessionID = uuid.New().String() } + req.SessionID = sessionID - session := newSession(response.SessionID, c.client, response.WorkspacePath) + // Create and register the session before issuing the RPC so that + // events emitted by the CLI (e.g. session.start) are not dropped. + session := newSession(sessionID, c.client, "") session.registerTools(config.Tools) session.registerPermissionHandler(config.OnPermissionRequest) @@ -547,11 +546,32 @@ func (c *Client) CreateSession(ctx context.Context, config *SessionConfig) (*Ses if config.Hooks != nil { session.registerHooks(config.Hooks) } + if config.OnEvent != nil { + session.On(config.OnEvent) + } c.sessionsMux.Lock() - c.sessions[response.SessionID] = session + c.sessions[sessionID] = session c.sessionsMux.Unlock() + result, err := c.client.Request("session.create", req) + if err != nil { + c.sessionsMux.Lock() + delete(c.sessions, sessionID) + c.sessionsMux.Unlock() + return nil, fmt.Errorf("failed to create session: %w", err) + } + + var response createSessionResponse + if err := json.Unmarshal(result, &response); err != nil { + c.sessionsMux.Lock() + delete(c.sessions, sessionID) + c.sessionsMux.Unlock() + return nil, fmt.Errorf("failed to unmarshal response: %w", err) + } + + session.workspacePath = response.WorkspacePath + return session, nil } @@ -627,17 +647,10 @@ func (c *Client) ResumeSessionWithOptions(ctx context.Context, sessionID string, req.InfiniteSessions = config.InfiniteSessions req.RequestPermission = Bool(true) - result, err := c.client.Request("session.resume", req) - if err != nil { - return nil, fmt.Errorf("failed to resume session: %w", err) - } + // Create and register the session before issuing the RPC so that + // events emitted by the CLI (e.g. session.start) are not dropped. + session := newSession(sessionID, c.client, "") - var response resumeSessionResponse - if err := json.Unmarshal(result, &response); err != nil { - return nil, fmt.Errorf("failed to unmarshal response: %w", err) - } - - session := newSession(response.SessionID, c.client, response.WorkspacePath) session.registerTools(config.Tools) session.registerPermissionHandler(config.OnPermissionRequest) if config.OnUserInputRequest != nil { @@ -646,11 +659,32 @@ func (c *Client) ResumeSessionWithOptions(ctx context.Context, sessionID string, if config.Hooks != nil { session.registerHooks(config.Hooks) } + if config.OnEvent != nil { + session.On(config.OnEvent) + } c.sessionsMux.Lock() - c.sessions[response.SessionID] = session + c.sessions[sessionID] = session c.sessionsMux.Unlock() + result, err := c.client.Request("session.resume", req) + if err != nil { + c.sessionsMux.Lock() + delete(c.sessions, sessionID) + c.sessionsMux.Unlock() + return nil, fmt.Errorf("failed to resume session: %w", err) + } + + var response resumeSessionResponse + if err := json.Unmarshal(result, &response); err != nil { + c.sessionsMux.Lock() + delete(c.sessions, sessionID) + c.sessionsMux.Unlock() + return nil, fmt.Errorf("failed to unmarshal response: %w", err) + } + + session.workspacePath = response.WorkspacePath + return session, nil } diff --git a/go/go.mod b/go/go.mod index c835cc88..48958254 100644 --- a/go/go.mod +++ b/go/go.mod @@ -6,3 +6,5 @@ require ( github.com/google/jsonschema-go v0.4.2 github.com/klauspost/compress v1.18.3 ) + +require github.com/google/uuid v1.6.0 diff --git a/go/go.sum b/go/go.sum index 0cc670e8..2ae02ef3 100644 --- a/go/go.sum +++ b/go/go.sum @@ -2,5 +2,7 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= diff --git a/go/internal/e2e/session_test.go b/go/internal/e2e/session_test.go index 8da66cdd..40f62d4c 100644 --- a/go/internal/e2e/session_test.go +++ b/go/internal/e2e/session_test.go @@ -588,11 +588,31 @@ func TestSession(t *testing.T) { t.Run("should receive session events", func(t *testing.T) { ctx.ConfigureForTest(t) - session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{OnPermissionRequest: copilot.PermissionHandler.ApproveAll}) + // Use OnEvent to capture events dispatched during session creation. + // session.start is emitted during the session.create RPC; if the session + // weren't registered in the sessions map before the RPC, it would be dropped. + var earlyEvents []copilot.SessionEvent + session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + OnEvent: func(event copilot.SessionEvent) { + earlyEvents = append(earlyEvents, event) + }, + }) if err != nil { t.Fatalf("Failed to create session: %v", err) } + hasSessionStart := false + for _, evt := range earlyEvents { + if evt.Type == "session.start" { + hasSessionStart = true + break + } + } + if !hasSessionStart { + t.Error("Expected session.start event via OnEvent during creation") + } + var receivedEvents []copilot.SessionEvent idle := make(chan bool) @@ -737,10 +757,10 @@ func TestSession(t *testing.T) { // Verify both sessions are in the list if !contains(sessionIDs, session1.SessionID) { - t.Errorf("Expected session1 ID %s to be in sessions list", session1.SessionID) + t.Errorf("Expected session1 ID %s to be in sessions list %v", session1.SessionID, sessionIDs) } if !contains(sessionIDs, session2.SessionID) { - t.Errorf("Expected session2 ID %s to be in sessions list", session2.SessionID) + t.Errorf("Expected session2 ID %s to be in sessions list %v", session2.SessionID, sessionIDs) } // Verify session metadata structure diff --git a/go/types.go b/go/types.go index eaee2fb1..a139f294 100644 --- a/go/types.go +++ b/go/types.go @@ -402,9 +402,13 @@ type SessionConfig struct { // InfiniteSessions configures infinite sessions for persistent workspaces and automatic compaction. // When enabled (default), sessions automatically manage context limits and persist state. InfiniteSessions *InfiniteSessionConfig + // OnEvent is an optional event handler that is registered on the session before + // the session.create RPC is issued. This guarantees that early events emitted + // by the CLI during session creation (e.g. session.start) are delivered to the + // handler. Equivalent to calling session.On(handler) immediately after creation, + // but executes earlier in the lifecycle so no events are missed. + OnEvent SessionEventHandler } - -// Tool describes a caller-implemented tool that can be invoked by Copilot type Tool struct { Name string `json:"name"` Description string `json:"description,omitempty"` @@ -490,9 +494,10 @@ type ResumeSessionConfig struct { // DisableResume, when true, skips emitting the session.resume event. // Useful for reconnecting to a session without triggering resume-related side effects. DisableResume bool + // OnEvent is an optional event handler registered before the session.resume RPC + // is issued, ensuring early events are delivered. See SessionConfig.OnEvent. + OnEvent SessionEventHandler } - -// ProviderConfig configures a custom model provider type ProviderConfig struct { // Type is the provider type: "openai", "azure", or "anthropic". Defaults to "openai". Type string `json:"type,omitempty"` diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts index b94c0a5a..bd4cc196 100644 --- a/nodejs/src/client.ts +++ b/nodejs/src/client.ts @@ -12,6 +12,7 @@ */ import { spawn, type ChildProcess } from "node:child_process"; +import { randomUUID } from "node:crypto"; import { existsSync } from "node:fs"; import { Socket } from "node:net"; import { dirname, join } from "node:path"; @@ -546,41 +547,11 @@ export class CopilotClient { } } - const response = await this.connection!.sendRequest("session.create", { - model: config.model, - sessionId: config.sessionId, - clientName: config.clientName, - reasoningEffort: config.reasoningEffort, - tools: config.tools?.map((tool) => ({ - name: tool.name, - description: tool.description, - parameters: toJsonSchema(tool.parameters), - overridesBuiltInTool: tool.overridesBuiltInTool, - })), - systemMessage: config.systemMessage, - availableTools: config.availableTools, - excludedTools: config.excludedTools, - provider: config.provider, - requestPermission: true, - requestUserInput: !!config.onUserInputRequest, - hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)), - workingDirectory: config.workingDirectory, - streaming: config.streaming, - mcpServers: config.mcpServers, - envValueMode: "direct", - customAgents: config.customAgents, - agent: config.agent, - configDir: config.configDir, - skillDirectories: config.skillDirectories, - disabledSkills: config.disabledSkills, - infiniteSessions: config.infiniteSessions, - }); + const sessionId = config.sessionId ?? randomUUID(); - const { sessionId, workspacePath } = response as { - sessionId: string; - workspacePath?: string; - }; - const session = new CopilotSession(sessionId, this.connection!, workspacePath); + // Create and register the session before issuing the RPC so that + // events emitted by the CLI (e.g. session.start) are not dropped. + const session = new CopilotSession(sessionId, this.connection!); session.registerTools(config.tools); session.registerPermissionHandler(config.onPermissionRequest); if (config.onUserInputRequest) { @@ -589,8 +560,52 @@ export class CopilotClient { if (config.hooks) { session.registerHooks(config.hooks); } + if (config.onEvent) { + session.on(config.onEvent); + } this.sessions.set(sessionId, session); + try { + const response = await this.connection!.sendRequest("session.create", { + model: config.model, + sessionId, + clientName: config.clientName, + reasoningEffort: config.reasoningEffort, + tools: config.tools?.map((tool) => ({ + name: tool.name, + description: tool.description, + parameters: toJsonSchema(tool.parameters), + overridesBuiltInTool: tool.overridesBuiltInTool, + })), + systemMessage: config.systemMessage, + availableTools: config.availableTools, + excludedTools: config.excludedTools, + provider: config.provider, + requestPermission: true, + requestUserInput: !!config.onUserInputRequest, + hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)), + workingDirectory: config.workingDirectory, + streaming: config.streaming, + mcpServers: config.mcpServers, + envValueMode: "direct", + customAgents: config.customAgents, + agent: config.agent, + configDir: config.configDir, + skillDirectories: config.skillDirectories, + disabledSkills: config.disabledSkills, + infiniteSessions: config.infiniteSessions, + }); + + const { workspacePath } = response as { + sessionId: string; + workspacePath?: string; + }; + session["_workspacePath"] = workspacePath; + } catch (e) { + this.sessions.delete(sessionId); + throw e; + } + return session; } @@ -633,42 +648,9 @@ export class CopilotClient { } } - const response = await this.connection!.sendRequest("session.resume", { - sessionId, - clientName: config.clientName, - model: config.model, - reasoningEffort: config.reasoningEffort, - systemMessage: config.systemMessage, - availableTools: config.availableTools, - excludedTools: config.excludedTools, - tools: config.tools?.map((tool) => ({ - name: tool.name, - description: tool.description, - parameters: toJsonSchema(tool.parameters), - overridesBuiltInTool: tool.overridesBuiltInTool, - })), - provider: config.provider, - requestPermission: true, - requestUserInput: !!config.onUserInputRequest, - hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)), - workingDirectory: config.workingDirectory, - configDir: config.configDir, - streaming: config.streaming, - mcpServers: config.mcpServers, - envValueMode: "direct", - customAgents: config.customAgents, - agent: config.agent, - skillDirectories: config.skillDirectories, - disabledSkills: config.disabledSkills, - infiniteSessions: config.infiniteSessions, - disableResume: config.disableResume, - }); - - const { sessionId: resumedSessionId, workspacePath } = response as { - sessionId: string; - workspacePath?: string; - }; - const session = new CopilotSession(resumedSessionId, this.connection!, workspacePath); + // Create and register the session before issuing the RPC so that + // events emitted by the CLI (e.g. session.start) are not dropped. + const session = new CopilotSession(sessionId, this.connection!); session.registerTools(config.tools); session.registerPermissionHandler(config.onPermissionRequest); if (config.onUserInputRequest) { @@ -677,7 +659,52 @@ export class CopilotClient { if (config.hooks) { session.registerHooks(config.hooks); } - this.sessions.set(resumedSessionId, session); + if (config.onEvent) { + session.on(config.onEvent); + } + this.sessions.set(sessionId, session); + + try { + const response = await this.connection!.sendRequest("session.resume", { + sessionId, + clientName: config.clientName, + model: config.model, + reasoningEffort: config.reasoningEffort, + systemMessage: config.systemMessage, + availableTools: config.availableTools, + excludedTools: config.excludedTools, + tools: config.tools?.map((tool) => ({ + name: tool.name, + description: tool.description, + parameters: toJsonSchema(tool.parameters), + overridesBuiltInTool: tool.overridesBuiltInTool, + })), + provider: config.provider, + requestPermission: true, + requestUserInput: !!config.onUserInputRequest, + hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)), + workingDirectory: config.workingDirectory, + configDir: config.configDir, + streaming: config.streaming, + mcpServers: config.mcpServers, + envValueMode: "direct", + customAgents: config.customAgents, + agent: config.agent, + skillDirectories: config.skillDirectories, + disabledSkills: config.disabledSkills, + infiniteSessions: config.infiniteSessions, + disableResume: config.disableResume, + }); + + const { workspacePath } = response as { + sessionId: string; + workspacePath?: string; + }; + session["_workspacePath"] = workspacePath; + } catch (e) { + this.sessions.delete(sessionId); + throw e; + } return session; } diff --git a/nodejs/src/session.ts b/nodejs/src/session.ts index c8c88d2c..849daf18 100644 --- a/nodejs/src/session.ts +++ b/nodejs/src/session.ts @@ -77,7 +77,7 @@ export class CopilotSession { constructor( public readonly sessionId: string, private connection: MessageConnection, - private readonly _workspacePath?: string + private _workspacePath?: string ) {} /** diff --git a/nodejs/src/types.ts b/nodejs/src/types.ts index 69c29396..99b9af75 100644 --- a/nodejs/src/types.ts +++ b/nodejs/src/types.ts @@ -756,6 +756,17 @@ export interface SessionConfig { * Set to `{ enabled: false }` to disable. */ infiniteSessions?: InfiniteSessionConfig; + + /** + * Optional event handler that is registered on the session before the + * session.create RPC is issued. This guarantees that early events emitted + * by the CLI during session creation (e.g. session.start) are delivered to + * the handler. + * + * Equivalent to calling `session.on(handler)` immediately after creation, + * but executes earlier in the lifecycle so no events are missed. + */ + onEvent?: SessionEventHandler; } /** @@ -783,6 +794,7 @@ export type ResumeSessionConfig = Pick< | "skillDirectories" | "disabledSkills" | "infiniteSessions" + | "onEvent" > & { /** * When true, skips emitting the session.resume event. diff --git a/nodejs/test/e2e/session.test.ts b/nodejs/test/e2e/session.test.ts index 7cd781bc..0ad60edc 100644 --- a/nodejs/test/e2e/session.test.ts +++ b/nodejs/test/e2e/session.test.ts @@ -297,7 +297,19 @@ describe("Sessions", async () => { }); it("should receive session events", async () => { - const session = await client.createSession({ onPermissionRequest: approveAll }); + // Use onEvent to capture events dispatched during session creation. + // session.start is emitted during the session.create RPC; if the session + // weren't registered in the sessions map before the RPC, it would be dropped. + const earlyEvents: Array<{ type: string }> = []; + const session = await client.createSession({ + onPermissionRequest: approveAll, + onEvent: (event) => { + earlyEvents.push(event); + }, + }); + + expect(earlyEvents.some((e) => e.type === "session.start")).toBe(true); + const receivedEvents: Array<{ type: string }> = []; session.on((event) => { diff --git a/python/copilot/client.py b/python/copilot/client.py index ff587d99..df09a755 100644 --- a/python/copilot/client.py +++ b/python/copilot/client.py @@ -19,6 +19,7 @@ import subprocess import sys import threading +import uuid from collections.abc import Callable from pathlib import Path from typing import Any, cast @@ -507,8 +508,6 @@ async def create_session(self, config: SessionConfig) -> CopilotSession: payload: dict[str, Any] = {} if cfg.get("model"): payload["model"] = cfg["model"] - if cfg.get("session_id"): - payload["sessionId"] = cfg["session_id"] if cfg.get("client_name"): payload["clientName"] = cfg["client_name"] if cfg.get("reasoning_effort"): @@ -609,20 +608,33 @@ async def create_session(self, config: SessionConfig) -> CopilotSession: if not self._client: raise RuntimeError("Client not connected") - response = await self._client.request("session.create", payload) - session_id = response["sessionId"] - workspace_path = response.get("workspacePath") - session = CopilotSession(session_id, self._client, workspace_path) + session_id = cfg.get("session_id") or str(uuid.uuid4()) + payload["sessionId"] = session_id + + # Create and register the session before issuing the RPC so that + # events emitted by the CLI (e.g. session.start) are not dropped. + session = CopilotSession(session_id, self._client, None) session._register_tools(tools) session._register_permission_handler(on_permission_request) if on_user_input_request: session._register_user_input_handler(on_user_input_request) if hooks: session._register_hooks(hooks) + on_event = cfg.get("on_event") + if on_event: + session.on(on_event) with self._sessions_lock: self._sessions[session_id] = session + try: + response = await self._client.request("session.create", payload) + session._workspace_path = response.get("workspacePath") + except BaseException: + with self._sessions_lock: + self._sessions.pop(session_id, None) + raise + return session async def resume_session(self, session_id: str, config: ResumeSessionConfig) -> CopilotSession: @@ -798,19 +810,29 @@ async def resume_session(self, session_id: str, config: ResumeSessionConfig) -> if not self._client: raise RuntimeError("Client not connected") - response = await self._client.request("session.resume", payload) - resumed_session_id = response["sessionId"] - workspace_path = response.get("workspacePath") - session = CopilotSession(resumed_session_id, self._client, workspace_path) + # Create and register the session before issuing the RPC so that + # events emitted by the CLI (e.g. session.start) are not dropped. + session = CopilotSession(session_id, self._client, None) session._register_tools(cfg.get("tools")) session._register_permission_handler(on_permission_request) if on_user_input_request: session._register_user_input_handler(on_user_input_request) if hooks: session._register_hooks(hooks) + on_event = cfg.get("on_event") + if on_event: + session.on(on_event) with self._sessions_lock: - self._sessions[resumed_session_id] = session + self._sessions[session_id] = session + + try: + response = await self._client.request("session.resume", payload) + session._workspace_path = response.get("workspacePath") + except BaseException: + with self._sessions_lock: + self._sessions.pop(session_id, None) + raise return session diff --git a/python/copilot/types.py b/python/copilot/types.py index 5f4b7e20..33764e5d 100644 --- a/python/copilot/types.py +++ b/python/copilot/types.py @@ -526,9 +526,13 @@ class SessionConfig(TypedDict, total=False): # When enabled (default), sessions automatically manage context limits and persist state. # Set to {"enabled": False} to disable. infinite_sessions: InfiniteSessionConfig + # Optional event handler that is registered on the session before the + # session.create RPC is issued, ensuring early events (e.g. session.start) + # are delivered. Equivalent to calling session.on(handler) immediately + # after creation, but executes earlier in the lifecycle so no events are missed. + on_event: Callable[[SessionEvent], None] -# Azure-specific provider options class AzureProviderOptions(TypedDict, total=False): """Azure-specific provider configuration""" @@ -595,6 +599,9 @@ class ResumeSessionConfig(TypedDict, total=False): # When True, skips emitting the session.resume event. # Useful for reconnecting to a session without triggering resume-related side effects. disable_resume: bool + # Optional event handler registered before the session.resume RPC is issued, + # ensuring early events are delivered. See SessionConfig.on_event. + on_event: Callable[[SessionEvent], None] # Options for sending a message to a session diff --git a/python/e2e/test_session.py b/python/e2e/test_session.py index aa93ed42..79fb661d 100644 --- a/python/e2e/test_session.py +++ b/python/e2e/test_session.py @@ -450,9 +450,23 @@ async def test_should_abort_a_session(self, ctx: E2ETestContext): async def test_should_receive_session_events(self, ctx: E2ETestContext): import asyncio + # Use on_event to capture events dispatched during session creation. + # session.start is emitted during the session.create RPC; if the session + # weren't registered in the sessions map before the RPC, it would be dropped. + early_events = [] + + def capture_early(event): + early_events.append(event) + session = await ctx.client.create_session( - {"on_permission_request": PermissionHandler.approve_all} + { + "on_permission_request": PermissionHandler.approve_all, + "on_event": capture_early, + } ) + + assert any(e.type.value == "session.start" for e in early_events) + received_events = [] idle_event = asyncio.Event() diff --git a/test/scenarios/auth/byok-anthropic/go/go.mod b/test/scenarios/auth/byok-anthropic/go/go.mod index 9a727c69..005601ee 100644 --- a/test/scenarios/auth/byok-anthropic/go/go.mod +++ b/test/scenarios/auth/byok-anthropic/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/auth/byok-anthropic/go/go.sum b/test/scenarios/auth/byok-anthropic/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/auth/byok-anthropic/go/go.sum +++ b/test/scenarios/auth/byok-anthropic/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/auth/byok-azure/go/go.mod b/test/scenarios/auth/byok-azure/go/go.mod index f0dd0866..21997114 100644 --- a/test/scenarios/auth/byok-azure/go/go.mod +++ b/test/scenarios/auth/byok-azure/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/auth/byok-azure/go/go.sum b/test/scenarios/auth/byok-azure/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/auth/byok-azure/go/go.sum +++ b/test/scenarios/auth/byok-azure/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/auth/byok-ollama/go/go.mod b/test/scenarios/auth/byok-ollama/go/go.mod index 806aaa5c..a6891a81 100644 --- a/test/scenarios/auth/byok-ollama/go/go.mod +++ b/test/scenarios/auth/byok-ollama/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/auth/byok-ollama/go/go.sum b/test/scenarios/auth/byok-ollama/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/auth/byok-ollama/go/go.sum +++ b/test/scenarios/auth/byok-ollama/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/auth/byok-openai/go/go.mod b/test/scenarios/auth/byok-openai/go/go.mod index 2d5a75ec..65b3c902 100644 --- a/test/scenarios/auth/byok-openai/go/go.mod +++ b/test/scenarios/auth/byok-openai/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/auth/byok-openai/go/go.sum b/test/scenarios/auth/byok-openai/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/auth/byok-openai/go/go.sum +++ b/test/scenarios/auth/byok-openai/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/auth/gh-app/go/go.mod b/test/scenarios/auth/gh-app/go/go.mod index a0d270c6..7012daa6 100644 --- a/test/scenarios/auth/gh-app/go/go.mod +++ b/test/scenarios/auth/gh-app/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/auth/gh-app/go/go.sum b/test/scenarios/auth/gh-app/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/auth/gh-app/go/go.sum +++ b/test/scenarios/auth/gh-app/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/bundling/app-backend-to-server/go/go.mod b/test/scenarios/bundling/app-backend-to-server/go/go.mod index 6d01df73..c225d6a2 100644 --- a/test/scenarios/bundling/app-backend-to-server/go/go.mod +++ b/test/scenarios/bundling/app-backend-to-server/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/bundling/app-backend-to-server/go/go.sum b/test/scenarios/bundling/app-backend-to-server/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/bundling/app-backend-to-server/go/go.sum +++ b/test/scenarios/bundling/app-backend-to-server/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/bundling/app-direct-server/go/go.mod b/test/scenarios/bundling/app-direct-server/go/go.mod index db24ae39..e36e0f50 100644 --- a/test/scenarios/bundling/app-direct-server/go/go.mod +++ b/test/scenarios/bundling/app-direct-server/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/bundling/app-direct-server/go/go.sum b/test/scenarios/bundling/app-direct-server/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/bundling/app-direct-server/go/go.sum +++ b/test/scenarios/bundling/app-direct-server/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/bundling/container-proxy/go/go.mod b/test/scenarios/bundling/container-proxy/go/go.mod index 086f4317..270a60c6 100644 --- a/test/scenarios/bundling/container-proxy/go/go.mod +++ b/test/scenarios/bundling/container-proxy/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/bundling/container-proxy/go/go.sum b/test/scenarios/bundling/container-proxy/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/bundling/container-proxy/go/go.sum +++ b/test/scenarios/bundling/container-proxy/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/bundling/fully-bundled/go/go.mod b/test/scenarios/bundling/fully-bundled/go/go.mod index 93af1915..5c7d03b1 100644 --- a/test/scenarios/bundling/fully-bundled/go/go.mod +++ b/test/scenarios/bundling/fully-bundled/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/bundling/fully-bundled/go/go.sum b/test/scenarios/bundling/fully-bundled/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/bundling/fully-bundled/go/go.sum +++ b/test/scenarios/bundling/fully-bundled/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/callbacks/hooks/go/go.mod b/test/scenarios/callbacks/hooks/go/go.mod index 51b27e49..3220cd50 100644 --- a/test/scenarios/callbacks/hooks/go/go.mod +++ b/test/scenarios/callbacks/hooks/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/callbacks/hooks/go/go.sum b/test/scenarios/callbacks/hooks/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/callbacks/hooks/go/go.sum +++ b/test/scenarios/callbacks/hooks/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/callbacks/permissions/go/go.mod b/test/scenarios/callbacks/permissions/go/go.mod index 25eb7d22..bf88ca7e 100644 --- a/test/scenarios/callbacks/permissions/go/go.mod +++ b/test/scenarios/callbacks/permissions/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/callbacks/permissions/go/go.sum b/test/scenarios/callbacks/permissions/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/callbacks/permissions/go/go.sum +++ b/test/scenarios/callbacks/permissions/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/callbacks/user-input/go/go.mod b/test/scenarios/callbacks/user-input/go/go.mod index 11419b63..b050ef88 100644 --- a/test/scenarios/callbacks/user-input/go/go.mod +++ b/test/scenarios/callbacks/user-input/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/callbacks/user-input/go/go.sum b/test/scenarios/callbacks/user-input/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/callbacks/user-input/go/go.sum +++ b/test/scenarios/callbacks/user-input/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/modes/default/go/go.mod b/test/scenarios/modes/default/go/go.mod index 50b92181..5ce3524d 100644 --- a/test/scenarios/modes/default/go/go.mod +++ b/test/scenarios/modes/default/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/modes/default/go/go.sum b/test/scenarios/modes/default/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/modes/default/go/go.sum +++ b/test/scenarios/modes/default/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/modes/minimal/go/go.mod b/test/scenarios/modes/minimal/go/go.mod index 72fbe354..c8eb4bbf 100644 --- a/test/scenarios/modes/minimal/go/go.mod +++ b/test/scenarios/modes/minimal/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/modes/minimal/go/go.sum b/test/scenarios/modes/minimal/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/modes/minimal/go/go.sum +++ b/test/scenarios/modes/minimal/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/prompts/attachments/go/go.mod b/test/scenarios/prompts/attachments/go/go.mod index 0a5dc6c1..22aa80a1 100644 --- a/test/scenarios/prompts/attachments/go/go.mod +++ b/test/scenarios/prompts/attachments/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/prompts/attachments/go/go.sum b/test/scenarios/prompts/attachments/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/prompts/attachments/go/go.sum +++ b/test/scenarios/prompts/attachments/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/prompts/reasoning-effort/go/go.mod b/test/scenarios/prompts/reasoning-effort/go/go.mod index f2aa4740..b3fafcc1 100644 --- a/test/scenarios/prompts/reasoning-effort/go/go.mod +++ b/test/scenarios/prompts/reasoning-effort/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/prompts/reasoning-effort/go/go.sum b/test/scenarios/prompts/reasoning-effort/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/prompts/reasoning-effort/go/go.sum +++ b/test/scenarios/prompts/reasoning-effort/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/prompts/system-message/go/go.mod b/test/scenarios/prompts/system-message/go/go.mod index b8301c15..8bc1c55c 100644 --- a/test/scenarios/prompts/system-message/go/go.mod +++ b/test/scenarios/prompts/system-message/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/prompts/system-message/go/go.sum b/test/scenarios/prompts/system-message/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/prompts/system-message/go/go.sum +++ b/test/scenarios/prompts/system-message/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/sessions/concurrent-sessions/go/go.mod b/test/scenarios/sessions/concurrent-sessions/go/go.mod index c0164232..a69dedd1 100644 --- a/test/scenarios/sessions/concurrent-sessions/go/go.mod +++ b/test/scenarios/sessions/concurrent-sessions/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/sessions/concurrent-sessions/go/go.sum b/test/scenarios/sessions/concurrent-sessions/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/sessions/concurrent-sessions/go/go.sum +++ b/test/scenarios/sessions/concurrent-sessions/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/sessions/infinite-sessions/go/go.mod b/test/scenarios/sessions/infinite-sessions/go/go.mod index cb8d2713..15f8e48f 100644 --- a/test/scenarios/sessions/infinite-sessions/go/go.mod +++ b/test/scenarios/sessions/infinite-sessions/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/sessions/infinite-sessions/go/go.sum b/test/scenarios/sessions/infinite-sessions/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/sessions/infinite-sessions/go/go.sum +++ b/test/scenarios/sessions/infinite-sessions/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/sessions/session-resume/go/go.mod b/test/scenarios/sessions/session-resume/go/go.mod index 3722b78d..ab1b82c3 100644 --- a/test/scenarios/sessions/session-resume/go/go.mod +++ b/test/scenarios/sessions/session-resume/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/sessions/session-resume/go/go.sum b/test/scenarios/sessions/session-resume/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/sessions/session-resume/go/go.sum +++ b/test/scenarios/sessions/session-resume/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/sessions/streaming/go/go.mod b/test/scenarios/sessions/streaming/go/go.mod index acb51637..f6c55368 100644 --- a/test/scenarios/sessions/streaming/go/go.mod +++ b/test/scenarios/sessions/streaming/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/sessions/streaming/go/go.sum b/test/scenarios/sessions/streaming/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/sessions/streaming/go/go.sum +++ b/test/scenarios/sessions/streaming/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/tools/custom-agents/go/go.mod b/test/scenarios/tools/custom-agents/go/go.mod index 9acbccb0..f6f670b8 100644 --- a/test/scenarios/tools/custom-agents/go/go.mod +++ b/test/scenarios/tools/custom-agents/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/tools/custom-agents/go/go.sum b/test/scenarios/tools/custom-agents/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/tools/custom-agents/go/go.sum +++ b/test/scenarios/tools/custom-agents/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/tools/mcp-servers/go/go.mod b/test/scenarios/tools/mcp-servers/go/go.mod index 4b93e09e..65de0a40 100644 --- a/test/scenarios/tools/mcp-servers/go/go.mod +++ b/test/scenarios/tools/mcp-servers/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/tools/mcp-servers/go/go.sum b/test/scenarios/tools/mcp-servers/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/tools/mcp-servers/go/go.sum +++ b/test/scenarios/tools/mcp-servers/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/tools/no-tools/go/go.mod b/test/scenarios/tools/no-tools/go/go.mod index 74131d3e..387c1b51 100644 --- a/test/scenarios/tools/no-tools/go/go.mod +++ b/test/scenarios/tools/no-tools/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/tools/no-tools/go/go.sum b/test/scenarios/tools/no-tools/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/tools/no-tools/go/go.sum +++ b/test/scenarios/tools/no-tools/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/tools/skills/go/go.mod b/test/scenarios/tools/skills/go/go.mod index 1467fd64..ad94ef6b 100644 --- a/test/scenarios/tools/skills/go/go.mod +++ b/test/scenarios/tools/skills/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/tools/skills/go/go.sum b/test/scenarios/tools/skills/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/tools/skills/go/go.sum +++ b/test/scenarios/tools/skills/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/tools/tool-filtering/go/go.mod b/test/scenarios/tools/tool-filtering/go/go.mod index c3051c52..ad36d3f6 100644 --- a/test/scenarios/tools/tool-filtering/go/go.mod +++ b/test/scenarios/tools/tool-filtering/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/tools/tool-filtering/go/go.sum b/test/scenarios/tools/tool-filtering/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/tools/tool-filtering/go/go.sum +++ b/test/scenarios/tools/tool-filtering/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/tools/tool-overrides/go/go.mod b/test/scenarios/tools/tool-overrides/go/go.mod index 35306676..ba48b0e7 100644 --- a/test/scenarios/tools/tool-overrides/go/go.mod +++ b/test/scenarios/tools/tool-overrides/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/tools/tool-overrides/go/go.sum b/test/scenarios/tools/tool-overrides/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/tools/tool-overrides/go/go.sum +++ b/test/scenarios/tools/tool-overrides/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/tools/virtual-filesystem/go/go.mod b/test/scenarios/tools/virtual-filesystem/go/go.mod index d6606bb7..e5f12161 100644 --- a/test/scenarios/tools/virtual-filesystem/go/go.mod +++ b/test/scenarios/tools/virtual-filesystem/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/tools/virtual-filesystem/go/go.sum b/test/scenarios/tools/virtual-filesystem/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/tools/virtual-filesystem/go/go.sum +++ b/test/scenarios/tools/virtual-filesystem/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/transport/reconnect/go/go.mod b/test/scenarios/transport/reconnect/go/go.mod index 7a1f80d6..e1267bb7 100644 --- a/test/scenarios/transport/reconnect/go/go.mod +++ b/test/scenarios/transport/reconnect/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/transport/reconnect/go/go.sum b/test/scenarios/transport/reconnect/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/transport/reconnect/go/go.sum +++ b/test/scenarios/transport/reconnect/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/transport/stdio/go/go.mod b/test/scenarios/transport/stdio/go/go.mod index 2dcc3531..63ad24be 100644 --- a/test/scenarios/transport/stdio/go/go.mod +++ b/test/scenarios/transport/stdio/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/transport/stdio/go/go.sum b/test/scenarios/transport/stdio/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/transport/stdio/go/go.sum +++ b/test/scenarios/transport/stdio/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/test/scenarios/transport/tcp/go/go.mod b/test/scenarios/transport/tcp/go/go.mod index dc1a0b6f..85fac792 100644 --- a/test/scenarios/transport/tcp/go/go.mod +++ b/test/scenarios/transport/tcp/go/go.mod @@ -4,6 +4,9 @@ go 1.24 require github.com/github/copilot-sdk/go v0.0.0 -require github.com/google/jsonschema-go v0.4.2 // indirect +require ( + github.com/google/jsonschema-go v0.4.2 // indirect + github.com/google/uuid v1.6.0 // indirect +) replace github.com/github/copilot-sdk/go => ../../../../../go diff --git a/test/scenarios/transport/tcp/go/go.sum b/test/scenarios/transport/tcp/go/go.sum index 6e171099..6029a9b7 100644 --- a/test/scenarios/transport/tcp/go/go.sum +++ b/test/scenarios/transport/tcp/go/go.sum @@ -2,3 +2,5 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=