Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13,609 changes: 9,855 additions & 3,754 deletions dotnet/src/Generated/Rpc.cs

Large diffs are not rendered by default.

174 changes: 87 additions & 87 deletions dotnet/src/Generated/SessionEvents.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dotnet/src/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,7 @@ public async Task LogAsync(string message, SessionLogLevel? level = null, bool?
ArgumentNullException.ThrowIfNull(message);
ThrowIfDisposed();

await Rpc.LogAsync(message, level, ephemeral, url, cancellationToken);
await Rpc.LogAsync(message, level, ephemeral: ephemeral, url: url, cancellationToken: cancellationToken);
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions dotnet/src/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2795,9 +2795,9 @@ public class PingResponse
/// </summary>
public string Message { get; set; } = string.Empty;
/// <summary>
/// Server timestamp when the ping was processed.
/// ISO 8601 timestamp when the ping was processed.
/// </summary>
public long Timestamp { get; set; }
public DateTimeOffset Timestamp { get; set; }
/// <summary>
/// Protocol version supported by the server.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion dotnet/test/E2E/ClientE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public async Task Should_Start_And_Connect_To_Server(bool useStdio)

var pong = await client.PingAsync("test message");
Assert.Equal("pong: test message", pong.Message);
Assert.True(pong.Timestamp >= 0);
Assert.NotEqual(default, pong.Timestamp);

await client.StopAsync();
Assert.Equal(ConnectionState.Disconnected, client.State);
Expand Down
7 changes: 6 additions & 1 deletion dotnet/test/E2E/HookLifecycleAndOutputE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,12 @@ public async Task Should_Allow_PostToolUse_To_Return_ModifiedResult()

return Task.FromResult<PostToolUseHookOutput?>(new PostToolUseHookOutput
{
ModifiedResult = "modified by post hook",
ModifiedResult = new ToolResultObject
{
TextResultForLlm = "modified by post hook",
ResultType = "success",
ToolTelemetry = new Dictionary<string, object>(),
},
SuppressOutput = false,
});
},
Expand Down
5 changes: 3 additions & 2 deletions dotnet/test/E2E/ModeHandlersE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ public async Task Should_Invoke_Auto_Mode_Switch_Handler_When_Rate_Limited()
},
});

