@dexto/tui 1.8.2 → 1.8.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/dist/agent-backend.d.ts +2 -2
- package/dist/agent-backend.d.ts.map +1 -1
- package/dist/hooks/useTokenCounter.cjs +9 -11
- package/dist/hooks/useTokenCounter.d.ts.map +1 -1
- package/dist/hooks/useTokenCounter.js +9 -11
- package/dist/index.d.cts +2 -2
- package/dist/services/processStream.cjs +29 -20
- package/dist/services/processStream.d.ts.map +1 -1
- package/dist/services/processStream.js +29 -20
- package/dist/services/processStream.test.cjs +58 -20
- package/dist/services/processStream.test.js +58 -20
- package/package.json +5 -5
package/dist/agent-backend.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentEventMap, DextoAgent, EventListener, SessionMetadata, SkillManager } from '@dexto/core';
|
|
1
|
+
import type { AgentEventMap, DextoAgent, EventArgs, EventListener, SessionMetadata, SkillManager } from '@dexto/core';
|
|
2
2
|
import type { CommandDefinition } from './interactive-commands/command-parser.js';
|
|
3
3
|
export interface TuiAgentCapabilities {
|
|
4
4
|
supportedCommands?: readonly string[];
|
|
@@ -47,7 +47,7 @@ export interface TuiAgentBackend extends Pick<DextoAgent, 'stream' | 'stop' | 'r
|
|
|
47
47
|
on: <K extends keyof AgentEventMap>(event: K, listener: EventListener<AgentEventMap[K]>, options?: {
|
|
48
48
|
signal?: AbortSignal;
|
|
49
49
|
}) => void;
|
|
50
|
-
emit: <K extends keyof AgentEventMap>(event: K, ...args: AgentEventMap[K]
|
|
50
|
+
emit: <K extends keyof AgentEventMap>(event: K, ...args: EventArgs<AgentEventMap[K]>) => boolean;
|
|
51
51
|
logger: RootLogger;
|
|
52
52
|
config: {
|
|
53
53
|
agentId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-backend.d.ts","sourceRoot":"","sources":["../src/agent-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,aAAa,EACb,UAAU,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAElF,MAAM,WAAW,oBAAoB;IACjC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,KAAK,UAAU,GAAG,IAAI,CAClB,UAAU,CAAC,QAAQ,CAAC,EACpB,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,gBAAgB,CACtE,CAAC;AAEF,UAAU,eAAe;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAC5C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;KAC3C,CAAC;IACF,WAAW,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,CAAC,EACH;QACI,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACnC,GACD,SAAS,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACjD,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eACb,SAAQ,IAAI,CACR,UAAU,EACR,QAAQ,GACR,MAAM,GACN,KAAK,GACL,cAAc,GACd,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GACjB,iBAAiB,GACjB,sBAAsB,GACtB,aAAa,GACb,qBAAqB,GACrB,uBAAuB,GACvB,WAAW,GACX,uBAAuB,GACvB,oBAAoB,GACpB,iBAAiB,GACjB,cAAc,GACd,gBAAgB,GAChB,OAAO,GACP,UAAU,GACV,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,uBAAuB,GACvB,iBAAiB,GACjB,oBAAoB,GACpB,QAAQ,GACR,gBAAgB,GAChB,aAAa,GACb,gBAAgB,GAChB,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,gBAAgB,GAChB,wBAAwB,GACxB,yBAAyB,GACzB,4BAA4B,GAC5B,4BAA4B,GAC5B,yBAAyB,GACzB,cAAc,GACd,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,kBAAkB,GAClB,eAAe,GACf,yBAAyB,CAC9B;IACD,aAAa,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;QAC3C,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAC,CAAC;KAC3D,CAAC,CAAC;IACH,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CACpC;QACI,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAC,CAAC;KAC3D,GACD,SAAS,CACd,CAAC;IACF,kBAAkB,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,kBAAkB,CAAC;IAC/D,EAAE,EAAE,CAAC,CAAC,SAAS,MAAM,aAAa,EAC9B,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EACzC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KACjC,IAAI,CAAC;IACV,IAAI,EAAE,CAAC,CAAC,SAAS,MAAM,aAAa,EAChC,KAAK,EAAE,CAAC,EACR,GAAG,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-backend.d.ts","sourceRoot":"","sources":["../src/agent-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,17 +67,15 @@ function useTokenCounter({ agent, isActive }) {
|
|
|
67
67
|
"llm:response",
|
|
68
68
|
(payload) => {
|
|
69
69
|
const usage = payload.tokenUsage;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
setCumulativeOutputTokens((prev) => prev + outputTokens);
|
|
80
|
-
}
|
|
70
|
+
const rawInputTokens = usage.inputTokens ?? 0;
|
|
71
|
+
const cacheWriteTokens = usage.cacheWriteTokens ?? 0;
|
|
72
|
+
const inputTokens = Math.max(0, rawInputTokens - cacheWriteTokens);
|
|
73
|
+
if (inputTokens > 0) {
|
|
74
|
+
setLastInputTokens(inputTokens);
|
|
75
|
+
}
|
|
76
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
77
|
+
if (outputTokens > 0) {
|
|
78
|
+
setCumulativeOutputTokens((prev) => prev + outputTokens);
|
|
81
79
|
}
|
|
82
80
|
currentCharCountRef.current = 0;
|
|
83
81
|
setCurrentSegmentEstimate(0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenCounter.d.ts","sourceRoot":"","sources":["../../src/hooks/useTokenCounter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAChC,+CAA+C;IAC/C,KAAK,EAAE,eAAe,CAAC;IACvB,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAC/B,yDAAyD;IACzD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qDAAqD;IACrD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;CACrB;AAsBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"useTokenCounter.d.ts","sourceRoot":"","sources":["../../src/hooks/useTokenCounter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAChC,+CAA+C;IAC/C,KAAK,EAAE,eAAe,CAAC;IACvB,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAC/B,yDAAyD;IACzD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qDAAqD;IACrD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;CACrB;AAsBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,GAAG,kBAAkB,CA2F5F"}
|
|
@@ -44,17 +44,15 @@ function useTokenCounter({ agent, isActive }) {
|
|
|
44
44
|
"llm:response",
|
|
45
45
|
(payload) => {
|
|
46
46
|
const usage = payload.tokenUsage;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
setCumulativeOutputTokens((prev) => prev + outputTokens);
|
|
57
|
-
}
|
|
47
|
+
const rawInputTokens = usage.inputTokens ?? 0;
|
|
48
|
+
const cacheWriteTokens = usage.cacheWriteTokens ?? 0;
|
|
49
|
+
const inputTokens = Math.max(0, rawInputTokens - cacheWriteTokens);
|
|
50
|
+
if (inputTokens > 0) {
|
|
51
|
+
setLastInputTokens(inputTokens);
|
|
52
|
+
}
|
|
53
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
54
|
+
if (outputTokens > 0) {
|
|
55
|
+
setCumulativeOutputTokens((prev) => prev + outputTokens);
|
|
58
56
|
}
|
|
59
57
|
currentCharCountRef.current = 0;
|
|
60
58
|
setCurrentSegmentEstimate(0);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { DextoAgent, AgentEventMap, EventListener, SessionMetadata, SkillManager } from '@dexto/core';
|
|
2
|
+
import { DextoAgent, AgentEventMap, EventListener, EventArgs, SessionMetadata, SkillManager } from '@dexto/core';
|
|
3
3
|
import { LLMProvider } from '@dexto/llm';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -241,7 +241,7 @@ interface TuiAgentBackend extends Pick<DextoAgent, 'stream' | 'stop' | 'run' | '
|
|
|
241
241
|
on: <K extends keyof AgentEventMap>(event: K, listener: EventListener<AgentEventMap[K]>, options?: {
|
|
242
242
|
signal?: AbortSignal;
|
|
243
243
|
}) => void;
|
|
244
|
-
emit: <K extends keyof AgentEventMap>(event: K, ...args: AgentEventMap[K]
|
|
244
|
+
emit: <K extends keyof AgentEventMap>(event: K, ...args: EventArgs<AgentEventMap[K]>) => boolean;
|
|
245
245
|
logger: RootLogger;
|
|
246
246
|
config: {
|
|
247
247
|
agentId: string;
|
|
@@ -90,9 +90,6 @@ function hasMeaningfulTokenUsageForAnalytics(tokenUsage, estimatedCost) {
|
|
|
90
90
|
if (estimatedCost !== void 0) {
|
|
91
91
|
return true;
|
|
92
92
|
}
|
|
93
|
-
if (!tokenUsage) {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
93
|
return (tokenUsage.inputTokens ?? 0) > 0 || (tokenUsage.outputTokens ?? 0) > 0 || (tokenUsage.reasoningTokens ?? 0) > 0 || (tokenUsage.cacheReadTokens ?? 0) > 0 || (tokenUsage.cacheWriteTokens ?? 0) > 0 || (tokenUsage.totalTokens ?? 0) > 0;
|
|
97
94
|
}
|
|
98
95
|
async function processStream(iterator, setters, options) {
|
|
@@ -378,20 +375,18 @@ async function processStream(iterator, setters, options) {
|
|
|
378
375
|
if (!useStreaming) {
|
|
379
376
|
setUi((prev) => ({ ...prev, isThinking: false }));
|
|
380
377
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
state.cumulativeOutputTokens += event.tokenUsage.outputTokens;
|
|
390
|
-
}
|
|
378
|
+
const rawInputTokens = event.tokenUsage.inputTokens ?? 0;
|
|
379
|
+
const cacheWriteTokens = event.tokenUsage.cacheWriteTokens ?? 0;
|
|
380
|
+
const inputTokens = Math.max(0, rawInputTokens - cacheWriteTokens);
|
|
381
|
+
if (inputTokens > 0) {
|
|
382
|
+
state.lastInputTokens = inputTokens;
|
|
383
|
+
}
|
|
384
|
+
if (event.tokenUsage.outputTokens) {
|
|
385
|
+
state.cumulativeOutputTokens += event.tokenUsage.outputTokens;
|
|
391
386
|
}
|
|
392
387
|
if (hasMeaningfulTokenUsageForAnalytics(event.tokenUsage, event.estimatedCost)) {
|
|
393
388
|
let estimateAccuracyPercent;
|
|
394
|
-
const actualInputTokens = event.tokenUsage
|
|
389
|
+
const actualInputTokens = event.tokenUsage.inputTokens;
|
|
395
390
|
if (event.estimatedInputTokens !== void 0 && actualInputTokens) {
|
|
396
391
|
const diff = event.estimatedInputTokens - actualInputTokens;
|
|
397
392
|
estimateAccuracyPercent = Math.round(diff / actualInputTokens * 100);
|
|
@@ -403,12 +398,12 @@ async function processStream(iterator, setters, options) {
|
|
|
403
398
|
model: event.model,
|
|
404
399
|
reasoningVariant: event.reasoningVariant ?? void 0,
|
|
405
400
|
reasoningBudgetTokens: event.reasoningBudgetTokens ?? void 0,
|
|
406
|
-
inputTokens: event.tokenUsage
|
|
407
|
-
outputTokens: event.tokenUsage
|
|
408
|
-
reasoningTokens: event.tokenUsage
|
|
409
|
-
totalTokens: event.tokenUsage
|
|
410
|
-
cacheReadTokens: event.tokenUsage
|
|
411
|
-
cacheWriteTokens: event.tokenUsage
|
|
401
|
+
inputTokens: event.tokenUsage.inputTokens,
|
|
402
|
+
outputTokens: event.tokenUsage.outputTokens,
|
|
403
|
+
reasoningTokens: event.tokenUsage.reasoningTokens,
|
|
404
|
+
totalTokens: event.tokenUsage.totalTokens,
|
|
405
|
+
cacheReadTokens: event.tokenUsage.cacheReadTokens,
|
|
406
|
+
cacheWriteTokens: event.tokenUsage.cacheWriteTokens,
|
|
412
407
|
estimatedCostUsd: event.estimatedCost,
|
|
413
408
|
inputCostUsd: event.costBreakdown?.inputUsd,
|
|
414
409
|
outputCostUsd: event.costBreakdown?.outputUsd,
|
|
@@ -457,6 +452,20 @@ async function processStream(iterator, setters, options) {
|
|
|
457
452
|
state.textFinalizedBeforeTool = false;
|
|
458
453
|
break;
|
|
459
454
|
}
|
|
455
|
+
case "interaction:blocked": {
|
|
456
|
+
setUi((prev) => ({ ...prev, isThinking: false }));
|
|
457
|
+
setMessages((prev) => [
|
|
458
|
+
...prev,
|
|
459
|
+
{
|
|
460
|
+
id: event.messageId,
|
|
461
|
+
role: "assistant",
|
|
462
|
+
content: event.content,
|
|
463
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
464
|
+
isStreaming: false
|
|
465
|
+
}
|
|
466
|
+
]);
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
460
469
|
case "llm:tool-call": {
|
|
461
470
|
if ((0, import_messageFormatting.shouldHideTool)(event.toolName)) {
|
|
462
471
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processStream.d.ts","sourceRoot":"","sources":["../../src/services/processStream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAGvE,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAc,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAoEvE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,oFAAoF;IACpF,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,kEAAkE;IAClE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3F,4CAA4C;IAC5C,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IAC9F,2CAA2C;IAC3C,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IAC/F,4DAA4D;IAC5D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,uDAAuD;IACvD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;CAC7E;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2FAA2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2FAA2F;IAC3F,mBAAmB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1C,wFAAwF;IACxF,oBAAoB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3C,yDAAyD;IACzD,QAAQ,EAAE,IAAI,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;IAC5D,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,+BAA+B,EAAE,wBAAwB,CAAC;IAChF,kEAAkE;IAClE,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;CAC3F;
|
|
1
|
+
{"version":3,"file":"processStream.d.ts","sourceRoot":"","sources":["../../src/services/processStream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAGvE,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAc,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAoEvE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,oFAAoF;IACpF,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,kEAAkE;IAClE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3F,4CAA4C;IAC5C,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IAC9F,2CAA2C;IAC3C,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IAC/F,4DAA4D;IAC5D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,uDAAuD;IACvD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;CAC7E;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2FAA2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2FAA2F;IAC3F,mBAAmB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1C,wFAAwF;IACxF,oBAAoB,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3C,yDAAyD;IACzD,QAAQ,EAAE,IAAI,CAAC,OAAO,aAAa,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;IAC5D,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,+BAA+B,EAAE,wBAAwB,CAAC;IAChF,kEAAkE;IAClE,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;CAC3F;AAgDD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAC/B,QAAQ,EAAE,qBAAqB,CAAC,cAAc,CAAC,EAC/C,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,oBAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAsuCf"}
|
|
@@ -57,9 +57,6 @@ function hasMeaningfulTokenUsageForAnalytics(tokenUsage, estimatedCost) {
|
|
|
57
57
|
if (estimatedCost !== void 0) {
|
|
58
58
|
return true;
|
|
59
59
|
}
|
|
60
|
-
if (!tokenUsage) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
60
|
return (tokenUsage.inputTokens ?? 0) > 0 || (tokenUsage.outputTokens ?? 0) > 0 || (tokenUsage.reasoningTokens ?? 0) > 0 || (tokenUsage.cacheReadTokens ?? 0) > 0 || (tokenUsage.cacheWriteTokens ?? 0) > 0 || (tokenUsage.totalTokens ?? 0) > 0;
|
|
64
61
|
}
|
|
65
62
|
async function processStream(iterator, setters, options) {
|
|
@@ -345,20 +342,18 @@ async function processStream(iterator, setters, options) {
|
|
|
345
342
|
if (!useStreaming) {
|
|
346
343
|
setUi((prev) => ({ ...prev, isThinking: false }));
|
|
347
344
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
state.cumulativeOutputTokens += event.tokenUsage.outputTokens;
|
|
357
|
-
}
|
|
345
|
+
const rawInputTokens = event.tokenUsage.inputTokens ?? 0;
|
|
346
|
+
const cacheWriteTokens = event.tokenUsage.cacheWriteTokens ?? 0;
|
|
347
|
+
const inputTokens = Math.max(0, rawInputTokens - cacheWriteTokens);
|
|
348
|
+
if (inputTokens > 0) {
|
|
349
|
+
state.lastInputTokens = inputTokens;
|
|
350
|
+
}
|
|
351
|
+
if (event.tokenUsage.outputTokens) {
|
|
352
|
+
state.cumulativeOutputTokens += event.tokenUsage.outputTokens;
|
|
358
353
|
}
|
|
359
354
|
if (hasMeaningfulTokenUsageForAnalytics(event.tokenUsage, event.estimatedCost)) {
|
|
360
355
|
let estimateAccuracyPercent;
|
|
361
|
-
const actualInputTokens = event.tokenUsage
|
|
356
|
+
const actualInputTokens = event.tokenUsage.inputTokens;
|
|
362
357
|
if (event.estimatedInputTokens !== void 0 && actualInputTokens) {
|
|
363
358
|
const diff = event.estimatedInputTokens - actualInputTokens;
|
|
364
359
|
estimateAccuracyPercent = Math.round(diff / actualInputTokens * 100);
|
|
@@ -370,12 +365,12 @@ async function processStream(iterator, setters, options) {
|
|
|
370
365
|
model: event.model,
|
|
371
366
|
reasoningVariant: event.reasoningVariant ?? void 0,
|
|
372
367
|
reasoningBudgetTokens: event.reasoningBudgetTokens ?? void 0,
|
|
373
|
-
inputTokens: event.tokenUsage
|
|
374
|
-
outputTokens: event.tokenUsage
|
|
375
|
-
reasoningTokens: event.tokenUsage
|
|
376
|
-
totalTokens: event.tokenUsage
|
|
377
|
-
cacheReadTokens: event.tokenUsage
|
|
378
|
-
cacheWriteTokens: event.tokenUsage
|
|
368
|
+
inputTokens: event.tokenUsage.inputTokens,
|
|
369
|
+
outputTokens: event.tokenUsage.outputTokens,
|
|
370
|
+
reasoningTokens: event.tokenUsage.reasoningTokens,
|
|
371
|
+
totalTokens: event.tokenUsage.totalTokens,
|
|
372
|
+
cacheReadTokens: event.tokenUsage.cacheReadTokens,
|
|
373
|
+
cacheWriteTokens: event.tokenUsage.cacheWriteTokens,
|
|
379
374
|
estimatedCostUsd: event.estimatedCost,
|
|
380
375
|
inputCostUsd: event.costBreakdown?.inputUsd,
|
|
381
376
|
outputCostUsd: event.costBreakdown?.outputUsd,
|
|
@@ -424,6 +419,20 @@ async function processStream(iterator, setters, options) {
|
|
|
424
419
|
state.textFinalizedBeforeTool = false;
|
|
425
420
|
break;
|
|
426
421
|
}
|
|
422
|
+
case "interaction:blocked": {
|
|
423
|
+
setUi((prev) => ({ ...prev, isThinking: false }));
|
|
424
|
+
setMessages((prev) => [
|
|
425
|
+
...prev,
|
|
426
|
+
{
|
|
427
|
+
id: event.messageId,
|
|
428
|
+
role: "assistant",
|
|
429
|
+
content: event.content,
|
|
430
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
431
|
+
isStreaming: false
|
|
432
|
+
}
|
|
433
|
+
]);
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
427
436
|
case "llm:tool-call": {
|
|
428
437
|
if (shouldHideTool(event.toolName)) {
|
|
429
438
|
break;
|
|
@@ -25,6 +25,22 @@ async function* eventStream(events) {
|
|
|
25
25
|
yield event;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
function llmResponse(overrides) {
|
|
29
|
+
return {
|
|
30
|
+
name: "llm:response",
|
|
31
|
+
sessionId: "test-session",
|
|
32
|
+
content: "Hello",
|
|
33
|
+
provider: "openai",
|
|
34
|
+
model: "gpt-4",
|
|
35
|
+
finishReason: "stop",
|
|
36
|
+
tokenUsage: {
|
|
37
|
+
inputTokens: 1,
|
|
38
|
+
outputTokens: 1,
|
|
39
|
+
totalTokens: 2
|
|
40
|
+
},
|
|
41
|
+
...overrides
|
|
42
|
+
};
|
|
43
|
+
}
|
|
28
44
|
function createSetters({
|
|
29
45
|
steerMessages: initialSteerMessages = [],
|
|
30
46
|
queuedMessages: initialQueuedMessages = []
|
|
@@ -137,6 +153,38 @@ function createSetters({
|
|
|
137
153
|
(0, import_vitest.expect)(getSteerMessages()).toEqual([]);
|
|
138
154
|
(0, import_vitest.expect)(getQueuedMessages()).toEqual([followUp]);
|
|
139
155
|
});
|
|
156
|
+
(0, import_vitest.it)("renders blocked interactions as final assistant messages", async () => {
|
|
157
|
+
const { getMessages, getUi, setters } = createSetters();
|
|
158
|
+
await (0, import_processStream.processStream)(
|
|
159
|
+
eventStream([
|
|
160
|
+
{ name: "llm:thinking", sessionId: "test-session" },
|
|
161
|
+
{
|
|
162
|
+
name: "interaction:blocked",
|
|
163
|
+
sessionId: "test-session",
|
|
164
|
+
content: "Error: blocked by policy",
|
|
165
|
+
provider: "openai",
|
|
166
|
+
model: "gpt-4",
|
|
167
|
+
messageId: "blocked-message"
|
|
168
|
+
}
|
|
169
|
+
]),
|
|
170
|
+
setters,
|
|
171
|
+
{
|
|
172
|
+
useStreaming: true,
|
|
173
|
+
autoApproveEditsRef: { current: false },
|
|
174
|
+
bypassPermissionsRef: { current: false },
|
|
175
|
+
eventBus: { emit: import_vitest.vi.fn() }
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
(0, import_vitest.expect)(getUi().isThinking).toBe(false);
|
|
179
|
+
(0, import_vitest.expect)(getMessages()).toEqual([
|
|
180
|
+
import_vitest.expect.objectContaining({
|
|
181
|
+
id: "blocked-message",
|
|
182
|
+
role: "assistant",
|
|
183
|
+
content: "Error: blocked by policy",
|
|
184
|
+
isStreaming: false
|
|
185
|
+
})
|
|
186
|
+
]);
|
|
187
|
+
});
|
|
140
188
|
(0, import_vitest.it)("attaches streamed reasoning chunks to the assistant message", async () => {
|
|
141
189
|
const { getMessages, getPendingMessages, setters } = createSetters();
|
|
142
190
|
const events = [
|
|
@@ -159,11 +207,9 @@ function createSetters({
|
|
|
159
207
|
chunkType: "text",
|
|
160
208
|
content: "Hello"
|
|
161
209
|
},
|
|
162
|
-
{
|
|
163
|
-
name: "llm:response",
|
|
164
|
-
sessionId: "test-session",
|
|
210
|
+
llmResponse({
|
|
165
211
|
content: "Hello"
|
|
166
|
-
},
|
|
212
|
+
}),
|
|
167
213
|
{
|
|
168
214
|
name: "run:complete",
|
|
169
215
|
sessionId: "test-session",
|
|
@@ -202,11 +248,9 @@ function createSetters({
|
|
|
202
248
|
chunkType: "text",
|
|
203
249
|
content: longText
|
|
204
250
|
},
|
|
205
|
-
{
|
|
206
|
-
name: "llm:response",
|
|
207
|
-
sessionId: "test-session",
|
|
251
|
+
llmResponse({
|
|
208
252
|
content: longText
|
|
209
|
-
},
|
|
253
|
+
}),
|
|
210
254
|
{
|
|
211
255
|
name: "run:complete",
|
|
212
256
|
sessionId: "test-session",
|
|
@@ -244,11 +288,9 @@ function createSetters({
|
|
|
244
288
|
chunkType: "text",
|
|
245
289
|
content: "Hello"
|
|
246
290
|
},
|
|
247
|
-
{
|
|
248
|
-
name: "llm:response",
|
|
249
|
-
sessionId: "test-session",
|
|
291
|
+
llmResponse({
|
|
250
292
|
content: "Hello"
|
|
251
|
-
},
|
|
293
|
+
}),
|
|
252
294
|
{
|
|
253
295
|
name: "run:complete",
|
|
254
296
|
sessionId: "test-session",
|
|
@@ -286,12 +328,10 @@ function createSetters({
|
|
|
286
328
|
callId: "call-1",
|
|
287
329
|
args: {}
|
|
288
330
|
},
|
|
289
|
-
{
|
|
290
|
-
name: "llm:response",
|
|
291
|
-
sessionId: "test-session",
|
|
331
|
+
llmResponse({
|
|
292
332
|
content: "Final",
|
|
293
333
|
reasoning: "R"
|
|
294
|
-
},
|
|
334
|
+
}),
|
|
295
335
|
{
|
|
296
336
|
name: "run:complete",
|
|
297
337
|
sessionId: "test-session",
|
|
@@ -348,9 +388,7 @@ function createSetters({
|
|
|
348
388
|
const { setters } = createSetters();
|
|
349
389
|
const events = [
|
|
350
390
|
{ name: "llm:thinking", sessionId: "test-session" },
|
|
351
|
-
{
|
|
352
|
-
name: "llm:response",
|
|
353
|
-
sessionId: "test-session",
|
|
391
|
+
llmResponse({
|
|
354
392
|
content: "Priced response",
|
|
355
393
|
provider: "openai",
|
|
356
394
|
model: "gpt-4",
|
|
@@ -368,7 +406,7 @@ function createSetters({
|
|
|
368
406
|
outputTokens: 20,
|
|
369
407
|
totalTokens: 30
|
|
370
408
|
}
|
|
371
|
-
},
|
|
409
|
+
}),
|
|
372
410
|
{
|
|
373
411
|
name: "run:complete",
|
|
374
412
|
sessionId: "test-session",
|
|
@@ -24,6 +24,22 @@ async function* eventStream(events) {
|
|
|
24
24
|
yield event;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
function llmResponse(overrides) {
|
|
28
|
+
return {
|
|
29
|
+
name: "llm:response",
|
|
30
|
+
sessionId: "test-session",
|
|
31
|
+
content: "Hello",
|
|
32
|
+
provider: "openai",
|
|
33
|
+
model: "gpt-4",
|
|
34
|
+
finishReason: "stop",
|
|
35
|
+
tokenUsage: {
|
|
36
|
+
inputTokens: 1,
|
|
37
|
+
outputTokens: 1,
|
|
38
|
+
totalTokens: 2
|
|
39
|
+
},
|
|
40
|
+
...overrides
|
|
41
|
+
};
|
|
42
|
+
}
|
|
27
43
|
function createSetters({
|
|
28
44
|
steerMessages: initialSteerMessages = [],
|
|
29
45
|
queuedMessages: initialQueuedMessages = []
|
|
@@ -136,6 +152,38 @@ describe("processStream (reasoning)", () => {
|
|
|
136
152
|
expect(getSteerMessages()).toEqual([]);
|
|
137
153
|
expect(getQueuedMessages()).toEqual([followUp]);
|
|
138
154
|
});
|
|
155
|
+
it("renders blocked interactions as final assistant messages", async () => {
|
|
156
|
+
const { getMessages, getUi, setters } = createSetters();
|
|
157
|
+
await processStream(
|
|
158
|
+
eventStream([
|
|
159
|
+
{ name: "llm:thinking", sessionId: "test-session" },
|
|
160
|
+
{
|
|
161
|
+
name: "interaction:blocked",
|
|
162
|
+
sessionId: "test-session",
|
|
163
|
+
content: "Error: blocked by policy",
|
|
164
|
+
provider: "openai",
|
|
165
|
+
model: "gpt-4",
|
|
166
|
+
messageId: "blocked-message"
|
|
167
|
+
}
|
|
168
|
+
]),
|
|
169
|
+
setters,
|
|
170
|
+
{
|
|
171
|
+
useStreaming: true,
|
|
172
|
+
autoApproveEditsRef: { current: false },
|
|
173
|
+
bypassPermissionsRef: { current: false },
|
|
174
|
+
eventBus: { emit: vi.fn() }
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
expect(getUi().isThinking).toBe(false);
|
|
178
|
+
expect(getMessages()).toEqual([
|
|
179
|
+
expect.objectContaining({
|
|
180
|
+
id: "blocked-message",
|
|
181
|
+
role: "assistant",
|
|
182
|
+
content: "Error: blocked by policy",
|
|
183
|
+
isStreaming: false
|
|
184
|
+
})
|
|
185
|
+
]);
|
|
186
|
+
});
|
|
139
187
|
it("attaches streamed reasoning chunks to the assistant message", async () => {
|
|
140
188
|
const { getMessages, getPendingMessages, setters } = createSetters();
|
|
141
189
|
const events = [
|
|
@@ -158,11 +206,9 @@ describe("processStream (reasoning)", () => {
|
|
|
158
206
|
chunkType: "text",
|
|
159
207
|
content: "Hello"
|
|
160
208
|
},
|
|
161
|
-
{
|
|
162
|
-
name: "llm:response",
|
|
163
|
-
sessionId: "test-session",
|
|
209
|
+
llmResponse({
|
|
164
210
|
content: "Hello"
|
|
165
|
-
},
|
|
211
|
+
}),
|
|
166
212
|
{
|
|
167
213
|
name: "run:complete",
|
|
168
214
|
sessionId: "test-session",
|
|
@@ -201,11 +247,9 @@ describe("processStream (reasoning)", () => {
|
|
|
201
247
|
chunkType: "text",
|
|
202
248
|
content: longText
|
|
203
249
|
},
|
|
204
|
-
{
|
|
205
|
-
name: "llm:response",
|
|
206
|
-
sessionId: "test-session",
|
|
250
|
+
llmResponse({
|
|
207
251
|
content: longText
|
|
208
|
-
},
|
|
252
|
+
}),
|
|
209
253
|
{
|
|
210
254
|
name: "run:complete",
|
|
211
255
|
sessionId: "test-session",
|
|
@@ -243,11 +287,9 @@ describe("processStream (reasoning)", () => {
|
|
|
243
287
|
chunkType: "text",
|
|
244
288
|
content: "Hello"
|
|
245
289
|
},
|
|
246
|
-
{
|
|
247
|
-
name: "llm:response",
|
|
248
|
-
sessionId: "test-session",
|
|
290
|
+
llmResponse({
|
|
249
291
|
content: "Hello"
|
|
250
|
-
},
|
|
292
|
+
}),
|
|
251
293
|
{
|
|
252
294
|
name: "run:complete",
|
|
253
295
|
sessionId: "test-session",
|
|
@@ -285,12 +327,10 @@ describe("processStream (reasoning)", () => {
|
|
|
285
327
|
callId: "call-1",
|
|
286
328
|
args: {}
|
|
287
329
|
},
|
|
288
|
-
{
|
|
289
|
-
name: "llm:response",
|
|
290
|
-
sessionId: "test-session",
|
|
330
|
+
llmResponse({
|
|
291
331
|
content: "Final",
|
|
292
332
|
reasoning: "R"
|
|
293
|
-
},
|
|
333
|
+
}),
|
|
294
334
|
{
|
|
295
335
|
name: "run:complete",
|
|
296
336
|
sessionId: "test-session",
|
|
@@ -347,9 +387,7 @@ describe("processStream (reasoning)", () => {
|
|
|
347
387
|
const { setters } = createSetters();
|
|
348
388
|
const events = [
|
|
349
389
|
{ name: "llm:thinking", sessionId: "test-session" },
|
|
350
|
-
{
|
|
351
|
-
name: "llm:response",
|
|
352
|
-
sessionId: "test-session",
|
|
390
|
+
llmResponse({
|
|
353
391
|
content: "Priced response",
|
|
354
392
|
provider: "openai",
|
|
355
393
|
model: "gpt-4",
|
|
@@ -367,7 +405,7 @@ describe("processStream (reasoning)", () => {
|
|
|
367
405
|
outputTokens: 20,
|
|
368
406
|
totalTokens: 30
|
|
369
407
|
}
|
|
370
|
-
},
|
|
408
|
+
}),
|
|
371
409
|
{
|
|
372
410
|
name: "run:complete",
|
|
373
411
|
sessionId: "test-session",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexto/tui",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
4
|
"description": "Interactive terminal UI for Dexto CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"string-width": "^8.1.0",
|
|
29
29
|
"strip-ansi": "^7.1.2",
|
|
30
30
|
"wrap-ansi": "^9.0.2",
|
|
31
|
-
"@dexto/
|
|
32
|
-
"@dexto/
|
|
33
|
-
"@dexto/llm": "1.8.
|
|
34
|
-
"@dexto/registry": "1.8.
|
|
31
|
+
"@dexto/core": "1.8.3",
|
|
32
|
+
"@dexto/agent-management": "1.8.3",
|
|
33
|
+
"@dexto/llm": "1.8.3",
|
|
34
|
+
"@dexto/registry": "1.8.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/react": "^19.0.0",
|