| ... | @@ -2821,6 +2821,67 @@ describe("PiAdapterV2", () => { | ... | @@ -2821,6 +2821,67 @@ describe("PiAdapterV2", () => { |
| 2821 | ), | 2821 | ), |
| 2822 | ); | 2822 | ); |
| 2823 | | 2823 | |
| | 2824 | it.effect.each([ |
| | 2825 | { toolName: "bash", exitCode: 0, legacy: false }, |
| | 2826 | { toolName: "powershell", exitCode: 2, legacy: false }, |
| | 2827 | { toolName: "bash", exitCode: 1, legacy: true }, |
| | 2828 | { toolName: "powershell", exitCode: 0, legacy: true }, |
| | 2829 | ])( |
| | 2830 | "normalizes $toolName command results, exit=$exitCode legacy=$legacy", |
| | 2831 | ({ toolName, exitCode, legacy }) => |
| | 2832 | Effect.gen(function* () { |
| | 2833 | const fake = yield* makeFakePi; |
| | 2834 | const { runtime, takeEvent } = yield* openRuntime(fake); |
| | 2835 | const providerThread = yield* runtime.ensureThread({ |
| | 2836 | threadId: THREAD_ID, |
| | 2837 | modelSelection: modelSelection("default"), |
| | 2838 | runtimePolicy, |
| | 2839 | }); |
| | 2840 | yield* startTurn(runtime, providerThread); |
| | 2841 | yield* fake.takeRequest("prompt"); |
| | 2842 | yield* fake.emit({ |
| | 2843 | type: "tool_execution_start", |
| | 2844 | toolCallId: "shell-call", |
| | 2845 | toolName, |
| | 2846 | args: { command: "echo hello" }, |
| | 2847 | }); |
| | 2848 | const running = yield* takeEvent( |
| | 2849 | (event) => |
| | 2850 | event.type === "turn_item.updated" && event.turnItem.type === "command_execution", |
| | 2851 | ); |
| | 2852 | assert.isTrue( |
| | 2853 | running.type === "turn_item.updated" && |
| | 2854 | running.turnItem.type === "command_execution" && |
| | 2855 | running.turnItem.status === "running" && |
| | 2856 | running.turnItem.input === "echo hello", |
| | 2857 | ); |
| | 2858 | yield* fake.emit({ |
| | 2859 | type: "tool_execution_end", |
| | 2860 | toolCallId: "shell-call", |
| | 2861 | toolName, |
| | 2862 | isError: exitCode !== 0, |
| | 2863 | result: { |
| | 2864 | content: [{ type: "text", text: "hello" }], |
| | 2865 | details: { exitCode: legacy ? exitCode : 99 }, |
| | 2866 | ...(legacy ? {} : { structuredContent: { exit_code: exitCode } }), |
| | 2867 | }, |
| | 2868 | }); |
| | 2869 | const completed = yield* takeEvent( |
| | 2870 | (event) => |
| | 2871 | event.type === "turn_item.updated" && event.turnItem.type === "command_execution", |
| | 2872 | ); |
| | 2873 | assert.isTrue( |
| | 2874 | completed.type === "turn_item.updated" && |
| | 2875 | completed.turnItem.type === "command_execution" && |
| | 2876 | completed.turnItem.title === toolName && |
| | 2877 | completed.turnItem.input === "echo hello" && |
| | 2878 | completed.turnItem.output === "hello" && |
| | 2879 | completed.turnItem.exitCode === exitCode && |
| | 2880 | completed.turnItem.status === (exitCode === 0 ? "completed" : "failed"), |
| | 2881 | ); |
| | 2882 | }).pipe(Effect.scoped, Effect.provide(layerTest)), |
| | 2883 | ); |
| | 2884 | |
| 2824 | it.effect("emits session-start dialogs before a turn exists", () => | 2885 | it.effect("emits session-start dialogs before a turn exists", () => |
| 2825 | Effect.gen(function* () { | 2886 | Effect.gen(function* () { |
| 2826 | const fake = yield* makeFakePi; | 2887 | const fake = yield* makeFakePi; |