@dudousxd/nestjs-agent-opencode 0.1.2 → 0.2.0

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/index.cjs CHANGED
@@ -38,6 +38,8 @@ __export(index_exports, {
38
38
  OpenCodeToolsTokens: () => OpenCodeToolsTokens,
39
39
  OpenCodeTurn: () => OpenCodeTurn,
40
40
  OpenCodeTurns: () => OpenCodeTurns,
41
+ addUsage: () => addUsage,
42
+ emptyUsage: () => emptyUsage,
41
43
  keyValueOpenCodeSessionStore: () => keyValueOpenCodeSessionStore,
42
44
  openCode: () => openCode,
43
45
  openCodeControllers: () => openCodeControllers,
@@ -45,7 +47,8 @@ __export(index_exports, {
45
47
  sessionOf: () => sessionOf,
46
48
  toElicitation: () => toElicitation,
47
49
  toFormAnswer: () => toFormAnswer,
48
- toQuestion: () => toQuestion
50
+ toQuestion: () => toQuestion,
51
+ usageOf: () => usageOf
49
52
  });
50
53
  module.exports = __toCommonJS(index_exports);
51
54
 
@@ -287,6 +290,41 @@ function toFormAnswer(form, answers = {}) {
287
290
  __name(toFormAnswer, "toFormAnswer");
288
291
 
289
292
  // src/turn.ts
293
+ function emptyUsage() {
294
+ return {
295
+ inputTokens: 0,
296
+ outputTokens: 0,
297
+ cacheReadTokens: 0,
298
+ cacheWriteTokens: 0,
299
+ reasoningTokens: 0,
300
+ costUsd: 0
301
+ };
302
+ }
303
+ __name(emptyUsage, "emptyUsage");
304
+ function addUsage(a, b) {
305
+ const x = a ?? emptyUsage();
306
+ const y = b ?? emptyUsage();
307
+ return {
308
+ inputTokens: x.inputTokens + (y.inputTokens ?? 0),
309
+ outputTokens: x.outputTokens + (y.outputTokens ?? 0),
310
+ cacheReadTokens: (x.cacheReadTokens ?? 0) + (y.cacheReadTokens ?? 0),
311
+ cacheWriteTokens: (x.cacheWriteTokens ?? 0) + (y.cacheWriteTokens ?? 0),
312
+ reasoningTokens: (x.reasoningTokens ?? 0) + (y.reasoningTokens ?? 0),
313
+ costUsd: x.costUsd + (y.costUsd ?? 0)
314
+ };
315
+ }
316
+ __name(addUsage, "addUsage");
317
+ function subUsage(a, b) {
318
+ return {
319
+ inputTokens: a.inputTokens - b.inputTokens,
320
+ outputTokens: a.outputTokens - b.outputTokens,
321
+ cacheReadTokens: a.cacheReadTokens - b.cacheReadTokens,
322
+ cacheWriteTokens: a.cacheWriteTokens - b.cacheWriteTokens,
323
+ reasoningTokens: a.reasoningTokens - b.reasoningTokens,
324
+ costUsd: a.costUsd - b.costUsd
325
+ };
326
+ }
327
+ __name(subUsage, "subUsage");
290
328
  var ASK_TOOL_NAME = "ask";
291
329
  var FAILED_STATUSES = /* @__PURE__ */ new Set([
292
330
  "error",
@@ -352,11 +390,11 @@ var OpenCodeTurn = class {
352
390
  hidden = /* @__PURE__ */ new Set();
353
391
  milestones = [];
354
392
  waiting;
355
- usage = {
356
- inputTokens: 0,
357
- outputTokens: 0
358
- };
359
- costUsd;
393
+ /** What this turn object saw spent, and how much of it a milestone already reported. */
394
+ spent = emptyUsage();
395
+ reported = emptyUsage();
396
+ priced = false;
397
+ model;
360
398
  stepOpen = false;
361
399
  sawText = false;
362
400
  separator = false;
@@ -366,6 +404,11 @@ var OpenCodeTurn = class {
366
404
  stepError;
367
405
  constructor(a) {
368
406
  this.a = a;
407
+ this.model = modelOfLabel(a.input.model);
408
+ }
409
+ /** What the run spent so far: carried from before this turn object, plus what it saw. */
410
+ totalUsage() {
411
+ return addUsage(this.a.carried, this.spent);
369
412
  }
370
413
  get sessionId() {
371
414
  return this.a.sessionId;
@@ -448,7 +491,15 @@ var OpenCodeTurn = class {
448
491
  this.chain = this.chain.then(() => ask.kind === "approval" ? this.decided(ask, reply, tell) : this.answered(ask, reply, tell)).then(resolve, reject);
449
492
  });
450
493
  }
451
- reach(milestone) {
494
+ reach(reached) {
495
+ const usage = subUsage(this.spent, this.reported);
496
+ this.reported = {
497
+ ...this.spent
498
+ };
499
+ const milestone = {
500
+ ...reached,
501
+ usage
502
+ };
452
503
  const waiting = this.waiting;
453
504
  if (waiting !== void 0) {
454
505
  this.waiting = void 0;
@@ -604,9 +655,22 @@ var OpenCodeTurn = class {
604
655
  }
605
656
  }
606
657
  async onEvent(e) {
607
- if (this.ended) return;
608
658
  const d = e.data ?? {};
659
+ if (e.type === "session.usage.recorded") {
660
+ await this.usageRecorded(d);
661
+ return;
662
+ }
663
+ if (this.ended) return;
609
664
  switch (e.type) {
665
+ case "session.step.started":
666
+ case "session.model.selected": {
667
+ const model = d.model;
668
+ if (typeof model?.id === "string" && typeof model.providerID === "string") this.model = {
669
+ providerID: model.providerID,
670
+ id: model.id
671
+ };
672
+ return;
673
+ }
610
674
  case "session.text.delta": {
611
675
  const delta = typeof d.delta === "string" ? d.delta : "";
612
676
  if (!delta) return;
@@ -760,42 +824,63 @@ ${delta}` : delta;
760
824
  });
761
825
  }
762
826
  }
763
- async stepEnded(d) {
764
- const usage = {
765
- inputTokens: Number(d.tokens?.input) || 0,
766
- outputTokens: Number(d.tokens?.output) || 0,
767
- ...Number(d.tokens?.cache?.read) ? {
768
- cacheReadTokens: Number(d.tokens.cache.read)
769
- } : {},
770
- ...Number(d.tokens?.cache?.write) ? {
771
- cacheWriteTokens: Number(d.tokens.cache.write)
772
- } : {}
773
- };
774
- const costUsd = typeof d.cost === "number" ? d.cost : void 0;
775
- this.usage.inputTokens += usage.inputTokens;
776
- this.usage.outputTokens += usage.outputTokens;
777
- if (costUsd !== void 0) this.costUsd = (this.costUsd ?? 0) + costUsd;
827
+ modelId() {
828
+ return this.model !== void 0 ? `${this.model.providerID}/${this.model.id}` : this.a.modelLabel;
829
+ }
830
+ /** One model call's usage and cost, into the ledger and the run's total. */
831
+ async spend(d, purpose) {
832
+ const usage = usageOf(d.tokens);
833
+ const reportedCostUsd = typeof d.cost === "number" && Number.isFinite(d.cost) && d.cost >= 0 ? d.cost : void 0;
834
+ const fallback = reportedCostUsd !== void 0 ? {
835
+ costUsd: reportedCostUsd,
836
+ costSource: "provider"
837
+ } : {};
838
+ let cost = fallback;
839
+ if (this.a.priceStep !== void 0) {
840
+ cost = await this.a.priceStep({
841
+ model: this.model,
842
+ usage,
843
+ reportedCostUsd
844
+ }).catch(() => fallback);
845
+ }
846
+ this.spent = addUsage(this.spent, {
847
+ inputTokens: usage.inputTokens,
848
+ outputTokens: usage.outputTokens,
849
+ cacheReadTokens: usage.cacheReadTokens ?? 0,
850
+ cacheWriteTokens: usage.cacheWriteTokens ?? 0,
851
+ reasoningTokens: usage.reasoningTokens ?? 0,
852
+ costUsd: cost.costUsd ?? 0
853
+ });
854
+ if (cost.costUsd !== void 0) this.priced = true;
778
855
  await this.a.store.recordUsage({
779
856
  threadId: this.a.input.threadId,
780
857
  actorRef: this.a.input.actor.id,
781
- modelId: this.a.modelLabel,
782
- purpose: "chat",
858
+ modelId: this.modelId(),
859
+ purpose,
783
860
  usage,
784
- ...costUsd !== void 0 ? {
785
- costUsd,
786
- costSource: "provider"
787
- } : {}
861
+ ...cost
788
862
  });
863
+ return {
864
+ usage,
865
+ cost
866
+ };
867
+ }
868
+ /** `session.usage.recorded`: a call OpenCode made besides the steps (the title, a compaction). */
869
+ async usageRecorded(d) {
870
+ await this.spend(d, d.source === "title" ? "title" : "history_summary");
871
+ }
872
+ async stepEnded(d) {
873
+ const { usage, cost } = await this.spend(d, "chat");
789
874
  if (!this.stepOpen) return;
790
875
  this.stepOpen = false;
791
876
  await this.write({
792
877
  kind: "step-finish",
793
878
  usage,
794
- costUsd: costUsd ?? null,
879
+ costUsd: cost.costUsd ?? null,
795
880
  ...this.segment.reasoningMs > 0 ? {
796
881
  reasoningMs: this.segment.reasoningMs
797
882
  } : {},
798
- model: this.a.modelLabel
883
+ model: this.modelId()
799
884
  });
800
885
  }
801
886
  /**
@@ -814,12 +899,7 @@ ${delta}` : delta;
814
899
  content: s.text,
815
900
  runId: this.a.runId,
816
901
  ...final ? {
817
- usage: {
818
- ...this.usage,
819
- ...this.costUsd !== void 0 ? {
820
- costUsd: this.costUsd
821
- } : {}
822
- }
902
+ usage: this.messageUsage()
823
903
  } : {},
824
904
  ...this.a.input.agentName !== void 0 ? {
825
905
  agentName: this.a.input.agentName
@@ -847,6 +927,26 @@ ${delta}` : delta;
847
927
  ]);
848
928
  return message.id;
849
929
  }
930
+ /** The run's usage as its last message carries it: the whole run, cache tokens included. */
931
+ messageUsage() {
932
+ const total = this.totalUsage();
933
+ return {
934
+ inputTokens: total.inputTokens,
935
+ outputTokens: total.outputTokens,
936
+ ...total.cacheReadTokens > 0 ? {
937
+ cacheReadTokens: total.cacheReadTokens
938
+ } : {},
939
+ ...total.cacheWriteTokens > 0 ? {
940
+ cacheWriteTokens: total.cacheWriteTokens
941
+ } : {},
942
+ ...total.reasoningTokens > 0 ? {
943
+ reasoningTokens: total.reasoningTokens
944
+ } : {},
945
+ ...this.priced || (this.a.carried?.costUsd ?? 0) > 0 ? {
946
+ costUsd: total.costUsd
947
+ } : {}
948
+ };
949
+ }
850
950
  /** A request recorded by an earlier process (a turn resumed after a restart). */
851
951
  async alreadyRecorded(id) {
852
952
  return (await this.a.store.toolCallApproval?.(id) ?? null) !== null;
@@ -1216,6 +1316,35 @@ ${delta}` : delta;
1216
1316
  });
1217
1317
  }
1218
1318
  };
1319
+ function modelOfLabel(label) {
1320
+ const slash = label?.indexOf("/") ?? -1;
1321
+ if (label === void 0 || slash <= 0 || slash === label.length - 1) return void 0;
1322
+ return {
1323
+ providerID: label.slice(0, slash),
1324
+ id: label.slice(slash + 1)
1325
+ };
1326
+ }
1327
+ __name(modelOfLabel, "modelOfLabel");
1328
+ function usageOf(tokens) {
1329
+ const n = /* @__PURE__ */ __name((v) => typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0, "n");
1330
+ const read = n(tokens?.cache?.read);
1331
+ const write = n(tokens?.cache?.write);
1332
+ const reasoning = n(tokens?.reasoning);
1333
+ return {
1334
+ inputTokens: n(tokens?.input) + read + write,
1335
+ outputTokens: n(tokens?.output),
1336
+ ...read > 0 ? {
1337
+ cacheReadTokens: read
1338
+ } : {},
1339
+ ...write > 0 ? {
1340
+ cacheWriteTokens: write
1341
+ } : {},
1342
+ ...reasoning > 0 ? {
1343
+ reasoningTokens: reasoning
1344
+ } : {}
1345
+ };
1346
+ }
1347
+ __name(usageOf, "usageOf");
1219
1348
 
1220
1349
  // src/mcp.ts
1221
1350
  var LOOP_SERVED_KINDS = /* @__PURE__ */ new Set([
@@ -1647,7 +1776,7 @@ var OpenCodeTurns = class {
1647
1776
  spent = /* @__PURE__ */ new Set();
1648
1777
  /** When the tools endpoint was last registered for a location (`server|boot|directory|actor`). */
1649
1778
  toolsIssued = /* @__PURE__ */ new Map();
1650
- constructor(host, sessions, settings, store, sink, deps, registry, skills, memory, queue, toolsTokens2) {
1779
+ constructor(host, sessions, settings, store, sink, deps, registry, skills, memory, queue, toolsTokens2, pricingStore, agentOptions) {
1651
1780
  this.host = host;
1652
1781
  this.sessions = sessions;
1653
1782
  this.settings = settings;
@@ -1659,6 +1788,30 @@ var OpenCodeTurns = class {
1659
1788
  this.memory = memory;
1660
1789
  this.queue = queue;
1661
1790
  this.toolsTokens = toolsTokens2;
1791
+ this.prices = new import_nestjs_agent_core4.ModelPriceResolver({
1792
+ pricingStore,
1793
+ catalog: agentOptions?.priceCatalog,
1794
+ log: {
1795
+ info: /* @__PURE__ */ __name((message) => this.logger.log(message), "info"),
1796
+ warn: /* @__PURE__ */ __name((message) => this.logger.warn(message), "warn")
1797
+ }
1798
+ });
1799
+ }
1800
+ prices;
1801
+ /**
1802
+ * What a model call OpenCode made cost, by the same rule the library's loop records its own steps
1803
+ * at: a reported figure wins, else an estimate off the model's price — see
1804
+ * {@link OpenCodeEngineSettings.cost}.
1805
+ */
1806
+ async priceStep(step) {
1807
+ const { model, usage, reportedCostUsd } = step;
1808
+ const tokens = usage.inputTokens + usage.outputTokens;
1809
+ const reported = reportedCostUsd !== void 0 && (reportedCostUsd > 0 || tokens === 0);
1810
+ if (reported && this.settings.cost !== "estimate") {
1811
+ return (0, import_nestjs_agent_core4.resolveUsageCost)(usage, reportedCostUsd, void 0);
1812
+ }
1813
+ const price = model !== void 0 && tokens > 0 ? await this.prices.priceFor(priceRef(model)) : void 0;
1814
+ return (0, import_nestjs_agent_core4.resolveUsageCost)(usage, price === void 0 ? reportedCostUsd : void 0, price);
1662
1815
  }
1663
1816
  /** The tools server's name in OpenCode. */
1664
1817
  get toolsServer() {
@@ -2248,8 +2401,8 @@ ${body}
2248
2401
  }
2249
2402
  // ---- prompt / observe / reply --------------------------------------------------------------
2250
2403
  /** Start listening to the session (so nothing it says is missed), then send the user message. */
2251
- async prompt(runId, input, handle) {
2252
- const live = await this.ensureLive(runId, input, handle, false);
2404
+ async prompt(runId, input, handle, spent) {
2405
+ const live = await this.ensureLive(runId, input, handle, false, spent);
2253
2406
  try {
2254
2407
  const prompt = await this.host.promptFor?.({
2255
2408
  input,
@@ -2279,9 +2432,12 @@ ${body}
2279
2432
  * Wait for the turn's next milestone. In a process that was not following the turn (a resumed
2280
2433
  * durable run), the turn is rebuilt and first catches up on requests OpenCode raised meanwhile;
2281
2434
  * `session.wait` is the safety net for a terminal event that was missed.
2435
+ *
2436
+ * `spent` is what the run spent before (the sum of the `usage` of its earlier milestones): a turn
2437
+ * rebuilt here starts from it, so the answer it persists carries the whole run's usage.
2282
2438
  */
2283
- async observe(runId, input, handle) {
2284
- const live = await this.ensureLive(runId, input, handle, true);
2439
+ async observe(runId, input, handle, spent) {
2440
+ const live = await this.ensureLive(runId, input, handle, true, spent);
2285
2441
  const { turn, client } = live;
2286
2442
  if (turn.hasMilestone()) return this.reached(runId, input, handle, await turn.next());
2287
2443
  let done = false;
@@ -2320,23 +2476,23 @@ ${body}
2320
2476
  * request is gone with it: a new session is opened, told what the person decided, and prompted
2321
2477
  * to go on.
2322
2478
  */
2323
- async reply(runId, input, handle, ask, reply) {
2479
+ async reply(runId, input, handle, ask, reply, spent) {
2324
2480
  const server = await this.host.server(input.actor);
2325
2481
  if (server.key !== handle.serverKey || server.bootId !== handle.bootId) {
2326
- return this.continueAfterRestart(runId, input, server, ask, reply);
2482
+ return this.continueAfterRestart(runId, input, server, ask, reply, spent);
2327
2483
  }
2328
- const live = await this.ensureLive(runId, input, handle, false);
2484
+ const live = await this.ensureLive(runId, input, handle, false, spent);
2329
2485
  await live.turn.decide(ask, reply);
2330
2486
  return handle;
2331
2487
  }
2332
- async continueAfterRestart(runId, input, server, ask, reply) {
2488
+ async continueAfterRestart(runId, input, server, ask, reply, spent) {
2333
2489
  const approved = "approved" in reply && reply.approved === true;
2334
2490
  const note = ask.kind === "approval" ? approved ? `The user approved the action ${ask.action} you asked permission for. Continue the task.` : `The user did not approve the action ${ask.action}. Continue without it and explain.` : `The user answered your question: ${JSON.stringify("answers" in reply ? reply.answers : {})}. Continue.`;
2335
2491
  const thread = await this.store.getThread(input.threadId);
2336
2492
  const handle = await this.createSession(runId, input, server, thread?.messages ?? [], note);
2337
2493
  await this.refreshInstructions(runId, input, server.client, handle.sessionId);
2338
2494
  this.drop(runId);
2339
- const live = await this.ensureLive(runId, input, handle, false);
2495
+ const live = await this.ensureLive(runId, input, handle, false, spent);
2340
2496
  await live.turn.decide(ask, reply, {
2341
2497
  tellOpenCode: false
2342
2498
  });
@@ -2356,7 +2512,7 @@ ${body}
2356
2512
  sessionID: known.sessionId
2357
2513
  });
2358
2514
  }
2359
- async ensureLive(runId, input, handle, catchUp) {
2515
+ async ensureLive(runId, input, handle, catchUp, spent) {
2360
2516
  const current = this.live.get(runId);
2361
2517
  if (current !== void 0 && current.handle.sessionId === handle.sessionId) return current;
2362
2518
  current?.stop();
@@ -2382,6 +2538,10 @@ ${body}
2382
2538
  } : {}
2383
2539
  }), "approvalFor"),
2384
2540
  modelLabel: input.model ?? "opencode",
2541
+ priceStep: /* @__PURE__ */ __name((step) => this.priceStep(step), "priceStep"),
2542
+ ...spent !== void 0 ? {
2543
+ carried: spent
2544
+ } : {},
2385
2545
  logger: this.logger,
2386
2546
  onGranted: /* @__PURE__ */ __name((action, id) => {
2387
2547
  const grants = this.grants.get(runId) ?? [];
@@ -2428,20 +2588,14 @@ ${body}
2428
2588
  }
2429
2589
  return milestone;
2430
2590
  }
2431
- /** What the run produced, as the host's settle hooks see it. */
2432
- async runResult(runId, input, outcome, durationMs) {
2591
+ /**
2592
+ * What the run produced, as the host's settle hooks see it. `usage` is what the run spent — the
2593
+ * runner's sum of its milestones' usage, which a resumed run reads back from its journal — else
2594
+ * what the turn this process follows saw.
2595
+ */
2596
+ async runResult(runId, input, outcome, durationMs, usage) {
2433
2597
  const thread = await this.store.getThread(input.threadId);
2434
2598
  const messages = (thread?.messages ?? []).filter((m) => m.role === "assistant" && m.runId === runId);
2435
- const usage = {
2436
- inputTokens: 0,
2437
- outputTokens: 0,
2438
- costUsd: 0
2439
- };
2440
- for (const m of messages) {
2441
- usage.inputTokens += m.usage?.inputTokens ?? 0;
2442
- usage.outputTokens += m.usage?.outputTokens ?? 0;
2443
- usage.costUsd += m.usage?.costUsd ?? 0;
2444
- }
2445
2599
  return {
2446
2600
  runId,
2447
2601
  input,
@@ -2486,15 +2640,31 @@ ${body}
2486
2640
  this.logger.warn(`onSettled failed: ${errorText(error, "error")}`);
2487
2641
  }
2488
2642
  }
2489
- /** End the run's stream and bookkeeping for how its execution ended. */
2490
- async settle(runId, input, outcome, durationMs) {
2643
+ /**
2644
+ * What the run spent: the runner's sum of its milestones, or what the turn this process follows
2645
+ * saw (which starts from that sum) when it saw more — a run that failed or was cancelled between
2646
+ * two milestones.
2647
+ */
2648
+ spentBy(runId, spent) {
2649
+ const seen = this.live.get(runId)?.turn.totalUsage();
2650
+ if (spent === void 0) return seen ?? emptyUsage();
2651
+ if (seen === void 0) return spent;
2652
+ const tokens = /* @__PURE__ */ __name((u) => u.inputTokens + u.outputTokens, "tokens");
2653
+ return tokens(seen) > tokens(spent) ? seen : spent;
2654
+ }
2655
+ /**
2656
+ * End the run's stream and bookkeeping for how its execution ended. `spent` is what the run spent
2657
+ * (the sum of its milestones' `usage`); omit → what the turn this process follows saw.
2658
+ */
2659
+ async settle(runId, input, outcome, durationMs, spent) {
2491
2660
  if (outcome.status === "failed") {
2492
- await this.settleFailed(runId, input, outcome.error, durationMs);
2661
+ await this.settleFailed(runId, input, outcome.error, durationMs, spent);
2493
2662
  return;
2494
2663
  }
2664
+ const usage = this.spentBy(runId, spent);
2495
2665
  this.forget(runId);
2496
2666
  const writer = await this.sink.open(runId);
2497
- const result = await this.runResult(runId, input, outcome, durationMs);
2667
+ const result = await this.runResult(runId, input, outcome, durationMs, usage);
2498
2668
  await this.amend(writer, result);
2499
2669
  if (outcome.status === "interrupted") {
2500
2670
  this.logger.log(`agent run ${runId} cancelled`);
@@ -2522,13 +2692,14 @@ ${body}
2522
2692
  }
2523
2693
  await this.settled(result);
2524
2694
  }
2525
- async settleFailed(runId, input, error, durationMs = 0) {
2695
+ async settleFailed(runId, input, error, durationMs = 0, spent) {
2696
+ const usage = this.spentBy(runId, spent);
2526
2697
  this.forget(runId);
2527
2698
  const writer = await this.sink.open(runId);
2528
2699
  const result = await this.runResult(runId, input, {
2529
2700
  status: "failed",
2530
2701
  error
2531
- }, durationMs);
2702
+ }, durationMs, usage);
2532
2703
  const worded = (await this.amend(writer, result)).error;
2533
2704
  const message = worded ?? (0, import_nestjs_agent_core4.streamFailure)(new Error(error)).message;
2534
2705
  this.logger.error(`agent run ${runId} failed: ${error}`);
@@ -2598,6 +2769,10 @@ OpenCodeTurns = _ts_decorate2([
2598
2769
  _ts_param2(9, (0, import_common4.Inject)(import_nestjs_agent.AGENT_CHAT_QUEUE)),
2599
2770
  _ts_param2(10, (0, import_common4.Optional)()),
2600
2771
  _ts_param2(10, (0, import_common4.Inject)(OPENCODE_TOOLS_TOKENS)),
2772
+ _ts_param2(11, (0, import_common4.Optional)()),
2773
+ _ts_param2(11, (0, import_common4.Inject)(import_nestjs_agent_core4.AGENT_PRICING_STORE)),
2774
+ _ts_param2(12, (0, import_common4.Optional)()),
2775
+ _ts_param2(12, (0, import_common4.Inject)(import_nestjs_agent_core4.AGENT_OPTIONS)),
2601
2776
  _ts_metadata2("design:type", Function),
2602
2777
  _ts_metadata2("design:paramtypes", [
2603
2778
  typeof OpenCodeHost === "undefined" ? Object : OpenCodeHost,
@@ -2610,6 +2785,8 @@ OpenCodeTurns = _ts_decorate2([
2610
2785
  typeof SkillsConfig === "undefined" ? Object : SkillsConfig,
2611
2786
  typeof MemoryConfig === "undefined" ? Object : MemoryConfig,
2612
2787
  typeof ChatQueueService === "undefined" ? Object : ChatQueueService,
2788
+ Object,
2789
+ typeof AgentPricingStore === "undefined" ? Object : AgentPricingStore,
2613
2790
  Object
2614
2791
  ])
2615
2792
  ], OpenCodeTurns);
@@ -2652,6 +2829,19 @@ function uiEmitter(scope, push) {
2652
2829
  };
2653
2830
  }
2654
2831
  __name(uiEmitter, "uiEmitter");
2832
+ function priceRef(model) {
2833
+ const aliases = [
2834
+ model.id
2835
+ ];
2836
+ const tail = model.id.slice(model.id.lastIndexOf("/") + 1);
2837
+ if (tail !== model.id && (0, import_nestjs_agent_core4.parseBedrockModelId)(tail) !== void 0) aliases.push(tail);
2838
+ return {
2839
+ modelId: `${model.providerID}/${model.id}`,
2840
+ provider: model.providerID,
2841
+ aliases
2842
+ };
2843
+ }
2844
+ __name(priceRef, "priceRef");
2655
2845
 
2656
2846
  // src/runner.ts
2657
2847
  function _ts_decorate3(decorators, target, key, desc) {
@@ -2753,18 +2943,20 @@ var OpenCodeAgentRunner = class {
2753
2943
  async run(runId, input) {
2754
2944
  const started = Date.now();
2755
2945
  this.inputs.set(runId, input);
2946
+ let spent = emptyUsage();
2756
2947
  try {
2757
2948
  let handle = await this.turns.begin(runId, input);
2758
2949
  if (this.cancelled.has(runId)) throw new import_nestjs_agent_core5.RunCancelledError();
2759
- await this.turns.prompt(runId, input, handle);
2950
+ await this.turns.prompt(runId, input, handle, spent);
2760
2951
  for (; ; ) {
2761
- const milestone = await this.turns.observe(runId, input, handle);
2952
+ const milestone = await this.turns.observe(runId, input, handle, spent);
2953
+ spent = addUsage(spent, milestone.usage);
2762
2954
  if (milestone.kind === "finished") {
2763
- await this.turns.settle(runId, input, milestone.outcome, Date.now() - started);
2955
+ await this.turns.settle(runId, input, milestone.outcome, Date.now() - started, spent);
2764
2956
  return;
2765
2957
  }
2766
2958
  const reply = await this.park(runId, milestone.ask.id, milestone.ask.kind === "approval" ? "approval" : "answers", milestone.timeoutMs);
2767
- handle = await this.turns.reply(runId, input, handle, milestone.ask, reply);
2959
+ handle = await this.turns.reply(runId, input, handle, milestone.ask, reply, spent);
2768
2960
  }
2769
2961
  } catch (error) {
2770
2962
  if (error instanceof import_nestjs_agent_core5.RunCancelledError) {
@@ -2774,7 +2966,7 @@ var OpenCodeAgentRunner = class {
2774
2966
  }, Date.now() - started);
2775
2967
  return;
2776
2968
  }
2777
- await this.turns.settleFailed(runId, input, errorText(error, "the turn failed"));
2969
+ await this.turns.settleFailed(runId, input, errorText(error, "the turn failed"), Date.now() - started);
2778
2970
  } finally {
2779
2971
  this.inputs.delete(runId);
2780
2972
  }
@@ -2927,6 +3119,8 @@ __name(openCodeProviders, "openCodeProviders");
2927
3119
  OpenCodeToolsTokens,
2928
3120
  OpenCodeTurn,
2929
3121
  OpenCodeTurns,
3122
+ addUsage,
3123
+ emptyUsage,
2930
3124
  keyValueOpenCodeSessionStore,
2931
3125
  openCode,
2932
3126
  openCodeControllers,
@@ -2934,6 +3128,7 @@ __name(openCodeProviders, "openCodeProviders");
2934
3128
  sessionOf,
2935
3129
  toElicitation,
2936
3130
  toFormAnswer,
2937
- toQuestion
3131
+ toQuestion,
3132
+ usageOf
2938
3133
  });
2939
3134
  //# sourceMappingURL=index.cjs.map