@cursor/july 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +16 -5
- package/README.md +8 -9
- package/dist/bin/agent-serve.d.ts +3 -1
- package/dist/bin/agent-serve.d.ts.map +1 -1
- package/dist/bin/agent-serve.js +389 -152
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.Oje4vhlk.js → app.BR0RbIdx.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.H5XZ2zCB.js → VPLocalSearchBox.qjsVTneI.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CTR_TuaE.js → theme.2Kg8jIp_.js} +2 -2
- package/dist/docs/assets/{quickstart.md.CfU8_uTC.js → quickstart.md.BU6Iwi_9.js} +18 -6
- package/dist/docs/assets/{reference_cli.md.DA730zCu.js → reference_cli.md.Bv6pOxcF.js} +11 -6
- package/dist/docs/assets/{reference_cli.md.DA730zCu.lean.js → reference_cli.md.Bv6pOxcF.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/slack.html +3 -3
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +22 -10
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +14 -9
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/internal/chat-client.d.ts +29 -3
- package/dist/internal/chat-client.d.ts.map +1 -1
- package/dist/internal/chat-client.js +180 -27
- package/dist/internal/cli-ax.d.ts +75 -2
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +600 -52
- package/dist/internal/cli-cursor.d.ts.map +1 -1
- package/dist/internal/cli-cursor.js +8 -36
- package/dist/internal/cli-deploy.d.ts +59 -3
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +316 -38
- package/dist/internal/cursor/credentials.d.ts +9 -0
- package/dist/internal/cursor/credentials.d.ts.map +1 -1
- package/dist/internal/cursor/credentials.js +12 -0
- package/dist/internal/deploy-client.d.ts +9 -1
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +23 -3
- package/dist/internal/deploy-source.d.ts +35 -0
- package/dist/internal/deploy-source.d.ts.map +1 -0
- package/dist/internal/deploy-source.js +118 -0
- package/dist/internal/discovery.d.ts +11 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +43 -14
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +2 -1
- package/dist/internal/eval-runner.d.ts +2 -0
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +2 -0
- package/dist/internal/event-mapper.d.ts +54 -1
- package/dist/internal/event-mapper.d.ts.map +1 -1
- package/dist/internal/event-mapper.js +151 -41
- package/dist/internal/init-project.d.ts +88 -1
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +221 -31
- package/dist/internal/install-cursor-skills.d.ts +64 -0
- package/dist/internal/install-cursor-skills.d.ts.map +1 -0
- package/dist/internal/install-cursor-skills.js +274 -0
- package/dist/internal/logs-client.d.ts +60 -0
- package/dist/internal/logs-client.d.ts.map +1 -0
- package/dist/internal/logs-client.js +311 -0
- package/dist/internal/open-browser.d.ts +5 -0
- package/dist/internal/open-browser.d.ts.map +1 -0
- package/dist/internal/open-browser.js +34 -0
- package/dist/internal/playground/toolchain.d.ts.map +1 -1
- package/dist/internal/playground/toolchain.js +16 -11
- package/dist/internal/playground-proxy.d.ts +69 -0
- package/dist/internal/playground-proxy.d.ts.map +1 -0
- package/dist/internal/playground-proxy.js +468 -0
- package/dist/internal/prompt-context.d.ts +35 -0
- package/dist/internal/prompt-context.d.ts.map +1 -0
- package/dist/internal/prompt-context.js +71 -0
- package/dist/internal/request-headers.d.ts +11 -0
- package/dist/internal/request-headers.d.ts.map +1 -0
- package/dist/internal/request-headers.js +14 -0
- package/dist/internal/resolve-prod-target.d.ts +42 -0
- package/dist/internal/resolve-prod-target.d.ts.map +1 -0
- package/dist/internal/resolve-prod-target.js +111 -0
- package/dist/internal/run-client.d.ts +2 -2
- package/dist/internal/run-client.d.ts.map +1 -1
- package/dist/internal/run-client.js +38 -23
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +10 -4
- package/dist/internal/session-engine.d.ts +1 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +21 -6
- package/dist/internal/sessions-client.d.ts +21 -0
- package/dist/internal/sessions-client.d.ts.map +1 -0
- package/dist/internal/sessions-client.js +168 -0
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +31 -3
- package/dist/internal/terminal-style.d.ts +22 -0
- package/dist/internal/terminal-style.d.ts.map +1 -0
- package/dist/internal/terminal-style.js +49 -0
- package/dist/internal/trajectory.d.ts +10 -5
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +82 -10
- package/dist/internal/workspace.d.ts +11 -0
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +38 -4
- package/dist/playground/assets/index-D-vo2lV_.css +1 -0
- package/dist/playground/assets/index-x60b9q2j.js +312 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +26 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/quickstart.md +22 -7
- package/docs/reference/cli.md +51 -3
- package/package.json +3 -1
- package/skills/ab/SKILL.md +8 -8
- package/skills/create-agent/SKILL.md +28 -22
- package/skills/debug/SKILL.md +11 -11
- package/skills/evals/SKILL.md +16 -16
- package/skills/framework-map/SKILL.md +6 -6
- package/skills/github/SKILL.md +13 -13
- package/skills/hillclimb/SKILL.md +10 -10
- package/skills/setup-slack/SKILL.md +13 -13
- package/src/bin/agent-serve.ts +422 -188
- package/src/internal/chat-client.ts +252 -37
- package/src/internal/cli-ax.ts +722 -72
- package/src/internal/cli-cursor.ts +14 -42
- package/src/internal/cli-deploy.ts +428 -49
- package/src/internal/cursor/credentials.ts +14 -0
- package/src/internal/deploy-client.ts +45 -4
- package/src/internal/deploy-source.ts +133 -0
- package/src/internal/discovery.ts +53 -16
- package/src/internal/eval-run-store.ts +2 -1
- package/src/internal/eval-runner.ts +5 -0
- package/src/internal/event-mapper.ts +222 -42
- package/src/internal/init-project.ts +333 -51
- package/src/internal/install-cursor-skills.ts +327 -0
- package/src/internal/logs-client.ts +442 -0
- package/src/internal/open-browser.ts +41 -0
- package/src/internal/playground/toolchain.ts +15 -13
- package/src/internal/playground-proxy.ts +576 -0
- package/src/internal/prompt-context.ts +95 -0
- package/src/internal/request-headers.ts +23 -0
- package/src/internal/resolve-prod-target.ts +150 -0
- package/src/internal/run-client.ts +39 -36
- package/src/internal/server.ts +12 -3
- package/src/internal/session-engine.ts +22 -3
- package/src/internal/sessions-client.ts +182 -0
- package/src/internal/stream-progress.ts +36 -2
- package/src/internal/terminal-style.ts +74 -0
- package/src/internal/trajectory.ts +91 -13
- package/src/internal/workspace.ts +42 -4
- package/src/types.ts +42 -6
- package/dist/docs/assets/chunks/@localSearchIndexroot.zwQ9RCQ7.js +0 -1
- package/dist/playground/assets/index-B1Qc9h2u.css +0 -1
- package/dist/playground/assets/index-CpDYCj8W.js +0 -79
- /package/dist/docs/assets/{quickstart.md.CfU8_uTC.lean.js → quickstart.md.BU6Iwi_9.lean.js} +0 -0
|
@@ -8,12 +8,30 @@
|
|
|
8
8
|
|
|
9
9
|
import { createInterface } from "node:readline";
|
|
10
10
|
import type { SessionEvent } from "../types.js";
|
|
11
|
+
import { mergeRequestHeaders, type RequestAuth } from "./request-headers.js";
|
|
12
|
+
import { fetchSessionEvents, listSessions } from "./sessions-client.js";
|
|
11
13
|
|
|
12
|
-
export interface ChatClientOptions {
|
|
14
|
+
export interface ChatClientOptions extends RequestAuth {
|
|
13
15
|
baseUrl: string;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Optional opening user message. On a TTY (without `oneShot`), this seeds
|
|
18
|
+
* the first turn and then the REPL stays open for follow-ups. With
|
|
19
|
+
* `oneShot` (or a non-TTY stdin), send it and exit.
|
|
20
|
+
*/
|
|
16
21
|
message?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Reattach to an existing session. Looks up the current continuation
|
|
24
|
+
* token via `GET /v1/sessions` when `--continuation-token` is omitted,
|
|
25
|
+
* replays the transcript, then accepts follow-ups.
|
|
26
|
+
*/
|
|
27
|
+
sessionId?: string;
|
|
28
|
+
/** Optional; when omitted with `sessionId`, resolved from `/v1/sessions`. */
|
|
29
|
+
continuationToken?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Exit after the opening `--message` instead of entering the REPL.
|
|
32
|
+
* Implied when stdin is not a TTY.
|
|
33
|
+
*/
|
|
34
|
+
oneShot?: boolean;
|
|
17
35
|
/** Force plain output even on a TTY. */
|
|
18
36
|
noColor?: boolean;
|
|
19
37
|
logger?: (line: string) => void;
|
|
@@ -61,6 +79,10 @@ function makePalette(enabled: boolean): Palette {
|
|
|
61
79
|
/** Run the terminal chat client. Resolves when the session/REPL ends. */
|
|
62
80
|
export async function runChat(options: ChatClientOptions): Promise<void> {
|
|
63
81
|
const baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
82
|
+
const auth: RequestAuth = {
|
|
83
|
+
bearerToken: options.bearerToken,
|
|
84
|
+
headers: options.headers,
|
|
85
|
+
};
|
|
64
86
|
const colorEnabled =
|
|
65
87
|
!options.noColor && process.stdout.isTTY === true && !process.env.NO_COLOR;
|
|
66
88
|
const c = makePalette(colorEnabled);
|
|
@@ -68,11 +90,11 @@ export async function runChat(options: ChatClientOptions): Promise<void> {
|
|
|
68
90
|
process.stdout.write(s);
|
|
69
91
|
};
|
|
70
92
|
|
|
71
|
-
const health = await getJson(baseUrl, "/v1/health",
|
|
93
|
+
const health = await getJson(baseUrl, "/v1/health", auth);
|
|
72
94
|
const agentName =
|
|
73
95
|
typeof health?.name === "string" ? health.name : "agent-serve";
|
|
74
96
|
write(`${c.bold(agentName)} ${c.dim(`· ${baseUrl}`)}\n`);
|
|
75
|
-
const info = await getJson(baseUrl, "/v1/info",
|
|
97
|
+
const info = await getJson(baseUrl, "/v1/info", auth);
|
|
76
98
|
if (info && typeof info === "object") {
|
|
77
99
|
const model = (info as { model?: unknown }).model;
|
|
78
100
|
const tools = (info as { tools?: unknown[] }).tools ?? [];
|
|
@@ -86,22 +108,43 @@ export async function runChat(options: ChatClientOptions): Promise<void> {
|
|
|
86
108
|
}
|
|
87
109
|
write("\n");
|
|
88
110
|
|
|
89
|
-
let sessionId: string | undefined;
|
|
90
|
-
let continuationToken: string | undefined;
|
|
111
|
+
let sessionId: string | undefined = options.sessionId;
|
|
112
|
+
let continuationToken: string | undefined = options.continuationToken;
|
|
91
113
|
// Highest event index rendered so far; a follow-up streams from here so it
|
|
92
114
|
// shows only the new turn, not the replayed transcript.
|
|
93
115
|
let nextEventIndex = 0;
|
|
94
116
|
|
|
95
|
-
|
|
96
|
-
|
|
117
|
+
if (options.sessionId !== undefined) {
|
|
118
|
+
const attached = await attachSession({
|
|
119
|
+
baseUrl,
|
|
120
|
+
auth,
|
|
121
|
+
sessionId: options.sessionId,
|
|
122
|
+
continuationToken: options.continuationToken,
|
|
123
|
+
agentName,
|
|
124
|
+
palette: c,
|
|
125
|
+
write,
|
|
126
|
+
});
|
|
127
|
+
sessionId = attached.sessionId;
|
|
128
|
+
continuationToken = attached.continuationToken;
|
|
129
|
+
nextEventIndex = attached.nextEventIndex;
|
|
130
|
+
} else if (options.continuationToken !== undefined) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
"--continuation-token requires --session (session id to reattach to)"
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const runTurn = async (
|
|
137
|
+
message: string,
|
|
138
|
+
opts: { echoUser?: boolean } = {}
|
|
139
|
+
): Promise<void> => {
|
|
140
|
+
// REPL lines are already echoed by readline; only reprint for seeded
|
|
141
|
+
// `--message` / one-shot so the transcript still shows the user turn.
|
|
142
|
+
if (opts.echoUser !== false) {
|
|
143
|
+
write(`${c.cyan("› you")} ${message}\n`);
|
|
144
|
+
}
|
|
97
145
|
const startIndex = sessionId === undefined ? 0 : nextEventIndex;
|
|
98
146
|
if (sessionId === undefined) {
|
|
99
|
-
const created = await postJson(
|
|
100
|
-
baseUrl,
|
|
101
|
-
"/v1/session",
|
|
102
|
-
{ message },
|
|
103
|
-
options.bearerToken
|
|
104
|
-
);
|
|
147
|
+
const created = await postJson(baseUrl, "/v1/session", { message }, auth);
|
|
105
148
|
sessionId = str(created?.sessionId);
|
|
106
149
|
continuationToken = str(created?.continuationToken);
|
|
107
150
|
} else {
|
|
@@ -109,13 +152,13 @@ export async function runChat(options: ChatClientOptions): Promise<void> {
|
|
|
109
152
|
baseUrl,
|
|
110
153
|
`/v1/session/${sessionId}`,
|
|
111
154
|
{ message, continuationToken },
|
|
112
|
-
|
|
155
|
+
auth
|
|
113
156
|
);
|
|
114
157
|
if (resp?.ok === false) {
|
|
115
158
|
write(`${c.red("error")} ${str(resp.error)}: ${str(resp.message)}\n\n`);
|
|
116
159
|
return;
|
|
117
160
|
}
|
|
118
|
-
continuationToken = str(resp?.continuationToken);
|
|
161
|
+
continuationToken = str(resp?.continuationToken) ?? continuationToken;
|
|
119
162
|
}
|
|
120
163
|
if (sessionId === undefined) {
|
|
121
164
|
write(`${c.red("error")} server did not return a session id\n\n`);
|
|
@@ -125,16 +168,21 @@ export async function runChat(options: ChatClientOptions): Promise<void> {
|
|
|
125
168
|
baseUrl,
|
|
126
169
|
sessionId,
|
|
127
170
|
startIndex,
|
|
128
|
-
|
|
171
|
+
auth,
|
|
172
|
+
agentName,
|
|
129
173
|
palette: c,
|
|
130
174
|
write,
|
|
131
175
|
});
|
|
132
176
|
write("\n");
|
|
133
177
|
};
|
|
134
178
|
|
|
179
|
+
const oneShot = options.oneShot === true || process.stdin.isTTY !== true;
|
|
180
|
+
|
|
135
181
|
if (options.message !== undefined) {
|
|
136
182
|
await runTurn(options.message);
|
|
137
|
-
|
|
183
|
+
if (oneShot) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
138
186
|
}
|
|
139
187
|
|
|
140
188
|
write(c.dim("Type a message and press Enter. Ctrl-D or /quit to exit.\n\n"));
|
|
@@ -156,7 +204,7 @@ export async function runChat(options: ChatClientOptions): Promise<void> {
|
|
|
156
204
|
return;
|
|
157
205
|
}
|
|
158
206
|
rl.pause();
|
|
159
|
-
runTurn(text)
|
|
207
|
+
runTurn(text, { echoUser: false })
|
|
160
208
|
.catch((err) => {
|
|
161
209
|
write(`${c.red("error")} ${describe(err)}\n\n`);
|
|
162
210
|
})
|
|
@@ -172,11 +220,139 @@ export async function runChat(options: ChatClientOptions): Promise<void> {
|
|
|
172
220
|
});
|
|
173
221
|
}
|
|
174
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Resolve the current continuation token for a session via `GET /v1/sessions`.
|
|
225
|
+
* Throws when the session is missing or not followable.
|
|
226
|
+
*/
|
|
227
|
+
export async function lookupSessionContinuation(args: {
|
|
228
|
+
baseUrl: string;
|
|
229
|
+
sessionId: string;
|
|
230
|
+
auth?: RequestAuth;
|
|
231
|
+
}): Promise<string> {
|
|
232
|
+
const sessions = await listSessions({
|
|
233
|
+
baseUrl: args.baseUrl,
|
|
234
|
+
auth: args.auth,
|
|
235
|
+
});
|
|
236
|
+
const match = sessions.find((s) => s.sessionId === args.sessionId);
|
|
237
|
+
if (match === undefined) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
`Session ${args.sessionId} not found in /v1/sessions (wrong id, or not owned by this caller). ` +
|
|
240
|
+
`Pass --continuation-token if you have it.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
const token = str(match.continuationToken);
|
|
244
|
+
if (token === undefined) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
`Session ${args.sessionId} has no continuation token` +
|
|
247
|
+
(match.mode === "task" ? " (task sessions are not followable)." : ".")
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
return token;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async function attachSession(args: {
|
|
254
|
+
baseUrl: string;
|
|
255
|
+
auth: RequestAuth;
|
|
256
|
+
sessionId: string;
|
|
257
|
+
continuationToken?: string;
|
|
258
|
+
agentName: string;
|
|
259
|
+
palette: Palette;
|
|
260
|
+
write: (s: string) => void;
|
|
261
|
+
}): Promise<{
|
|
262
|
+
sessionId: string;
|
|
263
|
+
continuationToken: string;
|
|
264
|
+
nextEventIndex: number;
|
|
265
|
+
}> {
|
|
266
|
+
const { palette: c, write } = args;
|
|
267
|
+
let continuationToken = args.continuationToken;
|
|
268
|
+
|
|
269
|
+
if (continuationToken === undefined || continuationToken === "") {
|
|
270
|
+
continuationToken = await lookupSessionContinuation({
|
|
271
|
+
baseUrl: args.baseUrl,
|
|
272
|
+
sessionId: args.sessionId,
|
|
273
|
+
auth: args.auth,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const events = await fetchSessionEvents({
|
|
278
|
+
baseUrl: args.baseUrl,
|
|
279
|
+
sessionId: args.sessionId,
|
|
280
|
+
auth: args.auth,
|
|
281
|
+
});
|
|
282
|
+
if (events.length > 0) {
|
|
283
|
+
write(
|
|
284
|
+
c.dim(
|
|
285
|
+
`reattached ${args.sessionId} · replaying ${events.length} events\n\n`
|
|
286
|
+
)
|
|
287
|
+
);
|
|
288
|
+
renderTranscript(events, args.agentName, c, write);
|
|
289
|
+
write("\n");
|
|
290
|
+
} else {
|
|
291
|
+
write(c.dim(`reattached ${args.sessionId}\n\n`));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const lastIndex =
|
|
295
|
+
events.length === 0
|
|
296
|
+
? -1
|
|
297
|
+
: Math.max(
|
|
298
|
+
...events.map((e) => (typeof e.index === "number" ? e.index : -1))
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
sessionId: args.sessionId,
|
|
303
|
+
continuationToken,
|
|
304
|
+
nextEventIndex: lastIndex + 1,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** Compact historical transcript for reattach (final messages + tool calls). */
|
|
309
|
+
function renderTranscript(
|
|
310
|
+
events: SessionEvent[],
|
|
311
|
+
agentName: string,
|
|
312
|
+
c: Palette,
|
|
313
|
+
write: (s: string) => void
|
|
314
|
+
): void {
|
|
315
|
+
for (const event of events) {
|
|
316
|
+
if (event.type === "message.received") {
|
|
317
|
+
write(`${c.cyan("› you")} ${event.data.text}\n`);
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
if (event.type === "message.completed") {
|
|
321
|
+
const text = event.data.text?.trim() ?? "";
|
|
322
|
+
if (text !== "" && event.data.finishReason !== "tool_call") {
|
|
323
|
+
write(`${c.green(`‹ ${agentName}`)} ${text}\n`);
|
|
324
|
+
}
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (event.type === "actions.requested") {
|
|
328
|
+
for (const call of event.data.calls) {
|
|
329
|
+
write(
|
|
330
|
+
` ${c.magenta("⚙")} ${c.bold(call.toolName)}${c.dim(
|
|
331
|
+
formatArgs(call.args)
|
|
332
|
+
)}\n`
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (event.type === "action.result") {
|
|
338
|
+
const label = event.data.isError ? c.red("✗") : c.magenta("→");
|
|
339
|
+
write(
|
|
340
|
+
` ${label} ${c.dim(truncate(stringify(event.data.output), 100))}\n`
|
|
341
|
+
);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (event.type === "turn.completed") {
|
|
345
|
+
write(c.dim(" ─ turn done\n"));
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
175
350
|
interface StreamTurnArgs {
|
|
176
351
|
baseUrl: string;
|
|
177
352
|
sessionId: string;
|
|
178
353
|
startIndex: number;
|
|
179
|
-
|
|
354
|
+
auth: RequestAuth | undefined;
|
|
355
|
+
agentName: string;
|
|
180
356
|
palette: Palette;
|
|
181
357
|
write: (s: string) => void;
|
|
182
358
|
}
|
|
@@ -191,7 +367,7 @@ const TERMINAL_TYPES = new Set([
|
|
|
191
367
|
async function streamTurn(args: StreamTurnArgs): Promise<number> {
|
|
192
368
|
const { palette: c, write } = args;
|
|
193
369
|
const url = `${args.baseUrl}/v1/session/${args.sessionId}/stream?startIndex=${args.startIndex}`;
|
|
194
|
-
const resp = await fetch(url, { headers:
|
|
370
|
+
const resp = await fetch(url, { headers: mergeRequestHeaders(args.auth) });
|
|
195
371
|
if (!resp.ok || resp.body === null) {
|
|
196
372
|
write(`${c.red("error")} stream failed (${resp.status})\n`);
|
|
197
373
|
return args.startIndex;
|
|
@@ -242,28 +418,46 @@ async function streamTurn(args: StreamTurnArgs): Promise<number> {
|
|
|
242
418
|
}
|
|
243
419
|
continue;
|
|
244
420
|
}
|
|
245
|
-
if (
|
|
421
|
+
if (
|
|
422
|
+
event.type === "reasoning.appended" &&
|
|
423
|
+
event.data.parentCallId === undefined &&
|
|
424
|
+
!thinkingShown
|
|
425
|
+
) {
|
|
246
426
|
thinkingShown = true;
|
|
247
427
|
write(c.dim(" · thinking…\n"));
|
|
248
428
|
continue;
|
|
249
429
|
}
|
|
250
430
|
if (event.type === "message.appended") {
|
|
431
|
+
if (event.data.parentCallId !== undefined) {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
251
434
|
if (!assistantOpen) {
|
|
252
|
-
write(`${c.green(
|
|
435
|
+
write(`${c.green(`‹ ${args.agentName}`)} `);
|
|
253
436
|
assistantOpen = true;
|
|
254
437
|
}
|
|
255
438
|
write(event.data.delta);
|
|
256
439
|
continue;
|
|
257
440
|
}
|
|
258
441
|
if (event.type === "message.completed") {
|
|
442
|
+
if (event.data.parentCallId !== undefined) {
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
259
445
|
closeAssistant();
|
|
260
446
|
continue;
|
|
261
447
|
}
|
|
262
448
|
if (event.type === "actions.requested") {
|
|
263
449
|
closeAssistant();
|
|
264
450
|
for (const call of event.data.calls) {
|
|
451
|
+
if (call.toolName === "task" && call.parentCallId === undefined) {
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
const indent =
|
|
455
|
+
call.parentCallId !== undefined ||
|
|
456
|
+
event.data.parentCallId !== undefined
|
|
457
|
+
? " "
|
|
458
|
+
: " ";
|
|
265
459
|
write(
|
|
266
|
-
|
|
460
|
+
`${indent}${c.magenta("⚙")} ${c.bold(call.toolName)}${c.dim(
|
|
267
461
|
formatArgs(call.args)
|
|
268
462
|
)}\n`
|
|
269
463
|
);
|
|
@@ -290,9 +484,17 @@ async function streamTurn(args: StreamTurnArgs): Promise<number> {
|
|
|
290
484
|
continue;
|
|
291
485
|
}
|
|
292
486
|
if (event.type === "action.result") {
|
|
487
|
+
if (
|
|
488
|
+
event.data.toolName === "task" &&
|
|
489
|
+
event.data.parentCallId === undefined
|
|
490
|
+
) {
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
293
493
|
const label = event.data.isError ? c.red("✗") : c.magenta("→");
|
|
494
|
+
const indent =
|
|
495
|
+
event.data.parentCallId !== undefined ? " " : " ";
|
|
294
496
|
write(
|
|
295
|
-
|
|
497
|
+
`${indent}${label} ${c.dim(truncate(stringify(event.data.output), 100))}\n`
|
|
296
498
|
);
|
|
297
499
|
continue;
|
|
298
500
|
}
|
|
@@ -338,20 +540,14 @@ async function streamTurn(args: StreamTurnArgs): Promise<number> {
|
|
|
338
540
|
// HTTP helpers (built-in fetch; node 22+)
|
|
339
541
|
// ---------------------------------------------------------------------------
|
|
340
542
|
|
|
341
|
-
function authHeaders(bearerToken: string | undefined): Record<string, string> {
|
|
342
|
-
return bearerToken === undefined
|
|
343
|
-
? {}
|
|
344
|
-
: { authorization: `Bearer ${bearerToken}` };
|
|
345
|
-
}
|
|
346
|
-
|
|
347
543
|
async function getJson(
|
|
348
544
|
baseUrl: string,
|
|
349
545
|
path: string,
|
|
350
|
-
|
|
546
|
+
auth: RequestAuth | undefined
|
|
351
547
|
): Promise<Record<string, unknown> | undefined> {
|
|
352
548
|
try {
|
|
353
549
|
const resp = await fetch(`${baseUrl}${path}`, {
|
|
354
|
-
headers:
|
|
550
|
+
headers: mergeRequestHeaders(auth),
|
|
355
551
|
});
|
|
356
552
|
const text = await resp.text();
|
|
357
553
|
return text ? (JSON.parse(text) as Record<string, unknown>) : undefined;
|
|
@@ -364,18 +560,37 @@ async function postJson(
|
|
|
364
560
|
baseUrl: string,
|
|
365
561
|
path: string,
|
|
366
562
|
body: unknown,
|
|
367
|
-
|
|
563
|
+
auth: RequestAuth | undefined
|
|
368
564
|
): Promise<Record<string, unknown> | undefined> {
|
|
369
565
|
const resp = await fetch(`${baseUrl}${path}`, {
|
|
370
566
|
method: "POST",
|
|
371
567
|
headers: {
|
|
372
568
|
"content-type": "application/json",
|
|
373
|
-
...
|
|
569
|
+
...mergeRequestHeaders(auth),
|
|
374
570
|
},
|
|
375
571
|
body: JSON.stringify(body),
|
|
376
572
|
});
|
|
377
573
|
const text = await resp.text();
|
|
378
|
-
|
|
574
|
+
let parsed: Record<string, unknown> | undefined;
|
|
575
|
+
if (text) {
|
|
576
|
+
try {
|
|
577
|
+
parsed = JSON.parse(text) as Record<string, unknown>;
|
|
578
|
+
} catch {
|
|
579
|
+
parsed = { message: text };
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if (!resp.ok) {
|
|
583
|
+
const anyrunReason = resp.headers.get("x-anyrun-failure-reason");
|
|
584
|
+
const message =
|
|
585
|
+
(typeof parsed?.message === "string" && parsed.message !== ""
|
|
586
|
+
? parsed.message
|
|
587
|
+
: undefined) ??
|
|
588
|
+
(typeof parsed?.error === "string" ? parsed.error : undefined) ??
|
|
589
|
+
anyrunReason ??
|
|
590
|
+
`HTTP ${resp.status}`;
|
|
591
|
+
return { ok: false, error: "http_error", message, status: resp.status };
|
|
592
|
+
}
|
|
593
|
+
return parsed;
|
|
379
594
|
}
|
|
380
595
|
|
|
381
596
|
function str(value: unknown): string | undefined {
|