@odla-ai/ai 0.3.1 → 0.3.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/README.md +7 -0
- package/dist/{anthropic-2NPMHJZT.js → anthropic-AGA2NYWP.js} +3 -3
- package/dist/{chunk-OX4TA4ZH.js → chunk-J2NH2F4B.js} +2 -2
- package/dist/{chunk-PXXCN2EU.js → chunk-ZTY6FLZ5.js} +28 -11
- package/dist/chunk-ZTY6FLZ5.js.map +1 -0
- package/dist/{google-3XV2VWVB.js → google-H5CCSLJ2.js} +3 -3
- package/dist/index.cjs +34 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/{openai-NTQCF577.js → openai-ACSSZ3VC.js} +3 -3
- package/llms.txt +5 -0
- package/package.json +1 -1
- package/dist/chunk-PXXCN2EU.js.map +0 -1
- /package/dist/{anthropic-2NPMHJZT.js.map → anthropic-AGA2NYWP.js.map} +0 -0
- /package/dist/{chunk-OX4TA4ZH.js.map → chunk-J2NH2F4B.js.map} +0 -0
- /package/dist/{google-3XV2VWVB.js.map → google-H5CCSLJ2.js.map} +0 -0
- /package/dist/{openai-NTQCF577.js.map → openai-ACSSZ3VC.js.map} +0 -0
package/README.md
CHANGED
|
@@ -363,6 +363,13 @@ Every error is an `OdlaAIError` subclass carrying a stable `code` — branch on
|
|
|
363
363
|
`CapabilityError`, `ContextWindowError`, `InvalidRequestError`, `ToolInputError`,
|
|
364
364
|
`CancelledError`, `DeadlineExceededError`, `ProviderError`.
|
|
365
365
|
|
|
366
|
+
`OdlaAIError.usage` is present only when a provider response was already
|
|
367
|
+
received and a later forced-tool or schema check failed. It is a frozen,
|
|
368
|
+
sanitized token-usage record so accounting can charge a failed structured
|
|
369
|
+
response accurately; it may be absent for transport, authentication, timeout,
|
|
370
|
+
or preflight failures. `toShape()` and streaming `OracleErrorShape` deliberately
|
|
371
|
+
omit it.
|
|
372
|
+
|
|
366
373
|
## Develop
|
|
367
374
|
|
|
368
375
|
```bash
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
toolInput
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-J2NH2F4B.js";
|
|
4
4
|
import {
|
|
5
5
|
addUsage,
|
|
6
6
|
emptyUsage,
|
|
7
7
|
mapProviderError,
|
|
8
8
|
normalizeError,
|
|
9
9
|
signalWithDeadline
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZTY6FLZ5.js";
|
|
11
11
|
|
|
12
12
|
// src/providers/anthropic.ts
|
|
13
13
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -232,4 +232,4 @@ var AnthropicProvider = class {
|
|
|
232
232
|
export {
|
|
233
233
|
AnthropicProvider
|
|
234
234
|
};
|
|
235
|
-
//# sourceMappingURL=anthropic-
|
|
235
|
+
//# sourceMappingURL=anthropic-AGA2NYWP.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ToolInputError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZTY6FLZ5.js";
|
|
4
4
|
|
|
5
5
|
// src/providers/tool-input.ts
|
|
6
6
|
function toolInput(value, provider, name) {
|
|
@@ -13,4 +13,4 @@ function toolInput(value, provider, name) {
|
|
|
13
13
|
export {
|
|
14
14
|
toolInput
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=chunk-
|
|
16
|
+
//# sourceMappingURL=chunk-J2NH2F4B.js.map
|
|
@@ -18,12 +18,16 @@ var OdlaAIError = class extends Error {
|
|
|
18
18
|
code;
|
|
19
19
|
providerStatus;
|
|
20
20
|
retryAfter;
|
|
21
|
+
/** Sanitized provider usage when a response was received before a later
|
|
22
|
+
* validation/tool-shape failure. Omitted when usage is genuinely unknown. */
|
|
23
|
+
usage;
|
|
21
24
|
constructor(code, message, opts) {
|
|
22
25
|
super(message, opts?.cause !== void 0 ? { cause: opts.cause } : void 0);
|
|
23
26
|
this.name = new.target.name;
|
|
24
27
|
this.code = code;
|
|
25
28
|
this.providerStatus = opts?.providerStatus;
|
|
26
29
|
this.retryAfter = opts?.retryAfter;
|
|
30
|
+
this.usage = opts?.usage ? Object.freeze({ ...opts.usage }) : void 0;
|
|
27
31
|
}
|
|
28
32
|
toShape() {
|
|
29
33
|
return {
|
|
@@ -67,7 +71,7 @@ var InvalidRequestError = class extends OdlaAIError {
|
|
|
67
71
|
var ToolInputError = class extends OdlaAIError {
|
|
68
72
|
tool;
|
|
69
73
|
constructor(message, opts) {
|
|
70
|
-
super("tool_input_invalid", message, { cause: opts?.cause });
|
|
74
|
+
super("tool_input_invalid", message, { cause: opts?.cause, usage: opts?.usage });
|
|
71
75
|
this.tool = opts?.tool;
|
|
72
76
|
}
|
|
73
77
|
};
|
|
@@ -99,15 +103,28 @@ function statusOf(err) {
|
|
|
99
103
|
return void 0;
|
|
100
104
|
}
|
|
101
105
|
function retryAfterOf(err) {
|
|
102
|
-
if (err
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
if (!err || typeof err !== "object") return void 0;
|
|
107
|
+
const headers = err.headers;
|
|
108
|
+
if (!headers || typeof headers !== "object") return void 0;
|
|
109
|
+
const header = (name) => {
|
|
110
|
+
const get = headers.get;
|
|
111
|
+
if (typeof get === "function") return get.call(headers, name);
|
|
112
|
+
const entry = Object.entries(headers).find(([key]) => key.toLowerCase() === name);
|
|
113
|
+
return entry?.[1];
|
|
114
|
+
};
|
|
115
|
+
const milliseconds = numericHeader(header("retry-after-ms"));
|
|
116
|
+
if (milliseconds !== void 0) return milliseconds / 1e3;
|
|
117
|
+
const raw = header("retry-after");
|
|
118
|
+
const seconds = numericHeader(raw);
|
|
119
|
+
if (seconds !== void 0) return seconds;
|
|
120
|
+
if (typeof raw !== "string") return void 0;
|
|
121
|
+
const timestamp = Date.parse(raw);
|
|
122
|
+
if (!Number.isFinite(timestamp)) return void 0;
|
|
123
|
+
return Math.max(0, (timestamp - Date.now()) / 1e3);
|
|
124
|
+
}
|
|
125
|
+
function numericHeader(value) {
|
|
126
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : NaN;
|
|
127
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
|
|
111
128
|
}
|
|
112
129
|
function messageOf(err) {
|
|
113
130
|
if (err instanceof Error) return err.message;
|
|
@@ -189,4 +206,4 @@ export {
|
|
|
189
206
|
signalWithDeadline,
|
|
190
207
|
throwIfAborted
|
|
191
208
|
};
|
|
192
|
-
//# sourceMappingURL=chunk-
|
|
209
|
+
//# sourceMappingURL=chunk-ZTY6FLZ5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shape/usage.ts","../src/shape/errors.ts","../src/providers/errors.ts","../src/client/abort.ts"],"sourcesContent":["// Token usage accounting. The one runtime island with no dependencies.\n\nexport interface OracleUsage {\n inputTokens: number;\n outputTokens: number;\n cacheCreationTokens?: number;\n cacheReadTokens?: number;\n}\n\n/** A fresh zeroed usage tally (0 input/output tokens, no cache fields) — the seed for accumulation. */\nexport function emptyUsage(): OracleUsage {\n return { inputTokens: 0, outputTokens: 0 };\n}\n\n/** Accumulate `more` into `into`, in place. Cache fields sum when present. */\nexport function addUsage(into: OracleUsage, more: OracleUsage): void {\n into.inputTokens += more.inputTokens;\n into.outputTokens += more.outputTokens;\n if (more.cacheCreationTokens !== undefined) {\n into.cacheCreationTokens = (into.cacheCreationTokens ?? 0) + more.cacheCreationTokens;\n }\n if (more.cacheReadTokens !== undefined) {\n into.cacheReadTokens = (into.cacheReadTokens ?? 0) + more.cacheReadTokens;\n }\n}\n","// The normalized error taxonomy and the class hierarchy every adapter throws.\nimport type { OracleUsage } from \"./usage\";\n\n/** The closed taxonomy of normalized error codes carried by every OdlaAIError\n * and by the streaming `error` event. */\nexport type OracleErrorType =\n | \"invalid_request\"\n | \"auth\"\n | \"rate_limit\"\n | \"context_window\"\n | \"cancelled\"\n | \"deadline_exceeded\"\n | \"tool_input_invalid\"\n | \"capability_unsupported\"\n | \"config\"\n | \"provider_error\";\n\n/** The plain-data error shape used inside the streaming `error` event. */\nexport interface OracleErrorShape {\n code: OracleErrorType;\n message: string;\n /** HTTP status from the upstream provider, when applicable. */\n providerStatus?: number;\n /** Seconds until a retry might succeed (rate limit / overload). */\n retryAfter?: number;\n}\n\n/** Base class for every error odla-ai throws. Carries a stable string `code`\n * (the odla ecosystem convention — see odla-db's AuthError/RuleError) so\n * callers branch on `err.code`, never on message text. */\nexport class OdlaAIError extends Error {\n readonly code: OracleErrorType;\n readonly providerStatus?: number;\n readonly retryAfter?: number;\n /** Sanitized provider usage when a response was received before a later\n * validation/tool-shape failure. Omitted when usage is genuinely unknown. */\n readonly usage?: OracleUsage;\n\n constructor(\n code: OracleErrorType,\n message: string,\n opts?: { providerStatus?: number; retryAfter?: number; cause?: unknown; usage?: OracleUsage },\n ) {\n super(message, opts?.cause !== undefined ? { cause: opts.cause } : undefined);\n this.name = new.target.name;\n this.code = code;\n this.providerStatus = opts?.providerStatus;\n this.retryAfter = opts?.retryAfter;\n this.usage = opts?.usage ? Object.freeze({ ...opts.usage }) : undefined;\n }\n\n toShape(): OracleErrorShape {\n return {\n code: this.code,\n message: this.message,\n providerStatus: this.providerStatus,\n retryAfter: this.retryAfter,\n };\n }\n}\n\n/** A provider/model is not configured — e.g. no API key for its provider, or an\n * unknown canonical model id. The library analog of odla-db's 501 gating. */\nexport class ConfigError extends OdlaAIError {\n constructor(message: string) {\n super(\"config\", message);\n }\n}\n\n/** Authentication with the provider failed (bad/missing key). */\nexport class AuthError extends OdlaAIError {\n constructor(message: string, opts?: { providerStatus?: number; cause?: unknown }) {\n super(\"auth\", message, opts);\n }\n}\n\n/** The provider rate-limited or is overloaded; check `retryAfter`. */\nexport class RateLimitError extends OdlaAIError {\n constructor(message: string, opts?: { providerStatus?: number; retryAfter?: number; cause?: unknown }) {\n super(\"rate_limit\", message, opts);\n }\n}\n\n/** The request asked a model to do something it cannot — audio to Claude, tools\n * to a text-only model, web search where unsupported, etc. Raised before any\n * network call by `validateRequest`. */\nexport class CapabilityError extends OdlaAIError {\n constructor(message: string) {\n super(\"capability_unsupported\", message);\n }\n}\n\n/** The request exceeded the model's context window. */\nexport class ContextWindowError extends OdlaAIError {\n constructor(message: string, opts?: { providerStatus?: number; cause?: unknown }) {\n super(\"context_window\", message, opts);\n }\n}\n\n/** The request was malformed / rejected as invalid by the provider. */\nexport class InvalidRequestError extends OdlaAIError {\n constructor(message: string, opts?: { providerStatus?: number; cause?: unknown }) {\n super(\"invalid_request\", message, opts);\n }\n}\n\n/** A provider returned tool arguments that are malformed or do not satisfy the\n * declared JSON Schema. Tool handlers are never invoked for this error. */\nexport class ToolInputError extends OdlaAIError {\n readonly tool?: string;\n\n constructor(message: string, opts?: { tool?: string; cause?: unknown; usage?: OracleUsage }) {\n super(\"tool_input_invalid\", message, { cause: opts?.cause, usage: opts?.usage });\n this.tool = opts?.tool;\n }\n}\n\n/** The caller cancelled a request. This is not an upstream failure and should\n * not be retried unless the caller explicitly starts a new operation. */\nexport class CancelledError extends OdlaAIError {\n constructor(message = \"AI request was cancelled.\", opts?: { cause?: unknown }) {\n super(\"cancelled\", message, opts);\n }\n}\n\n/** The request's absolute deadline elapsed. Callers may choose a new deadline,\n * but should not classify this as a provider outage. */\nexport class DeadlineExceededError extends OdlaAIError {\n constructor(message = \"AI request deadline was exceeded.\", opts?: { cause?: unknown }) {\n super(\"deadline_exceeded\", message, opts);\n }\n}\n\n/** Any other upstream provider failure (5xx, transport, unexpected shape). */\nexport class ProviderError extends OdlaAIError {\n constructor(message: string, opts?: { providerStatus?: number; cause?: unknown; usage?: OracleUsage }) {\n super(\"provider_error\", message, opts);\n }\n}\n","// Normalize a thrown provider-SDK error into the odla-ai error taxonomy. Kept\n// dependency-light: it duck-types the HTTP status / retry-after off the error\n// object rather than importing each SDK's error classes, so it works uniformly\n// across @anthropic-ai/sdk, openai, and @google/genai.\n\nimport {\n AuthError,\n CancelledError,\n ContextWindowError,\n DeadlineExceededError,\n InvalidRequestError,\n OdlaAIError,\n ProviderError,\n RateLimitError,\n type ProviderId,\n} from \"../shape/index\";\n\nfunction statusOf(err: unknown): number | undefined {\n if (err && typeof err === \"object\") {\n const rec = err as Record<string, unknown>;\n for (const k of [\"status\", \"statusCode\", \"code\"]) {\n const v = rec[k];\n if (typeof v === \"number\") return v;\n }\n }\n return undefined;\n}\n\nfunction retryAfterOf(err: unknown): number | undefined {\n if (!err || typeof err !== \"object\") return undefined;\n const headers = (err as { headers?: unknown }).headers;\n if (!headers || typeof headers !== \"object\") return undefined;\n\n // The OpenAI and Anthropic SDKs expose a web `Headers` instance. Some\n // custom transports expose a plain object instead, occasionally preserving\n // the provider's original header casing. Support both without importing an\n // SDK-specific error type.\n const header = (name: string): unknown => {\n const get = (headers as { get?: unknown }).get;\n if (typeof get === \"function\") return get.call(headers, name);\n const entry = Object.entries(headers as Record<string, unknown>)\n .find(([key]) => key.toLowerCase() === name);\n return entry?.[1];\n };\n\n const milliseconds = numericHeader(header(\"retry-after-ms\"));\n if (milliseconds !== undefined) return milliseconds / 1_000;\n\n const raw = header(\"retry-after\");\n const seconds = numericHeader(raw);\n if (seconds !== undefined) return seconds;\n if (typeof raw !== \"string\") return undefined;\n const timestamp = Date.parse(raw);\n if (!Number.isFinite(timestamp)) return undefined;\n return Math.max(0, (timestamp - Date.now()) / 1_000);\n}\n\nfunction numericHeader(value: unknown): number | undefined {\n const parsed = typeof value === \"number\" ? value : typeof value === \"string\" && value.trim() ? Number(value) : NaN;\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;\n}\n\nfunction messageOf(err: unknown): string {\n if (err instanceof Error) return err.message;\n if (typeof err === \"string\") return err;\n return \"unknown provider error\";\n}\n\n/** Map any provider error to an OdlaAIError, returning it (does not throw).\n * Re-returns an OdlaAIError unchanged (already normalized). */\nexport function normalizeError(err: unknown, provider: ProviderId, signal?: AbortSignal): OdlaAIError {\n if (err instanceof OdlaAIError) return err;\n const cancellation = cancellationError(signal?.aborted ? signal.reason : err);\n if (signal?.aborted || cancellation) return cancellation ?? new CancelledError(undefined, { cause: err });\n\n const status = statusOf(err);\n const message = messageOf(err);\n const tagged = `[${provider}] ${message}`;\n\n if (status === 401 || status === 403) return new AuthError(tagged, { providerStatus: status, cause: err });\n if (status === 429) {\n return new RateLimitError(tagged, { providerStatus: status, retryAfter: retryAfterOf(err), cause: err });\n }\n if (status === 400 || status === 422) {\n if (/context|token limit|too long|maximum context/i.test(message)) {\n return new ContextWindowError(tagged, { providerStatus: status, cause: err });\n }\n return new InvalidRequestError(tagged, { providerStatus: status, cause: err });\n }\n return new ProviderError(tagged, { providerStatus: status, cause: err });\n}\n\n/**\n * Normalize and throw. The `never` return lets call sites write\n * `catch (e) { mapProviderError(e, id); }` with no fallthrough.\n */\nexport function mapProviderError(err: unknown, provider: ProviderId, signal?: AbortSignal): never {\n throw normalizeError(err, provider, signal);\n}\n\nfunction cancellationError(reason: unknown): CancelledError | DeadlineExceededError | undefined {\n if (reason instanceof DeadlineExceededError || reason instanceof CancelledError) return reason;\n if (!reason || typeof reason !== \"object\") return undefined;\n const rec = reason as { name?: unknown; code?: unknown; message?: unknown };\n if (rec.name === \"TimeoutError\") return new DeadlineExceededError(undefined, { cause: reason });\n if (rec.name === \"AbortError\" || rec.name === \"APIUserAbortError\" || rec.code === \"ABORT_ERR\") {\n return new CancelledError(undefined, { cause: reason });\n }\n return undefined;\n}\n","import { CancelledError, ConfigError, DeadlineExceededError } from \"../shape/errors\";\n\n/** Combine a caller signal with an absolute deadline. Kept provider-neutral so\n * every adapter and the agent loop observes the same cancellation contract. */\nexport function signalWithDeadline(signal?: AbortSignal, deadline?: number): AbortSignal | undefined {\n if (deadline === undefined) return signal;\n if (!Number.isSafeInteger(deadline)) throw new ConfigError(\"deadline must be a finite integer Unix timestamp in milliseconds.\");\n const remaining = deadline - Date.now();\n if (remaining <= 0) {\n const expired = new AbortController();\n expired.abort(new DeadlineExceededError());\n return signal ? AbortSignal.any([signal, expired.signal]) : expired.signal;\n }\n const timeout = AbortSignal.timeout(remaining);\n return signal ? AbortSignal.any([signal, timeout]) : timeout;\n}\n\n/** Fail synchronously before beginning a local side effect when a run was\n * cancelled or its deadline elapsed. Handlers must still observe the signal\n * while in flight; this closes the already-aborted race at invocation time. */\nexport function throwIfAborted(signal?: AbortSignal): void {\n if (!signal?.aborted) return;\n const reason = signal.reason;\n if (reason instanceof DeadlineExceededError || reason instanceof CancelledError) throw reason;\n if (reason && typeof reason === \"object\" && (reason as { name?: unknown }).name === \"TimeoutError\") {\n throw new DeadlineExceededError(undefined, { cause: reason });\n }\n throw new CancelledError(undefined, { cause: reason });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
} from "./chunk-U7F6VJCV.js";
|
|
4
4
|
import {
|
|
5
5
|
toolInput
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-J2NH2F4B.js";
|
|
7
7
|
import {
|
|
8
8
|
CapabilityError,
|
|
9
9
|
emptyUsage,
|
|
10
10
|
mapProviderError,
|
|
11
11
|
normalizeError,
|
|
12
12
|
signalWithDeadline
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ZTY6FLZ5.js";
|
|
14
14
|
|
|
15
15
|
// src/providers/google.ts
|
|
16
16
|
import { GoogleGenAI } from "@google/genai";
|
|
@@ -222,4 +222,4 @@ export {
|
|
|
222
222
|
mapResponse,
|
|
223
223
|
toContents
|
|
224
224
|
};
|
|
225
|
-
//# sourceMappingURL=google-
|
|
225
|
+
//# sourceMappingURL=google-H5CCSLJ2.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -85,12 +85,16 @@ var init_errors = __esm({
|
|
|
85
85
|
code;
|
|
86
86
|
providerStatus;
|
|
87
87
|
retryAfter;
|
|
88
|
+
/** Sanitized provider usage when a response was received before a later
|
|
89
|
+
* validation/tool-shape failure. Omitted when usage is genuinely unknown. */
|
|
90
|
+
usage;
|
|
88
91
|
constructor(code, message, opts) {
|
|
89
92
|
super(message, opts?.cause !== void 0 ? { cause: opts.cause } : void 0);
|
|
90
93
|
this.name = new.target.name;
|
|
91
94
|
this.code = code;
|
|
92
95
|
this.providerStatus = opts?.providerStatus;
|
|
93
96
|
this.retryAfter = opts?.retryAfter;
|
|
97
|
+
this.usage = opts?.usage ? Object.freeze({ ...opts.usage }) : void 0;
|
|
94
98
|
}
|
|
95
99
|
toShape() {
|
|
96
100
|
return {
|
|
@@ -134,7 +138,7 @@ var init_errors = __esm({
|
|
|
134
138
|
ToolInputError = class extends OdlaAIError {
|
|
135
139
|
tool;
|
|
136
140
|
constructor(message, opts) {
|
|
137
|
-
super("tool_input_invalid", message, { cause: opts?.cause });
|
|
141
|
+
super("tool_input_invalid", message, { cause: opts?.cause, usage: opts?.usage });
|
|
138
142
|
this.tool = opts?.tool;
|
|
139
143
|
}
|
|
140
144
|
};
|
|
@@ -585,15 +589,28 @@ function statusOf(err) {
|
|
|
585
589
|
return void 0;
|
|
586
590
|
}
|
|
587
591
|
function retryAfterOf(err) {
|
|
588
|
-
if (err
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
592
|
+
if (!err || typeof err !== "object") return void 0;
|
|
593
|
+
const headers = err.headers;
|
|
594
|
+
if (!headers || typeof headers !== "object") return void 0;
|
|
595
|
+
const header = (name) => {
|
|
596
|
+
const get = headers.get;
|
|
597
|
+
if (typeof get === "function") return get.call(headers, name);
|
|
598
|
+
const entry = Object.entries(headers).find(([key]) => key.toLowerCase() === name);
|
|
599
|
+
return entry?.[1];
|
|
600
|
+
};
|
|
601
|
+
const milliseconds = numericHeader(header("retry-after-ms"));
|
|
602
|
+
if (milliseconds !== void 0) return milliseconds / 1e3;
|
|
603
|
+
const raw = header("retry-after");
|
|
604
|
+
const seconds = numericHeader(raw);
|
|
605
|
+
if (seconds !== void 0) return seconds;
|
|
606
|
+
if (typeof raw !== "string") return void 0;
|
|
607
|
+
const timestamp = Date.parse(raw);
|
|
608
|
+
if (!Number.isFinite(timestamp)) return void 0;
|
|
609
|
+
return Math.max(0, (timestamp - Date.now()) / 1e3);
|
|
610
|
+
}
|
|
611
|
+
function numericHeader(value) {
|
|
612
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : NaN;
|
|
613
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
|
|
597
614
|
}
|
|
598
615
|
function messageOf(err) {
|
|
599
616
|
if (err instanceof Error) return err.message;
|
|
@@ -1920,12 +1937,12 @@ function init(opts = {}) {
|
|
|
1920
1937
|
const res = await provider.create(spec, req);
|
|
1921
1938
|
const block = res.content.find((b) => b.type === "tool_use" && b.name === c.tool.name);
|
|
1922
1939
|
if (!block || block.type !== "tool_use") {
|
|
1923
|
-
throw new ProviderError(`Model "${model}" did not return the forced tool call "${c.tool.name}"
|
|
1940
|
+
throw new ProviderError(`Model "${model}" did not return the forced tool call "${c.tool.name}".`, { usage: res.usage });
|
|
1924
1941
|
}
|
|
1925
1942
|
const validation = validateJsonSchema(c.tool.parameters, block.input);
|
|
1926
1943
|
if (!validation.valid) {
|
|
1927
1944
|
const detail = validation.issues.slice(0, 5).map((i) => `${i.path} ${i.message}`).join("; ");
|
|
1928
|
-
throw new ToolInputError(`Tool "${c.tool.name}" returned invalid input: ${detail}`, { tool: c.tool.name });
|
|
1945
|
+
throw new ToolInputError(`Tool "${c.tool.name}" returned invalid input: ${detail}`, { tool: c.tool.name, usage: res.usage });
|
|
1929
1946
|
}
|
|
1930
1947
|
return { value: block.input, usage: res.usage };
|
|
1931
1948
|
};
|
|
@@ -2102,6 +2119,11 @@ Every error is an OdlaAIError subclass with a stable \`code\` \u2014 branch on e
|
|
|
2102
2119
|
config, auth, rate_limit, capability_unsupported, context_window, invalid_request,
|
|
2103
2120
|
tool_input_invalid, cancelled, deadline_exceeded, provider_error.
|
|
2104
2121
|
|
|
2122
|
+
OdlaAIError.usage is an optional frozen token-usage record. It exists only when
|
|
2123
|
+
the provider returned a response before a later forced-tool/schema validation
|
|
2124
|
+
failure, and may be absent for every earlier failure. It is intentionally not
|
|
2125
|
+
included in toShape() or streaming OracleErrorShape.
|
|
2126
|
+
|
|
2105
2127
|
## Models
|
|
2106
2128
|
|
|
2107
2129
|
${models}
|