@agentfield/sdk 0.1.111-rc.1 → 0.1.111-rc.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/index.d.ts +236 -2
- package/dist/index.js +455 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -142,6 +142,34 @@ var init_openrouterAttribution = __esm({
|
|
|
142
142
|
DEFAULT_OPENROUTER_APP_NAME = "AgentField AI";
|
|
143
143
|
}
|
|
144
144
|
});
|
|
145
|
+
|
|
146
|
+
// src/harness/modelVariant.ts
|
|
147
|
+
function splitModelVariant(model) {
|
|
148
|
+
if (typeof model !== "string" || !model.trim()) {
|
|
149
|
+
return {};
|
|
150
|
+
}
|
|
151
|
+
const sepIndex = model.indexOf(MODEL_VARIANT_SEP);
|
|
152
|
+
const base = sepIndex === -1 ? model : model.slice(0, sepIndex);
|
|
153
|
+
const variant = sepIndex === -1 ? "" : model.slice(sepIndex + 1);
|
|
154
|
+
return {
|
|
155
|
+
model: base.trim() || void 0,
|
|
156
|
+
variant: variant.trim() || void 0
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function resolveModelAndVariant(options) {
|
|
160
|
+
const { model, variant } = splitModelVariant(options.model);
|
|
161
|
+
const explicit = options.variant;
|
|
162
|
+
if (typeof explicit === "string" && explicit.trim()) {
|
|
163
|
+
return { model, variant: explicit.trim() };
|
|
164
|
+
}
|
|
165
|
+
return { model, variant };
|
|
166
|
+
}
|
|
167
|
+
var MODEL_VARIANT_SEP;
|
|
168
|
+
var init_modelVariant = __esm({
|
|
169
|
+
"src/harness/modelVariant.ts"() {
|
|
170
|
+
MODEL_VARIANT_SEP = "#";
|
|
171
|
+
}
|
|
172
|
+
});
|
|
145
173
|
function getZodConverter() {
|
|
146
174
|
if (zodConverter !== void 0) {
|
|
147
175
|
return zodConverter;
|
|
@@ -155,14 +183,14 @@ function getZodConverter() {
|
|
|
155
183
|
}
|
|
156
184
|
return zodConverter;
|
|
157
185
|
}
|
|
158
|
-
function
|
|
186
|
+
function isRecord2(value) {
|
|
159
187
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
160
188
|
}
|
|
161
189
|
function hasJsonSchema(value) {
|
|
162
|
-
return
|
|
190
|
+
return isRecord2(value) && typeof value.jsonSchema === "function";
|
|
163
191
|
}
|
|
164
192
|
function hasParse(value) {
|
|
165
|
-
return
|
|
193
|
+
return isRecord2(value) && typeof value.parse === "function";
|
|
166
194
|
}
|
|
167
195
|
function estimateTokens(text2) {
|
|
168
196
|
return Math.floor(text2.length / 4);
|
|
@@ -191,7 +219,7 @@ function getSchemaPath(cwd) {
|
|
|
191
219
|
return path2__default.join(cwd, SCHEMA_FILENAME);
|
|
192
220
|
}
|
|
193
221
|
function schemaToJsonSchema(schema) {
|
|
194
|
-
if (
|
|
222
|
+
if (isRecord2(schema)) {
|
|
195
223
|
if ("type" in schema || "properties" in schema || "$schema" in schema) {
|
|
196
224
|
return schema;
|
|
197
225
|
}
|
|
@@ -339,7 +367,7 @@ var claude_exports = {};
|
|
|
339
367
|
__export(claude_exports, {
|
|
340
368
|
ClaudeCodeProvider: () => ClaudeCodeProvider
|
|
341
369
|
});
|
|
342
|
-
function
|
|
370
|
+
function isRecord3(value) {
|
|
343
371
|
return typeof value === "object" && value !== null;
|
|
344
372
|
}
|
|
345
373
|
function getString(record, key) {
|
|
@@ -354,6 +382,7 @@ var ClaudeCodeProvider;
|
|
|
354
382
|
var init_claude = __esm({
|
|
355
383
|
"src/harness/providers/claude.ts"() {
|
|
356
384
|
init_types();
|
|
385
|
+
init_modelVariant();
|
|
357
386
|
ClaudeCodeProvider = class {
|
|
358
387
|
async execute(prompt, options) {
|
|
359
388
|
let sdk;
|
|
@@ -366,7 +395,8 @@ var init_claude = __esm({
|
|
|
366
395
|
);
|
|
367
396
|
}
|
|
368
397
|
const agentOptions = {};
|
|
369
|
-
|
|
398
|
+
const { model: modelValue } = resolveModelAndVariant(options);
|
|
399
|
+
if (modelValue !== void 0) agentOptions.model = modelValue;
|
|
370
400
|
if (options.cwd !== void 0) agentOptions.cwd = options.cwd;
|
|
371
401
|
if (options.maxTurns !== void 0) agentOptions.max_turns = options.maxTurns;
|
|
372
402
|
if (options.tools !== void 0) agentOptions.allowed_tools = options.tools;
|
|
@@ -383,10 +413,16 @@ var init_claude = __esm({
|
|
|
383
413
|
let totalCost;
|
|
384
414
|
let numTurns = 0;
|
|
385
415
|
let sessionId = "";
|
|
416
|
+
let usageObj;
|
|
417
|
+
let inputTokens;
|
|
418
|
+
let outputTokens;
|
|
419
|
+
let cacheReadTokens;
|
|
420
|
+
let cacheCreationTokens;
|
|
421
|
+
let modelName;
|
|
386
422
|
const startApi = Date.now();
|
|
387
423
|
try {
|
|
388
424
|
for await (const msg of sdk.query({ prompt, options: agentOptions })) {
|
|
389
|
-
const msgObj =
|
|
425
|
+
const msgObj = isRecord3(msg) ? msg : { raw: String(msg) };
|
|
390
426
|
messages.push(msgObj);
|
|
391
427
|
const msgType = getString(msgObj, "type") ?? "";
|
|
392
428
|
if (msgType === "result") {
|
|
@@ -405,16 +441,28 @@ var init_claude = __esm({
|
|
|
405
441
|
}
|
|
406
442
|
const turns = getNumber(msgObj, "num_turns");
|
|
407
443
|
numTurns = turns === void 0 ? messages.length : Math.trunc(turns);
|
|
408
|
-
|
|
444
|
+
if (isRecord3(msgObj.usage)) {
|
|
445
|
+
usageObj = msgObj.usage;
|
|
446
|
+
inputTokens = getNumber(usageObj, "input_tokens");
|
|
447
|
+
outputTokens = getNumber(usageObj, "output_tokens");
|
|
448
|
+
cacheReadTokens = getNumber(usageObj, "cache_read_input_tokens");
|
|
449
|
+
cacheCreationTokens = getNumber(usageObj, "cache_creation_input_tokens");
|
|
450
|
+
}
|
|
451
|
+
modelName = getString(msgObj, "model") ?? modelName;
|
|
452
|
+
} else if (msgType === "assistant") {
|
|
453
|
+
if (modelName === void 0 && isRecord3(msgObj.message)) {
|
|
454
|
+
modelName = getString(msgObj.message, "model");
|
|
455
|
+
}
|
|
456
|
+
if (resultText !== void 0) continue;
|
|
409
457
|
let content = msgObj.content;
|
|
410
|
-
if (content === void 0 &&
|
|
458
|
+
if (content === void 0 && isRecord3(msgObj.message)) {
|
|
411
459
|
content = msgObj.message.content;
|
|
412
460
|
}
|
|
413
461
|
if (typeof content === "string") {
|
|
414
462
|
resultText = content;
|
|
415
463
|
} else if (Array.isArray(content)) {
|
|
416
464
|
for (const block of content) {
|
|
417
|
-
if (
|
|
465
|
+
if (isRecord3(block) && block.type === "text" && typeof block.text === "string") {
|
|
418
466
|
resultText = block.text;
|
|
419
467
|
}
|
|
420
468
|
}
|
|
@@ -428,7 +476,13 @@ var init_claude = __esm({
|
|
|
428
476
|
durationApiMs: Date.now() - startApi,
|
|
429
477
|
numTurns,
|
|
430
478
|
totalCostUsd: totalCost,
|
|
431
|
-
sessionId
|
|
479
|
+
sessionId,
|
|
480
|
+
usage: usageObj,
|
|
481
|
+
inputTokens,
|
|
482
|
+
outputTokens,
|
|
483
|
+
cacheReadTokens,
|
|
484
|
+
cacheCreationTokens,
|
|
485
|
+
model: modelName
|
|
432
486
|
}),
|
|
433
487
|
isError: false
|
|
434
488
|
});
|
|
@@ -586,6 +640,7 @@ var init_codex = __esm({
|
|
|
586
640
|
"src/harness/providers/codex.ts"() {
|
|
587
641
|
init_types();
|
|
588
642
|
init_cli();
|
|
643
|
+
init_modelVariant();
|
|
589
644
|
CodexProvider = class {
|
|
590
645
|
bin;
|
|
591
646
|
constructor(binPath = "codex") {
|
|
@@ -599,6 +654,13 @@ var init_codex = __esm({
|
|
|
599
654
|
if (options.permissionMode === "auto") {
|
|
600
655
|
cmd.push("--full-auto");
|
|
601
656
|
}
|
|
657
|
+
const { model: modelValue, variant: variantValue } = resolveModelAndVariant(options);
|
|
658
|
+
if (modelValue) {
|
|
659
|
+
cmd.push("-m", modelValue);
|
|
660
|
+
}
|
|
661
|
+
if (variantValue) {
|
|
662
|
+
cmd.push("-c", `model_reasoning_effort=${variantValue}`);
|
|
663
|
+
}
|
|
602
664
|
cmd.push(prompt);
|
|
603
665
|
const startApi = Date.now();
|
|
604
666
|
try {
|
|
@@ -625,7 +687,7 @@ var init_codex = __esm({
|
|
|
625
687
|
return createRawResult({
|
|
626
688
|
result: resultText,
|
|
627
689
|
messages: events,
|
|
628
|
-
metrics: createMetrics({ durationApiMs: Date.now() - startApi, numTurns, sessionId }),
|
|
690
|
+
metrics: createMetrics({ durationApiMs: Date.now() - startApi, numTurns, sessionId, model: modelValue }),
|
|
629
691
|
isError,
|
|
630
692
|
errorMessage: isError ? stderr.trim() : void 0
|
|
631
693
|
});
|
|
@@ -659,6 +721,7 @@ var init_gemini = __esm({
|
|
|
659
721
|
"src/harness/providers/gemini.ts"() {
|
|
660
722
|
init_types();
|
|
661
723
|
init_cli();
|
|
724
|
+
init_modelVariant();
|
|
662
725
|
GeminiProvider = class {
|
|
663
726
|
bin;
|
|
664
727
|
constructor(binPath = "gemini") {
|
|
@@ -672,8 +735,9 @@ var init_gemini = __esm({
|
|
|
672
735
|
if (options.permissionMode === "auto") {
|
|
673
736
|
cmd.push("--sandbox");
|
|
674
737
|
}
|
|
675
|
-
|
|
676
|
-
|
|
738
|
+
const { model: modelValue } = resolveModelAndVariant(options);
|
|
739
|
+
if (modelValue) {
|
|
740
|
+
cmd.push("-m", modelValue);
|
|
677
741
|
}
|
|
678
742
|
cmd.push("-p", prompt);
|
|
679
743
|
const startApi = Date.now();
|
|
@@ -725,6 +789,7 @@ var init_opencode = __esm({
|
|
|
725
789
|
"src/harness/providers/opencode.ts"() {
|
|
726
790
|
init_types();
|
|
727
791
|
init_cli();
|
|
792
|
+
init_modelVariant();
|
|
728
793
|
init_openrouterAttribution();
|
|
729
794
|
OpenCodeProvider = class {
|
|
730
795
|
bin;
|
|
@@ -739,8 +804,12 @@ var init_opencode = __esm({
|
|
|
739
804
|
cmd.push("--dir", options.project_dir);
|
|
740
805
|
}
|
|
741
806
|
const env = { ...options.env };
|
|
742
|
-
|
|
743
|
-
|
|
807
|
+
const { model: modelValue, variant: variantValue } = resolveModelAndVariant(options);
|
|
808
|
+
if (modelValue) {
|
|
809
|
+
cmd.push("-m", modelValue);
|
|
810
|
+
}
|
|
811
|
+
if (variantValue) {
|
|
812
|
+
cmd.push("--variant", variantValue);
|
|
744
813
|
}
|
|
745
814
|
let effectivePrompt = prompt;
|
|
746
815
|
if (options.system_prompt && typeof options.system_prompt === "string" && options.system_prompt.trim()) {
|
|
@@ -753,9 +822,8 @@ USER REQUEST:
|
|
|
753
822
|
${prompt}`;
|
|
754
823
|
}
|
|
755
824
|
cmd.push(effectivePrompt);
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
const modelSlug = explicitModel.slice("openrouter/".length);
|
|
825
|
+
if (modelValue && isOpenRouterRequest({ model: modelValue }) && !env.OPENCODE_CONFIG_CONTENT && !process.env.OPENCODE_CONFIG_CONTENT) {
|
|
826
|
+
const modelSlug = modelValue.slice("openrouter/".length);
|
|
759
827
|
const headers = openRouterAttributionHeaders({ env: { ...process.env, ...env } });
|
|
760
828
|
if (modelSlug && Object.keys(headers).length > 0) {
|
|
761
829
|
env.OPENCODE_CONFIG_CONTENT = JSON.stringify({
|
|
@@ -780,7 +848,8 @@ ${prompt}`;
|
|
|
780
848
|
metrics: createMetrics({
|
|
781
849
|
durationApiMs: Date.now() - startApi,
|
|
782
850
|
numTurns: resultText ? 1 : 0,
|
|
783
|
-
sessionId: ""
|
|
851
|
+
sessionId: "",
|
|
852
|
+
model: modelValue
|
|
784
853
|
}),
|
|
785
854
|
isError,
|
|
786
855
|
errorMessage: isError ? stderr.trim() : void 0
|
|
@@ -842,6 +911,10 @@ var runner_exports = {};
|
|
|
842
911
|
__export(runner_exports, {
|
|
843
912
|
HarnessRunner: () => HarnessRunner
|
|
844
913
|
});
|
|
914
|
+
function tokenMetrics(raw) {
|
|
915
|
+
const { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens, totalTokens, model } = raw.metrics;
|
|
916
|
+
return { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens, totalTokens, model };
|
|
917
|
+
}
|
|
845
918
|
var TRANSIENT_PATTERNS, HarnessRunner;
|
|
846
919
|
var init_runner = __esm({
|
|
847
920
|
"src/harness/runner.ts"() {
|
|
@@ -892,7 +965,8 @@ var init_runner = __esm({
|
|
|
892
965
|
numTurns: raw.metrics.numTurns,
|
|
893
966
|
durationMs: Date.now() - startTime,
|
|
894
967
|
sessionId: raw.metrics.sessionId,
|
|
895
|
-
messages: raw.messages
|
|
968
|
+
messages: raw.messages,
|
|
969
|
+
...tokenMetrics(raw)
|
|
896
970
|
});
|
|
897
971
|
} finally {
|
|
898
972
|
if (schema !== void 0) {
|
|
@@ -906,6 +980,7 @@ var init_runner = __esm({
|
|
|
906
980
|
for (const key of [
|
|
907
981
|
"provider",
|
|
908
982
|
"model",
|
|
983
|
+
"variant",
|
|
909
984
|
"maxTurns",
|
|
910
985
|
"maxBudgetUsd",
|
|
911
986
|
"maxRetries",
|
|
@@ -985,7 +1060,8 @@ var init_runner = __esm({
|
|
|
985
1060
|
numTurns: raw.metrics.numTurns,
|
|
986
1061
|
durationMs: Date.now() - startTime,
|
|
987
1062
|
sessionId: raw.metrics.sessionId,
|
|
988
|
-
messages: raw.messages
|
|
1063
|
+
messages: raw.messages,
|
|
1064
|
+
...tokenMetrics(raw)
|
|
989
1065
|
});
|
|
990
1066
|
}
|
|
991
1067
|
return createHarnessResult({
|
|
@@ -996,7 +1072,8 @@ var init_runner = __esm({
|
|
|
996
1072
|
numTurns: raw.metrics.numTurns,
|
|
997
1073
|
durationMs: Date.now() - startTime,
|
|
998
1074
|
sessionId: raw.metrics.sessionId,
|
|
999
|
-
messages: raw.messages
|
|
1075
|
+
messages: raw.messages,
|
|
1076
|
+
...tokenMetrics(raw)
|
|
1000
1077
|
});
|
|
1001
1078
|
}
|
|
1002
1079
|
async buildProvider(providerName, options) {
|
|
@@ -1553,6 +1630,134 @@ function applyTriggerTransform(triggerContext, bindings, input) {
|
|
|
1553
1630
|
}
|
|
1554
1631
|
return input;
|
|
1555
1632
|
}
|
|
1633
|
+
|
|
1634
|
+
// src/usage/costTracker.ts
|
|
1635
|
+
var USAGE_ENVELOPE_KEY = "__agentfield_usage__";
|
|
1636
|
+
function deriveProvider(model) {
|
|
1637
|
+
if (!model) return null;
|
|
1638
|
+
const slug = String(model).trim();
|
|
1639
|
+
const slash = slug.indexOf("/");
|
|
1640
|
+
if (slash < 0) return null;
|
|
1641
|
+
return slug.slice(0, slash).toLowerCase() || null;
|
|
1642
|
+
}
|
|
1643
|
+
function toCount(value) {
|
|
1644
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return 0;
|
|
1645
|
+
return Math.trunc(value);
|
|
1646
|
+
}
|
|
1647
|
+
function toCost(value) {
|
|
1648
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
1649
|
+
return value;
|
|
1650
|
+
}
|
|
1651
|
+
function round6(value) {
|
|
1652
|
+
return Math.round(value * 1e6) / 1e6;
|
|
1653
|
+
}
|
|
1654
|
+
var CostTracker = class {
|
|
1655
|
+
entries = [];
|
|
1656
|
+
/**
|
|
1657
|
+
* Record a single call's usage.
|
|
1658
|
+
*
|
|
1659
|
+
* Cost is optional: a call with known token counts but unknown price is
|
|
1660
|
+
* still recorded (`costUsd: null`) so tokens are never discarded.
|
|
1661
|
+
*/
|
|
1662
|
+
record(init) {
|
|
1663
|
+
this.entries.push({
|
|
1664
|
+
model: init.model,
|
|
1665
|
+
inputTokens: toCount(init.inputTokens),
|
|
1666
|
+
outputTokens: toCount(init.outputTokens),
|
|
1667
|
+
totalTokens: toCount(init.totalTokens),
|
|
1668
|
+
costUsd: toCost(init.costUsd),
|
|
1669
|
+
reasonerName: init.reasonerName ?? null,
|
|
1670
|
+
source: init.source ?? "llm",
|
|
1671
|
+
provider: init.provider ?? deriveProvider(init.model),
|
|
1672
|
+
harness: init.harness ?? null,
|
|
1673
|
+
cacheReadTokens: toCount(init.cacheReadTokens),
|
|
1674
|
+
cacheCreationTokens: toCount(init.cacheCreationTokens),
|
|
1675
|
+
costSource: init.costSource ?? null
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
/** Total accumulated cost in USD (unknown costs count as zero). */
|
|
1679
|
+
get totalCostUsd() {
|
|
1680
|
+
return this.entries.reduce((sum, e) => sum + (e.costUsd ?? 0), 0);
|
|
1681
|
+
}
|
|
1682
|
+
/** Total tokens used across all calls (per-entry total, no fallback). */
|
|
1683
|
+
get totalTokens() {
|
|
1684
|
+
return this.entries.reduce((sum, e) => sum + e.totalTokens, 0);
|
|
1685
|
+
}
|
|
1686
|
+
/** Number of calls tracked. */
|
|
1687
|
+
get callCount() {
|
|
1688
|
+
return this.entries.length;
|
|
1689
|
+
}
|
|
1690
|
+
get hasEntries() {
|
|
1691
|
+
return this.entries.length > 0;
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Return the transport contract form attached to execution envelopes.
|
|
1695
|
+
*
|
|
1696
|
+
* Matches the Python SDK's `CostTracker.serialize()` byte-for-byte in shape:
|
|
1697
|
+
* unset string fields serialize as null, `total_cost_usd` is null when no
|
|
1698
|
+
* entry had a known cost, and a per-entry `total_tokens` of zero falls back
|
|
1699
|
+
* to input + output.
|
|
1700
|
+
*/
|
|
1701
|
+
serialize() {
|
|
1702
|
+
const entries = [];
|
|
1703
|
+
let totalInput = 0;
|
|
1704
|
+
let totalOutput = 0;
|
|
1705
|
+
let totalTokens = 0;
|
|
1706
|
+
let totalCost = 0;
|
|
1707
|
+
let anyCost = false;
|
|
1708
|
+
for (const e of this.entries) {
|
|
1709
|
+
const entryTotal = e.totalTokens || e.inputTokens + e.outputTokens;
|
|
1710
|
+
entries.push({
|
|
1711
|
+
source: e.source,
|
|
1712
|
+
provider: e.provider,
|
|
1713
|
+
model: e.model,
|
|
1714
|
+
harness: e.harness,
|
|
1715
|
+
reasoner: e.reasonerName,
|
|
1716
|
+
input_tokens: e.inputTokens,
|
|
1717
|
+
output_tokens: e.outputTokens,
|
|
1718
|
+
cache_read_tokens: e.cacheReadTokens,
|
|
1719
|
+
cache_creation_tokens: e.cacheCreationTokens,
|
|
1720
|
+
total_tokens: entryTotal,
|
|
1721
|
+
cost_usd: e.costUsd,
|
|
1722
|
+
cost_source: e.costSource
|
|
1723
|
+
});
|
|
1724
|
+
totalInput += e.inputTokens;
|
|
1725
|
+
totalOutput += e.outputTokens;
|
|
1726
|
+
totalTokens += entryTotal;
|
|
1727
|
+
if (e.costUsd !== null) {
|
|
1728
|
+
totalCost += e.costUsd;
|
|
1729
|
+
anyCost = true;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
return {
|
|
1733
|
+
total_cost_usd: anyCost ? round6(totalCost) : null,
|
|
1734
|
+
total_input_tokens: totalInput,
|
|
1735
|
+
total_output_tokens: totalOutput,
|
|
1736
|
+
total_tokens: totalTokens,
|
|
1737
|
+
entries
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1740
|
+
/** Clear all tracked entries. */
|
|
1741
|
+
reset() {
|
|
1742
|
+
this.entries = [];
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
function usageSummaryOrNull(tracker) {
|
|
1746
|
+
if (!tracker || !tracker.hasEntries) return null;
|
|
1747
|
+
return tracker.serialize();
|
|
1748
|
+
}
|
|
1749
|
+
function isPlainObject(value) {
|
|
1750
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
1751
|
+
const proto = Object.getPrototypeOf(value);
|
|
1752
|
+
return proto === Object.prototype || proto === null;
|
|
1753
|
+
}
|
|
1754
|
+
function attachUsageToSyncResult(result, tracker) {
|
|
1755
|
+
const usage = usageSummaryOrNull(tracker);
|
|
1756
|
+
if (usage === null || !isPlainObject(result)) return result;
|
|
1757
|
+
return { ...result, [USAGE_ENVELOPE_KEY]: usage };
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
// src/context/ExecutionContext.ts
|
|
1556
1761
|
var store = new AsyncLocalStorage();
|
|
1557
1762
|
var ExecutionContext = class {
|
|
1558
1763
|
input;
|
|
@@ -1560,12 +1765,21 @@ var ExecutionContext = class {
|
|
|
1560
1765
|
req;
|
|
1561
1766
|
res;
|
|
1562
1767
|
agent;
|
|
1768
|
+
/**
|
|
1769
|
+
* Per-execution LLM/harness usage accumulator. Each top-level execution
|
|
1770
|
+
* binds a fresh tracker (isolated across concurrent executions via the
|
|
1771
|
+
* AsyncLocalStorage this context lives in); nested local `agent.call()`
|
|
1772
|
+
* executions inherit the parent's tracker so their usage rolls up into the
|
|
1773
|
+
* parent's report.
|
|
1774
|
+
*/
|
|
1775
|
+
costTracker;
|
|
1563
1776
|
constructor(params) {
|
|
1564
1777
|
this.input = params.input;
|
|
1565
1778
|
this.metadata = params.metadata;
|
|
1566
1779
|
this.req = params.req;
|
|
1567
1780
|
this.res = params.res;
|
|
1568
1781
|
this.agent = params.agent;
|
|
1782
|
+
this.costTracker = params.costTracker ?? new CostTracker();
|
|
1569
1783
|
}
|
|
1570
1784
|
get logger() {
|
|
1571
1785
|
return this.agent.getExecutionLogger();
|
|
@@ -1577,6 +1791,79 @@ var ExecutionContext = class {
|
|
|
1577
1791
|
return store.getStore();
|
|
1578
1792
|
}
|
|
1579
1793
|
};
|
|
1794
|
+
|
|
1795
|
+
// src/usage/aiUsage.ts
|
|
1796
|
+
function isRecord(value) {
|
|
1797
|
+
return typeof value === "object" && value !== null;
|
|
1798
|
+
}
|
|
1799
|
+
function num(value) {
|
|
1800
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
1801
|
+
}
|
|
1802
|
+
function extractTokenUsage(usage) {
|
|
1803
|
+
if (!isRecord(usage)) {
|
|
1804
|
+
return { inputTokens: 0, outputTokens: 0, totalTokens: 0, cacheReadTokens: 0, cacheCreationTokens: 0 };
|
|
1805
|
+
}
|
|
1806
|
+
const inputDetails = isRecord(usage.inputTokenDetails) ? usage.inputTokenDetails : void 0;
|
|
1807
|
+
return {
|
|
1808
|
+
inputTokens: num(usage.inputTokens),
|
|
1809
|
+
outputTokens: num(usage.outputTokens),
|
|
1810
|
+
totalTokens: num(usage.totalTokens),
|
|
1811
|
+
// `cachedInputTokens` is the deprecated pre-details alias — keep it as a
|
|
1812
|
+
// fallback so older provider adapters still report cache reads.
|
|
1813
|
+
cacheReadTokens: num(inputDetails?.cacheReadTokens) || num(usage.cachedInputTokens),
|
|
1814
|
+
cacheCreationTokens: num(inputDetails?.cacheWriteTokens)
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
function costFromUsageRaw(usage) {
|
|
1818
|
+
if (!isRecord(usage) || !isRecord(usage.raw)) return null;
|
|
1819
|
+
const cost = usage.raw.cost;
|
|
1820
|
+
return typeof cost === "number" && Number.isFinite(cost) && cost >= 0 ? cost : null;
|
|
1821
|
+
}
|
|
1822
|
+
function costFromProviderMetadata(providerMetadata) {
|
|
1823
|
+
if (!isRecord(providerMetadata)) return null;
|
|
1824
|
+
const openrouter = providerMetadata.openrouter;
|
|
1825
|
+
if (!isRecord(openrouter) || !isRecord(openrouter.usage)) return null;
|
|
1826
|
+
const cost = openrouter.usage.cost;
|
|
1827
|
+
return typeof cost === "number" && Number.isFinite(cost) && cost >= 0 ? cost : null;
|
|
1828
|
+
}
|
|
1829
|
+
function extractProviderCostUsd(source) {
|
|
1830
|
+
if (Array.isArray(source.steps) && source.steps.length > 0) {
|
|
1831
|
+
let sum = 0;
|
|
1832
|
+
let any = false;
|
|
1833
|
+
for (const step of source.steps) {
|
|
1834
|
+
const cost = costFromUsageRaw(isRecord(step) ? step.usage : void 0);
|
|
1835
|
+
if (cost !== null) {
|
|
1836
|
+
sum += cost;
|
|
1837
|
+
any = true;
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
if (any) return sum;
|
|
1841
|
+
}
|
|
1842
|
+
return costFromUsageRaw(source.totalUsage) ?? costFromUsageRaw(source.usage) ?? costFromProviderMetadata(source.providerMetadata);
|
|
1843
|
+
}
|
|
1844
|
+
function recordAiSdkUsage(params) {
|
|
1845
|
+
try {
|
|
1846
|
+
const current = ExecutionContext.getCurrent();
|
|
1847
|
+
const tracker = params.tracker ?? current?.costTracker;
|
|
1848
|
+
if (!tracker) return;
|
|
1849
|
+
const tokens = extractTokenUsage(params.source.totalUsage ?? params.source.usage);
|
|
1850
|
+
const cost = extractProviderCostUsd(params.source);
|
|
1851
|
+
const hasTokens = tokens.inputTokens > 0 || tokens.outputTokens > 0 || tokens.totalTokens > 0 || tokens.cacheReadTokens > 0 || tokens.cacheCreationTokens > 0;
|
|
1852
|
+
if (!hasTokens && cost === null) return;
|
|
1853
|
+
tracker.record({
|
|
1854
|
+
model: params.model,
|
|
1855
|
+
...tokens,
|
|
1856
|
+
costUsd: cost,
|
|
1857
|
+
costSource: cost !== null ? "provider" : null,
|
|
1858
|
+
reasonerName: params.reasonerName !== void 0 ? params.reasonerName : current?.metadata.reasonerId ?? null,
|
|
1859
|
+
source: "llm",
|
|
1860
|
+
provider: params.provider ?? void 0
|
|
1861
|
+
});
|
|
1862
|
+
} catch {
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
// src/ai/ToolCalling.ts
|
|
1580
1867
|
var DEFAULT_MAX_TURNS = 10;
|
|
1581
1868
|
var DEFAULT_MAX_TOOL_CALLS = 25;
|
|
1582
1869
|
var DEFAULT_HEALTH_STATUS = void 0;
|
|
@@ -1794,9 +2081,15 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
|
|
|
1794
2081
|
}
|
|
1795
2082
|
return { tools: observableTools, getTotalCalls: () => totalCalls };
|
|
1796
2083
|
}
|
|
1797
|
-
async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydration, buildModel, options = {}) {
|
|
2084
|
+
async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydration, buildModel, options = {}, modelChoice) {
|
|
1798
2085
|
const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
1799
2086
|
const maxToolCalls = config.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS;
|
|
2087
|
+
const usageModel = modelChoice?.modelName ?? options.model;
|
|
2088
|
+
const recordLoopUsage = (result2) => {
|
|
2089
|
+
if (usageModel) {
|
|
2090
|
+
recordAiSdkUsage({ source: result2, model: usageModel, provider: modelChoice?.provider });
|
|
2091
|
+
}
|
|
2092
|
+
};
|
|
1800
2093
|
const trace = {
|
|
1801
2094
|
calls: [],
|
|
1802
2095
|
totalTurns: 0,
|
|
@@ -1823,6 +2116,7 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
|
|
|
1823
2116
|
stopWhen: stepCountIs(1)
|
|
1824
2117
|
// Stop after LLM's first response (tool selection)
|
|
1825
2118
|
});
|
|
2119
|
+
recordLoopUsage(selectionResult);
|
|
1826
2120
|
const selectedNames = /* @__PURE__ */ new Set();
|
|
1827
2121
|
for (const step of selectionResult.steps) {
|
|
1828
2122
|
for (const tc of step.toolCalls) {
|
|
@@ -1866,6 +2160,7 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
|
|
|
1866
2160
|
trace.totalTurns = currentTurn;
|
|
1867
2161
|
}
|
|
1868
2162
|
});
|
|
2163
|
+
recordLoopUsage(result);
|
|
1869
2164
|
trace.finalResponse = result.text;
|
|
1870
2165
|
trace.totalTurns = result.steps.length;
|
|
1871
2166
|
return { text: result.text, trace };
|
|
@@ -1893,6 +2188,13 @@ var ReasonerContext = class {
|
|
|
1893
2188
|
memory;
|
|
1894
2189
|
workflow;
|
|
1895
2190
|
did;
|
|
2191
|
+
/**
|
|
2192
|
+
* Per-execution token/cost usage accumulator. LLM calls made through
|
|
2193
|
+
* `ctx.ai()` / `ctx.aiWithTools()` and harness runs record into it
|
|
2194
|
+
* automatically; reasoner authors may also `record()` custom entries. Its
|
|
2195
|
+
* serialized summary is attached to the execution's terminal report.
|
|
2196
|
+
*/
|
|
2197
|
+
costTracker;
|
|
1896
2198
|
/**
|
|
1897
2199
|
* AbortSignal that fires when the control plane cancels this execution
|
|
1898
2200
|
* (per-execution cancel, the bottom-up cancel-tree endpoint, or any
|
|
@@ -1930,6 +2232,7 @@ var ReasonerContext = class {
|
|
|
1930
2232
|
this.workflow = params.workflow;
|
|
1931
2233
|
this.did = params.did;
|
|
1932
2234
|
this.signal = params.signal ?? new AbortController().signal;
|
|
2235
|
+
this.costTracker = params.costTracker ?? ExecutionContext.getCurrent()?.costTracker ?? new CostTracker();
|
|
1933
2236
|
this.trigger = params.trigger;
|
|
1934
2237
|
}
|
|
1935
2238
|
ai(prompt, options) {
|
|
@@ -1954,6 +2257,7 @@ var ReasonerContext = class {
|
|
|
1954
2257
|
maxTurns: options.maxTurns ?? config.maxTurns ?? 10,
|
|
1955
2258
|
maxToolCalls: options.maxToolCalls ?? config.maxToolCalls ?? 25
|
|
1956
2259
|
};
|
|
2260
|
+
const modelChoice = typeof this.aiClient.resolveModelChoice === "function" ? this.aiClient.resolveModelChoice(options) : void 0;
|
|
1957
2261
|
return executeToolCallLoop(
|
|
1958
2262
|
this.agent,
|
|
1959
2263
|
prompt,
|
|
@@ -1961,7 +2265,8 @@ var ReasonerContext = class {
|
|
|
1961
2265
|
mergedConfig,
|
|
1962
2266
|
needsLazyHydration,
|
|
1963
2267
|
() => this.aiClient.getModel(options),
|
|
1964
|
-
options
|
|
2268
|
+
options,
|
|
2269
|
+
modelChoice
|
|
1965
2270
|
);
|
|
1966
2271
|
}
|
|
1967
2272
|
aiStream(prompt, options) {
|
|
@@ -2026,7 +2331,8 @@ function getCurrentContext() {
|
|
|
2026
2331
|
aiClient: agent.getAIClient(),
|
|
2027
2332
|
memory: agent.getMemoryInterface(metadata),
|
|
2028
2333
|
workflow: agent.getWorkflowReporter(metadata),
|
|
2029
|
-
did: agent.getDidInterface(metadata, input)
|
|
2334
|
+
did: agent.getDidInterface(metadata, input),
|
|
2335
|
+
costTracker: execution.costTracker
|
|
2030
2336
|
});
|
|
2031
2337
|
}
|
|
2032
2338
|
|
|
@@ -2288,6 +2594,26 @@ function toError(error) {
|
|
|
2288
2594
|
|
|
2289
2595
|
// src/ai/AIClient.ts
|
|
2290
2596
|
init_openrouterAttribution();
|
|
2597
|
+
|
|
2598
|
+
// src/ai/openrouterUsage.ts
|
|
2599
|
+
function withOpenRouterUsageInclude(baseFetch) {
|
|
2600
|
+
return (input, init) => {
|
|
2601
|
+
const impl = ((...args) => globalThis.fetch(...args));
|
|
2602
|
+
try {
|
|
2603
|
+
if (init && typeof init.body === "string") {
|
|
2604
|
+
const parsed = JSON.parse(init.body);
|
|
2605
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && parsed.usage === void 0) {
|
|
2606
|
+
parsed.usage = { include: true };
|
|
2607
|
+
return impl(input, { ...init, body: JSON.stringify(parsed) });
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
} catch {
|
|
2611
|
+
}
|
|
2612
|
+
return impl(input, init);
|
|
2613
|
+
};
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
// src/ai/AIClient.ts
|
|
2291
2617
|
function repairJsonText(text2) {
|
|
2292
2618
|
let cleaned = text2.trim();
|
|
2293
2619
|
const codeBlockMatch = cleaned.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
@@ -2322,6 +2648,7 @@ var AIClient = class {
|
|
|
2322
2648
|
};
|
|
2323
2649
|
}
|
|
2324
2650
|
async generate(prompt, options = {}) {
|
|
2651
|
+
const { provider, modelName } = this.resolveModelChoice(options);
|
|
2325
2652
|
const model = this.buildModel(options);
|
|
2326
2653
|
if (options.schema) {
|
|
2327
2654
|
const schema = options.schema;
|
|
@@ -2336,6 +2663,7 @@ var AIClient = class {
|
|
|
2336
2663
|
experimental_repairText: async ({ text: text2 }) => repairJsonText(text2)
|
|
2337
2664
|
});
|
|
2338
2665
|
const response2 = await this.withRateLimitRetry(call2);
|
|
2666
|
+
recordAiSdkUsage({ source: response2, model: modelName, provider });
|
|
2339
2667
|
return response2.object;
|
|
2340
2668
|
}
|
|
2341
2669
|
const call = async () => generateText({
|
|
@@ -2346,8 +2674,13 @@ var AIClient = class {
|
|
|
2346
2674
|
maxOutputTokens: options.maxTokens ?? this.config.maxTokens
|
|
2347
2675
|
});
|
|
2348
2676
|
const response = await this.withRateLimitRetry(call);
|
|
2677
|
+
recordAiSdkUsage({ source: response, model: modelName, provider });
|
|
2349
2678
|
return response.text;
|
|
2350
2679
|
}
|
|
2680
|
+
// NOTE: stream() usage is deliberately NOT captured. The AI SDK's
|
|
2681
|
+
// streamResult.usage/.totalUsage promises "automatically consume the
|
|
2682
|
+
// stream": attaching to them would force full background consumption of a
|
|
2683
|
+
// stream the caller may abandon early, changing stream semantics.
|
|
2351
2684
|
async stream(prompt, options = {}) {
|
|
2352
2685
|
const model = this.buildModel(options);
|
|
2353
2686
|
const streamResult = streamText({
|
|
@@ -2386,9 +2719,19 @@ var AIClient = class {
|
|
|
2386
2719
|
getModel(options = {}) {
|
|
2387
2720
|
return this.buildModel(options);
|
|
2388
2721
|
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Resolve the effective provider/model pair for a request without building
|
|
2724
|
+
* the model. Used by usage tracking to attribute token/cost entries to the
|
|
2725
|
+
* model actually called.
|
|
2726
|
+
*/
|
|
2727
|
+
resolveModelChoice(options = {}) {
|
|
2728
|
+
return {
|
|
2729
|
+
provider: options.provider ?? this.config.provider ?? "openai",
|
|
2730
|
+
modelName: options.model ?? this.config.model ?? "gpt-4o"
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
2389
2733
|
buildModel(options) {
|
|
2390
|
-
const provider
|
|
2391
|
-
const modelName = options.model ?? this.config.model ?? "gpt-4o";
|
|
2734
|
+
const { provider, modelName } = this.resolveModelChoice(options);
|
|
2392
2735
|
const openRouterHeaders = this.openRouterHeaders(provider, modelName);
|
|
2393
2736
|
switch (provider) {
|
|
2394
2737
|
case "anthropic": {
|
|
@@ -2444,7 +2787,8 @@ var AIClient = class {
|
|
|
2444
2787
|
const openrouter = createOpenAI({
|
|
2445
2788
|
apiKey: this.config.apiKey,
|
|
2446
2789
|
baseURL: this.config.baseUrl ?? "https://openrouter.ai/api/v1",
|
|
2447
|
-
headers: openRouterHeaders
|
|
2790
|
+
headers: openRouterHeaders,
|
|
2791
|
+
fetch: withOpenRouterUsageInclude()
|
|
2448
2792
|
});
|
|
2449
2793
|
return openrouter.chat(modelName);
|
|
2450
2794
|
}
|
|
@@ -2461,7 +2805,7 @@ var AIClient = class {
|
|
|
2461
2805
|
const openai = createOpenAI({
|
|
2462
2806
|
apiKey: this.config.apiKey,
|
|
2463
2807
|
baseURL: this.config.baseUrl,
|
|
2464
|
-
...openRouterHeaders ? { headers: openRouterHeaders } : {}
|
|
2808
|
+
...openRouterHeaders ? { headers: openRouterHeaders, fetch: withOpenRouterUsageInclude() } : {}
|
|
2465
2809
|
});
|
|
2466
2810
|
return openai(modelName);
|
|
2467
2811
|
}
|
|
@@ -3167,6 +3511,7 @@ var AgentFieldClient = class {
|
|
|
3167
3511
|
if (payload.result !== void 0) body.result = wrapResult(payload.result);
|
|
3168
3512
|
if (payload.error !== void 0) body.error = payload.error;
|
|
3169
3513
|
if (payload.errorDetails !== void 0) body.error_details = payload.errorDetails;
|
|
3514
|
+
if (payload.usage !== void 0) body.usage = payload.usage;
|
|
3170
3515
|
const bodyStr = JSON.stringify(body);
|
|
3171
3516
|
const authHeaders = this.didAuthenticator.signRequest(Buffer.from(bodyStr));
|
|
3172
3517
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
@@ -3386,6 +3731,9 @@ function wrapResult(result) {
|
|
|
3386
3731
|
}
|
|
3387
3732
|
return { result };
|
|
3388
3733
|
}
|
|
3734
|
+
|
|
3735
|
+
// src/agent/Agent.ts
|
|
3736
|
+
init_modelVariant();
|
|
3389
3737
|
var MemoryClientBase = class {
|
|
3390
3738
|
http;
|
|
3391
3739
|
defaultHeaders;
|
|
@@ -4918,7 +5266,54 @@ var Agent = class {
|
|
|
4918
5266
|
}
|
|
4919
5267
|
async harness(prompt, options) {
|
|
4920
5268
|
const runner = await this.getHarnessRunner();
|
|
4921
|
-
|
|
5269
|
+
const result = await runner.run(prompt, options ?? {});
|
|
5270
|
+
this.recordHarnessUsage(result, options);
|
|
5271
|
+
return result;
|
|
5272
|
+
}
|
|
5273
|
+
/**
|
|
5274
|
+
* Record a harness run's token/cost usage into the current execution's
|
|
5275
|
+
* tracker. Mirrors the Python SDK's `_record_harness_usage`: a no-op when
|
|
5276
|
+
* the harness reported neither tokens nor cost (the common case for
|
|
5277
|
+
* providers that don't expose usage) so empty entries are never emitted;
|
|
5278
|
+
* cost is threaded even when tokens are unknown, and vice versa. Never
|
|
5279
|
+
* throws — usage capture is best-effort.
|
|
5280
|
+
*/
|
|
5281
|
+
recordHarnessUsage(result, options) {
|
|
5282
|
+
try {
|
|
5283
|
+
const current = ExecutionContext.getCurrent();
|
|
5284
|
+
const tracker = current?.costTracker;
|
|
5285
|
+
if (!tracker) return;
|
|
5286
|
+
const inputTokens = result.inputTokens ?? 0;
|
|
5287
|
+
const outputTokens = result.outputTokens ?? 0;
|
|
5288
|
+
const cacheRead = result.cacheReadTokens ?? 0;
|
|
5289
|
+
const cacheCreation = result.cacheCreationTokens ?? 0;
|
|
5290
|
+
const reportedTotal = result.totalTokens ?? 0;
|
|
5291
|
+
const cost = typeof result.costUsd === "number" && Number.isFinite(result.costUsd) ? result.costUsd : null;
|
|
5292
|
+
if (!inputTokens && !outputTokens && !cacheRead && !cacheCreation && !reportedTotal && cost === null) {
|
|
5293
|
+
return;
|
|
5294
|
+
}
|
|
5295
|
+
const providerName = options?.provider ?? this.config.harnessConfig?.provider;
|
|
5296
|
+
const harnessName = providerName ? String(providerName).replace(/-/g, "_") : null;
|
|
5297
|
+
const rawModelName = String(
|
|
5298
|
+
result.model ?? options?.model ?? this.config.harnessConfig?.model ?? providerName ?? "harness"
|
|
5299
|
+
);
|
|
5300
|
+
const modelName = splitModelVariant(rawModelName).model ?? rawModelName;
|
|
5301
|
+
tracker.record({
|
|
5302
|
+
model: modelName,
|
|
5303
|
+
inputTokens,
|
|
5304
|
+
outputTokens,
|
|
5305
|
+
totalTokens: reportedTotal || inputTokens + outputTokens,
|
|
5306
|
+
costUsd: cost,
|
|
5307
|
+
reasonerName: current.metadata.reasonerId ?? null,
|
|
5308
|
+
source: "harness",
|
|
5309
|
+
provider: deriveProvider(modelName),
|
|
5310
|
+
harness: harnessName,
|
|
5311
|
+
cacheReadTokens: cacheRead,
|
|
5312
|
+
cacheCreationTokens: cacheCreation,
|
|
5313
|
+
costSource: cost !== null ? "provider" : null
|
|
5314
|
+
});
|
|
5315
|
+
} catch {
|
|
5316
|
+
}
|
|
4922
5317
|
}
|
|
4923
5318
|
getMemoryInterface(metadata) {
|
|
4924
5319
|
const defaultScope = this.config.memoryConfig?.defaultScope ?? "workflow";
|
|
@@ -5111,7 +5506,8 @@ var Agent = class {
|
|
|
5111
5506
|
}
|
|
5112
5507
|
async call(target, input) {
|
|
5113
5508
|
const { agentId, name } = this.parseTarget(target);
|
|
5114
|
-
const
|
|
5509
|
+
const parentContext = ExecutionContext.getCurrent();
|
|
5510
|
+
const parentMetadata = parentContext?.metadata;
|
|
5115
5511
|
if (!agentId || agentId === this.config.nodeId) {
|
|
5116
5512
|
const local = this.reasoners.get(name);
|
|
5117
5513
|
if (!local) throw new Error(`Reasoner not found: ${name}`);
|
|
@@ -5142,7 +5538,11 @@ var Agent = class {
|
|
|
5142
5538
|
},
|
|
5143
5539
|
req: dummyReq,
|
|
5144
5540
|
res: dummyRes,
|
|
5145
|
-
agent: this
|
|
5541
|
+
agent: this,
|
|
5542
|
+
// Nested local calls inherit the parent's cost tracker so their LLM /
|
|
5543
|
+
// harness usage rolls up into the parent execution's usage report
|
|
5544
|
+
// (entries still carry the child reasoner's name).
|
|
5545
|
+
costTracker: parentContext?.costTracker
|
|
5146
5546
|
});
|
|
5147
5547
|
const startTime = Date.now();
|
|
5148
5548
|
this.executionLogger.system("agent.call.started", "Local agent call started", {
|
|
@@ -5212,7 +5612,8 @@ var Agent = class {
|
|
|
5212
5612
|
memory: this.getMemoryInterface(execCtx.metadata),
|
|
5213
5613
|
workflow: this.getWorkflowReporter(execCtx.metadata),
|
|
5214
5614
|
did: this.getDidInterface(execCtx.metadata, resolvedInput, name),
|
|
5215
|
-
trigger: triggerContext
|
|
5615
|
+
trigger: triggerContext,
|
|
5616
|
+
costTracker: execCtx.costTracker
|
|
5216
5617
|
})
|
|
5217
5618
|
);
|
|
5218
5619
|
this.executionLogger.system("reasoner.completed", "Reasoner execution completed", {
|
|
@@ -5914,6 +6315,8 @@ var Agent = class {
|
|
|
5914
6315
|
watchdog.catch(() => {
|
|
5915
6316
|
});
|
|
5916
6317
|
const completedAt = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
6318
|
+
const usageTracker = new CostTracker();
|
|
6319
|
+
const usage = () => usageSummaryOrNull(usageTracker) ?? void 0;
|
|
5917
6320
|
try {
|
|
5918
6321
|
const result = await Promise.race([
|
|
5919
6322
|
this.runReasoner(reasoner, {
|
|
@@ -5921,7 +6324,8 @@ var Agent = class {
|
|
|
5921
6324
|
input: params.input,
|
|
5922
6325
|
metadata: params.metadata,
|
|
5923
6326
|
respond: false,
|
|
5924
|
-
controller
|
|
6327
|
+
controller,
|
|
6328
|
+
costTracker: usageTracker
|
|
5925
6329
|
}),
|
|
5926
6330
|
watchdog
|
|
5927
6331
|
]);
|
|
@@ -5930,7 +6334,8 @@ var Agent = class {
|
|
|
5930
6334
|
result,
|
|
5931
6335
|
durationMs: Date.now() - start,
|
|
5932
6336
|
completedAt: completedAt(),
|
|
5933
|
-
reasoner: reasonerName
|
|
6337
|
+
reasoner: reasonerName,
|
|
6338
|
+
usage: usage()
|
|
5934
6339
|
});
|
|
5935
6340
|
} catch (err) {
|
|
5936
6341
|
const durationMs = Date.now() - start;
|
|
@@ -5941,7 +6346,8 @@ var Agent = class {
|
|
|
5941
6346
|
errorDetails: { reason: "reasoner_timeout" },
|
|
5942
6347
|
durationMs,
|
|
5943
6348
|
completedAt: completedAt(),
|
|
5944
|
-
reasoner: reasonerName
|
|
6349
|
+
reasoner: reasonerName,
|
|
6350
|
+
usage: usage()
|
|
5945
6351
|
});
|
|
5946
6352
|
} else if (controller.signal.aborted) {
|
|
5947
6353
|
await this.agentFieldClient.reportExecutionResult(executionId, {
|
|
@@ -5950,7 +6356,8 @@ var Agent = class {
|
|
|
5950
6356
|
errorDetails: { reason: "cancelled" },
|
|
5951
6357
|
durationMs,
|
|
5952
6358
|
completedAt: completedAt(),
|
|
5953
|
-
reasoner: reasonerName
|
|
6359
|
+
reasoner: reasonerName,
|
|
6360
|
+
usage: usage()
|
|
5954
6361
|
});
|
|
5955
6362
|
} else {
|
|
5956
6363
|
await this.agentFieldClient.reportExecutionResult(executionId, {
|
|
@@ -5959,7 +6366,8 @@ var Agent = class {
|
|
|
5959
6366
|
errorDetails: err?.responseData,
|
|
5960
6367
|
durationMs,
|
|
5961
6368
|
completedAt: completedAt(),
|
|
5962
|
-
reasoner: reasonerName
|
|
6369
|
+
reasoner: reasonerName,
|
|
6370
|
+
usage: usage()
|
|
5963
6371
|
});
|
|
5964
6372
|
}
|
|
5965
6373
|
} finally {
|
|
@@ -5975,6 +6383,7 @@ var Agent = class {
|
|
|
5975
6383
|
rootWorkflowId: params.metadata.rootWorkflowId ?? params.metadata.workflowId ?? params.metadata.runId ?? params.metadata.executionId,
|
|
5976
6384
|
reasonerId: params.metadata.reasonerId ?? params.targetName
|
|
5977
6385
|
};
|
|
6386
|
+
const costTracker = params.costTracker ?? new CostTracker();
|
|
5978
6387
|
const { input: unwrappedInput, triggerContext } = unwrapEnvelope(params.input);
|
|
5979
6388
|
let resolvedInput = unwrappedInput;
|
|
5980
6389
|
if (triggerContext) {
|
|
@@ -5986,7 +6395,8 @@ var Agent = class {
|
|
|
5986
6395
|
metadata: executionMetadata,
|
|
5987
6396
|
req,
|
|
5988
6397
|
res,
|
|
5989
|
-
agent: this
|
|
6398
|
+
agent: this,
|
|
6399
|
+
costTracker
|
|
5990
6400
|
});
|
|
5991
6401
|
const { controller, release } = this.cancelRegistry.register(
|
|
5992
6402
|
executionMetadata.executionId,
|
|
@@ -6032,7 +6442,8 @@ var Agent = class {
|
|
|
6032
6442
|
workflow: this.getWorkflowReporter(executionMetadata),
|
|
6033
6443
|
did: this.getDidInterface(executionMetadata, resolvedInput, params.targetName),
|
|
6034
6444
|
signal: controller.signal,
|
|
6035
|
-
trigger: triggerContext
|
|
6445
|
+
trigger: triggerContext,
|
|
6446
|
+
costTracker
|
|
6036
6447
|
});
|
|
6037
6448
|
const result = await reasoner.handler(ctx);
|
|
6038
6449
|
this.executionLogger.system("reasoner.completed", "Reasoner execution completed", {
|
|
@@ -6051,7 +6462,7 @@ var Agent = class {
|
|
|
6051
6462
|
rootWorkflowId: executionMetadata.rootWorkflowId
|
|
6052
6463
|
});
|
|
6053
6464
|
if (params.respond && params.res) {
|
|
6054
|
-
params.res.json(result);
|
|
6465
|
+
params.res.json(attachUsageToSyncResult(result, costTracker));
|
|
6055
6466
|
return;
|
|
6056
6467
|
}
|
|
6057
6468
|
return result;
|
|
@@ -7711,6 +8122,7 @@ function sleep3(ms) {
|
|
|
7711
8122
|
|
|
7712
8123
|
// src/harness/index.ts
|
|
7713
8124
|
init_types();
|
|
8125
|
+
init_modelVariant();
|
|
7714
8126
|
init_factory();
|
|
7715
8127
|
init_runner();
|
|
7716
8128
|
async function simulateTrigger(handler, options) {
|
|
@@ -7762,6 +8174,6 @@ function loadFixture(source) {
|
|
|
7762
8174
|
);
|
|
7763
8175
|
}
|
|
7764
8176
|
|
|
7765
|
-
export { ACTIVE_STATUSES, AIClient, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, Text, Video, WorkflowReporter, applyTriggerTransform, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, encryptForDid, encryptToJwk, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, text, triggerToPayload, unwrapEnvelope, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
|
|
8177
|
+
export { ACTIVE_STATUSES, AIClient, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, CostTracker, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, Text, USAGE_ENVELOPE_KEY, Video, WorkflowReporter, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, deriveProvider, encryptForDid, encryptToJwk, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, resolveModelAndVariant, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
|
|
7766
8178
|
//# sourceMappingURL=index.js.map
|
|
7767
8179
|
//# sourceMappingURL=index.js.map
|