@dexto/core 1.8.2 → 1.8.4

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.
Files changed (56) hide show
  1. package/dist/agent/DextoAgent.cjs +11 -12
  2. package/dist/agent/DextoAgent.d.ts +4 -2
  3. package/dist/agent/DextoAgent.d.ts.map +1 -1
  4. package/dist/agent/DextoAgent.js +15 -13
  5. package/dist/events/index.cjs +8 -0
  6. package/dist/events/index.d.ts +25 -14
  7. package/dist/events/index.d.ts.map +1 -1
  8. package/dist/events/index.js +8 -0
  9. package/dist/index.browser.cjs +6 -0
  10. package/dist/index.browser.d.ts +2 -0
  11. package/dist/index.browser.d.ts.map +1 -1
  12. package/dist/index.browser.js +4 -0
  13. package/dist/llm/executor/provider-error.cjs +214 -0
  14. package/dist/llm/executor/provider-error.d.ts +26 -0
  15. package/dist/llm/executor/provider-error.d.ts.map +1 -0
  16. package/dist/llm/executor/provider-error.js +190 -0
  17. package/dist/llm/executor/stream-processor.cjs +34 -5
  18. package/dist/llm/executor/stream-processor.d.ts +4 -1
  19. package/dist/llm/executor/stream-processor.d.ts.map +1 -1
  20. package/dist/llm/executor/stream-processor.js +34 -5
  21. package/dist/llm/executor/turn-executor.cjs +185 -124
  22. package/dist/llm/executor/turn-executor.d.ts +5 -5
  23. package/dist/llm/executor/turn-executor.d.ts.map +1 -1
  24. package/dist/llm/executor/turn-executor.js +184 -120
  25. package/dist/session/chat-session.cjs +37 -22
  26. package/dist/session/chat-session.d.ts.map +1 -1
  27. package/dist/session/chat-session.js +38 -22
  28. package/dist/session/title-generator.cjs +19 -2
  29. package/dist/session/title-generator.d.ts +8 -0
  30. package/dist/session/title-generator.d.ts.map +1 -1
  31. package/dist/session/title-generator.js +19 -2
  32. package/dist/systemPrompt/contributors.cjs +10 -1
  33. package/dist/systemPrompt/contributors.d.ts.map +1 -1
  34. package/dist/systemPrompt/contributors.js +10 -1
  35. package/dist/telemetry/browser.cjs +138 -0
  36. package/dist/telemetry/browser.d.ts +30 -0
  37. package/dist/telemetry/browser.d.ts.map +1 -0
  38. package/dist/telemetry/browser.js +115 -0
  39. package/dist/telemetry/index.cjs +5 -2
  40. package/dist/telemetry/index.d.ts +1 -0
  41. package/dist/telemetry/index.d.ts.map +1 -1
  42. package/dist/telemetry/index.js +3 -1
  43. package/dist/telemetry/operation-span.cjs +73 -0
  44. package/dist/telemetry/operation-span.d.ts +13 -0
  45. package/dist/telemetry/operation-span.d.ts.map +1 -0
  46. package/dist/telemetry/operation-span.js +50 -0
  47. package/dist/telemetry/telemetry.cjs +2 -3
  48. package/dist/telemetry/telemetry.d.ts.map +1 -1
  49. package/dist/telemetry/telemetry.js +2 -3
  50. package/dist/telemetry/utils.cjs +11 -12
  51. package/dist/telemetry/utils.d.ts.map +1 -1
  52. package/dist/telemetry/utils.js +11 -12
  53. package/dist/tools/tool-call-metadata.cjs +118 -6
  54. package/dist/tools/tool-call-metadata.d.ts.map +1 -1
  55. package/dist/tools/tool-call-metadata.js +118 -6
  56. package/package.json +2 -2
@@ -13,9 +13,11 @@ import { StreamProcessor } from "./stream-processor.js";
13
13
  import { truncateToolResult } from "./tool-output-truncator.js";
14
14
  import { buildProviderOptions, getEffectiveReasoningBudgetTokens } from "./provider-options.js";
15
15
  import { DextoLogComponent } from "../../logger/v2/types.js";