const long expectedRetryAfter = 1;
var requestedEventTask = GetNextEventOfTypeAllowingRateLimitAsync<AutoModeSwitchRequestedEvent>(
session,
evt => evt.Data.ErrorCode == "user_weekly_rate_limited" && evt.Data.RetryAfterSeconds == 1,
evt => evt.Data.ErrorCode == "user_weekly_rate_limited" && evt.Data.RetryAfterSeconds == expectedRetryAfter,
TimeSpan.FromSeconds(30),
timeoutDescription: "auto_mode_switch.requested event");
var completedEventTask = GetNextEventOfTypeAllowingRateLimitAsync<AutoModeSwitchCompletedEvent>(
Expand Down Expand Up @@ -137,7 +138,7 @@ public async Task Should_Invoke_Auto_Mode_Switch_Handler_When_Rate_Limited()

var requestedEvent = await requestedEventTask;
Assert.Equal(request.ErrorCode, requestedEvent.Data.ErrorCode);
Assert.Equal(request.RetryAfterSeconds, requestedEvent.Data.RetryAfterSeconds);
Assert.Equal(expectedRetryAfter, requestedEvent.Data.RetryAfterSeconds);

var completedEvent = await completedEventTask;
Assert.Equal(AutoModeSwitchResponse.Yes, completedEvent.Data.Response);
Expand Down
4 changes: 2 additions & 2 deletions dotnet/test/E2E/RpcAdditionalEdgeCasesE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ public async Task Usage_GetMetrics_On_Fresh_Session_Returns_Zero_Tokens()
var metrics = await session.Rpc.Usage.GetMetricsAsync();

// Fresh session = no LLM calls yet. Last-call counters and the user-request count
// must be zero, and SessionStartTime must be a positive epoch (set at create-time).
// must be zero, and SessionStartTime must be populated at create-time.
Assert.Equal(0, metrics.LastCallInputTokens);
Assert.Equal(0, metrics.LastCallOutputTokens);
Assert.Equal(0, metrics.TotalUserRequests);
Assert.True(metrics.SessionStartTime > 0, "SessionStartTime should be a positive epoch.");
Assert.NotEqual(default, metrics.SessionStartTime);
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion dotnet/test/E2E/RpcServerE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public async Task Should_Call_Rpc_Ping_With_Typed_Params_And_Result()
var result = await Client.Rpc.PingAsync(message: "typed rpc test");

Assert.Equal("pong: typed rpc test", result.Message);
Assert.True(result.Timestamp >= 0);
Assert.NotEqual(default, result.Timestamp);
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion dotnet/test/E2E/RpcSessionStateE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ public async Task Should_Call_Session_Usage_And_Permission_Rpcs()
await using var session = await CreateSessionAsync();

var metrics = await session.Rpc.Usage.GetMetricsAsync();
Assert.True(metrics.SessionStartTime > 0);
Assert.NotEqual(default, metrics.SessionStartTime);
Assert.True(metrics.TotalNanoAiu is null or >= 0);
if (metrics.TokenDetails is not null)
{
Expand Down
2 changes: 1 addition & 1 deletion go/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,7 @@ func (c *Client) ActualPort() int {
// if err != nil {
// log.Printf("Server unreachable: %v", err)
// } else {
// log.Printf("Server responded at %d", resp.Timestamp)
// log.Printf("Server responded at %s", resp.Timestamp)
// }
func (c *Client) Ping(ctx context.Context, message string) (*PingResponse, error) {
if c.client == nil {
Expand Down
8 changes: 4 additions & 4 deletions go/internal/e2e/client_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func TestClientE2E(t *testing.T) {
t.Errorf("Expected pong.message to be 'pong: test message', got %q", pong.Message)
}

if pong.Timestamp < 0 {
t.Errorf("Expected pong.timestamp >= 0, got %d", pong.Timestamp)
if pong.Timestamp.IsZero() {
t.Errorf("Expected non-zero pong.timestamp, got %s", pong.Timestamp)
}

if err := client.Stop(); err != nil {
Expand Down Expand Up @@ -75,8 +75,8 @@ func TestClientE2E(t *testing.T) {
t.Errorf("Expected pong.message to be 'pong: test message', got %q", pong.Message)
}

if pong.Timestamp < 0 {
t.Errorf("Expected pong.timestamp >= 0, got %d", pong.Timestamp)
if pong.Timestamp.IsZero() {
t.Errorf("Expected non-zero pong.timestamp, got %s", pong.Timestamp)
}

if err := client.Stop(); err != nil {
Expand Down
6 changes: 5 additions & 1 deletion go/internal/e2e/hooks_extended_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,11 @@ func TestHooksExtendedE2E(t *testing.T) {
return nil, nil
}
return &copilot.PostToolUseHookOutput{
ModifiedResult: "modified by post hook",
ModifiedResult: copilot.ToolResult{
TextResultForLLM: "modified by post hook",
ResultType: "success",
ToolTelemetry: map[string]any{},
},
SuppressOutput: false,
}, nil
},
Expand Down
4 changes: 2 additions & 2 deletions go/internal/e2e/rpc_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ func TestRpcE2E(t *testing.T) {
t.Errorf("Expected message 'pong: typed rpc test', got %q", result.Message)
}

if result.Timestamp < 0 {
t.Errorf("Expected timestamp >= 0, got %d", result.Timestamp)
if result.Timestamp.IsZero() {
t.Errorf("Expected non-zero timestamp, got %s", result.Timestamp)
}

if err := client.Stop(); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion go/internal/e2e/rpc_event_side_effects_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func TestRpcEventSideEffectsE2E(t *testing.T) {
if !strings.EqualFold(rewindData.UpToEventID, targetEventID) {
t.Fatalf("Expected rewind to target %q, got %+v", targetEventID, rewindData)
}
if rewindData.EventsRemoved != float64(truncateResult.EventsRemoved) {
if rewindData.EventsRemoved != truncateResult.EventsRemoved {
t.Fatalf("Expected rewind count %d, got %+v", truncateResult.EventsRemoved, rewindData)
}

Expand Down
4 changes: 2 additions & 2 deletions go/internal/e2e/rpc_server_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func TestRpcServerE2E(t *testing.T) {
if !strings.Contains(result.Message, "typed rpc test") {
t.Errorf("Expected ping response to contain 'typed rpc test', got %q", result.Message)
}
if result.Timestamp < 0 {
t.Errorf("Expected non-negative Timestamp, got %d", result.Timestamp)
if result.Timestamp.IsZero() {
t.Errorf("Expected non-zero Timestamp, got %s", result.Timestamp)
}
})

Expand Down
4 changes: 2 additions & 2 deletions go/internal/e2e/rpc_session_state_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,8 @@ func TestRpcSessionStateE2E(t *testing.T) {
if err != nil {
t.Fatalf("Failed to get usage metrics: %v", err)
}
if metrics.SessionStartTime <= 0 {
t.Errorf("Expected positive sessionStartTime, got %d", metrics.SessionStartTime)
if metrics.SessionStartTime.IsZero() {
t.Errorf("Expected non-zero sessionStartTime, got %s", metrics.SessionStartTime)
}
if metrics.TotalNanoAiu != nil && *metrics.TotalNanoAiu < 0 {
t.Errorf("Expected non-negative totalNanoAiu, got %d", *metrics.TotalNanoAiu)
Expand Down
2 changes: 1 addition & 1 deletion go/internal/e2e/session_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1457,7 +1457,7 @@ func TestSessionAttachmentsE2E(t *testing.T) {
t.Fatalf("CreateSession failed: %v", err)
}

number := float64(1234)
number := int64(1234)
referenceType := copilot.UserMessageAttachmentGithubReferenceTypeIssue
state := "open"
title := "Add E2E attachment coverage"
Expand Down
32 changes: 32 additions & 0 deletions go/rpc/generated_rpc_union_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,38 @@ func TestMcpServerConfigJSONUnion(t *testing.T) {
}
}

func TestTaskProgressUnmarshalsTaskAgentProgressVariants(t *testing.T) {
var agentProgress TaskProgress
if err := json.Unmarshal([]byte(`{"type":"agent","recentActivity":[],"latestIntent":"Summarizing"}`), &agentProgress); err != nil {
t.Fatalf("unmarshal agent task progress: %v", err)
}
agentValue, ok := agentProgress.TaskAgentProgress.(*TaskAgentProgressAgent)
if !ok {
t.Fatalf("agent task progress = %T, want *TaskAgentProgressAgent", agentProgress.TaskAgentProgress)
}
if agentValue.LatestIntent == nil || *agentValue.LatestIntent != "Summarizing" {
t.Fatalf("agent latest intent = %v, want Summarizing", agentValue.LatestIntent)
}
if agentProgress.TaskShellProgress != nil {
t.Fatalf("agent task shell progress = %#v, want nil", *agentProgress.TaskShellProgress)
}

var shellProgress TaskProgress
if err := json.Unmarshal([]byte(`{"type":"shell","recentOutput":"building","pid":123}`), &shellProgress); err != nil {
t.Fatalf("unmarshal shell task progress: %v", err)
}
shellValue, ok := shellProgress.TaskAgentProgress.(*TaskAgentProgressShell)
if !ok {
t.Fatalf("shell task progress = %T, want *TaskAgentProgressShell", shellProgress.TaskAgentProgress)
}
if shellValue.RecentOutput != "building" {
t.Fatalf("shell recent output = %q, want building", shellValue.RecentOutput)
}
if shellValue.Pid == nil || *shellValue.Pid != 123 {
t.Fatalf("shell pid = %v, want 123", shellValue.Pid)
}
}

func TestCommandsInvokeUnmarshalsSlashCommandInvocationResult(t *testing.T) {
clientToServerReader, clientToServerWriter := io.Pipe()
serverToClientReader, serverToClientWriter := io.Pipe()
Expand Down
Loading
Loading