History

fix opencing in browser

Rhys Sullivan committed 8 months ago

Commit e7159681 parent f93d2873 files · +93 −14Browse files

Unified · Split

3 files
  1. apps/executor/src/cli/interaction-handling.test.ts +37 −0
  2. apps/executor/src/cli/interaction-handling.ts +18 −0
  3. apps/executor/src/cli/main.ts +38 −14
apps/executor/src/cli/interaction-handling.test.ts+37−0
@@ -0,0 +1,37 @@
1+import { describe, expect, it } from "@effect/vitest";
2+
3+import { decideInteractionHandling } from "./interaction-handling";
4+
5+describe("interaction-handling", () => {
6+ it("keeps URL interactions distinct when the terminal is non-interactive", () => {
7+ expect(decideInteractionHandling({
8+ parsed: {
9+ mode: "url",
10+ message: "Connect Axiom",
11+ url: "https://mcp.axiom.co/authorize",
12+ },
13+ isInteractiveTerminal: false,
14+ })).toBe("url_paused");
15+ });
16+
17+ it("waits on URL interactions in an interactive terminal", () => {
18+ expect(decideInteractionHandling({
19+ parsed: {
20+ mode: "url",
21+ message: "Connect Axiom",
22+ url: "https://mcp.axiom.co/authorize",
23+ },
24+ isInteractiveTerminal: true,
25+ })).toBe("url_interactive");
26+ });
27+
28+ it("falls back to form pause handling for non-interactive prompts", () => {
29+ expect(decideInteractionHandling({
30+ parsed: {
31+ mode: "form",
32+ message: "Approve tool call",
33+ },
34+ isInteractiveTerminal: false,
35+ })).toBe("form_paused");
36+ });
37+});
apps/executor/src/cli/interaction-handling.ts+18−0
@@ -0,0 +1,18 @@
1+import type { ParsedInteractionPayload } from "./pending-interaction-output";
2+
3+export type InteractionHandling =
4+ | "url_interactive"
5+ | "url_paused"
6+ | "form_interactive"
7+ | "form_paused";
8+
9+export const decideInteractionHandling = (input: {
10+ parsed: ParsedInteractionPayload | null;
11+ isInteractiveTerminal: boolean;
12+}): InteractionHandling => {
13+ if (input.parsed?.mode === "url") {
14+ return input.isInteractiveTerminal ? "url_interactive" : "url_paused";
15+ }
16+
17+ return input.isInteractiveTerminal ? "form_interactive" : "form_paused";
18+};
apps/executor/src/cli/main.ts+38−14
@@ -52,6 +52,7 @@ import { · 51 unmodified lines
5252 buildPausedExecutionOutput,
5353 parseInteractionPayload,
5454 } from "./pending-interaction-output";
55+import { decideInteractionHandling } from "./interaction-handling";
5556
5657 const toError = (cause: unknown): Error =>
5758 cause instanceof Error ? cause : new Error(String(cause));
@@ -1020,8 +1021,32 @@ const driveExecution = (input: { · 962 unmodified lines
10201021 }
10211022
10221023 const parsed = parseInteractionPayload(pending);
1023− const isInteractiveTerminal = process.stdin.isTTY && process.stdout.isTTY;
1024− if (!isInteractiveTerminal) {
1024+ const handling = decideInteractionHandling({
1025+ parsed,
1026+ isInteractiveTerminal: process.stdin.isTTY && process.stdout.isTTY,
1027+ });
1028+
1029+ if (handling === "url_interactive" && parsed?.mode === "url") {
1030+ yield* printUrlInteraction({
1031+ message: parsed.message,
1032+ url: parsed.url ?? null,
1033+ shouldOpen: input.shouldOpenUrls,
1034+ });
1035+
1036+ current = yield* waitForExecutionProgress({
1037+ client: input.client,
1038+ workspaceId: input.workspaceId,
1039+ executionId: current.execution.id,
1040+ pendingInteractionId: pending.id,
1041+ });
1042+ continue;
1043+ }
1044+
1045+ if (handling === "url_paused") {
1046+ if (input.shouldOpenUrls && parsed?.mode === "url" && parsed.url) {
1047+ yield* openUrlInBrowser(parsed.url);
1048+ }
1049+
10251050 const paused = buildPausedExecutionOutput({
10261051 executionId: current.execution.id,
10271052 interaction: pending,
@@ -1036,20 +1061,19 @@ const driveExecution = (input: { · 8 unmodified lines
10361061 return current;
10371062 }
10381063
1039− if (parsed?.mode === "url") {
1040− yield* printUrlInteraction({
1041− message: parsed.message,
1042− url: parsed.url ?? null,
1043− shouldOpen: input.shouldOpenUrls,
1044− });
1045−
1046− current = yield* waitForExecutionProgress({
1047− client: input.client,
1048− workspaceId: input.workspaceId,
1064+ if (handling === "form_paused") {
1065+ const paused = buildPausedExecutionOutput({
10491066 executionId: current.execution.id,
1050− pendingInteractionId: pending.id,
1067+ interaction: pending,
1068+ baseUrl: input.baseUrl,
1069+ shouldOpenUrls: input.shouldOpenUrls,
1070+ cliName: CLI_NAME,
10511071 });
1052− continue;
1072+ yield* Effect.sync(() => {
1073+ console.log(JSON.stringify(paused));
1074+ process.exitCode = 20;
1075+ });
1076+ return current;
10531077 }
10541078
10551079 const responseJson = yield* promptInteraction({