neoctl 0.2.41 → 0.2.43
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/README.md +2 -0
- package/dist/context/prompts.js +2 -1
- package/dist/context/prompts.js.map +1 -1
- package/dist/core/image-registry.js +1 -1
- package/dist/core/image-registry.js.map +1 -1
- package/dist/core/message-pipeline.js +2 -1
- package/dist/core/message-pipeline.js.map +1 -1
- package/dist/core/query-engine.d.ts +6 -0
- package/dist/core/query-engine.js +22 -0
- package/dist/core/query-engine.js.map +1 -1
- package/dist/core/query-timing.d.ts +43 -0
- package/dist/core/query-timing.js +124 -0
- package/dist/core/query-timing.js.map +1 -0
- package/dist/core/query.d.ts +5 -0
- package/dist/core/query.js +60 -10
- package/dist/core/query.js.map +1 -1
- package/dist/core/run-agent.d.ts +2 -0
- package/dist/core/run-agent.js +4 -0
- package/dist/core/run-agent.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/model/model-gateway.d.ts +6 -0
- package/dist/model/model-gateway.js.map +1 -1
- package/dist/model/openai-chat-mapper.js +6 -0
- package/dist/model/openai-chat-mapper.js.map +1 -1
- package/dist/model/openai-mappers.js +2 -2
- package/dist/model/openai-mappers.js.map +1 -1
- package/dist/model/openai-responses-mapper.js +6 -0
- package/dist/model/openai-responses-mapper.js.map +1 -1
- package/dist/repl/index.js +13 -1
- package/dist/repl/index.js.map +1 -1
- package/dist/session/session-store.d.ts +11 -0
- package/dist/session/session-store.js +24 -0
- package/dist/session/session-store.js.map +1 -1
- package/dist/tools/builtins/image-capabilities.d.ts +22 -0
- package/dist/tools/builtins/image-capabilities.js +98 -0
- package/dist/tools/builtins/image-capabilities.js.map +1 -0
- package/dist/tools/builtins/image-generation-tool.d.ts +14 -7
- package/dist/tools/builtins/image-generation-tool.js +183 -158
- package/dist/tools/builtins/image-generation-tool.js.map +1 -1
- package/dist/tools/builtins/image-output-verification.d.ts +14 -0
- package/dist/tools/builtins/image-output-verification.js +183 -0
- package/dist/tools/builtins/image-output-verification.js.map +1 -0
- package/dist/tools/registry.d.ts +2 -0
- package/dist/tools/registry.js +6 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run-tool-use.js +5 -0
- package/dist/tools/run-tool-use.js.map +1 -1
- package/dist/tools/tool-orchestration.d.ts +5 -0
- package/dist/tools/tool-orchestration.js +1 -0
- package/dist/tools/tool-orchestration.js.map +1 -1
- package/dist/types/events.d.ts +10 -0
- package/dist/web/image-result-metadata.d.ts +20 -0
- package/dist/web/image-result-metadata.js +20 -0
- package/dist/web/image-result-metadata.js.map +1 -0
- package/dist/web/index.d.ts +18 -3
- package/dist/web/index.js +68 -17
- package/dist/web/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-result-metadata.js","sourceRoot":"","sources":["../../src/web/image-result-metadata.ts"],"names":[],"mappings":"AAYA,wGAAwG;AACxG,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IACrF,MAAM,IAAI,GAAG,MAAiC,CAAC;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAClD,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5H,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QAClH,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QAC1H,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC9B,MAAM,KAAK,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,oBAAoB,EAAE,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC5O,CAAC,CAAC;KACH,CAAC;AACJ,CAAC"}
|
package/dist/web/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import type { TimingRecord } from "../core/query-timing.js";
|
|
3
|
+
import { type ImageResultMetadata } from "./image-result-metadata.js";
|
|
2
4
|
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
3
5
|
import { QueryEngine } from "../core/query-engine.js";
|
|
4
6
|
import { type AppPromptStore } from "../app/app-prompt.js";
|
|
@@ -82,6 +84,7 @@ export declare class SessionUsageTracker {
|
|
|
82
84
|
}
|
|
83
85
|
interface UiLineImage {
|
|
84
86
|
src?: string;
|
|
87
|
+
originalSrc?: string;
|
|
85
88
|
imageId?: string;
|
|
86
89
|
label?: string;
|
|
87
90
|
mimeType: string;
|
|
@@ -159,6 +162,7 @@ interface UiLine {
|
|
|
159
162
|
toolPresentation?: ToolPresentation;
|
|
160
163
|
parentToolName?: string;
|
|
161
164
|
toolUseId?: string;
|
|
165
|
+
timing?: TimingRecord;
|
|
162
166
|
parentToolUseId?: string;
|
|
163
167
|
title?: string;
|
|
164
168
|
bodyTitle?: string;
|
|
@@ -174,6 +178,7 @@ interface UiLine {
|
|
|
174
178
|
live?: boolean;
|
|
175
179
|
collapsible?: boolean;
|
|
176
180
|
image?: UiLineImage;
|
|
181
|
+
imageResult?: ImageResultMetadata;
|
|
177
182
|
compaction?: UiCompactionReport;
|
|
178
183
|
}
|
|
179
184
|
type WebActionFailure = {
|
|
@@ -185,6 +190,15 @@ type WebActionResult<T extends object = object> = ({
|
|
|
185
190
|
ok: true;
|
|
186
191
|
} & T) | WebActionFailure;
|
|
187
192
|
interface UiStatus {
|
|
193
|
+
modelOutput?: {
|
|
194
|
+
kind: "text";
|
|
195
|
+
} | {
|
|
196
|
+
kind: "tool_call";
|
|
197
|
+
callId: string;
|
|
198
|
+
name?: string;
|
|
199
|
+
};
|
|
200
|
+
queryTiming?: TimingRecord;
|
|
201
|
+
toolTimings?: TimingRecord[];
|
|
188
202
|
phase: string;
|
|
189
203
|
detail?: string;
|
|
190
204
|
currentTool?: {
|
|
@@ -235,7 +249,7 @@ export interface CreateWebRuntimeOptions {
|
|
|
235
249
|
sessionPluginOverrides?: Readonly<Record<string, boolean>>;
|
|
236
250
|
persistSessionPluginOverrides?: WebRuntimePluginSupport["persist"];
|
|
237
251
|
resolveSessionPluginOverrides?: WebRuntimePluginSupport["resolve"];
|
|
238
|
-
/** Global tool
|
|
252
|
+
/** Global tool overrides. Missing names use registry defaults (delegation tools are opt-in). */
|
|
239
253
|
globalToolOverrides?: Readonly<Record<string, boolean>>;
|
|
240
254
|
/** Per-session tool overrides. Missing names inherit their global default. */
|
|
241
255
|
sessionToolOverrides?: Readonly<Record<string, boolean>>;
|
|
@@ -435,7 +449,7 @@ export declare class WebRepl {
|
|
|
435
449
|
steps: {
|
|
436
450
|
id: string;
|
|
437
451
|
title: string;
|
|
438
|
-
status: "
|
|
452
|
+
status: "running" | "completed" | "failed";
|
|
439
453
|
}[] | undefined;
|
|
440
454
|
};
|
|
441
455
|
pendingMessageCount: number;
|
|
@@ -563,7 +577,7 @@ export declare class WebRepl {
|
|
|
563
577
|
steps: {
|
|
564
578
|
id: string;
|
|
565
579
|
title: string;
|
|
566
|
-
status: "
|
|
580
|
+
status: "running" | "completed" | "failed";
|
|
567
581
|
}[] | undefined;
|
|
568
582
|
};
|
|
569
583
|
pendingMessageCount: number;
|
|
@@ -788,6 +802,7 @@ export declare class WebRepl {
|
|
|
788
802
|
private backgroundTasks;
|
|
789
803
|
private detachRunningForeground;
|
|
790
804
|
private reattachRunningSession;
|
|
805
|
+
private timedStatus;
|
|
791
806
|
private reduce;
|
|
792
807
|
private finalizeLiveLine;
|
|
793
808
|
private finalizeThinkingLine;
|
package/dist/web/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { imageResultMetadata } from "./image-result-metadata.js";
|
|
2
3
|
import { subagentHeader, subagentStatusFacts } from "./status-semantics.js";
|
|
3
4
|
import { handlePromptConfigRequest } from "./prompt-config-protocol.js";
|
|
4
5
|
import http from "node:http";
|
|
@@ -17,7 +18,7 @@ import { readModelProviderConfig } from "../model/config.js";
|
|
|
17
18
|
import { findModelMetadata, loadModelCatalog, reasoningEffortsForModel, resolveContextWindowTokens } from "../model/context-window.js";
|
|
18
19
|
import { CommunicationLogger, LoggingModelGateway } from "../model/communication-logger.js";
|
|
19
20
|
import { createModelGatewayFromConfig, createModelGatewayFromProcessEnv } from "../model/provider-factory.js";
|
|
20
|
-
import { ToolRegistry } from "../tools/registry.js";
|
|
21
|
+
import { ToolRegistry, isToolEnabledByDefault } from "../tools/registry.js";
|
|
21
22
|
import { builtinToolPresentation, toolPresentationForSource } from "../tools/tool-catalog.js";
|
|
22
23
|
import { editTool, writeTool } from "../tools/builtins/edit-tool.js";
|
|
23
24
|
import { createExecTool, createWriteStdinTool } from "../tools/builtins/exec-tool.js";
|
|
@@ -287,7 +288,7 @@ function normalizeToolOverrides(value, catalog) {
|
|
|
287
288
|
}
|
|
288
289
|
function applyToolOverrides(registry, catalog, globalOverrides, sessionOverrides) {
|
|
289
290
|
for (const tool of catalog)
|
|
290
|
-
registry.setEnabled(tool.name, sessionOverrides[tool.name] ?? globalOverrides[tool.name] ??
|
|
291
|
+
registry.setEnabled(tool.name, sessionOverrides[tool.name] ?? globalOverrides[tool.name] ?? isToolEnabledByDefault(tool.name));
|
|
291
292
|
}
|
|
292
293
|
/** Called only at a safe turn boundary or while idle, never during tool execution. */
|
|
293
294
|
export function refreshGlobalToolOverrides(runtime) {
|
|
@@ -544,7 +545,7 @@ export class WebRepl {
|
|
|
544
545
|
}
|
|
545
546
|
return {
|
|
546
547
|
lines: this.lines.map(line => line.toolError ? { ...line, toolError: this.runtime.engine.redactDisplayValue?.(line.toolError) ?? line.toolError } : line),
|
|
547
|
-
status: this.
|
|
548
|
+
status: this.timedStatus(),
|
|
548
549
|
busy: this.busy,
|
|
549
550
|
queuedInput: this.queuedInput,
|
|
550
551
|
backgroundTaskCount: backgroundTasks.length,
|
|
@@ -596,7 +597,7 @@ export class WebRepl {
|
|
|
596
597
|
return {
|
|
597
598
|
items: support.catalog.map((tool) => ({
|
|
598
599
|
...tool,
|
|
599
|
-
configuredEnabled: support.globalOverrides[tool.name] ??
|
|
600
|
+
configuredEnabled: support.globalOverrides[tool.name] ?? isToolEnabledByDefault(tool.name),
|
|
600
601
|
})),
|
|
601
602
|
};
|
|
602
603
|
}
|
|
@@ -614,7 +615,7 @@ export class WebRepl {
|
|
|
614
615
|
busy: this.busy,
|
|
615
616
|
items: support.catalog.map((tool) => {
|
|
616
617
|
const override = support.sessionOverrides[tool.name];
|
|
617
|
-
const globallyEnabled = support.globalOverrides[tool.name] ??
|
|
618
|
+
const globallyEnabled = support.globalOverrides[tool.name] ?? isToolEnabledByDefault(tool.name);
|
|
618
619
|
const available = tool.source !== "plugin" || Boolean(tool.pluginId && activePluginIds.has(tool.pluginId));
|
|
619
620
|
return {
|
|
620
621
|
...tool,
|
|
@@ -1405,6 +1406,14 @@ export class WebRepl {
|
|
|
1405
1406
|
this.setBusy(true);
|
|
1406
1407
|
this.setStatus({ ...this.status, phase: "running", detail: "working" });
|
|
1407
1408
|
}
|
|
1409
|
+
timedStatus() {
|
|
1410
|
+
const records = this.runtime.engine.getTimingRecords?.() ?? [];
|
|
1411
|
+
if (records.length === 0)
|
|
1412
|
+
return this.status;
|
|
1413
|
+
const queryTiming = records.filter(record => record.kind === "query").at(-1);
|
|
1414
|
+
return { ...this.status, queryTiming,
|
|
1415
|
+
toolTimings: records.filter(record => record.kind === "tool" && record.runId === queryTiming?.runId) };
|
|
1416
|
+
}
|
|
1408
1417
|
reduce(event) {
|
|
1409
1418
|
this.status = reduceStatus(this.status, event);
|
|
1410
1419
|
if (event.type === "usage")
|
|
@@ -1565,6 +1574,18 @@ export class WebRepl {
|
|
|
1565
1574
|
}
|
|
1566
1575
|
handleEvent(event) {
|
|
1567
1576
|
this.reduce(event);
|
|
1577
|
+
if (event.type === "timing.updated") {
|
|
1578
|
+
if (event.timing.kind === "tool") {
|
|
1579
|
+
const line = this.lines.find(item => item.timing?.id === event.timing.id)
|
|
1580
|
+
?? this.lines.find(item => item.id === this.liveToolLineIds.get(event.timing.toolUseId));
|
|
1581
|
+
if (line) {
|
|
1582
|
+
this.lines = this.lines.map(item => item.id === line.id ? { ...item, timing: event.timing } : item);
|
|
1583
|
+
this.queueDeltaOperation({ type: "line.patch", id: line.id, patch: { timing: event.timing } });
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
this.queueDeltaStatus();
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1568
1589
|
if (event.type === "message" && this.matchesPendingUserImageEcho(event.message)) {
|
|
1569
1590
|
const messageId = this.pendingUserImageEchoMessageId;
|
|
1570
1591
|
this.pendingUserImageEchoIds = undefined;
|
|
@@ -1573,7 +1594,7 @@ export class WebRepl {
|
|
|
1573
1594
|
this.broadcastSync();
|
|
1574
1595
|
return;
|
|
1575
1596
|
}
|
|
1576
|
-
if (event.type === "tool_call.delta") {
|
|
1597
|
+
if (event.type === "tool_call.started" || event.type === "tool_call.delta") {
|
|
1577
1598
|
this.queueDeltaStatus();
|
|
1578
1599
|
return;
|
|
1579
1600
|
}
|
|
@@ -1818,7 +1839,7 @@ export class WebRepl {
|
|
|
1818
1839
|
this.activeAbortController = abortController;
|
|
1819
1840
|
this.interruptArmed = false;
|
|
1820
1841
|
this.setBusy(true);
|
|
1821
|
-
this.setStatus({ ...this.status, phase: "running", detail: "working", usage: undefined, streamedOutputTokens: 0, inputTokenUpdatedAt: undefined, outputTokenUpdatedAt: undefined, retryCooldownUntil: undefined });
|
|
1842
|
+
this.setStatus({ ...this.status, phase: "running", detail: "working", modelOutput: undefined, usage: undefined, streamedOutputTokens: 0, inputTokenUpdatedAt: undefined, outputTokenUpdatedAt: undefined, retryCooldownUntil: undefined });
|
|
1822
1843
|
const engine = this.runtime.engine;
|
|
1823
1844
|
try {
|
|
1824
1845
|
for await (const event of engine.sendUserText(promptPayload.text, {
|
|
@@ -1832,7 +1853,7 @@ export class WebRepl {
|
|
|
1832
1853
|
if (this.runtime.engine !== engine)
|
|
1833
1854
|
continue;
|
|
1834
1855
|
if (this.suppressReattachedStreaming.has(engine)) {
|
|
1835
|
-
if (event.type === "message" || event.type === "terminal" || event.type === "error" || event.type === "context.metrics" || event.type === "usage") {
|
|
1856
|
+
if (event.type === "message" || event.type === "terminal" || event.type === "error" || event.type === "context.metrics" || event.type === "usage" || event.type === "timing.updated") {
|
|
1836
1857
|
if (event.type === "message" || event.type === "terminal" || event.type === "error")
|
|
1837
1858
|
this.suppressReattachedStreaming.delete(engine);
|
|
1838
1859
|
this.handleEvent(event);
|
|
@@ -2002,7 +2023,7 @@ export class WebRepl {
|
|
|
2002
2023
|
protocolVersion: 2,
|
|
2003
2024
|
sessionId: this.runtime.engine.snapshot().session?.sessionId,
|
|
2004
2025
|
operations,
|
|
2005
|
-
status: this.
|
|
2026
|
+
status: this.timedStatus(),
|
|
2006
2027
|
};
|
|
2007
2028
|
for (const subscriber of this.subscribers)
|
|
2008
2029
|
this.send(subscriber, "delta", payload);
|
|
@@ -2376,6 +2397,14 @@ function restoredHistoryLines(runtime) {
|
|
|
2376
2397
|
historyToolLineIndexes.set(line.toolUseId, lines.length - 1);
|
|
2377
2398
|
return lines.length;
|
|
2378
2399
|
};
|
|
2400
|
+
const toolTimings = new Map();
|
|
2401
|
+
for (const record of runtime.engine.getTimingRecords?.() ?? []) {
|
|
2402
|
+
if (record.kind !== "tool" || !record.toolUseId)
|
|
2403
|
+
continue;
|
|
2404
|
+
const matches = toolTimings.get(record.toolUseId) ?? [];
|
|
2405
|
+
matches.push(record);
|
|
2406
|
+
toolTimings.set(record.toolUseId, matches);
|
|
2407
|
+
}
|
|
2379
2408
|
const entries = runtime.engine.getDisplayEntries();
|
|
2380
2409
|
let lastCompactionIndex = -1;
|
|
2381
2410
|
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
@@ -2396,6 +2425,12 @@ function restoredHistoryLines(runtime) {
|
|
|
2396
2425
|
const report = entry.report ?? legacyCompactionReport(entry.reason);
|
|
2397
2426
|
append(compactionLine(report, entry.createdAt, entryIndex === lastCompactionIndex));
|
|
2398
2427
|
}
|
|
2428
|
+
// Legacy histories can reuse call IDs. Ambiguous associations stay unknown.
|
|
2429
|
+
for (const line of lines) {
|
|
2430
|
+
const matches = line.toolUseId ? toolTimings.get(line.toolUseId) : undefined;
|
|
2431
|
+
if (matches?.length === 1)
|
|
2432
|
+
line.timing = matches[0];
|
|
2433
|
+
}
|
|
2399
2434
|
return lines;
|
|
2400
2435
|
}
|
|
2401
2436
|
function initialStatus(runtime, metrics = runtime.initialMetrics) {
|
|
@@ -2543,7 +2578,7 @@ function toolStreamStepStatus(phase) {
|
|
|
2543
2578
|
}
|
|
2544
2579
|
function reduceStatus(status, event) {
|
|
2545
2580
|
if (event.type === "state")
|
|
2546
|
-
return { ...status, phase: event.phase, detail: event.detail, currentTool: event.phase === "running_tools" ? status.currentTool : undefined, usage: event.phase === "preparing" ? undefined : status.usage, streamedOutputTokens: event.phase === "preparing" ? 0 : status.streamedOutputTokens, inputTokenUpdatedAt: event.phase === "preparing" ? undefined : status.inputTokenUpdatedAt, outputTokenUpdatedAt: event.phase === "preparing" ? undefined : status.outputTokenUpdatedAt, retryCooldownUntil: event.phase === "preparing" ? undefined : status.retryCooldownUntil, activityTick: status.activityTick + 1 };
|
|
2581
|
+
return { ...status, phase: event.phase, detail: event.detail, modelOutput: undefined, currentTool: event.phase === "running_tools" ? status.currentTool : undefined, usage: event.phase === "preparing" ? undefined : status.usage, streamedOutputTokens: event.phase === "preparing" ? 0 : status.streamedOutputTokens, inputTokenUpdatedAt: event.phase === "preparing" ? undefined : status.inputTokenUpdatedAt, outputTokenUpdatedAt: event.phase === "preparing" ? undefined : status.outputTokenUpdatedAt, retryCooldownUntil: event.phase === "preparing" ? undefined : status.retryCooldownUntil, activityTick: status.activityTick + 1 };
|
|
2547
2582
|
if (event.type === "context.compacted")
|
|
2548
2583
|
return { ...status, phase: "compacting", detail: formatCompactionReportSummary(event.compaction), activityTick: status.activityTick + 1 };
|
|
2549
2584
|
if (event.type === "context.metrics")
|
|
@@ -2551,21 +2586,23 @@ function reduceStatus(status, event) {
|
|
|
2551
2586
|
if (event.type === "usage")
|
|
2552
2587
|
return { ...status, usage: event.usage, inputTokenUpdatedAt: event.usage.inputTokens !== undefined ? Date.now() : status.inputTokenUpdatedAt, outputTokenUpdatedAt: event.usage.outputTokens !== undefined ? Date.now() : status.outputTokenUpdatedAt, activityTick: status.activityTick + 1 };
|
|
2553
2588
|
if (event.type === "assistant.delta")
|
|
2554
|
-
return { ...status, phase: "calling_model", streamedOutputTokens: status.streamedOutputTokens + estimateTokens(event.text), outputTokenUpdatedAt: Date.now(), activityTick: status.activityTick + 1 };
|
|
2589
|
+
return { ...status, phase: "calling_model", modelOutput: { kind: "text" }, streamedOutputTokens: status.streamedOutputTokens + estimateTokens(event.text), outputTokenUpdatedAt: Date.now(), activityTick: status.activityTick + 1 };
|
|
2555
2590
|
if (event.type === "thinking.delta")
|
|
2556
|
-
return { ...status, phase: "thinking", streamedOutputTokens: status.streamedOutputTokens + estimateTokens(event.text), outputTokenUpdatedAt: Date.now(), activityTick: status.activityTick + 1 };
|
|
2591
|
+
return { ...status, phase: "thinking", modelOutput: undefined, streamedOutputTokens: status.streamedOutputTokens + estimateTokens(event.text), outputTokenUpdatedAt: Date.now(), activityTick: status.activityTick + 1 };
|
|
2592
|
+
if (event.type === "tool_call.started")
|
|
2593
|
+
return { ...status, phase: "calling_model", modelOutput: { kind: "tool_call", callId: event.callId, name: event.name }, activityTick: status.activityTick + 1 };
|
|
2557
2594
|
if (event.type === "tool_call.delta")
|
|
2558
|
-
return { ...status, phase: "calling_model", streamedOutputTokens: status.streamedOutputTokens + estimateTokens(event.argumentsDelta), outputTokenUpdatedAt: Date.now(), activityTick: status.activityTick + 1 };
|
|
2595
|
+
return { ...status, phase: "calling_model", modelOutput: { kind: "tool_call", callId: event.callId, name: event.name ?? (status.modelOutput?.kind === "tool_call" && status.modelOutput.callId === event.callId ? status.modelOutput.name : undefined) }, streamedOutputTokens: status.streamedOutputTokens + estimateTokens(event.argumentsDelta), outputTokenUpdatedAt: Date.now(), activityTick: status.activityTick + 1 };
|
|
2559
2596
|
if (event.type === "retrying")
|
|
2560
|
-
return { ...status, phase: "calling_model", detail: `retrying in ${(event.delayMs / 1000).toFixed(1)}s`, retryCooldownUntil: Date.now() + event.delayMs, activityTick: status.activityTick + 1 };
|
|
2597
|
+
return { ...status, phase: "calling_model", modelOutput: undefined, detail: `retrying in ${(event.delayMs / 1000).toFixed(1)}s`, retryCooldownUntil: Date.now() + event.delayMs, activityTick: status.activityTick + 1 };
|
|
2561
2598
|
if (event.type === "tool.started")
|
|
2562
|
-
return { ...status, phase: "running_tools", currentTool: { id: event.toolUse.id, name: event.toolUse.name, input: event.toolUse.input, startedAt: Date.now() }, activityTick: status.activityTick + 1 };
|
|
2599
|
+
return { ...status, phase: "running_tools", modelOutput: undefined, currentTool: { id: event.toolUse.id, name: event.toolUse.name, input: event.toolUse.input, startedAt: Date.now() }, activityTick: status.activityTick + 1 };
|
|
2563
2600
|
if (event.type === "tool.progress")
|
|
2564
2601
|
return { ...status, phase: "running_tools", detail: event.progress.message || status.detail, currentTool: { id: event.toolUse.id, name: event.toolUse.name, input: event.toolUse.input, startedAt: status.currentTool?.id === event.toolUse.id ? status.currentTool.startedAt : Date.now() }, activityTick: status.activityTick + 1 };
|
|
2565
2602
|
if (event.type === "tool.result.available" || event.type === "tool.finished" || event.type === "tool.batch.completed")
|
|
2566
2603
|
return { ...status, currentTool: "toolUse" in event && status.currentTool?.id === event.toolUse.id ? undefined : status.currentTool, activityTick: status.activityTick + 1 };
|
|
2567
2604
|
if (event.type === "terminal")
|
|
2568
|
-
return { ...status, phase: "stopped", detail: event.reason, currentTool: undefined, inputTokenUpdatedAt: undefined, outputTokenUpdatedAt: undefined, retryCooldownUntil: undefined, activityTick: status.activityTick + 1 };
|
|
2605
|
+
return { ...status, phase: "stopped", modelOutput: undefined, detail: event.reason, currentTool: undefined, inputTokenUpdatedAt: undefined, outputTokenUpdatedAt: undefined, retryCooldownUntil: undefined, activityTick: status.activityTick + 1 };
|
|
2569
2606
|
if (event.type === "message" || event.type === "error")
|
|
2570
2607
|
return { ...status, activityTick: status.activityTick + 1 };
|
|
2571
2608
|
return status;
|
|
@@ -2948,6 +2985,7 @@ function imageLineForBlock(role, block, messageId, blockIndex) {
|
|
|
2948
2985
|
text: block.label ?? `[image ${block.mimeType}]`,
|
|
2949
2986
|
image: {
|
|
2950
2987
|
src: resolution.available ? (block.imageId ? `/api/images/by-id/${encodeURIComponent(block.imageId)}` : `/api/images/${encodeURIComponent(messageId)}/${blockIndex}`) : undefined,
|
|
2988
|
+
originalSrc: resolution.available ? (block.imageId ? `/api/images/by-id/${encodeURIComponent(block.imageId)}` : `/api/images/${encodeURIComponent(messageId)}/${blockIndex}`) : undefined,
|
|
2951
2989
|
imageId: block.imageId,
|
|
2952
2990
|
label: block.label,
|
|
2953
2991
|
mimeType: block.mimeType,
|
|
@@ -3090,6 +3128,7 @@ function formatToolResultLine(toolName, output, ok, presentToolResult) {
|
|
|
3090
3128
|
title: presentation?.title ?? toolTitle(toolName, "finished"),
|
|
3091
3129
|
bodyTitle: presentation?.bodyTitle ?? formatted.bodyTitle,
|
|
3092
3130
|
titleStatus: ok ? "success" : "failure",
|
|
3131
|
+
imageResult: toolName === "image_create" ? imageResultMetadata(output) : undefined,
|
|
3093
3132
|
text: presentation?.text ?? formatted.text,
|
|
3094
3133
|
toolDisplay: resources?.length ? undefined : buildToolResultDisplay(toolName, output, ok),
|
|
3095
3134
|
format: formatted.format,
|
|
@@ -3593,7 +3632,19 @@ function formatImageGenerationToolResult(output, ok) {
|
|
|
3593
3632
|
const lines = [`${mode === "edit" ? "edited" : "generated"} ${returnedImages ?? 0} image${returnedImages === 1 ? "" : "s"}`];
|
|
3594
3633
|
const details = [provider, model, size, quality && quality !== "auto" ? quality : undefined, format].filter((value) => Boolean(value));
|
|
3595
3634
|
if (details.length > 0)
|
|
3596
|
-
lines.push(details.join(" · "));
|
|
3635
|
+
lines.push(`${output.requested ? "requested: " : ""}${details.join(" · ")}`);
|
|
3636
|
+
if (isRecord(output.actual)) {
|
|
3637
|
+
lines.push(`upstream-reported quality: ${String(output.actual.quality ?? "unreported")}`);
|
|
3638
|
+
if (Array.isArray(output.images))
|
|
3639
|
+
for (const image of output.images.filter(isRecord)) {
|
|
3640
|
+
if (typeof image.width === "number" && typeof image.height === "number")
|
|
3641
|
+
lines.push(`actual image: ${image.width}x${image.height} · ${String(image.mimeType ?? "")}`);
|
|
3642
|
+
}
|
|
3643
|
+
}
|
|
3644
|
+
if (Array.isArray(output.warnings))
|
|
3645
|
+
for (const warning of output.warnings.filter(isRecord)) {
|
|
3646
|
+
lines.push(`warning [${String(warning.code ?? "IMAGE_WARNING")}]: ${String(warning.message ?? "")}`);
|
|
3647
|
+
}
|
|
3597
3648
|
if (sourceImages !== undefined)
|
|
3598
3649
|
lines.push(`source images: ${sourceImages}`);
|
|
3599
3650
|
const duration = imageGenerationDuration(output);
|