@theokit/sdk 4.28.0 → 4.29.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/{cron-BN6JJlDw.d.ts → agent-BZz4X8ZM.d.ts} +2 -577
- package/dist/{cron-CoQREV_k.d.cts → agent-CdjSCbYz.d.cts} +2 -577
- package/dist/agent-FBTLZI6V.js +41 -0
- package/dist/agent-FBTLZI6V.js.map +1 -0
- package/dist/agent-LBCEK6VH.cjs +50 -0
- package/dist/agent-LBCEK6VH.cjs.map +1 -0
- package/dist/{chunk-I53QDJVI.cjs → chunk-54YLX4Q6.cjs} +5 -5
- package/dist/{chunk-I53QDJVI.cjs.map → chunk-54YLX4Q6.cjs.map} +1 -1
- package/dist/{chunk-AKSBP7OO.js → chunk-5IB2UKSN.js} +5 -41
- package/dist/chunk-5IB2UKSN.js.map +1 -0
- package/dist/chunk-BNIFFFH3.js +129 -0
- package/dist/chunk-BNIFFFH3.js.map +1 -0
- package/dist/{chunk-LSLPF6OI.cjs → chunk-DHLZIMP6.cjs} +5 -43
- package/dist/chunk-DHLZIMP6.cjs.map +1 -0
- package/dist/{chunk-PF5Y5BHG.js → chunk-EULKRTB5.js} +3 -3
- package/dist/{chunk-PF5Y5BHG.js.map → chunk-EULKRTB5.js.map} +1 -1
- package/dist/chunk-FKCC2MED.js +43 -0
- package/dist/chunk-FKCC2MED.js.map +1 -0
- package/dist/{chunk-QUTUJ6P6.cjs → chunk-HK7ZHSAX.cjs} +25 -16
- package/dist/chunk-HK7ZHSAX.cjs.map +1 -0
- package/dist/{chunk-MQLCZ4HJ.cjs → chunk-JLMXKTBX.cjs} +4 -4
- package/dist/{chunk-MQLCZ4HJ.cjs.map → chunk-JLMXKTBX.cjs.map} +1 -1
- package/dist/chunk-LALRCFSN.cjs +46 -0
- package/dist/chunk-LALRCFSN.cjs.map +1 -0
- package/dist/{chunk-DUK5WMKJ.js → chunk-R6ZP6KNB.js} +25 -16
- package/dist/chunk-R6ZP6KNB.js.map +1 -0
- package/dist/chunk-RZQ6E5YZ.cjs +131 -0
- package/dist/chunk-RZQ6E5YZ.cjs.map +1 -0
- package/dist/{chunk-XW6RXVGB.js → chunk-VUJ3NVDC.js} +691 -807
- package/dist/chunk-VUJ3NVDC.js.map +1 -0
- package/dist/{chunk-G6GO6BXD.js → chunk-XAUBQMQU.js} +3 -3
- package/dist/{chunk-G6GO6BXD.js.map → chunk-XAUBQMQU.js.map} +1 -1
- package/dist/{chunk-PN53WGEI.cjs → chunk-YQAPEYUV.cjs} +714 -830
- package/dist/chunk-YQAPEYUV.cjs.map +1 -0
- package/dist/compact-session-OO2GD76G.js +1 -1
- package/dist/compact-session-OO7NVWPB.cjs +1 -1
- package/dist/cron-CIIshMs3.d.cts +579 -0
- package/dist/cron-dElBjDaL.d.ts +579 -0
- package/dist/cron.cjs +13 -11
- package/dist/cron.d.cts +2 -1
- package/dist/cron.d.ts +2 -1
- package/dist/cron.js +12 -10
- package/dist/eval.cjs +17 -15
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +13 -11
- package/dist/eval.js.map +1 -1
- package/dist/{index-manager-CB6I7XFQ.cjs → index-manager-H7HUMW52.cjs} +5 -5
- package/dist/{index-manager-CB6I7XFQ.cjs.map → index-manager-H7HUMW52.cjs.map} +1 -1
- package/dist/{index-manager-L27Q3QAC.js → index-manager-P7ZUX2RG.js} +4 -4
- package/dist/{index-manager-L27Q3QAC.js.map → index-manager-P7ZUX2RG.js.map} +1 -1
- package/dist/index.cjs +65 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -4
- package/dist/index.d.ts +18 -4
- package/dist/index.js +41 -20
- package/dist/index.js.map +1 -1
- package/dist/internal/persistence/index.cjs +10 -10
- package/dist/internal/persistence/index.js +2 -2
- package/dist/internal/persistence/jsonl.d.cts +7 -0
- package/dist/internal/persistence/jsonl.d.ts +7 -0
- package/dist/internal/persistence/session-writer.d.cts +56 -0
- package/dist/internal/persistence/session-writer.d.ts +56 -0
- package/dist/internal/persistence/transcript-ops.d.cts +71 -0
- package/dist/internal/persistence/transcript-ops.d.ts +71 -0
- package/dist/persistence.cjs +115 -12
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.d.cts +2 -0
- package/dist/persistence.d.ts +2 -0
- package/dist/persistence.js +105 -3
- package/dist/persistence.js.map +1 -1
- package/dist/skills.cjs +4 -3
- package/dist/skills.js +2 -1
- package/dist/subagents-loader.cjs +19 -0
- package/dist/subagents-loader.cjs.map +1 -0
- package/dist/subagents-loader.d.cts +39 -0
- package/dist/subagents-loader.d.ts +39 -0
- package/dist/subagents-loader.js +16 -0
- package/dist/subagents-loader.js.map +1 -0
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.js +1 -1
- package/package.json +12 -2
- package/dist/chunk-AKSBP7OO.js.map +0 -1
- package/dist/chunk-DUK5WMKJ.js.map +0 -1
- package/dist/chunk-LSLPF6OI.cjs.map +0 -1
- package/dist/chunk-PN53WGEI.cjs.map +0 -1
- package/dist/chunk-QUTUJ6P6.cjs.map +0 -1
- package/dist/chunk-XW6RXVGB.js.map +0 -1
|
@@ -1,32 +1,34 @@
|
|
|
1
|
+
import { extractCodePlugins } from './chunk-2SFBB54R.js';
|
|
1
2
|
import { submit, emitRunEvent } from './chunk-HRA3CPGG.js';
|
|
2
3
|
import { enqueueSessionWrite, hydrateSession, flushSessionWrites, appendSessionMessage, persistTurnToTranscript, getSessionMessages, clearSession } from './chunk-SQLZ7ONU.js';
|
|
4
|
+
import { FsSessionStore } from './chunk-U6QGZHPN.js';
|
|
3
5
|
import { discoverProviderPlugins, CircuitBreaker, buildDefaultSummarizer, parseSseStream, resolveProviderChain, inferProviderFromApiKey, detectPrimaryProvider, tryFirstEvent, relayStream, mapOpenAICompatibleError, renderToolResultContentText } from './chunk-NRSH7RJY.js';
|
|
4
|
-
import { IndexManager, writeSessionSummary, memoryDir, globalEmbeddingCache, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-
|
|
6
|
+
import { IndexManager, writeSessionSummary, memoryDir, globalEmbeddingCache, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-XAUBQMQU.js';
|
|
5
7
|
import { loadHookConfig, warnOnce, currentPersonalityContext, warnPersonalitySwitchInsideFork } from './chunk-XIG2IE3L.js';
|
|
6
|
-
import {
|
|
8
|
+
import { resolveChildEnv } from './chunk-7GFX45DD.js';
|
|
7
9
|
import { readVersionedJson, getTheokitHome, writeVersionedJson } from './chunk-DGRZNMTU.js';
|
|
8
|
-
import { FsSessionStore } from './chunk-U6QGZHPN.js';
|
|
9
10
|
import { sanitizeToolInput } from './chunk-U54XCYG3.js';
|
|
10
11
|
import { subAgentToolsFromDefinitions, inheritSubAgentCredentials } from './chunk-FV3YEMQ7.js';
|
|
11
12
|
import { setAgentFacade } from './chunk-6X6ID4MO.js';
|
|
12
|
-
import {
|
|
13
|
+
import { findGitRoot, DEFAULT_DISCOVERY_SPECS, walkUpForFile, walkUpForGlob } from './chunk-UJ7IQJAG.js';
|
|
13
14
|
import { withToolWhitelist, checkToolWhitelist } from './chunk-7AD3ZTZL.js';
|
|
14
15
|
import { mapWithConcurrency } from './chunk-V4XRLPEF.js';
|
|
15
16
|
import { withFileLock } from './chunk-HZQEDNF6.js';
|
|
16
17
|
import { withCwdMutex } from './chunk-2XLKLVVR.js';
|
|
17
18
|
import { defaultBaseDir, expandTilde } from './chunk-ZZWTY3RX.js';
|
|
18
19
|
import { toJsonSchema } from './chunk-4VPXM6UU.js';
|
|
20
|
+
import { atomicWriteJson } from './chunk-S2BBRVQX.js';
|
|
21
|
+
import { loadSubagents } from './chunk-BNIFFFH3.js';
|
|
19
22
|
import { resolveEffectiveContextWindow, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN } from './chunk-WA3FO4R7.js';
|
|
20
23
|
import { parseModelId } from './chunk-X2FR4OIT.js';
|
|
21
24
|
import { getCatalogModelInfo, registerBuiltins, getProviderProfile, registerProvider, isPatchedModelKey } from './chunk-KAP4GJHO.js';
|
|
22
|
-
import { escapeBlockBody, buildSkillsBlock, discoverSkills, stripSkillFrontmatter
|
|
25
|
+
import { escapeBlockBody, buildSkillsBlock, discoverSkills, stripSkillFrontmatter } from './chunk-5IB2UKSN.js';
|
|
23
26
|
import { validateArtifactPath, PathTraversalError, safePathJoin } from './chunk-POQT2OIF.js';
|
|
24
|
-
import {
|
|
25
|
-
import { atomicWriteJson } from './chunk-S2BBRVQX.js';
|
|
27
|
+
import { readWorkspaceDir, parseSimpleYaml } from './chunk-FKCC2MED.js';
|
|
26
28
|
import { AgentRunError, coerceToKnownAgentRunErrorCode, UnknownAgentError, ConfigurationError, AuthenticationError, UnsupportedRunOperationError, AgentDisposedError, NetworkError, IntegrationNotConnectedError, RateLimitError, TheokitAgentError } from './chunk-WLKFWQSJ.js';
|
|
27
29
|
import { redactSecrets } from './chunk-JTFYYKDT.js';
|
|
28
|
-
import { randomUUID, createHash } from 'crypto';
|
|
29
30
|
import { stat, mkdir, readFile, readdir, access, unlink } from 'fs/promises';
|
|
31
|
+
import { randomUUID, createHash } from 'crypto';
|
|
30
32
|
import { existsSync } from 'fs';
|
|
31
33
|
import { join, dirname, resolve, relative, isAbsolute } from 'path';
|
|
32
34
|
import { spawn } from 'child_process';
|
|
@@ -140,6 +142,140 @@ var AgentBuilder = class {
|
|
|
140
142
|
}
|
|
141
143
|
};
|
|
142
144
|
|
|
145
|
+
// src/internal/auth/api-key-validator.ts
|
|
146
|
+
var FIXTURE_KEY_PREFIX = "theo_test_";
|
|
147
|
+
var LOCAL_RUNTIME_MOCK_KEY = "local";
|
|
148
|
+
var MIN_KEY_LENGTH = 16;
|
|
149
|
+
var KNOWN_PROVIDER_PREFIXES = [
|
|
150
|
+
{ provider: "openai", prefix: "sk-" },
|
|
151
|
+
{ provider: "anthropic", prefix: "sk-ant-" },
|
|
152
|
+
{ provider: "openrouter", prefix: "sk-or-" }
|
|
153
|
+
];
|
|
154
|
+
function validateApiKeyShape(key, options = {}) {
|
|
155
|
+
const opts = typeof options === "string" ? { provider: options } : options;
|
|
156
|
+
const tier1 = checkTier1(key);
|
|
157
|
+
if (tier1.malformed) return tier1;
|
|
158
|
+
const validKey = key;
|
|
159
|
+
if (validKey.startsWith(FIXTURE_KEY_PREFIX) || validKey === LOCAL_RUNTIME_MOCK_KEY) {
|
|
160
|
+
return { malformed: false };
|
|
161
|
+
}
|
|
162
|
+
if (opts.strict === false) return { malformed: false };
|
|
163
|
+
return checkTier2(validKey, opts.provider);
|
|
164
|
+
}
|
|
165
|
+
function checkTier1(key) {
|
|
166
|
+
if (key === void 0 || key.length === 0) {
|
|
167
|
+
return { malformed: true, reason: "empty", message: "API key is empty." };
|
|
168
|
+
}
|
|
169
|
+
if (key.trim().length === 0) {
|
|
170
|
+
return {
|
|
171
|
+
malformed: true,
|
|
172
|
+
reason: "whitespace_only",
|
|
173
|
+
message: "API key contains only whitespace."
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (key.length < 4) {
|
|
177
|
+
return {
|
|
178
|
+
malformed: true,
|
|
179
|
+
reason: "too_short",
|
|
180
|
+
message: `API key must be at least 4 chars (got ${key.length}).`
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return { malformed: false };
|
|
184
|
+
}
|
|
185
|
+
function checkTier2(key, provider) {
|
|
186
|
+
if (key.length < MIN_KEY_LENGTH) {
|
|
187
|
+
return {
|
|
188
|
+
malformed: true,
|
|
189
|
+
reason: "too_short",
|
|
190
|
+
message: `API key must be at least ${MIN_KEY_LENGTH} chars (got ${key.length}).`
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
if (/\s/.test(key)) {
|
|
194
|
+
return {
|
|
195
|
+
malformed: true,
|
|
196
|
+
reason: "embedded_whitespace",
|
|
197
|
+
message: "API key contains embedded whitespace."
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return checkProviderPrefix(key, provider);
|
|
201
|
+
}
|
|
202
|
+
function checkProviderPrefix(key, provider) {
|
|
203
|
+
if (provider === void 0) return { malformed: false };
|
|
204
|
+
const hint = KNOWN_PROVIDER_PREFIXES.find((p) => p.provider === provider.toLowerCase());
|
|
205
|
+
if (hint === void 0) return { malformed: false };
|
|
206
|
+
if (!key.startsWith(hint.prefix)) {
|
|
207
|
+
return {
|
|
208
|
+
malformed: true,
|
|
209
|
+
reason: "missing_known_prefix",
|
|
210
|
+
message: `API key for provider "${hint.provider}" expected to start with "${hint.prefix}".`
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return { malformed: false };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/internal/runtime/config/default-model.ts
|
|
217
|
+
var DEFAULT_AGENTIC_MODEL_ID = "google/gemini-2.0-flash-001";
|
|
218
|
+
|
|
219
|
+
// src/agent-generate.ts
|
|
220
|
+
async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input, options) {
|
|
221
|
+
const { output, maxRetries, errorStrategy, ...sendOptions } = options;
|
|
222
|
+
const run = await agent.send(input, sendOptions);
|
|
223
|
+
const result = await run.wait();
|
|
224
|
+
const { generateObjectImpl, GenerateObjectError } = await import('./generate-object-YJPDV5BS.js');
|
|
225
|
+
const answer = structurableAnswerOrThrow(result, GenerateObjectError);
|
|
226
|
+
const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
|
|
227
|
+
const facade = getAgentFacade();
|
|
228
|
+
const structured = await generateObjectImpl(
|
|
229
|
+
{
|
|
230
|
+
prompt: answer,
|
|
231
|
+
schema: output,
|
|
232
|
+
// `agentModel` arrives already normalized (`this.model` passed through
|
|
233
|
+
// `normalizeModel` in the LocalAgent/CloudAgent constructor), so the widened
|
|
234
|
+
// `string | ModelSelection` field only ever receives a `ModelSelection` here.
|
|
235
|
+
model: agentModel ?? { id: DEFAULT_AGENTIC_MODEL_ID },
|
|
236
|
+
// `local` is required to keep the transient structuring agent local-only;
|
|
237
|
+
// default to the process cwd when the agent had no explicit local config.
|
|
238
|
+
local: agentLocal ?? { cwd: process.cwd() },
|
|
239
|
+
...agentApiKey !== void 0 ? { apiKey: agentApiKey } : {},
|
|
240
|
+
...maxRetries !== void 0 ? { maxRetries } : {},
|
|
241
|
+
...errorStrategy !== void 0 ? { errorStrategy } : {}
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
create: (opts) => facade.create(opts),
|
|
245
|
+
delete: (agentId) => facade.delete(agentId)
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
return {
|
|
249
|
+
object: structured.object,
|
|
250
|
+
result,
|
|
251
|
+
raw: structured.raw,
|
|
252
|
+
usage: structured.usage
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function structurableAnswerOrThrow(result, GenerateObjectError) {
|
|
256
|
+
if (result.status === "error") {
|
|
257
|
+
throw new GenerateObjectError(
|
|
258
|
+
"no_tool_call",
|
|
259
|
+
`Agent run failed before an answer could be structured: ${result.error?.message ?? "unknown error"} [${result.error?.code ?? "?"}]`,
|
|
260
|
+
result.error
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
if (result.status === "cancelled") {
|
|
264
|
+
throw new GenerateObjectError(
|
|
265
|
+
"no_tool_call",
|
|
266
|
+
"Agent run was cancelled before an answer could be structured."
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
const answer = result.result;
|
|
270
|
+
if (answer === void 0 || answer.length === 0) {
|
|
271
|
+
throw new GenerateObjectError(
|
|
272
|
+
"no_tool_call",
|
|
273
|
+
"The tool loop finished with no text answer (tool-only completion) \u2014 there is nothing to structure."
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
return answer;
|
|
277
|
+
}
|
|
278
|
+
|
|
143
279
|
// src/internal/env.ts
|
|
144
280
|
var API_KEY_ENV_VAR = "THEOKIT_API_KEY";
|
|
145
281
|
function resolveApiKey(explicit) {
|
|
@@ -181,600 +317,49 @@ function generateRequestId() {
|
|
|
181
317
|
function isLocalAgentId(id) {
|
|
182
318
|
return id.startsWith(PREFIX.localAgent);
|
|
183
319
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const raw = spec.sanitize ? sanitizeToolInput(input, {
|
|
189
|
-
...spec.sanitize === true ? {} : spec.sanitize,
|
|
190
|
-
schema: spec.inputSchema
|
|
191
|
-
}).value : input;
|
|
192
|
-
const parsed = spec.inputSchema.parse(raw);
|
|
193
|
-
const out = await spec.handler(parsed, ctx);
|
|
194
|
-
return spec.outputSchema === void 0 ? out : spec.outputSchema.parse(out);
|
|
320
|
+
var FIXTURE_API_KEY_PREFIX = "theo_test_";
|
|
321
|
+
function isFixtureApiKey(apiKey) {
|
|
322
|
+
if (apiKey === void 0) return false;
|
|
323
|
+
return apiKey.startsWith(FIXTURE_API_KEY_PREFIX);
|
|
195
324
|
}
|
|
196
|
-
function
|
|
197
|
-
|
|
325
|
+
function getConfiguredBaseUrl() {
|
|
326
|
+
const value = process.env.THEOKIT_API_BASE_URL;
|
|
327
|
+
if (value === void 0 || value.length === 0) return void 0;
|
|
328
|
+
return value;
|
|
198
329
|
}
|
|
199
|
-
function
|
|
200
|
-
if (
|
|
201
|
-
return
|
|
330
|
+
function shouldUseFixtureMode(apiKey) {
|
|
331
|
+
if (getConfiguredBaseUrl() !== void 0) return false;
|
|
332
|
+
return isFixtureApiKey(apiKey);
|
|
202
333
|
}
|
|
203
|
-
|
|
204
|
-
|
|
334
|
+
function shouldUseRealLocalRuntime(apiKey) {
|
|
335
|
+
if (isFixtureApiKey(apiKey)) return false;
|
|
336
|
+
if (apiKey === void 0 || apiKey.length === 0) return false;
|
|
337
|
+
return typeof process.env.ANTHROPIC_API_KEY === "string" && process.env.ANTHROPIC_API_KEY.length > 0 || typeof process.env.OPENAI_API_KEY === "string" && process.env.OPENAI_API_KEY.length > 0 || typeof process.env.OPENROUTER_API_KEY === "string" && process.env.OPENROUTER_API_KEY.length > 0 || isAwsBedrockAuthAvailable() || isGcpVertexAuthAvailable() || isLocalNoAuthProviderAvailable();
|
|
338
|
+
}
|
|
339
|
+
function isAwsBedrockAuthAvailable() {
|
|
340
|
+
if (typeof process.env.AWS_BEARER_TOKEN_BEDROCK === "string" && process.env.AWS_BEARER_TOKEN_BEDROCK.length > 0) {
|
|
341
|
+
return true;
|
|
205
342
|
}
|
|
206
|
-
|
|
207
|
-
return
|
|
343
|
+
if (typeof process.env.AWS_ACCESS_KEY_ID === "string" && process.env.AWS_ACCESS_KEY_ID.length > 0) {
|
|
344
|
+
return true;
|
|
208
345
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const inputSchema = toJsonSchema(spec.inputSchema, {
|
|
212
|
-
unrepresentable: "any"
|
|
213
|
-
});
|
|
214
|
-
const handler = async (input, ctx) => {
|
|
215
|
-
const validated = await runValidated(spec, input, ctx);
|
|
216
|
-
return shapeModelOutput(spec, validated);
|
|
217
|
-
};
|
|
218
|
-
const tool = { name: spec.name, description: spec.description, inputSchema, handler };
|
|
219
|
-
if (spec.toModelOutput !== void 0) {
|
|
220
|
-
const resolver = async (input, ctx) => {
|
|
221
|
-
const validated = await runValidated(spec, input, ctx);
|
|
222
|
-
return { model: shapeModelOutput(spec, validated), app: serializeOutput(validated) };
|
|
223
|
-
};
|
|
224
|
-
handler[TOOL_SPLIT_RESOLVER] = resolver;
|
|
346
|
+
if (typeof process.env.AWS_PROFILE === "string" && process.env.AWS_PROFILE.length > 0) {
|
|
347
|
+
return true;
|
|
225
348
|
}
|
|
226
|
-
return
|
|
349
|
+
return awsCredentialsFileExists();
|
|
227
350
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
reasoning = 0;
|
|
236
|
-
requests = [];
|
|
237
|
-
add(step) {
|
|
238
|
-
const inputTokens = step.inputTokens ?? 0;
|
|
239
|
-
const outputTokens = step.outputTokens ?? 0;
|
|
240
|
-
const cacheReadTokens = step.cacheReadTokens ?? 0;
|
|
241
|
-
const cacheWriteTokens = step.cacheWriteTokens ?? 0;
|
|
242
|
-
const reasoningTokens = step.reasoningTokens ?? 0;
|
|
243
|
-
this.input += inputTokens;
|
|
244
|
-
this.output += outputTokens;
|
|
245
|
-
this.cacheRead += cacheReadTokens;
|
|
246
|
-
this.cacheWrite += cacheWriteTokens;
|
|
247
|
-
this.reasoning += reasoningTokens;
|
|
248
|
-
this.requests.push({
|
|
249
|
-
inputTokens,
|
|
250
|
-
outputTokens,
|
|
251
|
-
...cacheReadTokens > 0 ? { cacheReadTokens } : {},
|
|
252
|
-
...cacheWriteTokens > 0 ? { cacheWriteTokens } : {},
|
|
253
|
-
...reasoningTokens > 0 ? { reasoningTokens } : {},
|
|
254
|
-
totalTokens: inputTokens + outputTokens
|
|
255
|
-
});
|
|
351
|
+
function awsCredentialsFileExists() {
|
|
352
|
+
try {
|
|
353
|
+
const home = process.env.HOME ?? process.env.USERPROFILE;
|
|
354
|
+
if (home === void 0 || home.length === 0) return false;
|
|
355
|
+
return existsSync(`${home}/.aws/credentials`) || existsSync(`${home}/.aws/config`);
|
|
356
|
+
} catch {
|
|
357
|
+
return false;
|
|
256
358
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
toTokenUsage() {
|
|
262
|
-
return {
|
|
263
|
-
inputTokens: this.input,
|
|
264
|
-
outputTokens: this.output,
|
|
265
|
-
...this.cacheRead > 0 ? { cacheReadTokens: this.cacheRead } : {},
|
|
266
|
-
...this.cacheWrite > 0 ? { cacheWriteTokens: this.cacheWrite } : {},
|
|
267
|
-
...this.reasoning > 0 ? { reasoningTokens: this.reasoning } : {},
|
|
268
|
-
totalTokens: this.input + this.output,
|
|
269
|
-
...this.requests.length > 1 ? { requests: this.requests.slice() } : {}
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
// src/tool-error.ts
|
|
275
|
-
var ToolError = class extends TheokitAgentError {
|
|
276
|
-
name = "ToolError";
|
|
277
|
-
/** The error content surfaced to the model: a string, or text/image blocks. */
|
|
278
|
-
content;
|
|
279
|
-
constructor(content, options = {}) {
|
|
280
|
-
super(renderToolErrorMessage(content), { ...options, isRetryable: false });
|
|
281
|
-
this.content = content;
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
function renderToolErrorMessage(content) {
|
|
285
|
-
if (typeof content === "string") return content;
|
|
286
|
-
return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// src/internal/budget/pricing-data.json
|
|
290
|
-
var pricing_data_default = {
|
|
291
|
-
_meta: {
|
|
292
|
-
pricingVersion: "litellm-2026-05-snapshot"},
|
|
293
|
-
models: {
|
|
294
|
-
"anthropic/claude-opus-4-7": {
|
|
295
|
-
input: 5,
|
|
296
|
-
output: 25,
|
|
297
|
-
cacheRead: 0.5,
|
|
298
|
-
cacheWrite: 6.25
|
|
299
|
-
},
|
|
300
|
-
"anthropic/claude-opus-4-6": {
|
|
301
|
-
input: 5,
|
|
302
|
-
output: 25,
|
|
303
|
-
cacheRead: 0.5,
|
|
304
|
-
cacheWrite: 6.25
|
|
305
|
-
},
|
|
306
|
-
"anthropic/claude-opus-4-5": {
|
|
307
|
-
input: 5,
|
|
308
|
-
output: 25,
|
|
309
|
-
cacheRead: 0.5,
|
|
310
|
-
cacheWrite: 6.25
|
|
311
|
-
},
|
|
312
|
-
"anthropic/claude-sonnet-4-6": {
|
|
313
|
-
input: 3,
|
|
314
|
-
output: 15,
|
|
315
|
-
cacheRead: 0.3,
|
|
316
|
-
cacheWrite: 3.75
|
|
317
|
-
},
|
|
318
|
-
"anthropic/claude-sonnet-4-5": {
|
|
319
|
-
input: 3,
|
|
320
|
-
output: 15,
|
|
321
|
-
cacheRead: 0.3,
|
|
322
|
-
cacheWrite: 3.75
|
|
323
|
-
},
|
|
324
|
-
"anthropic/claude-haiku-4-5": {
|
|
325
|
-
input: 1,
|
|
326
|
-
output: 5,
|
|
327
|
-
cacheRead: 0.1,
|
|
328
|
-
cacheWrite: 1.25
|
|
329
|
-
},
|
|
330
|
-
"anthropic/claude-3-5-sonnet": {
|
|
331
|
-
input: 3,
|
|
332
|
-
output: 15,
|
|
333
|
-
cacheRead: 0.3,
|
|
334
|
-
cacheWrite: 3.75
|
|
335
|
-
},
|
|
336
|
-
"anthropic/claude-3-5-haiku": {
|
|
337
|
-
input: 0.8,
|
|
338
|
-
output: 4,
|
|
339
|
-
cacheRead: 0.08,
|
|
340
|
-
cacheWrite: 1
|
|
341
|
-
},
|
|
342
|
-
"anthropic/claude-3-opus": {
|
|
343
|
-
input: 15,
|
|
344
|
-
output: 75,
|
|
345
|
-
cacheRead: 1.5,
|
|
346
|
-
cacheWrite: 18.75
|
|
347
|
-
},
|
|
348
|
-
"anthropic/claude-3-haiku": {
|
|
349
|
-
input: 0.25,
|
|
350
|
-
output: 1.25,
|
|
351
|
-
cacheRead: 0.03,
|
|
352
|
-
cacheWrite: 0.3
|
|
353
|
-
},
|
|
354
|
-
"openai/gpt-4o": {
|
|
355
|
-
input: 2.5,
|
|
356
|
-
output: 10,
|
|
357
|
-
cacheRead: 1.25
|
|
358
|
-
},
|
|
359
|
-
"openai/gpt-4o-mini": {
|
|
360
|
-
input: 0.15,
|
|
361
|
-
output: 0.6,
|
|
362
|
-
cacheRead: 0.075
|
|
363
|
-
},
|
|
364
|
-
"openai/gpt-4.1": {
|
|
365
|
-
input: 2,
|
|
366
|
-
output: 8,
|
|
367
|
-
cacheRead: 0.5
|
|
368
|
-
},
|
|
369
|
-
"openai/gpt-4.1-mini": {
|
|
370
|
-
input: 0.4,
|
|
371
|
-
output: 1.6,
|
|
372
|
-
cacheRead: 0.1
|
|
373
|
-
},
|
|
374
|
-
"openai/gpt-4.1-nano": {
|
|
375
|
-
input: 0.1,
|
|
376
|
-
output: 0.4,
|
|
377
|
-
cacheRead: 0.025
|
|
378
|
-
},
|
|
379
|
-
"openai/o3": {
|
|
380
|
-
input: 2,
|
|
381
|
-
output: 8,
|
|
382
|
-
cacheRead: 0.5
|
|
383
|
-
},
|
|
384
|
-
"openai/o3-mini": {
|
|
385
|
-
input: 1.1,
|
|
386
|
-
output: 4.4,
|
|
387
|
-
cacheRead: 0.55
|
|
388
|
-
},
|
|
389
|
-
"openai/o4-mini": {
|
|
390
|
-
input: 1.1,
|
|
391
|
-
output: 4.4,
|
|
392
|
-
cacheRead: 0.275
|
|
393
|
-
},
|
|
394
|
-
"deepseek/deepseek-chat": {
|
|
395
|
-
input: 0.14,
|
|
396
|
-
output: 0.28
|
|
397
|
-
},
|
|
398
|
-
"deepseek/deepseek-reasoner": {
|
|
399
|
-
input: 0.55,
|
|
400
|
-
output: 2.19
|
|
401
|
-
},
|
|
402
|
-
"google/gemini-2.5-pro": {
|
|
403
|
-
input: 1.25,
|
|
404
|
-
output: 10
|
|
405
|
-
},
|
|
406
|
-
"google/gemini-2.5-flash": {
|
|
407
|
-
input: 0.15,
|
|
408
|
-
output: 0.6
|
|
409
|
-
},
|
|
410
|
-
"google/gemini-2.0-flash": {
|
|
411
|
-
input: 0.1,
|
|
412
|
-
output: 0.4
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
// src/internal/budget/pricing-registry.ts
|
|
418
|
-
var data = pricing_data_default;
|
|
419
|
-
function buildEntry(key, raw) {
|
|
420
|
-
const [provider, ...modelParts] = key.split("/");
|
|
421
|
-
return {
|
|
422
|
-
provider: provider ?? "unknown",
|
|
423
|
-
model: modelParts.join("/"),
|
|
424
|
-
inputCostPerMillion: raw.input,
|
|
425
|
-
outputCostPerMillion: raw.output,
|
|
426
|
-
...raw.cacheRead !== void 0 ? { cacheReadCostPerMillion: raw.cacheRead } : {},
|
|
427
|
-
...raw.cacheWrite !== void 0 ? { cacheWriteCostPerMillion: raw.cacheWrite } : {},
|
|
428
|
-
...raw.reasoning !== void 0 ? { reasoningCostPerMillion: raw.reasoning } : {},
|
|
429
|
-
pricingVersion: data._meta.pricingVersion
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
function stripDateSuffix(model) {
|
|
433
|
-
return model.replace(/-\d{4}-?\d{2}-?\d{2}$/, "");
|
|
434
|
-
}
|
|
435
|
-
function normalizeAnthropicDots(model) {
|
|
436
|
-
return model.replace(/(\d+)\.(\d+)/g, "$1-$2");
|
|
437
|
-
}
|
|
438
|
-
function stripOpenRouterPrefix(modelId) {
|
|
439
|
-
return modelId.startsWith("openrouter/") ? modelId.slice("openrouter/".length) : modelId;
|
|
440
|
-
}
|
|
441
|
-
function lookupRaw(key) {
|
|
442
|
-
return data.models[key];
|
|
443
|
-
}
|
|
444
|
-
function getPricingEntry(opts) {
|
|
445
|
-
const cleaned = stripOpenRouterPrefix(opts.model);
|
|
446
|
-
const directKey = `${opts.provider}/${cleaned}`;
|
|
447
|
-
const direct = lookupRaw(directKey);
|
|
448
|
-
if (direct !== void 0) return buildEntry(directKey, direct);
|
|
449
|
-
const noSuffix = stripDateSuffix(cleaned);
|
|
450
|
-
if (noSuffix !== cleaned) {
|
|
451
|
-
const noSuffixKey = `${opts.provider}/${noSuffix}`;
|
|
452
|
-
const found = lookupRaw(noSuffixKey);
|
|
453
|
-
if (found !== void 0) return buildEntry(noSuffixKey, found);
|
|
454
|
-
}
|
|
455
|
-
if (opts.provider === "anthropic") {
|
|
456
|
-
const normalized = normalizeAnthropicDots(stripDateSuffix(cleaned));
|
|
457
|
-
const normKey = `${opts.provider}/${normalized}`;
|
|
458
|
-
const found = lookupRaw(normKey);
|
|
459
|
-
if (found !== void 0) return buildEntry(normKey, found);
|
|
460
|
-
}
|
|
461
|
-
if (cleaned.includes("/")) {
|
|
462
|
-
const found = lookupRaw(cleaned);
|
|
463
|
-
if (found !== void 0) return buildEntry(cleaned, found);
|
|
464
|
-
const stripped = stripDateSuffix(cleaned);
|
|
465
|
-
if (stripped !== cleaned) {
|
|
466
|
-
const found2 = lookupRaw(stripped);
|
|
467
|
-
if (found2 !== void 0) return buildEntry(stripped, found2);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
const catalogEntry = catalogCostFallback(opts.provider, cleaned);
|
|
471
|
-
if (catalogEntry !== void 0) return catalogEntry;
|
|
472
|
-
return void 0;
|
|
473
|
-
}
|
|
474
|
-
function catalogCostFallback(provider, cleanedModel) {
|
|
475
|
-
const stripped = stripDateSuffix(cleanedModel);
|
|
476
|
-
const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
|
|
477
|
-
if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
|
|
478
|
-
for (const key of candidates) {
|
|
479
|
-
const info = getCatalogModelInfo(key);
|
|
480
|
-
const cost = info?.cost;
|
|
481
|
-
if (cost === void 0) continue;
|
|
482
|
-
const [prov, ...modelParts] = key.split("/");
|
|
483
|
-
return {
|
|
484
|
-
provider: prov ?? provider,
|
|
485
|
-
model: modelParts.join("/") || cleanedModel,
|
|
486
|
-
inputCostPerMillion: cost.input,
|
|
487
|
-
outputCostPerMillion: cost.output,
|
|
488
|
-
...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
|
|
489
|
-
...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
|
|
490
|
-
// M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
|
|
491
|
-
pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
return void 0;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// src/internal/budget/compute-cost.ts
|
|
498
|
-
var MICROCENT = 1e6;
|
|
499
|
-
function isSubscriptionIncluded(provider) {
|
|
500
|
-
return provider === "openai-codex" || provider === "codex";
|
|
501
|
-
}
|
|
502
|
-
function pricingHasValidRates(entry) {
|
|
503
|
-
return entry.inputCostPerMillion >= 0 && entry.outputCostPerMillion >= 0 && (entry.cacheReadCostPerMillion === void 0 || entry.cacheReadCostPerMillion >= 0) && (entry.cacheWriteCostPerMillion === void 0 || entry.cacheWriteCostPerMillion >= 0) && (entry.reasoningCostPerMillion === void 0 || entry.reasoningCostPerMillion >= 0);
|
|
504
|
-
}
|
|
505
|
-
function costForTokens(tokens, perMillion) {
|
|
506
|
-
if (tokens === 0 || perMillion === 0) return 0;
|
|
507
|
-
return Math.round(tokens * perMillion * MICROCENT / 1e6) / MICROCENT;
|
|
508
|
-
}
|
|
509
|
-
function computeCost(args) {
|
|
510
|
-
if (isSubscriptionIncluded(args.provider)) {
|
|
511
|
-
return {
|
|
512
|
-
amountUsd: 0,
|
|
513
|
-
status: "included",
|
|
514
|
-
currency: "USD",
|
|
515
|
-
source: "subscription_included",
|
|
516
|
-
pricingVersion: void 0
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
const entry = getPricingEntry({
|
|
520
|
-
provider: args.provider,
|
|
521
|
-
model: args.model,
|
|
522
|
-
...args.baseUrl !== void 0 ? { baseUrl: args.baseUrl } : {}
|
|
523
|
-
});
|
|
524
|
-
if (entry === void 0) {
|
|
525
|
-
return {
|
|
526
|
-
amountUsd: void 0,
|
|
527
|
-
status: "unknown",
|
|
528
|
-
currency: "USD",
|
|
529
|
-
source: "unknown",
|
|
530
|
-
pricingVersion: void 0
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
if (!pricingHasValidRates(entry)) {
|
|
534
|
-
return {
|
|
535
|
-
amountUsd: void 0,
|
|
536
|
-
status: "unknown",
|
|
537
|
-
currency: "USD",
|
|
538
|
-
source: "unknown",
|
|
539
|
-
pricingVersion: entry.pricingVersion,
|
|
540
|
-
notes: ["pricing entry has negative rates; treated as invalid"]
|
|
541
|
-
};
|
|
542
|
-
}
|
|
543
|
-
const notes = [];
|
|
544
|
-
const detail = {};
|
|
545
|
-
const u = args.usage;
|
|
546
|
-
const inputCost = costForTokens(u.inputTokens, entry.inputCostPerMillion);
|
|
547
|
-
const outputCost = costForTokens(u.outputTokens, entry.outputCostPerMillion);
|
|
548
|
-
detail.input = inputCost;
|
|
549
|
-
detail.output = outputCost;
|
|
550
|
-
let total = inputCost + outputCost;
|
|
551
|
-
if (u.cacheReadTokens !== void 0 && u.cacheReadTokens > 0) {
|
|
552
|
-
if (entry.cacheReadCostPerMillion === void 0) {
|
|
553
|
-
return {
|
|
554
|
-
amountUsd: void 0,
|
|
555
|
-
status: "unknown",
|
|
556
|
-
currency: "USD",
|
|
557
|
-
source: "litellm_snapshot",
|
|
558
|
-
pricingVersion: entry.pricingVersion,
|
|
559
|
-
notes: ["cache-read tokens present but cacheReadCostPerMillion is undefined"]
|
|
560
|
-
};
|
|
561
|
-
}
|
|
562
|
-
const c = costForTokens(u.cacheReadTokens, entry.cacheReadCostPerMillion);
|
|
563
|
-
detail.cacheRead = c;
|
|
564
|
-
total += c;
|
|
565
|
-
}
|
|
566
|
-
if (u.cacheWriteTokens !== void 0 && u.cacheWriteTokens > 0) {
|
|
567
|
-
if (entry.cacheWriteCostPerMillion === void 0) {
|
|
568
|
-
return {
|
|
569
|
-
amountUsd: void 0,
|
|
570
|
-
status: "unknown",
|
|
571
|
-
currency: "USD",
|
|
572
|
-
source: "litellm_snapshot",
|
|
573
|
-
pricingVersion: entry.pricingVersion,
|
|
574
|
-
notes: ["cache-write tokens present but cacheWriteCostPerMillion is undefined"]
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
const c = costForTokens(u.cacheWriteTokens, entry.cacheWriteCostPerMillion);
|
|
578
|
-
detail.cacheWrite = c;
|
|
579
|
-
total += c;
|
|
580
|
-
}
|
|
581
|
-
if (u.reasoningTokens !== void 0 && u.reasoningTokens > 0) {
|
|
582
|
-
const rate = entry.reasoningCostPerMillion ?? entry.outputCostPerMillion;
|
|
583
|
-
const c = costForTokens(u.reasoningTokens, rate);
|
|
584
|
-
detail.reasoning = c;
|
|
585
|
-
total += c;
|
|
586
|
-
if (entry.reasoningCostPerMillion === void 0) {
|
|
587
|
-
notes.push("reasoning tokens billed at output rate (no dedicated reasoning rate available)");
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
const amountUsd = Math.round(total * MICROCENT) / MICROCENT;
|
|
591
|
-
return {
|
|
592
|
-
amountUsd,
|
|
593
|
-
status: "estimated",
|
|
594
|
-
currency: "USD",
|
|
595
|
-
source: "litellm_snapshot",
|
|
596
|
-
pricingVersion: entry.pricingVersion,
|
|
597
|
-
...notes.length > 0 ? { notes } : {},
|
|
598
|
-
detail
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// src/internal/auth/api-key-validator.ts
|
|
603
|
-
var FIXTURE_KEY_PREFIX = "theo_test_";
|
|
604
|
-
var LOCAL_RUNTIME_MOCK_KEY = "local";
|
|
605
|
-
var MIN_KEY_LENGTH = 16;
|
|
606
|
-
var KNOWN_PROVIDER_PREFIXES = [
|
|
607
|
-
{ provider: "openai", prefix: "sk-" },
|
|
608
|
-
{ provider: "anthropic", prefix: "sk-ant-" },
|
|
609
|
-
{ provider: "openrouter", prefix: "sk-or-" }
|
|
610
|
-
];
|
|
611
|
-
function validateApiKeyShape(key, options = {}) {
|
|
612
|
-
const opts = typeof options === "string" ? { provider: options } : options;
|
|
613
|
-
const tier1 = checkTier1(key);
|
|
614
|
-
if (tier1.malformed) return tier1;
|
|
615
|
-
const validKey = key;
|
|
616
|
-
if (validKey.startsWith(FIXTURE_KEY_PREFIX) || validKey === LOCAL_RUNTIME_MOCK_KEY) {
|
|
617
|
-
return { malformed: false };
|
|
618
|
-
}
|
|
619
|
-
if (opts.strict === false) return { malformed: false };
|
|
620
|
-
return checkTier2(validKey, opts.provider);
|
|
621
|
-
}
|
|
622
|
-
function checkTier1(key) {
|
|
623
|
-
if (key === void 0 || key.length === 0) {
|
|
624
|
-
return { malformed: true, reason: "empty", message: "API key is empty." };
|
|
625
|
-
}
|
|
626
|
-
if (key.trim().length === 0) {
|
|
627
|
-
return {
|
|
628
|
-
malformed: true,
|
|
629
|
-
reason: "whitespace_only",
|
|
630
|
-
message: "API key contains only whitespace."
|
|
631
|
-
};
|
|
632
|
-
}
|
|
633
|
-
if (key.length < 4) {
|
|
634
|
-
return {
|
|
635
|
-
malformed: true,
|
|
636
|
-
reason: "too_short",
|
|
637
|
-
message: `API key must be at least 4 chars (got ${key.length}).`
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
return { malformed: false };
|
|
641
|
-
}
|
|
642
|
-
function checkTier2(key, provider) {
|
|
643
|
-
if (key.length < MIN_KEY_LENGTH) {
|
|
644
|
-
return {
|
|
645
|
-
malformed: true,
|
|
646
|
-
reason: "too_short",
|
|
647
|
-
message: `API key must be at least ${MIN_KEY_LENGTH} chars (got ${key.length}).`
|
|
648
|
-
};
|
|
649
|
-
}
|
|
650
|
-
if (/\s/.test(key)) {
|
|
651
|
-
return {
|
|
652
|
-
malformed: true,
|
|
653
|
-
reason: "embedded_whitespace",
|
|
654
|
-
message: "API key contains embedded whitespace."
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
return checkProviderPrefix(key, provider);
|
|
658
|
-
}
|
|
659
|
-
function checkProviderPrefix(key, provider) {
|
|
660
|
-
if (provider === void 0) return { malformed: false };
|
|
661
|
-
const hint = KNOWN_PROVIDER_PREFIXES.find((p) => p.provider === provider.toLowerCase());
|
|
662
|
-
if (hint === void 0) return { malformed: false };
|
|
663
|
-
if (!key.startsWith(hint.prefix)) {
|
|
664
|
-
return {
|
|
665
|
-
malformed: true,
|
|
666
|
-
reason: "missing_known_prefix",
|
|
667
|
-
message: `API key for provider "${hint.provider}" expected to start with "${hint.prefix}".`
|
|
668
|
-
};
|
|
669
|
-
}
|
|
670
|
-
return { malformed: false };
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
// src/internal/runtime/config/default-model.ts
|
|
674
|
-
var DEFAULT_AGENTIC_MODEL_ID = "google/gemini-2.0-flash-001";
|
|
675
|
-
|
|
676
|
-
// src/agent-generate.ts
|
|
677
|
-
async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input, options) {
|
|
678
|
-
const { output, maxRetries, errorStrategy, ...sendOptions } = options;
|
|
679
|
-
const run = await agent.send(input, sendOptions);
|
|
680
|
-
const result = await run.wait();
|
|
681
|
-
const { generateObjectImpl, GenerateObjectError } = await import('./generate-object-YJPDV5BS.js');
|
|
682
|
-
const answer = structurableAnswerOrThrow(result, GenerateObjectError);
|
|
683
|
-
const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
|
|
684
|
-
const facade = getAgentFacade();
|
|
685
|
-
const structured = await generateObjectImpl(
|
|
686
|
-
{
|
|
687
|
-
prompt: answer,
|
|
688
|
-
schema: output,
|
|
689
|
-
// `agentModel` arrives already normalized (`this.model` passed through
|
|
690
|
-
// `normalizeModel` in the LocalAgent/CloudAgent constructor), so the widened
|
|
691
|
-
// `string | ModelSelection` field only ever receives a `ModelSelection` here.
|
|
692
|
-
model: agentModel ?? { id: DEFAULT_AGENTIC_MODEL_ID },
|
|
693
|
-
// `local` is required to keep the transient structuring agent local-only;
|
|
694
|
-
// default to the process cwd when the agent had no explicit local config.
|
|
695
|
-
local: agentLocal ?? { cwd: process.cwd() },
|
|
696
|
-
...agentApiKey !== void 0 ? { apiKey: agentApiKey } : {},
|
|
697
|
-
...maxRetries !== void 0 ? { maxRetries } : {},
|
|
698
|
-
...errorStrategy !== void 0 ? { errorStrategy } : {}
|
|
699
|
-
},
|
|
700
|
-
{
|
|
701
|
-
create: (opts) => facade.create(opts),
|
|
702
|
-
delete: (agentId) => facade.delete(agentId)
|
|
703
|
-
}
|
|
704
|
-
);
|
|
705
|
-
return {
|
|
706
|
-
object: structured.object,
|
|
707
|
-
result,
|
|
708
|
-
raw: structured.raw,
|
|
709
|
-
usage: structured.usage
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
function structurableAnswerOrThrow(result, GenerateObjectError) {
|
|
713
|
-
if (result.status === "error") {
|
|
714
|
-
throw new GenerateObjectError(
|
|
715
|
-
"no_tool_call",
|
|
716
|
-
`Agent run failed before an answer could be structured: ${result.error?.message ?? "unknown error"} [${result.error?.code ?? "?"}]`,
|
|
717
|
-
result.error
|
|
718
|
-
);
|
|
719
|
-
}
|
|
720
|
-
if (result.status === "cancelled") {
|
|
721
|
-
throw new GenerateObjectError(
|
|
722
|
-
"no_tool_call",
|
|
723
|
-
"Agent run was cancelled before an answer could be structured."
|
|
724
|
-
);
|
|
725
|
-
}
|
|
726
|
-
const answer = result.result;
|
|
727
|
-
if (answer === void 0 || answer.length === 0) {
|
|
728
|
-
throw new GenerateObjectError(
|
|
729
|
-
"no_tool_call",
|
|
730
|
-
"The tool loop finished with no text answer (tool-only completion) \u2014 there is nothing to structure."
|
|
731
|
-
);
|
|
732
|
-
}
|
|
733
|
-
return answer;
|
|
734
|
-
}
|
|
735
|
-
var FIXTURE_API_KEY_PREFIX = "theo_test_";
|
|
736
|
-
function isFixtureApiKey(apiKey) {
|
|
737
|
-
if (apiKey === void 0) return false;
|
|
738
|
-
return apiKey.startsWith(FIXTURE_API_KEY_PREFIX);
|
|
739
|
-
}
|
|
740
|
-
function getConfiguredBaseUrl() {
|
|
741
|
-
const value = process.env.THEOKIT_API_BASE_URL;
|
|
742
|
-
if (value === void 0 || value.length === 0) return void 0;
|
|
743
|
-
return value;
|
|
744
|
-
}
|
|
745
|
-
function shouldUseFixtureMode(apiKey) {
|
|
746
|
-
if (getConfiguredBaseUrl() !== void 0) return false;
|
|
747
|
-
return isFixtureApiKey(apiKey);
|
|
748
|
-
}
|
|
749
|
-
function shouldUseRealLocalRuntime(apiKey) {
|
|
750
|
-
if (isFixtureApiKey(apiKey)) return false;
|
|
751
|
-
if (apiKey === void 0 || apiKey.length === 0) return false;
|
|
752
|
-
return typeof process.env.ANTHROPIC_API_KEY === "string" && process.env.ANTHROPIC_API_KEY.length > 0 || typeof process.env.OPENAI_API_KEY === "string" && process.env.OPENAI_API_KEY.length > 0 || typeof process.env.OPENROUTER_API_KEY === "string" && process.env.OPENROUTER_API_KEY.length > 0 || isAwsBedrockAuthAvailable() || isGcpVertexAuthAvailable() || isLocalNoAuthProviderAvailable();
|
|
753
|
-
}
|
|
754
|
-
function isAwsBedrockAuthAvailable() {
|
|
755
|
-
if (typeof process.env.AWS_BEARER_TOKEN_BEDROCK === "string" && process.env.AWS_BEARER_TOKEN_BEDROCK.length > 0) {
|
|
756
|
-
return true;
|
|
757
|
-
}
|
|
758
|
-
if (typeof process.env.AWS_ACCESS_KEY_ID === "string" && process.env.AWS_ACCESS_KEY_ID.length > 0) {
|
|
759
|
-
return true;
|
|
760
|
-
}
|
|
761
|
-
if (typeof process.env.AWS_PROFILE === "string" && process.env.AWS_PROFILE.length > 0) {
|
|
762
|
-
return true;
|
|
763
|
-
}
|
|
764
|
-
return awsCredentialsFileExists();
|
|
765
|
-
}
|
|
766
|
-
function awsCredentialsFileExists() {
|
|
767
|
-
try {
|
|
768
|
-
const home = process.env.HOME ?? process.env.USERPROFILE;
|
|
769
|
-
if (home === void 0 || home.length === 0) return false;
|
|
770
|
-
return existsSync(`${home}/.aws/credentials`) || existsSync(`${home}/.aws/config`);
|
|
771
|
-
} catch {
|
|
772
|
-
return false;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
function isGcpVertexAuthAvailable() {
|
|
776
|
-
if (typeof process.env.GOOGLE_APPLICATION_CREDENTIALS === "string" && process.env.GOOGLE_APPLICATION_CREDENTIALS.length > 0) {
|
|
777
|
-
return true;
|
|
359
|
+
}
|
|
360
|
+
function isGcpVertexAuthAvailable() {
|
|
361
|
+
if (typeof process.env.GOOGLE_APPLICATION_CREDENTIALS === "string" && process.env.GOOGLE_APPLICATION_CREDENTIALS.length > 0) {
|
|
362
|
+
return true;
|
|
778
363
|
}
|
|
779
364
|
if (typeof process.env.GOOGLE_CLOUD_PROJECT === "string" && process.env.GOOGLE_CLOUD_PROJECT.length > 0) {
|
|
780
365
|
return true;
|
|
@@ -3382,126 +2967,52 @@ var LiveAgentRegistry = class {
|
|
|
3382
2967
|
}
|
|
3383
2968
|
};
|
|
3384
2969
|
var liveAgentRegistry = new LiveAgentRegistry();
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
}
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
}
|
|
3397
|
-
}
|
|
3398
|
-
return result;
|
|
3399
|
-
}
|
|
3400
|
-
async function readProjectSubagents(cwd) {
|
|
3401
|
-
const root = join(cwd, ".theokit", "agents");
|
|
3402
|
-
const entries = await readWorkspaceDir(root, "subagents_read_error", "subagents directory");
|
|
3403
|
-
const subagents = {};
|
|
3404
|
-
for (const entry of entries) {
|
|
3405
|
-
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
3406
|
-
const path = join(root, entry.name);
|
|
3407
|
-
const raw = await readFile(path, "utf8");
|
|
3408
|
-
const definition = parseSubagentMarkdown(raw, entry.name);
|
|
3409
|
-
subagents[definition.name] = definition.definition;
|
|
3410
|
-
}
|
|
3411
|
-
return subagents;
|
|
3412
|
-
}
|
|
3413
|
-
var ACCEPTED_FIELDS = /* @__PURE__ */ new Set([
|
|
3414
|
-
"name",
|
|
3415
|
-
"description",
|
|
3416
|
-
"model",
|
|
3417
|
-
"tools",
|
|
3418
|
-
"reasoning_effort",
|
|
3419
|
-
"mcp",
|
|
3420
|
-
"sandbox"
|
|
3421
|
-
]);
|
|
3422
|
-
function parseSubagentMarkdown(raw, filename) {
|
|
3423
|
-
const { frontmatter, body } = splitFrontmatter(raw, filename);
|
|
3424
|
-
const fields = parseFrontmatterFields(frontmatter);
|
|
3425
|
-
rejectUnknownFields(fields, filename);
|
|
3426
|
-
rejectMcp(fields, filename);
|
|
3427
|
-
const definition = {
|
|
3428
|
-
description: asString(fields.description) ?? "",
|
|
3429
|
-
prompt: body
|
|
3430
|
-
};
|
|
3431
|
-
const model = resolveModel(fields, filename);
|
|
3432
|
-
if (model !== void 0) definition.model = model;
|
|
3433
|
-
const tools = toStringList(fields.tools);
|
|
3434
|
-
if (tools.length > 0) definition.tools = tools;
|
|
3435
|
-
const sandbox = resolveSandbox(fields, filename);
|
|
3436
|
-
if (sandbox !== void 0) definition.sandbox = sandbox;
|
|
3437
|
-
const name = asString(fields.name) ?? filename.replace(/\.md$/, "");
|
|
3438
|
-
return { name, definition };
|
|
3439
|
-
}
|
|
3440
|
-
function rejectUnknownFields(fields, filename) {
|
|
3441
|
-
for (const key of Object.keys(fields)) {
|
|
3442
|
-
if (!ACCEPTED_FIELDS.has(key)) {
|
|
3443
|
-
throw new ConfigurationError(
|
|
3444
|
-
`Subagent ${filename}: unknown frontmatter field "${key}" (accepted: ${[...ACCEPTED_FIELDS].join(", ")})`,
|
|
3445
|
-
{ code: "subagent_unknown_field" }
|
|
3446
|
-
);
|
|
3447
|
-
}
|
|
3448
|
-
}
|
|
2970
|
+
|
|
2971
|
+
// src/define-tool.ts
|
|
2972
|
+
var TOOL_SPLIT_RESOLVER = /* @__PURE__ */ Symbol("theokit.toolSplitResolver");
|
|
2973
|
+
async function runValidated(spec, input, ctx) {
|
|
2974
|
+
const raw = spec.sanitize ? sanitizeToolInput(input, {
|
|
2975
|
+
...spec.sanitize === true ? {} : spec.sanitize,
|
|
2976
|
+
schema: spec.inputSchema
|
|
2977
|
+
}).value : input;
|
|
2978
|
+
const parsed = spec.inputSchema.parse(raw);
|
|
2979
|
+
const out = await spec.handler(parsed, ctx);
|
|
2980
|
+
return spec.outputSchema === void 0 ? out : spec.outputSchema.parse(out);
|
|
3449
2981
|
}
|
|
3450
|
-
function
|
|
3451
|
-
|
|
3452
|
-
throw new ConfigurationError(
|
|
3453
|
-
`Subagent ${filename}: per-subagent "mcp" is not yet supported on the local delegation path; declare MCP servers in .theokit/mcp.json (or the parent) instead`,
|
|
3454
|
-
{ code: "subagent_mcp_unsupported_local" }
|
|
3455
|
-
);
|
|
3456
|
-
}
|
|
2982
|
+
function serializeOutput(validated) {
|
|
2983
|
+
return typeof validated === "string" ? validated : JSON.stringify(validated);
|
|
3457
2984
|
}
|
|
3458
|
-
function
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
if (effort !== void 0 && (modelId === void 0 || modelId === "inherit")) {
|
|
3462
|
-
throw new ConfigurationError(
|
|
3463
|
-
`Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or "inherit" cannot carry it)`,
|
|
3464
|
-
{ code: "subagent_reasoning_effort_without_model" }
|
|
3465
|
-
);
|
|
3466
|
-
}
|
|
3467
|
-
if (modelId === void 0) return void 0;
|
|
3468
|
-
if (modelId === "inherit") return "inherit";
|
|
3469
|
-
return effort !== void 0 ? { id: modelId, params: [{ id: "thinking", value: effort }] } : { id: modelId };
|
|
2985
|
+
function shapeModelOutput(spec, validated) {
|
|
2986
|
+
if (spec.toModelOutput !== void 0) return spec.toModelOutput(validated);
|
|
2987
|
+
return serializeOutput(validated);
|
|
3470
2988
|
}
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
if (typeof fields.sandbox !== "boolean") {
|
|
3474
|
-
throw new ConfigurationError(
|
|
3475
|
-
`Subagent ${filename}: sandbox must be a boolean (got "${String(fields.sandbox)}"); granular sandbox modes are not supported by the runtime`,
|
|
3476
|
-
{ code: "subagent_sandbox_not_boolean" }
|
|
3477
|
-
);
|
|
2989
|
+
var Tool = class {
|
|
2990
|
+
constructor() {
|
|
3478
2991
|
}
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
function asString(v) {
|
|
3482
|
-
if (typeof v !== "string") return void 0;
|
|
3483
|
-
const m = /^(["'])(.*)\1$/.exec(v);
|
|
3484
|
-
return m ? m[2] : v;
|
|
3485
|
-
}
|
|
3486
|
-
function toStringList(v) {
|
|
3487
|
-
if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);
|
|
3488
|
-
if (typeof v === "string") {
|
|
3489
|
-
return v.split(/[\s,]+/).map((t) => t.trim()).filter((t) => t.length > 0);
|
|
2992
|
+
static create(spec) {
|
|
2993
|
+
return defineTool(spec);
|
|
3490
2994
|
}
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
2995
|
+
};
|
|
2996
|
+
function defineTool(spec) {
|
|
2997
|
+
const inputSchema = toJsonSchema(spec.inputSchema, {
|
|
2998
|
+
unrepresentable: "any"
|
|
2999
|
+
});
|
|
3000
|
+
const handler = async (input, ctx) => {
|
|
3001
|
+
const validated = await runValidated(spec, input, ctx);
|
|
3002
|
+
return shapeModelOutput(spec, validated);
|
|
3003
|
+
};
|
|
3004
|
+
const tool = { name: spec.name, description: spec.description, inputSchema, handler };
|
|
3005
|
+
if (spec.toModelOutput !== void 0) {
|
|
3006
|
+
const resolver = async (input, ctx) => {
|
|
3007
|
+
const validated = await runValidated(spec, input, ctx);
|
|
3008
|
+
return { model: shapeModelOutput(spec, validated), app: serializeOutput(validated) };
|
|
3009
|
+
};
|
|
3010
|
+
handler[TOOL_SPLIT_RESOLVER] = resolver;
|
|
3499
3011
|
}
|
|
3500
|
-
return
|
|
3501
|
-
}
|
|
3502
|
-
function parseFrontmatterFields(frontmatter) {
|
|
3503
|
-
return parseSimpleYaml(frontmatter);
|
|
3012
|
+
return tool;
|
|
3504
3013
|
}
|
|
3014
|
+
|
|
3015
|
+
// src/internal/runtime/reasoning/native-reasoning.ts
|
|
3505
3016
|
var NATIVE_REASONING_PARAM_IDS = /* @__PURE__ */ new Set(["thinking", "reasoning", "reasoning_effort"]);
|
|
3506
3017
|
var REASONING_PREAMBLE = "Think step by step before answering: use the `think` tool to reason through each step, validate your work, then answer. Reason about magnitude before comparing numbers.";
|
|
3507
3018
|
function createThinkTool() {
|
|
@@ -4498,7 +4009,7 @@ async function loadMarkdownEntities(opts) {
|
|
|
4498
4009
|
await assertFileSizeUnderCap(resolved.source, errorCodePrefix);
|
|
4499
4010
|
const raw = await readFile(resolved.source, "utf8").catch(() => null);
|
|
4500
4011
|
if (raw === null) continue;
|
|
4501
|
-
const split =
|
|
4012
|
+
const split = splitFrontmatter(raw, resolved.source, errorCodePrefix);
|
|
4502
4013
|
const fields = parseSimpleYaml(split.frontmatter);
|
|
4503
4014
|
const parsed = schema.safeParse(fields);
|
|
4504
4015
|
if (!parsed.success) {
|
|
@@ -4549,7 +4060,7 @@ function resolveEntryPath(entry, pattern, dir) {
|
|
|
4549
4060
|
if (!entry.isDirectory()) return null;
|
|
4550
4061
|
return { slug: entry.name, source: join(dir, entry.name, "PLUGIN.md") };
|
|
4551
4062
|
}
|
|
4552
|
-
function
|
|
4063
|
+
function splitFrontmatter(raw, source, errorCodePrefix) {
|
|
4553
4064
|
const match = /^---\s*\n([\s\S]*?)\n---\s*(?:\n|$)/.exec(raw);
|
|
4554
4065
|
if (match === null) {
|
|
4555
4066
|
throw new ConfigurationError(
|
|
@@ -4717,7 +4228,7 @@ function anyGlobMatches(patterns, paths) {
|
|
|
4717
4228
|
|
|
4718
4229
|
// src/internal/runtime/context/context-yaml-lite.ts
|
|
4719
4230
|
var FRONTMATTER_RE = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
|
|
4720
|
-
function
|
|
4231
|
+
function splitFrontmatter2(content) {
|
|
4721
4232
|
const m = FRONTMATTER_RE.exec(content);
|
|
4722
4233
|
if (m === null) return { yaml: void 0, body: content };
|
|
4723
4234
|
return { yaml: m[1] ?? "", body: m[2] ?? "" };
|
|
@@ -4775,7 +4286,7 @@ var McdFrontmatterSchema = z.object({
|
|
|
4775
4286
|
alwaysApply: z.boolean().optional()
|
|
4776
4287
|
});
|
|
4777
4288
|
function parseMdc(content) {
|
|
4778
|
-
const { yaml, body } =
|
|
4289
|
+
const { yaml, body } = splitFrontmatter2(content);
|
|
4779
4290
|
if (yaml === void 0) {
|
|
4780
4291
|
return { frontmatter: { alwaysApply: true }, body: content };
|
|
4781
4292
|
}
|
|
@@ -4801,7 +4312,7 @@ var RulesFrontmatterSchema = z.object({
|
|
|
4801
4312
|
enabled: z.boolean().optional()
|
|
4802
4313
|
});
|
|
4803
4314
|
function parseRules(content) {
|
|
4804
|
-
const { yaml, body } =
|
|
4315
|
+
const { yaml, body } = splitFrontmatter2(content);
|
|
4805
4316
|
if (yaml === void 0) {
|
|
4806
4317
|
return { frontmatter: { alwaysApply: true }, body: content };
|
|
4807
4318
|
}
|
|
@@ -5629,15 +5140,60 @@ var DoomLoopTracker = class {
|
|
|
5629
5140
|
this.#count = 0;
|
|
5630
5141
|
}
|
|
5631
5142
|
};
|
|
5632
|
-
function firstDoomLoopVerdict(tracker, calls) {
|
|
5633
|
-
let escalation = { kind: "ok" };
|
|
5634
|
-
for (const call of calls) {
|
|
5635
|
-
const v = tracker.inspect(call);
|
|
5636
|
-
if (v.kind === "hard") return v;
|
|
5637
|
-
if (v.kind === "soft" && escalation.kind === "ok") escalation = v;
|
|
5638
|
-
}
|
|
5639
|
-
return escalation;
|
|
5640
|
-
}
|
|
5143
|
+
function firstDoomLoopVerdict(tracker, calls) {
|
|
5144
|
+
let escalation = { kind: "ok" };
|
|
5145
|
+
for (const call of calls) {
|
|
5146
|
+
const v = tracker.inspect(call);
|
|
5147
|
+
if (v.kind === "hard") return v;
|
|
5148
|
+
if (v.kind === "soft" && escalation.kind === "ok") escalation = v;
|
|
5149
|
+
}
|
|
5150
|
+
return escalation;
|
|
5151
|
+
}
|
|
5152
|
+
|
|
5153
|
+
// src/internal/budget/usage-accumulator.ts
|
|
5154
|
+
var UsageAccumulator = class {
|
|
5155
|
+
input = 0;
|
|
5156
|
+
output = 0;
|
|
5157
|
+
cacheRead = 0;
|
|
5158
|
+
cacheWrite = 0;
|
|
5159
|
+
reasoning = 0;
|
|
5160
|
+
requests = [];
|
|
5161
|
+
add(step) {
|
|
5162
|
+
const inputTokens = step.inputTokens ?? 0;
|
|
5163
|
+
const outputTokens = step.outputTokens ?? 0;
|
|
5164
|
+
const cacheReadTokens = step.cacheReadTokens ?? 0;
|
|
5165
|
+
const cacheWriteTokens = step.cacheWriteTokens ?? 0;
|
|
5166
|
+
const reasoningTokens = step.reasoningTokens ?? 0;
|
|
5167
|
+
this.input += inputTokens;
|
|
5168
|
+
this.output += outputTokens;
|
|
5169
|
+
this.cacheRead += cacheReadTokens;
|
|
5170
|
+
this.cacheWrite += cacheWriteTokens;
|
|
5171
|
+
this.reasoning += reasoningTokens;
|
|
5172
|
+
this.requests.push({
|
|
5173
|
+
inputTokens,
|
|
5174
|
+
outputTokens,
|
|
5175
|
+
...cacheReadTokens > 0 ? { cacheReadTokens } : {},
|
|
5176
|
+
...cacheWriteTokens > 0 ? { cacheWriteTokens } : {},
|
|
5177
|
+
...reasoningTokens > 0 ? { reasoningTokens } : {},
|
|
5178
|
+
totalTokens: inputTokens + outputTokens
|
|
5179
|
+
});
|
|
5180
|
+
}
|
|
5181
|
+
/** Did we observe any usage at all? */
|
|
5182
|
+
hasAny() {
|
|
5183
|
+
return this.requests.length > 0;
|
|
5184
|
+
}
|
|
5185
|
+
toTokenUsage() {
|
|
5186
|
+
return {
|
|
5187
|
+
inputTokens: this.input,
|
|
5188
|
+
outputTokens: this.output,
|
|
5189
|
+
...this.cacheRead > 0 ? { cacheReadTokens: this.cacheRead } : {},
|
|
5190
|
+
...this.cacheWrite > 0 ? { cacheWriteTokens: this.cacheWrite } : {},
|
|
5191
|
+
...this.reasoning > 0 ? { reasoningTokens: this.reasoning } : {},
|
|
5192
|
+
totalTokens: this.input + this.output,
|
|
5193
|
+
...this.requests.length > 1 ? { requests: this.requests.slice() } : {}
|
|
5194
|
+
};
|
|
5195
|
+
}
|
|
5196
|
+
};
|
|
5641
5197
|
|
|
5642
5198
|
// src/internal/agent-loop/message-builders.ts
|
|
5643
5199
|
function buildSystemEvent(inputs, toolNames) {
|
|
@@ -6118,6 +5674,21 @@ function coerceArgsToSchema(args, schema) {
|
|
|
6118
5674
|
return { value: out, changed };
|
|
6119
5675
|
}
|
|
6120
5676
|
|
|
5677
|
+
// src/tool-error.ts
|
|
5678
|
+
var ToolError = class extends TheokitAgentError {
|
|
5679
|
+
name = "ToolError";
|
|
5680
|
+
/** The error content surfaced to the model: a string, or text/image blocks. */
|
|
5681
|
+
content;
|
|
5682
|
+
constructor(content, options = {}) {
|
|
5683
|
+
super(renderToolErrorMessage(content), { ...options, isRetryable: false });
|
|
5684
|
+
this.content = content;
|
|
5685
|
+
}
|
|
5686
|
+
};
|
|
5687
|
+
function renderToolErrorMessage(content) {
|
|
5688
|
+
if (typeof content === "string") return content;
|
|
5689
|
+
return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
|
|
5690
|
+
}
|
|
5691
|
+
|
|
6121
5692
|
// src/internal/runtime/tools/shell-tool.ts
|
|
6122
5693
|
async function runShell(options) {
|
|
6123
5694
|
if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
|
|
@@ -6538,101 +6109,414 @@ function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan)
|
|
|
6538
6109
|
);
|
|
6539
6110
|
});
|
|
6540
6111
|
return {
|
|
6541
|
-
type: "tool_result",
|
|
6542
|
-
toolUseId: call.id,
|
|
6543
|
-
// SE7 — structured content blocks (handler-returned or ToolError-carried)
|
|
6544
|
-
// are authoritative; otherwise the legacy string rendering.
|
|
6545
|
-
content: result.content !== void 0 ? result.content : renderToolResult(result),
|
|
6546
|
-
...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
|
|
6112
|
+
type: "tool_result",
|
|
6113
|
+
toolUseId: call.id,
|
|
6114
|
+
// SE7 — structured content blocks (handler-returned or ToolError-carried)
|
|
6115
|
+
// are authoritative; otherwise the legacy string rendering.
|
|
6116
|
+
content: result.content !== void 0 ? result.content : renderToolResult(result),
|
|
6117
|
+
...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
|
|
6118
|
+
};
|
|
6119
|
+
}
|
|
6120
|
+
async function emitToolLifecycleDelta(inputs, update) {
|
|
6121
|
+
if (inputs.onDelta === void 0) return;
|
|
6122
|
+
try {
|
|
6123
|
+
await inputs.onDelta({ update });
|
|
6124
|
+
} catch (err) {
|
|
6125
|
+
process.stderr.write(
|
|
6126
|
+
`[theokit-sdk] onDelta tool-lifecycle emit error (swallowed): ${err instanceof Error ? err.message : String(err)}
|
|
6127
|
+
`
|
|
6128
|
+
);
|
|
6129
|
+
}
|
|
6130
|
+
}
|
|
6131
|
+
async function safeEmitToolHook(callback, event) {
|
|
6132
|
+
if (callback === void 0) return;
|
|
6133
|
+
try {
|
|
6134
|
+
await callback(event);
|
|
6135
|
+
} catch (cause) {
|
|
6136
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
6137
|
+
process.stderr.write(`[theokit-sdk] tool lifecycle hook threw: ${msg}
|
|
6138
|
+
`);
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
function buildToolUseRunning(inputs, callId, call) {
|
|
6142
|
+
return {
|
|
6143
|
+
type: "tool_call",
|
|
6144
|
+
agent_id: inputs.agentId,
|
|
6145
|
+
run_id: inputs.runId,
|
|
6146
|
+
call_id: callId,
|
|
6147
|
+
name: call.name,
|
|
6148
|
+
status: "running",
|
|
6149
|
+
args: call.input
|
|
6150
|
+
};
|
|
6151
|
+
}
|
|
6152
|
+
function buildRepairRegistry(tools) {
|
|
6153
|
+
const out = /* @__PURE__ */ new Map();
|
|
6154
|
+
for (const t of tools) {
|
|
6155
|
+
out.set(t.name, { name: t.name, inputSchema: t.inputSchema });
|
|
6156
|
+
}
|
|
6157
|
+
return out;
|
|
6158
|
+
}
|
|
6159
|
+
function buildToolUseCompleted(inputs, callId, call, result) {
|
|
6160
|
+
return {
|
|
6161
|
+
type: "tool_call",
|
|
6162
|
+
agent_id: inputs.agentId,
|
|
6163
|
+
run_id: inputs.runId,
|
|
6164
|
+
call_id: callId,
|
|
6165
|
+
name: call.name,
|
|
6166
|
+
status: "completed",
|
|
6167
|
+
args: call.input,
|
|
6168
|
+
result: {
|
|
6169
|
+
stdout: result.stdout,
|
|
6170
|
+
stderr: result.stderr,
|
|
6171
|
+
exitCode: result.exitCode ?? 0
|
|
6172
|
+
}
|
|
6173
|
+
};
|
|
6174
|
+
}
|
|
6175
|
+
|
|
6176
|
+
// src/internal/agent-loop/tool-result-guard.ts
|
|
6177
|
+
var OPEN = "<untrusted-tool-output>";
|
|
6178
|
+
var CLOSE = "</untrusted-tool-output>";
|
|
6179
|
+
var PII_PATTERNS = [
|
|
6180
|
+
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
|
|
6181
|
+
// email
|
|
6182
|
+
/\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
|
|
6183
|
+
// phone
|
|
6184
|
+
];
|
|
6185
|
+
function guardText(content, opts) {
|
|
6186
|
+
let out = content;
|
|
6187
|
+
if (opts.redactPii === true) {
|
|
6188
|
+
for (const re of PII_PATTERNS) out = out.replace(re, "[REDACTED]");
|
|
6189
|
+
}
|
|
6190
|
+
if (opts.delimit === true) {
|
|
6191
|
+
const safe2 = out.split(CLOSE).join("</ untrusted-tool-output>");
|
|
6192
|
+
out = `${OPEN}
|
|
6193
|
+
${safe2}
|
|
6194
|
+
${CLOSE}`;
|
|
6195
|
+
}
|
|
6196
|
+
return out;
|
|
6197
|
+
}
|
|
6198
|
+
function applyToolResultGuard(parts, opts) {
|
|
6199
|
+
if (opts.delimit !== true && opts.redactPii !== true) return parts;
|
|
6200
|
+
return parts.map(
|
|
6201
|
+
(p) => (
|
|
6202
|
+
// SE7 — guard the TEXT of a tool result (string or the text blocks of a
|
|
6203
|
+
// structured content); image blocks pass through untouched.
|
|
6204
|
+
p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
|
|
6205
|
+
)
|
|
6206
|
+
);
|
|
6207
|
+
}
|
|
6208
|
+
|
|
6209
|
+
// src/internal/budget/pricing-data.json
|
|
6210
|
+
var pricing_data_default = {
|
|
6211
|
+
_meta: {
|
|
6212
|
+
pricingVersion: "litellm-2026-05-snapshot"},
|
|
6213
|
+
models: {
|
|
6214
|
+
"anthropic/claude-opus-4-7": {
|
|
6215
|
+
input: 5,
|
|
6216
|
+
output: 25,
|
|
6217
|
+
cacheRead: 0.5,
|
|
6218
|
+
cacheWrite: 6.25
|
|
6219
|
+
},
|
|
6220
|
+
"anthropic/claude-opus-4-6": {
|
|
6221
|
+
input: 5,
|
|
6222
|
+
output: 25,
|
|
6223
|
+
cacheRead: 0.5,
|
|
6224
|
+
cacheWrite: 6.25
|
|
6225
|
+
},
|
|
6226
|
+
"anthropic/claude-opus-4-5": {
|
|
6227
|
+
input: 5,
|
|
6228
|
+
output: 25,
|
|
6229
|
+
cacheRead: 0.5,
|
|
6230
|
+
cacheWrite: 6.25
|
|
6231
|
+
},
|
|
6232
|
+
"anthropic/claude-sonnet-4-6": {
|
|
6233
|
+
input: 3,
|
|
6234
|
+
output: 15,
|
|
6235
|
+
cacheRead: 0.3,
|
|
6236
|
+
cacheWrite: 3.75
|
|
6237
|
+
},
|
|
6238
|
+
"anthropic/claude-sonnet-4-5": {
|
|
6239
|
+
input: 3,
|
|
6240
|
+
output: 15,
|
|
6241
|
+
cacheRead: 0.3,
|
|
6242
|
+
cacheWrite: 3.75
|
|
6243
|
+
},
|
|
6244
|
+
"anthropic/claude-haiku-4-5": {
|
|
6245
|
+
input: 1,
|
|
6246
|
+
output: 5,
|
|
6247
|
+
cacheRead: 0.1,
|
|
6248
|
+
cacheWrite: 1.25
|
|
6249
|
+
},
|
|
6250
|
+
"anthropic/claude-3-5-sonnet": {
|
|
6251
|
+
input: 3,
|
|
6252
|
+
output: 15,
|
|
6253
|
+
cacheRead: 0.3,
|
|
6254
|
+
cacheWrite: 3.75
|
|
6255
|
+
},
|
|
6256
|
+
"anthropic/claude-3-5-haiku": {
|
|
6257
|
+
input: 0.8,
|
|
6258
|
+
output: 4,
|
|
6259
|
+
cacheRead: 0.08,
|
|
6260
|
+
cacheWrite: 1
|
|
6261
|
+
},
|
|
6262
|
+
"anthropic/claude-3-opus": {
|
|
6263
|
+
input: 15,
|
|
6264
|
+
output: 75,
|
|
6265
|
+
cacheRead: 1.5,
|
|
6266
|
+
cacheWrite: 18.75
|
|
6267
|
+
},
|
|
6268
|
+
"anthropic/claude-3-haiku": {
|
|
6269
|
+
input: 0.25,
|
|
6270
|
+
output: 1.25,
|
|
6271
|
+
cacheRead: 0.03,
|
|
6272
|
+
cacheWrite: 0.3
|
|
6273
|
+
},
|
|
6274
|
+
"openai/gpt-4o": {
|
|
6275
|
+
input: 2.5,
|
|
6276
|
+
output: 10,
|
|
6277
|
+
cacheRead: 1.25
|
|
6278
|
+
},
|
|
6279
|
+
"openai/gpt-4o-mini": {
|
|
6280
|
+
input: 0.15,
|
|
6281
|
+
output: 0.6,
|
|
6282
|
+
cacheRead: 0.075
|
|
6283
|
+
},
|
|
6284
|
+
"openai/gpt-4.1": {
|
|
6285
|
+
input: 2,
|
|
6286
|
+
output: 8,
|
|
6287
|
+
cacheRead: 0.5
|
|
6288
|
+
},
|
|
6289
|
+
"openai/gpt-4.1-mini": {
|
|
6290
|
+
input: 0.4,
|
|
6291
|
+
output: 1.6,
|
|
6292
|
+
cacheRead: 0.1
|
|
6293
|
+
},
|
|
6294
|
+
"openai/gpt-4.1-nano": {
|
|
6295
|
+
input: 0.1,
|
|
6296
|
+
output: 0.4,
|
|
6297
|
+
cacheRead: 0.025
|
|
6298
|
+
},
|
|
6299
|
+
"openai/o3": {
|
|
6300
|
+
input: 2,
|
|
6301
|
+
output: 8,
|
|
6302
|
+
cacheRead: 0.5
|
|
6303
|
+
},
|
|
6304
|
+
"openai/o3-mini": {
|
|
6305
|
+
input: 1.1,
|
|
6306
|
+
output: 4.4,
|
|
6307
|
+
cacheRead: 0.55
|
|
6308
|
+
},
|
|
6309
|
+
"openai/o4-mini": {
|
|
6310
|
+
input: 1.1,
|
|
6311
|
+
output: 4.4,
|
|
6312
|
+
cacheRead: 0.275
|
|
6313
|
+
},
|
|
6314
|
+
"deepseek/deepseek-chat": {
|
|
6315
|
+
input: 0.14,
|
|
6316
|
+
output: 0.28
|
|
6317
|
+
},
|
|
6318
|
+
"deepseek/deepseek-reasoner": {
|
|
6319
|
+
input: 0.55,
|
|
6320
|
+
output: 2.19
|
|
6321
|
+
},
|
|
6322
|
+
"google/gemini-2.5-pro": {
|
|
6323
|
+
input: 1.25,
|
|
6324
|
+
output: 10
|
|
6325
|
+
},
|
|
6326
|
+
"google/gemini-2.5-flash": {
|
|
6327
|
+
input: 0.15,
|
|
6328
|
+
output: 0.6
|
|
6329
|
+
},
|
|
6330
|
+
"google/gemini-2.0-flash": {
|
|
6331
|
+
input: 0.1,
|
|
6332
|
+
output: 0.4
|
|
6333
|
+
}
|
|
6334
|
+
}
|
|
6335
|
+
};
|
|
6336
|
+
|
|
6337
|
+
// src/internal/budget/pricing-registry.ts
|
|
6338
|
+
var data = pricing_data_default;
|
|
6339
|
+
function buildEntry(key, raw) {
|
|
6340
|
+
const [provider, ...modelParts] = key.split("/");
|
|
6341
|
+
return {
|
|
6342
|
+
provider: provider ?? "unknown",
|
|
6343
|
+
model: modelParts.join("/"),
|
|
6344
|
+
inputCostPerMillion: raw.input,
|
|
6345
|
+
outputCostPerMillion: raw.output,
|
|
6346
|
+
...raw.cacheRead !== void 0 ? { cacheReadCostPerMillion: raw.cacheRead } : {},
|
|
6347
|
+
...raw.cacheWrite !== void 0 ? { cacheWriteCostPerMillion: raw.cacheWrite } : {},
|
|
6348
|
+
...raw.reasoning !== void 0 ? { reasoningCostPerMillion: raw.reasoning } : {},
|
|
6349
|
+
pricingVersion: data._meta.pricingVersion
|
|
6547
6350
|
};
|
|
6548
6351
|
}
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
try {
|
|
6552
|
-
await inputs.onDelta({ update });
|
|
6553
|
-
} catch (err) {
|
|
6554
|
-
process.stderr.write(
|
|
6555
|
-
`[theokit-sdk] onDelta tool-lifecycle emit error (swallowed): ${err instanceof Error ? err.message : String(err)}
|
|
6556
|
-
`
|
|
6557
|
-
);
|
|
6558
|
-
}
|
|
6352
|
+
function stripDateSuffix(model) {
|
|
6353
|
+
return model.replace(/-\d{4}-?\d{2}-?\d{2}$/, "");
|
|
6559
6354
|
}
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
try {
|
|
6563
|
-
await callback(event);
|
|
6564
|
-
} catch (cause) {
|
|
6565
|
-
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
6566
|
-
process.stderr.write(`[theokit-sdk] tool lifecycle hook threw: ${msg}
|
|
6567
|
-
`);
|
|
6568
|
-
}
|
|
6355
|
+
function normalizeAnthropicDots(model) {
|
|
6356
|
+
return model.replace(/(\d+)\.(\d+)/g, "$1-$2");
|
|
6569
6357
|
}
|
|
6570
|
-
function
|
|
6571
|
-
return
|
|
6572
|
-
type: "tool_call",
|
|
6573
|
-
agent_id: inputs.agentId,
|
|
6574
|
-
run_id: inputs.runId,
|
|
6575
|
-
call_id: callId,
|
|
6576
|
-
name: call.name,
|
|
6577
|
-
status: "running",
|
|
6578
|
-
args: call.input
|
|
6579
|
-
};
|
|
6358
|
+
function stripOpenRouterPrefix(modelId) {
|
|
6359
|
+
return modelId.startsWith("openrouter/") ? modelId.slice("openrouter/".length) : modelId;
|
|
6580
6360
|
}
|
|
6581
|
-
function
|
|
6582
|
-
|
|
6583
|
-
for (const t of tools) {
|
|
6584
|
-
out.set(t.name, { name: t.name, inputSchema: t.inputSchema });
|
|
6585
|
-
}
|
|
6586
|
-
return out;
|
|
6361
|
+
function lookupRaw(key) {
|
|
6362
|
+
return data.models[key];
|
|
6587
6363
|
}
|
|
6588
|
-
function
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6364
|
+
function getPricingEntry(opts) {
|
|
6365
|
+
const cleaned = stripOpenRouterPrefix(opts.model);
|
|
6366
|
+
const directKey = `${opts.provider}/${cleaned}`;
|
|
6367
|
+
const direct = lookupRaw(directKey);
|
|
6368
|
+
if (direct !== void 0) return buildEntry(directKey, direct);
|
|
6369
|
+
const noSuffix = stripDateSuffix(cleaned);
|
|
6370
|
+
if (noSuffix !== cleaned) {
|
|
6371
|
+
const noSuffixKey = `${opts.provider}/${noSuffix}`;
|
|
6372
|
+
const found = lookupRaw(noSuffixKey);
|
|
6373
|
+
if (found !== void 0) return buildEntry(noSuffixKey, found);
|
|
6374
|
+
}
|
|
6375
|
+
if (opts.provider === "anthropic") {
|
|
6376
|
+
const normalized = normalizeAnthropicDots(stripDateSuffix(cleaned));
|
|
6377
|
+
const normKey = `${opts.provider}/${normalized}`;
|
|
6378
|
+
const found = lookupRaw(normKey);
|
|
6379
|
+
if (found !== void 0) return buildEntry(normKey, found);
|
|
6380
|
+
}
|
|
6381
|
+
if (cleaned.includes("/")) {
|
|
6382
|
+
const found = lookupRaw(cleaned);
|
|
6383
|
+
if (found !== void 0) return buildEntry(cleaned, found);
|
|
6384
|
+
const stripped = stripDateSuffix(cleaned);
|
|
6385
|
+
if (stripped !== cleaned) {
|
|
6386
|
+
const found2 = lookupRaw(stripped);
|
|
6387
|
+
if (found2 !== void 0) return buildEntry(stripped, found2);
|
|
6601
6388
|
}
|
|
6602
|
-
}
|
|
6389
|
+
}
|
|
6390
|
+
const catalogEntry = catalogCostFallback(opts.provider, cleaned);
|
|
6391
|
+
if (catalogEntry !== void 0) return catalogEntry;
|
|
6392
|
+
return void 0;
|
|
6393
|
+
}
|
|
6394
|
+
function catalogCostFallback(provider, cleanedModel) {
|
|
6395
|
+
const stripped = stripDateSuffix(cleanedModel);
|
|
6396
|
+
const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
|
|
6397
|
+
if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
|
|
6398
|
+
for (const key of candidates) {
|
|
6399
|
+
const info = getCatalogModelInfo(key);
|
|
6400
|
+
const cost = info?.cost;
|
|
6401
|
+
if (cost === void 0) continue;
|
|
6402
|
+
const [prov, ...modelParts] = key.split("/");
|
|
6403
|
+
return {
|
|
6404
|
+
provider: prov ?? provider,
|
|
6405
|
+
model: modelParts.join("/") || cleanedModel,
|
|
6406
|
+
inputCostPerMillion: cost.input,
|
|
6407
|
+
outputCostPerMillion: cost.output,
|
|
6408
|
+
...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
|
|
6409
|
+
...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
|
|
6410
|
+
// M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
|
|
6411
|
+
pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
|
|
6412
|
+
};
|
|
6413
|
+
}
|
|
6414
|
+
return void 0;
|
|
6603
6415
|
}
|
|
6604
6416
|
|
|
6605
|
-
// src/internal/
|
|
6606
|
-
var
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6417
|
+
// src/internal/budget/compute-cost.ts
|
|
6418
|
+
var MICROCENT = 1e6;
|
|
6419
|
+
function isSubscriptionIncluded(provider) {
|
|
6420
|
+
return provider === "openai-codex" || provider === "codex";
|
|
6421
|
+
}
|
|
6422
|
+
function pricingHasValidRates(entry) {
|
|
6423
|
+
return entry.inputCostPerMillion >= 0 && entry.outputCostPerMillion >= 0 && (entry.cacheReadCostPerMillion === void 0 || entry.cacheReadCostPerMillion >= 0) && (entry.cacheWriteCostPerMillion === void 0 || entry.cacheWriteCostPerMillion >= 0) && (entry.reasoningCostPerMillion === void 0 || entry.reasoningCostPerMillion >= 0);
|
|
6424
|
+
}
|
|
6425
|
+
function costForTokens(tokens, perMillion) {
|
|
6426
|
+
if (tokens === 0 || perMillion === 0) return 0;
|
|
6427
|
+
return Math.round(tokens * perMillion * MICROCENT / 1e6) / MICROCENT;
|
|
6428
|
+
}
|
|
6429
|
+
function computeCost(args) {
|
|
6430
|
+
if (isSubscriptionIncluded(args.provider)) {
|
|
6431
|
+
return {
|
|
6432
|
+
amountUsd: 0,
|
|
6433
|
+
status: "included",
|
|
6434
|
+
currency: "USD",
|
|
6435
|
+
source: "subscription_included",
|
|
6436
|
+
pricingVersion: void 0
|
|
6437
|
+
};
|
|
6618
6438
|
}
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6439
|
+
const entry = getPricingEntry({
|
|
6440
|
+
provider: args.provider,
|
|
6441
|
+
model: args.model,
|
|
6442
|
+
...args.baseUrl !== void 0 ? { baseUrl: args.baseUrl } : {}
|
|
6443
|
+
});
|
|
6444
|
+
if (entry === void 0) {
|
|
6445
|
+
return {
|
|
6446
|
+
amountUsd: void 0,
|
|
6447
|
+
status: "unknown",
|
|
6448
|
+
currency: "USD",
|
|
6449
|
+
source: "unknown",
|
|
6450
|
+
pricingVersion: void 0
|
|
6451
|
+
};
|
|
6624
6452
|
}
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6453
|
+
if (!pricingHasValidRates(entry)) {
|
|
6454
|
+
return {
|
|
6455
|
+
amountUsd: void 0,
|
|
6456
|
+
status: "unknown",
|
|
6457
|
+
currency: "USD",
|
|
6458
|
+
source: "unknown",
|
|
6459
|
+
pricingVersion: entry.pricingVersion,
|
|
6460
|
+
notes: ["pricing entry has negative rates; treated as invalid"]
|
|
6461
|
+
};
|
|
6462
|
+
}
|
|
6463
|
+
const notes = [];
|
|
6464
|
+
const detail = {};
|
|
6465
|
+
const u = args.usage;
|
|
6466
|
+
const inputCost = costForTokens(u.inputTokens, entry.inputCostPerMillion);
|
|
6467
|
+
const outputCost = costForTokens(u.outputTokens, entry.outputCostPerMillion);
|
|
6468
|
+
detail.input = inputCost;
|
|
6469
|
+
detail.output = outputCost;
|
|
6470
|
+
let total = inputCost + outputCost;
|
|
6471
|
+
if (u.cacheReadTokens !== void 0 && u.cacheReadTokens > 0) {
|
|
6472
|
+
if (entry.cacheReadCostPerMillion === void 0) {
|
|
6473
|
+
return {
|
|
6474
|
+
amountUsd: void 0,
|
|
6475
|
+
status: "unknown",
|
|
6476
|
+
currency: "USD",
|
|
6477
|
+
source: "litellm_snapshot",
|
|
6478
|
+
pricingVersion: entry.pricingVersion,
|
|
6479
|
+
notes: ["cache-read tokens present but cacheReadCostPerMillion is undefined"]
|
|
6480
|
+
};
|
|
6481
|
+
}
|
|
6482
|
+
const c = costForTokens(u.cacheReadTokens, entry.cacheReadCostPerMillion);
|
|
6483
|
+
detail.cacheRead = c;
|
|
6484
|
+
total += c;
|
|
6485
|
+
}
|
|
6486
|
+
if (u.cacheWriteTokens !== void 0 && u.cacheWriteTokens > 0) {
|
|
6487
|
+
if (entry.cacheWriteCostPerMillion === void 0) {
|
|
6488
|
+
return {
|
|
6489
|
+
amountUsd: void 0,
|
|
6490
|
+
status: "unknown",
|
|
6491
|
+
currency: "USD",
|
|
6492
|
+
source: "litellm_snapshot",
|
|
6493
|
+
pricingVersion: entry.pricingVersion,
|
|
6494
|
+
notes: ["cache-write tokens present but cacheWriteCostPerMillion is undefined"]
|
|
6495
|
+
};
|
|
6496
|
+
}
|
|
6497
|
+
const c = costForTokens(u.cacheWriteTokens, entry.cacheWriteCostPerMillion);
|
|
6498
|
+
detail.cacheWrite = c;
|
|
6499
|
+
total += c;
|
|
6500
|
+
}
|
|
6501
|
+
if (u.reasoningTokens !== void 0 && u.reasoningTokens > 0) {
|
|
6502
|
+
const rate = entry.reasoningCostPerMillion ?? entry.outputCostPerMillion;
|
|
6503
|
+
const c = costForTokens(u.reasoningTokens, rate);
|
|
6504
|
+
detail.reasoning = c;
|
|
6505
|
+
total += c;
|
|
6506
|
+
if (entry.reasoningCostPerMillion === void 0) {
|
|
6507
|
+
notes.push("reasoning tokens billed at output rate (no dedicated reasoning rate available)");
|
|
6508
|
+
}
|
|
6509
|
+
}
|
|
6510
|
+
const amountUsd = Math.round(total * MICROCENT) / MICROCENT;
|
|
6511
|
+
return {
|
|
6512
|
+
amountUsd,
|
|
6513
|
+
status: "estimated",
|
|
6514
|
+
currency: "USD",
|
|
6515
|
+
source: "litellm_snapshot",
|
|
6516
|
+
pricingVersion: entry.pricingVersion,
|
|
6517
|
+
...notes.length > 0 ? { notes } : {},
|
|
6518
|
+
detail
|
|
6519
|
+
};
|
|
6636
6520
|
}
|
|
6637
6521
|
|
|
6638
6522
|
// src/internal/agent-loop/usage-and-cost.ts
|
|
@@ -10569,5 +10453,5 @@ async function abrirStoreLocal(reg) {
|
|
|
10569
10453
|
}
|
|
10570
10454
|
|
|
10571
10455
|
export { Agent, AgentBuilder, DEFAULT_AGENTIC_MODEL_ID, MEMORY_EMBEDDING_ADAPTERS, Tool, ToolError, UsageAccumulator, computeCost, generateCronId, getPricingEntry, httpRequest, isFixtureApiKey, openRouterMemoryEmbeddingProviderAdapter, resolveApiKey, shouldUseFixtureMode };
|
|
10572
|
-
//# sourceMappingURL=chunk-
|
|
10573
|
-
//# sourceMappingURL=chunk-
|
|
10456
|
+
//# sourceMappingURL=chunk-VUJ3NVDC.js.map
|
|
10457
|
+
//# sourceMappingURL=chunk-VUJ3NVDC.js.map
|