Commit ec72d41
Pass structured tool results via RPC instead of stringifying (#970)
* Pass structured tool results via RPC instead of stringifying
In both the Node and Go SDKs, _executeToolAndRespond / executeToolAndRespond
was converting structured ToolResultObject values into plain JSON strings
before sending them over RPC. This destroyed the object shape, causing
toolTelemetry (and other structured fields like resultType) to be silently
lost on the server side.
Node SDK: detect ToolResultObject by checking for textResultForLlm +
resultType properties and pass it directly to handlePendingToolCall, which
already accepts the union type (string | object) in its RPC schema.
Go SDK: send a ResultUnion with ResultResult populated (preserving
TextResultForLlm, ResultType, Error, and ToolTelemetry) instead of
extracting only the text and sending ResultUnion with String.
Fixes the SDK side of github/copilot-agent-runtime#5574.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review feedback: restore Go fallback, add test, fix snapshot
- Go: restore fallback to fmt.Sprintf when TextResultForLLM is empty,
preserving prior behavior for handlers that don't set it.
- Node: add e2e test verifying toolTelemetry is not leaked into LLM
content and that the tool.execution_complete event fires.
- Update failure-resulttype snapshot to expect just textResultForLlm
content instead of the old stringified JSON.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Strengthen toolTelemetry test assertions
Assert tool.execution_complete event has success=true and that
toolTelemetry, when present, is non-empty (not the {} that results
from the old stringification bug).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add tool_results e2e tests for Python, Go, and .NET
Mirror the Node e2e tests from tool_results.test.ts in all three
remaining SDK languages, reusing the shared YAML snapshots. Each
suite covers:
- structured ToolResultObject with success resultType
- failure resultType
- toolTelemetry preservation (verifies LLM content has no stringified
JSON and no toolTelemetry/resultType leakage)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Python ruff formatting and .NET JSON serialization
- Python: run ruff format on test_tool_results.py
- .NET: add JsonSerializerContext with ToolResultAIContent and pass
serializerOptions to AIFunctionFactory.Create, matching the pattern
used in ToolsTests for complex types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Python line length and .NET partial class for source gen
- Python: split long string on line 54 to stay under 100 char limit
- .NET: mark ToolResultsTests as partial so the nested
ToolResultsJsonContext source generator can emit code
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Python SDK to always send structured tool results
Remove the failure special-case that sent only the error string for
result_type='failure'. Now the Python SDK always sends the full
ResultResult struct (including error, resultType, toolTelemetry),
consistent with Node, Go, and .NET SDKs.
This fixes the e2e test snapshot mismatch: the shared YAML snapshots
expect the CLI to receive a structured result (which it formats as
'Failed to execute ... due to error: Error: Tool execution failed'),
but the old Python path sent only the error string, producing a
different message format that the replay proxy couldn't match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Distinguish exception-originated failures from deliberate ones
The previous commit broke test_handles_tool_calling_errors because
define_tool's exception handler wraps exceptions as ToolResult(failure),
which was then sent as a structured result instead of a top-level error.
Fix: introduce TOOL_EXCEPTION_TEXT constant shared between define_tool's
exception handler and _execute_tool_and_respond. When the failure's
textResultForLlm matches the known exception wrapper message, send via
the top-level error param (CLI formats as 'Failed to execute...');
otherwise send the full structured result to preserve metadata.
This preserves backward compatibility for thrown exceptions while
allowing user-returned ToolResult(failure) to carry toolTelemetry.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address code review: tighter guards, default ResultType, session cleanup
- Node: validate resultType against allowed values in isToolResultObject
- Go: default empty ResultType to 'success' (or 'failure' when error set)
- Python: use _from_exception attribute instead of sentinel string match
- Python/Go: disconnect sessions in e2e tests to avoid leaking state
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add 'timeout' to ToolResultType in Node and Python
The agent runtime recently added 'timeout' as a fifth valid
resultType. Update the type guard and type definitions to match.
* Fix prettier formatting in session.ts
* Make _from_exception a typed dataclass field; revert accidental snapshot changes
- Python: replace dynamic attribute with proper dataclass field
(field(default=False, repr=False)) so type-checkers can see it
- Revert accidentally committed snapshot modifications for
blob_attachments and message_attachments tests
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 8fb154e commit ec72d41
File tree
11 files changed
+559
-17
lines changed- dotnet/test
- go
- internal/e2e
- nodejs
- src
- test/e2e
- python
- copilot
- e2e
- test/snapshots/tool_results
11 files changed
+559
-17
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
620 | 620 | | |
621 | 621 | | |
622 | 622 | | |
623 | | - | |
624 | | - | |
625 | | - | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
626 | 647 | | |
627 | 648 | | |
628 | 649 | | |
629 | | - | |
| 650 | + | |
630 | 651 | | |
631 | 652 | | |
632 | 653 | | |
| |||
0 commit comments