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 1b4da2ffb..5b7474a64 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 b9d70a2ab..324b3df6d 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 4d268434e..633a97654 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 20d6f3ac5..800439584 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 d440b49b4..021de2b14 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 c835cc889..489582545 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 0cc670e8f..2ae02ef35 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 8da66cdd2..40f62d4c6 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 eaee2fb11..a139f294f 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 b94c0a5a6..bd4cc1960 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 c8c88d2cd..849daf188 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 69c29396a..99b9af75c 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 7cd781bc2..0ad60edca 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 ff587d997..df09a755b 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 5f4b7e20d..33764e5d1 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 aa93ed42d..79fb661df 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 9a727c69c..005601ee3 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 6e171099c..6029a9b71 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 f0dd08661..21997114b 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 6e171099c..6029a9b71 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 806aaa5c2..a6891a811 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 6e171099c..6029a9b71 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 2d5a75ecf..65b3c9028 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 6e171099c..6029a9b71 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 a0d270c6e..7012daa68 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 6e171099c..6029a9b71 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 6d01df73b..c225d6a2c 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 6e171099c..6029a9b71 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 db24ae393..e36e0f50d 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 6e171099c..6029a9b71 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 086f43175..270a60c61 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 6e171099c..6029a9b71 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 93af1915a..5c7d03b11 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 6e171099c..6029a9b71 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 51b27e491..3220cd506 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 6e171099c..6029a9b71 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 25eb7d22a..bf88ca7ec 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 6e171099c..6029a9b71 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 11419b634..b050ef88b 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 6e171099c..6029a9b71 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 50b92181f..5ce3524d7 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 6e171099c..6029a9b71 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 72fbe3540..c8eb4bbfd 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 6e171099c..6029a9b71 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 0a5dc6c1f..22aa80a14 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 6e171099c..6029a9b71 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 f2aa4740c..b3fafcc1c 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 6e171099c..6029a9b71 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 b8301c15a..8bc1c55ce 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 6e171099c..6029a9b71 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 c01642320..a69dedd16 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 6e171099c..6029a9b71 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 cb8d2713d..15f8e48f7 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 6e171099c..6029a9b71 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 3722b78d2..ab1b82c39 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 6e171099c..6029a9b71 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 acb516379..f6c553680 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 6e171099c..6029a9b71 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 9acbccb06..f6f670b8c 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 6e171099c..6029a9b71 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 4b93e09e7..65de0a40b 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 6e171099c..6029a9b71 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 74131d3e6..387c1b51d 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 6e171099c..6029a9b71 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 1467fd64f..ad94ef6b7 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 6e171099c..6029a9b71 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 c3051c52b..ad36d3f63 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 6e171099c..6029a9b71 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 353066761..ba48b0e7b 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 6e171099c..6029a9b71 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 d6606bb7b..e5f121611 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 6e171099c..6029a9b71 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 7a1f80d6c..e1267bb72 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 6e171099c..6029a9b71 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 2dcc35310..63ad24bee 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 6e171099c..6029a9b71 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 dc1a0b6f9..85fac7926 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 6e171099c..6029a9b71 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=