16
- import { DextoRuntimeError } from "../../errors/DextoRuntimeError.js";
17
- import { ErrorScope, ErrorType } from "../../errors/types.js";
18
- import { LLMErrorCode } from "../error-codes.js";
16
+ import { recordOperationSpan } from "../../telemetry/operation-span.js";
17
+ import {
18
+ extractProviderErrorDetails,
19
+ mapProviderError as mapCoreProviderError
20
+ } from "./provider-error.js";
19
21
  import { toError } from "../../utils/error-conversion.js";
20
22
  import { isCodexBaseURL } from "../providers/codex-base-url.js";
21
23
  import { createModelToolDefinitions } from "./tool-definitions.js";
@@ -350,11 +352,19 @@ class TurnExecutor {
350
352
  this.currentModelStepId = `in-memory-model-step-${stepCount}`;
351
353
  modelStepPreparing = true;
352
354
  try {
353
- preparedModelRequest = await this.prepareNextModelRequest({
354
- contributorContext,
355
- supportsTools: turn.supportsTools,
356
- streaming: options.streaming
357
- });
355
+ preparedModelRequest = await recordOperationSpan(
356
+ {
357
+ name: "turn.prepare_model_step",
358
+ componentName: "TurnExecutor",
359
+ attributes: { "turn.step_count": stepCount }
360
+ },
361
+ () => this.prepareNextModelRequest({
362
+ contributorContext,
363
+ supportsTools: turn.supportsTools,
364
+ streaming: options.streaming
365
+ }),
366
+ this.logger
367
+ );
358
368
  } catch (error) {
359
369
  currentStepScope[Symbol.dispose]();
360
370
  currentStepScope = null;
@@ -380,11 +390,19 @@ class TurnExecutor {
380
390
  }
381
391
  currentStepScope = this.startModelStepScope();
382
392
  this.currentModelStepId = `in-memory-model-step-${stepCount}`;
383
- preparedModelRequest = await this.prepareNextModelRequest({
384
- contributorContext,
385
- supportsTools: turn.supportsTools,
386
- streaming: options.streaming
387
- });
393
+ preparedModelRequest = await recordOperationSpan(
394
+ {
395
+ name: "turn.prepare_model_step",
396
+ componentName: "TurnExecutor",
397
+ attributes: { "turn.step_count": stepCount }
398
+ },
399
+ () => this.prepareNextModelRequest({
400
+ contributorContext,
401
+ supportsTools: turn.supportsTools,
402
+ streaming: options.streaming
403
+ }),
404
+ this.logger
405
+ );
388
406
  }
389
407
  const modelStepRequest = preparedModelRequest;
390
408
  if (currentStepScope === null || modelStepRequest === null) {
@@ -576,7 +594,13 @@ class TurnExecutor {
576
594
  this.eventBus.emit("llm:error", {
577
595
  error: mappedError,
578
596
  context: "TurnExecutor",
579
- recoverable: false
597
+ recoverable: false,
598
+ details: extractProviderErrorDetails({
599
+ error,
600
+ provider: this.llmContext.provider,
601
+ model: this.llmContext.model,
602
+ sessionId: this.sessionId
603
+ })
580
604
  });
581
605
  await this.contextManager.flush();
582
606
  this.eventBus.emit("run:complete", {
@@ -773,48 +797,159 @@ class TurnExecutor {
773
797
  await this.injectQueuedMessages(coalesced);
774
798
  }
775
799
  await this.pruneOldToolOutputs();
776
- let prepared = await this.contextManager.getFormattedMessagesForLLM(
777
- input.contributorContext,
778
- this.llmContext
800
+ let systemPrompt = await recordOperationSpan(
801
+ {
802
+ name: "system_prompt.build",
803
+ componentName: "TurnExecutor",
804
+ attributes: {
805
+ "llm.model": this.llmContext.model,
806
+ "llm.provider": this.llmContext.provider
807
+ }
808
+ },
809
+ () => this.contextManager.getSystemPrompt(input.contributorContext),
810
+ this.logger
779
811
  );
780
- const toolDefinitions = input.supportsTools ? this.toolManager.filterToolsForSession(
781
- await this.toolManager.getAllTools(),
782
- this.sessionId
812
+ let { preparedHistory, formattedMessages } = await recordOperationSpan(
813
+ {
814
+ name: "context.build_messages",
815
+ componentName: "TurnExecutor",
816
+ attributes: {
817
+ "llm.model": this.llmContext.model,
818
+ "llm.provider": this.llmContext.provider
819
+ }
820
+ },
821
+ async () => {
822
+ const preparedHistory2 = (await this.contextManager.prepareHistory()).preparedHistory;
823
+ const formattedMessages2 = await this.contextManager.getFormattedMessages(
824
+ input.contributorContext,
825
+ this.llmContext,
826
+ systemPrompt,
827
+ preparedHistory2
828
+ );
829
+ return { preparedHistory: preparedHistory2, formattedMessages: formattedMessages2 };
830
+ },
831
+ this.logger
832
+ );
833
+ const toolDefinitions = input.supportsTools ? await recordOperationSpan(
834
+ {
835
+ name: "tools.list",
836
+ componentName: "TurnExecutor",
837
+ attributes: { "tools.supports": input.supportsTools },
838
+ resultAttributes: (tools) => ({ "tools.count": Object.keys(tools).length })
839
+ },
840
+ async () => this.toolManager.filterToolsForSession(
841
+ await this.toolManager.getAllTools(),
842
+ this.sessionId
843
+ ),
844
+ this.logger
783
845
  ) : {};
784
- let estimatedInputTokens = await this.contextManager.getEstimatedNextInputTokens(
785
- prepared.systemPrompt,
786
- prepared.preparedHistory,
787
- toolDefinitions
846
+ let estimatedInputTokens = await recordOperationSpan(
847
+ {
848
+ name: "context.token_estimate",
849
+ componentName: "TurnExecutor",
850
+ attributes: { "tools.count": Object.keys(toolDefinitions).length },
851
+ resultAttributes: (tokens) => ({ "context.estimated_input_tokens": tokens })
852
+ },
853
+ () => this.contextManager.getEstimatedNextInputTokens(
854
+ systemPrompt,
855
+ preparedHistory,
856
+ toolDefinitions
857
+ ),
858
+ this.logger
788
859
  );
789
860
  if (this.shouldCompact(estimatedInputTokens)) {
790
861
  this.logger.debug(
791
862
  `Pre-check: estimated ${estimatedInputTokens} tokens exceeds threshold, compacting`
792
863
  );
793
- const didCompact = await this.compactContext(
794
- estimatedInputTokens,
795
- input.contributorContext,
796
- toolDefinitions
864
+ const didCompact = await recordOperationSpan(
865
+ {
866
+ name: "context.compact",
867
+ componentName: "TurnExecutor",
868
+ attributes: { "context.estimated_input_tokens": estimatedInputTokens }
869
+ },
870
+ () => this.compactContext(
871
+ estimatedInputTokens,
872
+ input.contributorContext,
873
+ toolDefinitions
874
+ ),
875
+ this.logger
797
876
  );
798
877
  if (didCompact) {
799
- prepared = await this.contextManager.getFormattedMessagesForLLM(
800
- input.contributorContext,
801
- this.llmContext
878
+ systemPrompt = await recordOperationSpan(
879
+ {
880
+ name: "system_prompt.build",
881
+ componentName: "TurnExecutor",
882
+ attributes: {
883
+ "context.after_compaction": true,
884
+ "llm.model": this.llmContext.model,
885
+ "llm.provider": this.llmContext.provider
886
+ }
887
+ },
888
+ () => this.contextManager.getSystemPrompt(input.contributorContext),
889
+ this.logger
802
890
  );
803
- estimatedInputTokens = await this.contextManager.getEstimatedNextInputTokens(
804
- prepared.systemPrompt,
805
- prepared.preparedHistory,
806
- toolDefinitions
891
+ ({ preparedHistory, formattedMessages } = await recordOperationSpan(
892
+ {
893
+ name: "context.build_messages",
894
+ componentName: "TurnExecutor",
895
+ attributes: {
896
+ "context.after_compaction": true,
897
+ "llm.model": this.llmContext.model,
898
+ "llm.provider": this.llmContext.provider
899
+ }
900
+ },
901
+ async () => {
902
+ const preparedHistory2 = (await this.contextManager.prepareHistory()).preparedHistory;
903
+ const formattedMessages2 = await this.contextManager.getFormattedMessages(
904
+ input.contributorContext,
905
+ this.llmContext,
906
+ systemPrompt,
907
+ preparedHistory2
908
+ );
909
+ return { preparedHistory: preparedHistory2, formattedMessages: formattedMessages2 };
910
+ },
911
+ this.logger
912
+ ));
913
+ estimatedInputTokens = await recordOperationSpan(
914
+ {
915
+ name: "context.token_estimate",
916
+ componentName: "TurnExecutor",
917
+ attributes: {
918
+ "context.after_compaction": true,
919
+ "tools.count": Object.keys(toolDefinitions).length
920
+ },
921
+ resultAttributes: (tokens) => ({
922
+ "context.estimated_input_tokens": tokens
923
+ })
924
+ },
925
+ () => this.contextManager.getEstimatedNextInputTokens(
926
+ systemPrompt,
927
+ preparedHistory,
928
+ toolDefinitions
929
+ ),
930
+ this.logger
807
931
  );
808
932
  this.logger.debug(
809
933
  `Post-compaction: recomputed estimate is ${estimatedInputTokens} tokens`
810
934
  );
811
935
  }
812
936
  }
813
- const providerOptions = buildProviderOptions({
814
- provider: this.llmContext.provider,
815
- model: this.llmContext.model,
816
- reasoning: this.config.reasoning
817
- });
937
+ const providerOptions = await recordOperationSpan(
938
+ {
939
+ name: "llm.request_setup",
940
+ componentName: "TurnExecutor",
941
+ attributes: {
942
+ "llm.model": this.llmContext.model,
943
+ "llm.provider": this.llmContext.provider
944
+ }
945
+ },
946
+ () => buildProviderOptions({
947
+ provider: this.llmContext.provider,
948
+ model: this.llmContext.model,
949
+ reasoning: this.config.reasoning
950
+ }),
951
+ this.logger
952
+ );
818
953
  this.logger.debug("LLM request options", {
819
954
  provider: this.llmContext.provider,
820
955
  model: this.llmContext.model,
@@ -831,7 +966,7 @@ class TurnExecutor {
831
966
  ...reasoningBudgetTokens !== void 0 && { reasoningBudgetTokens }
832
967
  } : void 0;
833
968
  return {
834
- messages: prepared.formattedMessages,
969
+ messages: formattedMessages,
835
970
  tools: input.supportsTools ? createModelToolDefinitions(toolDefinitions) : {},
836
971
  toolDefinitions,
837
972
  estimatedInputTokens,
@@ -862,7 +997,8 @@ class TurnExecutor {
862
997
  this.stepAbortController.signal,
863
998
  this.getStreamProcessorConfig(request.estimatedInputTokens, request.reasoning),
864
999
  this.logger,
865
- request.streaming
1000
+ request.streaming,
1001
+ false
866
1002
  );
867
1003
  return streamProcessor.process(
868
1004
  () => streamText({
@@ -1499,84 +1635,12 @@ class TurnExecutor {
1499
1635
  * Map provider errors to DextoRuntimeError.
1500
1636
  */
1501
1637
  mapProviderError(err) {
1502
- if (APICallError.isInstance?.(err)) {
1503
- const status = err.statusCode;
1504
- const headers = err.responseHeaders || {};
1505
- const retryAfter = headers["retry-after"] ? Number(headers["retry-after"]) : void 0;
1506
- const body = typeof err.responseBody === "string" ? err.responseBody : JSON.stringify(err.responseBody ?? "");
1507
- if (status === 402) {
1508
- let balance;
1509
- try {
1510
- const parsed = JSON.parse(body);
1511
- const msg = parsed?.error?.message || "";
1512
- const match = msg.match(/Balance:\s*\$?([\d.]+)/i);
1513
- if (match) {
1514
- balance = parseFloat(match[1]);
1515
- }
1516
- } catch {
1517
- }
1518
- return new DextoRuntimeError(
1519
- LLMErrorCode.INSUFFICIENT_CREDITS,
1520
- ErrorScope.LLM,
1521
- ErrorType.PAYMENT_REQUIRED,
1522
- `Insufficient Dexto credits${balance !== void 0 ? `. Balance: $${balance.toFixed(2)}` : ""}`,
1523
- {
1524
- sessionId: this.sessionId,
1525
- provider: this.llmContext.provider,
1526
- model: this.llmContext.model,
1527
- status,
1528
- balance,
1529
- body
1530
- },
1531
- "Run `dexto billing` to check your balance"
1532
- );
1533
- }
1534
- if (status === 429) {
1535
- return new DextoRuntimeError(
1536
- LLMErrorCode.RATE_LIMIT_EXCEEDED,
1537
- ErrorScope.LLM,
1538
- ErrorType.RATE_LIMIT,
1539
- `Rate limit exceeded${body ? ` - ${body}` : ""}`,
1540
- {
1541
- sessionId: this.sessionId,
1542
- provider: this.llmContext.provider,
1543
- model: this.llmContext.model,
1544
- status,
1545
- retryAfter,
1546
- body
1547
- }
1548
- );
1549
- }
1550
- if (status === 408) {
1551
- return new DextoRuntimeError(
1552
- LLMErrorCode.GENERATION_FAILED,
1553
- ErrorScope.LLM,
1554
- ErrorType.TIMEOUT,
1555
- `Provider timed out${body ? ` - ${body}` : ""}`,
1556
- {
1557
- sessionId: this.sessionId,
1558
- provider: this.llmContext.provider,
1559
- model: this.llmContext.model,
1560
- status,
1561
- body
1562
- }
1563
- );
1564
- }
1565
- return new DextoRuntimeError(
1566
- LLMErrorCode.GENERATION_FAILED,
1567
- ErrorScope.LLM,
1568
- ErrorType.THIRD_PARTY,
1569
- `Provider error ${status}${body ? ` - ${body}` : ""}`,
1570
- {
1571
- sessionId: this.sessionId,
1572
- provider: this.llmContext.provider,
1573
- model: this.llmContext.model,
1574
- status,
1575
- body
1576
- }
1577
- );
1578
- }
1579
- return toError(err, this.logger);
1638
+ return mapCoreProviderError({
1639
+ error: err,
1640
+ provider: this.llmContext.provider,
1641
+ model: this.llmContext.model,
1642
+ sessionId: this.sessionId
1643
+ });
1580
1644
  }
1581
1645
  }
1582
1646
  export {
@@ -29,6 +29,7 @@ var import_errors = require("../errors/index.js");
29
29
  var import_error_codes = require("../hooks/error-codes.js");
30
30
  var import_message_queue = require("./message-queue.js");
31
31
  var import_usage_metadata = require("../llm/usage-metadata.js");
32
+ var import_codex_base_url = require("../llm/providers/codex-base-url.js");
32
33
  var import_errors2 = require("./errors.js");
33
34
  class ChatSession {
34
35
  /**
@@ -134,29 +135,37 @@ class ChatSession {
134
135
  */
135
136
  setupTokenAccumulation() {
136
137
  this.tokenAccumulatorListener = (payload) => {
137
- if (payload.tokenUsage) {
138
- const tokenUsage = (0, import_usage_metadata.normalizeTokenUsageForAccounting)(payload.tokenUsage);
139
- const llmConfig = this.services.stateManager.getLLMConfig(this.id);
140
- const modelInfo = {
141
- provider: payload.provider ?? llmConfig.provider,
142
- model: payload.model ?? llmConfig.model
143
- };
144
- const pricingMetadata = (0, import_usage_metadata.getUsagePricingMetadata)({
145
- provider: modelInfo.provider,
146
- model: modelInfo.model,
147
- tokenUsage
148
- });
149
- this.services.sessionManager.accumulateTokenUsage(
150
- this.id,
151
- tokenUsage,
152
- payload.estimatedCost ?? pricingMetadata.estimatedCost,
153
- modelInfo
154
- ).catch((err) => {
138
+ const tokenUsage = (0, import_usage_metadata.normalizeTokenUsageForAccounting)(payload.tokenUsage);
139
+ const llmConfig = this.services.stateManager.getLLMConfig(this.id);
140
+ const isChatGPTLogin = llmConfig.provider === "openai-compatible" && (0, import_codex_base_url.parseCodexBaseURL)(llmConfig.baseURL)?.authMode === "chatgpt";
141
+ const hasMeaningfulUsage = (0, import_usage_metadata.hasMeaningfulTokenUsage)(tokenUsage);
142
+ if (isChatGPTLogin && !hasMeaningfulUsage) {
143
+ this.services.sessionManager.markUntrackedChatGPTLoginUsage(this.id).catch((err) => {
155
144
  this.logger.warn(
156
- `Failed to accumulate token usage: ${err instanceof Error ? err.message : String(err)}`
145
+ `Failed to mark ChatGPT Login usage as untracked: ${err instanceof Error ? err.message : String(err)}`
157
146
  );
158
147
  });
148
+ return;
159
149
  }
150
+ const modelInfo = {
151
+ provider: payload.provider,
152
+ model: payload.model
153
+ };
154
+ const pricingMetadata = (0, import_usage_metadata.getUsagePricingMetadata)({
155
+ provider: modelInfo.provider,
156
+ model: modelInfo.model,
157
+ tokenUsage
158
+ });
159
+ this.services.sessionManager.accumulateTokenUsage(
160
+ this.id,
161
+ tokenUsage,
162
+ payload.estimatedCost ?? pricingMetadata.estimatedCost,
163
+ modelInfo
164
+ ).catch((err) => {
165
+ this.logger.warn(
166
+ `Failed to accumulate token usage: ${err instanceof Error ? err.message : String(err)}`
167
+ );
168
+ });
160
169
  };
161
170
  this.eventBus.on("llm:response", this.tokenAccumulatorListener);
162
171
  }
@@ -215,8 +224,9 @@ class ChatSession {
215
224
  content: [{ type: "text", text: "[Blocked by content policy: input redacted]" }]
216
225
  };
217
226
  const errorContent = `Error: ${errorMessage}`;
227
+ const assistantMessageId = (0, import_crypto.randomUUID)();
218
228
  const assistantMessage = {
219
- id: (0, import_crypto.randomUUID)(),
229
+ id: assistantMessageId,
220
230
  role: "assistant",
221
231
  timestamp: timestamp + 1,
222
232
  content: [{ type: "text", text: errorContent }]
@@ -224,11 +234,16 @@ class ChatSession {
224
234
  await this.conversationStore.saveMessage({ sessionId: this.id, message: userMessage });
225
235
  await this.conversationStore.saveMessage({ sessionId: this.id, message: assistantMessage });
226
236
  const llmConfig = this.services.stateManager.getLLMConfig(this.id);
227
- this.eventBus.emit("llm:response", {
237
+ this.eventBus.emit("interaction:blocked", {
228
238
  content: errorContent,
229
239
  provider: llmConfig.provider,
230
240
  model: llmConfig.model,
231
- ...assistantMessage.id && { messageId: assistantMessage.id }
241
+ messageId: assistantMessageId
242
+ });
243
+ this.eventBus.emit("run:complete", {
244
+ finishReason: "stop",
245
+ stepCount: 0,
246
+ durationMs: 0
232
247
  });
233
248
  }
234
249
  normalizeContent(content) {
@@ -1 +1 @@
1
- {"version":3,"file":"chat-session.d.ts","sourceRoot":"","sources":["../../src/session/chat-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-session.d.ts","sourceRoot":"","sources":["../../src/session/chat-session.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,10 @@ import { HookErrorCode } from "../hooks/error-codes.js";
11
11
  import { MessageQueueService } from "./message-queue.js";
12
12
  import {
13
13
  getUsagePricingMetadata,
14
+ hasMeaningfulTokenUsage,
14
15
  normalizeTokenUsageForAccounting
15
16
  } from "../llm/usage-metadata.js";
17
+ import { parseCodexBaseURL } from "../llm/providers/codex-base-url.js";
16
18
  import { SessionError } from "./errors.js";
17
19
  class ChatSession {
18
20
  /**
@@ -118,29 +120,37 @@ class ChatSession {
118
120
  */
119
121
  setupTokenAccumulation() {
120
122
  this.tokenAccumulatorListener = (payload) => {
121
- if (payload.tokenUsage) {
122
- const tokenUsage = normalizeTokenUsageForAccounting(payload.tokenUsage);
123
- const llmConfig = this.services.stateManager.getLLMConfig(this.id);
124
- const modelInfo = {
125
- provider: payload.provider ?? llmConfig.provider,
126
- model: payload.model ?? llmConfig.model
127
- };
128
- const pricingMetadata = getUsagePricingMetadata({
129
- provider: modelInfo.provider,
130
- model: modelInfo.model,
131
- tokenUsage
132
- });
133
- this.services.sessionManager.accumulateTokenUsage(
134
- this.id,
135
- tokenUsage,
136
- payload.estimatedCost ?? pricingMetadata.estimatedCost,
137
- modelInfo
138
- ).catch((err) => {
123
+ const tokenUsage = normalizeTokenUsageForAccounting(payload.tokenUsage);
124
+ const llmConfig = this.services.stateManager.getLLMConfig(this.id);
125
+ const isChatGPTLogin = llmConfig.provider === "openai-compatible" && parseCodexBaseURL(llmConfig.baseURL)?.authMode === "chatgpt";
126
+ const hasMeaningfulUsage = hasMeaningfulTokenUsage(tokenUsage);
127
+ if (isChatGPTLogin && !hasMeaningfulUsage) {
128
+ this.services.sessionManager.markUntrackedChatGPTLoginUsage(this.id).catch((err) => {
139
129
  this.logger.warn(
140
- `Failed to accumulate token usage: ${err instanceof Error ? err.message : String(err)}`
130
+ `Failed to mark ChatGPT Login usage as untracked: ${err instanceof Error ? err.message : String(err)}`
141
131
  );
142
132
  });
133
+ return;
143
134
  }
135
+ const modelInfo = {
136
+ provider: payload.provider,
137
+ model: payload.model
138
+ };
139
+ const pricingMetadata = getUsagePricingMetadata({
140
+ provider: modelInfo.provider,
141
+ model: modelInfo.model,
142
+ tokenUsage
143
+ });
144
+ this.services.sessionManager.accumulateTokenUsage(
145
+ this.id,
146
+ tokenUsage,
147
+ payload.estimatedCost ?? pricingMetadata.estimatedCost,
148
+ modelInfo
149
+ ).catch((err) => {
150
+ this.logger.warn(
151
+ `Failed to accumulate token usage: ${err instanceof Error ? err.message : String(err)}`
152
+ );
153
+ });
144
154
  };
145
155
  this.eventBus.on("llm:response", this.tokenAccumulatorListener);
146
156
  }
@@ -199,8 +209,9 @@ class ChatSession {
199
209
  content: [{ type: "text", text: "[Blocked by content policy: input redacted]" }]
200
210
  };
201
211
  const errorContent = `Error: ${errorMessage}`;
212
+ const assistantMessageId = randomUUID();
202
213
  const assistantMessage = {
203
- id: randomUUID(),
214
+ id: assistantMessageId,
204
215
  role: "assistant",
205
216
  timestamp: timestamp + 1,
206
217
  content: [{ type: "text", text: errorContent }]
@@ -208,11 +219,16 @@ class ChatSession {
208
219
  await this.conversationStore.saveMessage({ sessionId: this.id, message: userMessage });
209
220
  await this.conversationStore.saveMessage({ sessionId: this.id, message: assistantMessage });
210
221
  const llmConfig = this.services.stateManager.getLLMConfig(this.id);
211
- this.eventBus.emit("llm:response", {
222
+ this.eventBus.emit("interaction:blocked", {
212
223
  content: errorContent,
213
224
  provider: llmConfig.provider,
214
225
  model: llmConfig.model,
215
- ...assistantMessage.id && { messageId: assistantMessage.id }
226
+ messageId: assistantMessageId
227
+ });
228
+ this.eventBus.emit("run:complete", {
229
+ finishReason: "stop",
230
+ stepCount: 0,
231
+ durationMs: 0
216
232
  });
217
233
  }
218
234
  normalizeContent(content) {
@@ -53,9 +53,12 @@ async function generateSessionTitle(config, userText, logger, opts = {}) {
53
53
  });
54
54
  const processed = postProcessTitle(result.text);
55
55
  if (!processed) {
56
- return { error: "LLM returned empty title" };
56
+ return {
57
+ error: "LLM returned empty title",
58
+ usage: toSessionTitleTokenUsage(result.totalUsage)
59
+ };
57
60
  }
58
- return { title: processed };
61
+ return { title: processed, usage: toSessionTitleTokenUsage(result.totalUsage) };
59
62
  } catch (error) {
60
63
  if (controller?.signal.aborted) {
61
64
  return { timedOut: true, error: "Timed out while waiting for LLM response" };
@@ -68,6 +71,20 @@ async function generateSessionTitle(config, userText, logger, opts = {}) {
68
71
  }
69
72
  }
70
73
  }
74
+ function toSessionTitleTokenUsage(usage) {
75
+ const tokenUsage = {};
76
+ copyTokenUsageNumber(tokenUsage, "cachedInputTokens", usage.cachedInputTokens);
77
+ copyTokenUsageNumber(tokenUsage, "inputTokens", usage.inputTokens);
78
+ copyTokenUsageNumber(tokenUsage, "outputTokens", usage.outputTokens);
79
+ copyTokenUsageNumber(tokenUsage, "reasoningTokens", usage.reasoningTokens);
80
+ copyTokenUsageNumber(tokenUsage, "totalTokens", usage.totalTokens);
81
+ return tokenUsage;
82
+ }
83
+ function copyTokenUsageNumber(target, key, value) {
84
+ if (typeof value === "number" && Number.isFinite(value)) {
85
+ target[key] = value;
86
+ }
87
+ }
71
88
  function deriveHeuristicTitle(userText) {
72
89
  const sanitized = sanitizeUserText(userText, 120);
73
90
  if (!sanitized) return void 0;
@@ -1,10 +1,18 @@
1
1
  import type { ValidatedLLMConfig } from '../llm/schemas.js';
2
2
  import type { Logger } from '../logger/v2/types.js';
3
3
  import type { DextoProviderContext, LanguageModelFactory } from '../llm/services/types.js';
4
+ export interface GenerateSessionTitleTokenUsage {
5
+ cachedInputTokens?: number;
6
+ inputTokens?: number;
7
+ outputTokens?: number;
8
+ reasoningTokens?: number;
9
+ totalTokens?: number;
10
+ }
4
11
  export interface GenerateSessionTitleResult {
5
12
  title?: string;
6
13
  error?: string;
7
14
  timedOut?: boolean;
15
+ usage?: GenerateSessionTitleTokenUsage;
8
16
  }
9
17
  /**
10
18
  * Generate a concise title for a chat based on the first user message.
@@ -1 +1 @@
1
- {"version":3,"file":"title-generator.d.ts","sourceRoot":"","sources":["../../src/session/title-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAI3F,MAAM,WAAW,0BAA0B;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IACF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,eAAe,CAAC,EAAE,oBAAoB,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACjB,GACP,OAAO,CAAC,0BAA0B,CAAC,CAgDrC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA8BzE"}
1
+ {"version":3,"file":"title-generator.d.ts","sourceRoot":"","sources":["../../src/session/title-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAI3F,MAAM,WAAW,8BAA8B;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,8BAA8B,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IACF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,eAAe,CAAC,EAAE,oBAAoB,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACjB,GACP,OAAO,CAAC,0BAA0B,CAAC,CAmDrC;AAsBD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA8BzE"}