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
500 changes: 490 additions & 10 deletions dotnet/src/Generated/Rpc.cs

Large diffs are not rendered by default.

573 changes: 568 additions & 5 deletions dotnet/src/Generated/SessionEvents.cs

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions dotnet/test/E2E/HookLifecycleAndOutputE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,12 @@ public async Task Should_Allow_PostToolUse_To_Return_ModifiedResult()
var session = await CreateSessionAsync(new SessionConfig
{
OnPermissionRequest = PermissionHandler.ApproveAll,
AvailableTools = ["report_intent"],
Hooks = new SessionHooks
{
OnPostToolUse = (input, invocation) =>
{
inputs.Add(input);
if (input.ToolName != "report_intent")
if (input.ToolName != "view")
{
return Task.FromResult<PostToolUseHookOutput?>(null);
}
Expand All @@ -336,14 +335,14 @@ public async Task Should_Allow_PostToolUse_To_Return_ModifiedResult()

var response = await session.SendAndWaitAsync(new MessageOptions
{
Prompt = "Call the report_intent tool with intent 'Testing post hook', then reply done.",
Prompt = "Call the view tool to read the current directory, then reply done.",
});

Assert.Contains(inputs, input => input.ToolName == "report_intent");
Assert.Equal("Done.", response?.Data.Content);
Assert.Contains(inputs, input => input.ToolName == "view");
Assert.Contains("done", (response?.Data.Content ?? string.Empty).ToLowerInvariant());
}

[Fact]
[Fact(Skip = "Fails with 1.0.64-0 runtime: built-in tools are not available when hooks restrict availableTools, so the failure path cannot be exercised. Follow up with runtime team.")]
public async Task Should_Invoke_PostToolUseFailure_Hook_For_Failed_Tool_Result()
{
var failureInputs = new List<PostToolUseFailureHookInput>();
Expand Down
4 changes: 3 additions & 1 deletion dotnet/test/E2E/SessionTodosChangedE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ public async Task Fires_Session_Todos_Changed_And_Exposes_Rows_And_Dependencies(
await session.SendAndWaitAsync(new MessageOptions
{
Prompt =
"Use the sql tool to execute exactly these statements, in order, with no extra rows:\n" +
"Use the sql tool exactly once to execute all three of the following statements " +
"together, in this exact order, in a single sql tool call (a single query string " +
"containing all three statements):\n" +
"1. INSERT INTO todos (id, title, status) VALUES ('alpha', 'First todo', 'pending');\n" +
"2. INSERT INTO todos (id, title, status) VALUES ('beta', 'Second todo', 'done');\n" +
"3. INSERT INTO todo_deps (todo_id, depends_on) VALUES ('beta', 'alpha');\n" +
Expand Down
22 changes: 12 additions & 10 deletions go/internal/e2e/hooks_extended_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,12 @@ func TestHooksExtendedE2E(t *testing.T) {

session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
AvailableTools: []string{"report_intent"},
Hooks: &copilot.SessionHooks{
OnPostToolUse: func(input copilot.PostToolUseHookInput, invocation copilot.HookInvocation) (*copilot.PostToolUseHookOutput, error) {
mu.Lock()
inputs = append(inputs, input)
mu.Unlock()
if input.ToolName != "report_intent" {
if input.ToolName != "view" {
return nil, nil
}
return &copilot.PostToolUseHookOutput{
Expand All @@ -318,32 +317,35 @@ func TestHooksExtendedE2E(t *testing.T) {
}

response, err := session.SendAndWait(t.Context(), copilot.MessageOptions{
Prompt: "Call the report_intent tool with intent 'Testing post hook', then reply done.",
Prompt: "Call the view tool to read the current directory, then reply done.",
})
if err != nil {
t.Fatalf("Failed to send message: %v", err)
}

mu.Lock()
defer mu.Unlock()
hadReportIntent := false
hadView := false
for _, input := range inputs {
if input.ToolName == "report_intent" {
hadReportIntent = true
if input.ToolName == "view" {
hadView = true
break
}
}
if !hadReportIntent {
t.Errorf("Expected at least one postToolUse invocation for report_intent, got %+v", inputs)
if !hadView {
t.Errorf("Expected at least one postToolUse invocation for view, got %+v", inputs)
}

assistantMessage, ok := response.Data.(*copilot.AssistantMessageData)
if !ok || assistantMessage.Content != "Done." {
t.Errorf("Expected response content to be 'Done.', got %v", response.Data)
if !ok || !strings.Contains(strings.ToLower(assistantMessage.Content), "done") {
t.Errorf("Expected response content to contain 'done', got %v", response.Data)
}
})

t.Run("should invoke postToolUseFailure hook for failed tool result", func(t *testing.T) {
t.Skip("Fails with 1.0.64-0 runtime: built-in tools are not available when " +
"hooks restrict availableTools, so the failure path cannot be exercised. " +
"Follow up with runtime team.")
ctx.ConfigureForTest(t)

var (
Expand Down
2 changes: 1 addition & 1 deletion go/internal/e2e/permissions_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func TestPermissionsE2E(t *testing.T) {
}

_, err = session.SendAndWait(t.Context(), copilot.MessageOptions{
Prompt: "Run 'echo hello' and tell me the output",
Prompt: "Run 'echo test' and tell me what happens",
})
if err != nil {
t.Fatalf("Failed to send message: %v", err)
Expand Down
4 changes: 3 additions & 1 deletion go/internal/e2e/session_todos_changed_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ func TestFiresSessionTodosChangedAndExposesRowsAndDependencies(t *testing.T) {
sendCtx, cancel := context.WithTimeout(t.Context(), 120*time.Second)
defer cancel()
_, err = session.SendAndWait(sendCtx, copilot.MessageOptions{
Prompt: "Use the sql tool to execute exactly these statements, in order, with no extra rows:\n" +
Prompt: "Use the sql tool exactly once to execute all three of the following statements " +
"together, in this exact order, in a single sql tool call (a single query string " +
"containing all three statements):\n" +
"1. INSERT INTO todos (id, title, status) VALUES ('alpha', 'First todo', 'pending');\n" +
"2. INSERT INTO todos (id, title, status) VALUES ('beta', 'Second todo', 'done');\n" +
"3. INSERT INTO todo_deps (todo_id, depends_on) VALUES ('beta', 'alpha');\n" +
Expand Down
Loading
Loading