@jxburros/ai-nugget 0.4.1 → 0.7.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/README.md +158 -382
- package/UPGRADING.md +182 -0
- package/dist/adapters/engines/anthropic.d.ts +7 -1
- package/dist/adapters/engines/anthropic.js +82 -37
- package/dist/adapters/engines/base.d.ts +29 -2
- package/dist/adapters/engines/base.js +52 -8
- package/dist/adapters/engines/google.d.ts +7 -1
- package/dist/adapters/engines/google.js +80 -29
- package/dist/adapters/engines/ollama.d.ts +2 -1
- package/dist/adapters/engines/ollama.js +57 -15
- package/dist/adapters/engines/openaiChat.d.ts +8 -1
- package/dist/adapters/engines/openaiChat.js +109 -29
- package/dist/adapters/profiles.d.ts +21 -1
- package/dist/adapters/profiles.js +12 -2
- package/dist/agent/loop.d.ts +45 -1
- package/dist/agent/loop.js +117 -12
- package/dist/cjs/adapters/engines/anthropic.js +326 -0
- package/dist/cjs/adapters/engines/base.js +147 -0
- package/dist/cjs/adapters/engines/google.js +291 -0
- package/dist/cjs/adapters/engines/ollama.js +205 -0
- package/dist/cjs/adapters/engines/openaiChat.js +312 -0
- package/dist/cjs/adapters/index.js +22 -0
- package/dist/cjs/adapters/profiles.js +125 -0
- package/dist/cjs/agent/index.js +18 -0
- package/dist/cjs/agent/loop.js +373 -0
- package/dist/cjs/agent/tools.js +51 -0
- package/dist/cjs/connect.js +27 -0
- package/dist/cjs/errors.js +110 -0
- package/dist/cjs/handler.js +586 -0
- package/dist/cjs/index.js +28 -0
- package/dist/cjs/json.js +121 -0
- package/dist/cjs/keys.js +81 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/policy.js +42 -0
- package/dist/cjs/reasoning.js +159 -0
- package/dist/cjs/redact.js +78 -0
- package/dist/cjs/tokens.js +22 -0
- package/dist/cjs/transport.js +172 -0
- package/dist/cjs/types.js +6 -0
- package/dist/cjs/util.js +126 -0
- package/dist/errors.js +25 -1
- package/dist/handler.d.ts +67 -1
- package/dist/handler.js +266 -61
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/reasoning.d.ts +45 -0
- package/dist/reasoning.js +154 -0
- package/dist/redact.d.ts +18 -0
- package/dist/redact.js +29 -1
- package/dist/transport.d.ts +3 -1
- package/dist/transport.js +21 -1
- package/dist/types.d.ts +112 -2
- package/dist/util.d.ts +22 -0
- package/dist/util.js +59 -0
- package/nugget/VERSION.txt +2 -2
- package/nugget/dist/adapters/engines/anthropic.d.ts +14 -0
- package/nugget/dist/adapters/engines/anthropic.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/anthropic.js +323 -0
- package/nugget/dist/adapters/engines/anthropic.js.map +1 -0
- package/nugget/dist/adapters/engines/base.d.ts +50 -0
- package/nugget/dist/adapters/engines/base.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/base.js +137 -0
- package/nugget/dist/adapters/engines/base.js.map +1 -0
- package/nugget/dist/adapters/engines/google.d.ts +24 -0
- package/nugget/dist/adapters/engines/google.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/google.js +288 -0
- package/nugget/dist/adapters/engines/google.js.map +1 -0
- package/nugget/dist/adapters/engines/ollama.d.ts +11 -0
- package/nugget/dist/adapters/engines/ollama.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/ollama.js +202 -0
- package/nugget/dist/adapters/engines/ollama.js.map +1 -0
- package/nugget/dist/adapters/engines/openaiChat.d.ts +22 -0
- package/nugget/dist/adapters/engines/openaiChat.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/openaiChat.js +308 -0
- package/nugget/dist/adapters/engines/openaiChat.js.map +1 -0
- package/nugget/dist/adapters/index.d.ts +5 -0
- package/nugget/dist/adapters/index.d.ts.map +1 -0
- package/nugget/dist/adapters/index.js +17 -0
- package/nugget/dist/adapters/index.js.map +1 -0
- package/nugget/dist/adapters/profiles.d.ts +62 -0
- package/nugget/dist/adapters/profiles.d.ts.map +1 -0
- package/nugget/dist/adapters/profiles.js +121 -0
- package/nugget/dist/adapters/profiles.js.map +1 -0
- package/nugget/dist/agent/index.d.ts +3 -0
- package/nugget/dist/agent/index.d.ts.map +1 -0
- package/nugget/dist/agent/index.js +3 -0
- package/nugget/dist/agent/index.js.map +1 -0
- package/nugget/dist/agent/loop.d.ts +114 -0
- package/nugget/dist/agent/loop.d.ts.map +1 -0
- package/nugget/dist/agent/loop.js +371 -0
- package/nugget/dist/agent/loop.js.map +1 -0
- package/nugget/dist/agent/tools.d.ts +29 -0
- package/nugget/dist/agent/tools.d.ts.map +1 -0
- package/nugget/dist/agent/tools.js +48 -0
- package/nugget/dist/agent/tools.js.map +1 -0
- package/nugget/dist/cjs/adapters/engines/anthropic.js +326 -0
- package/nugget/dist/cjs/adapters/engines/base.js +147 -0
- package/nugget/dist/cjs/adapters/engines/google.js +291 -0
- package/nugget/dist/cjs/adapters/engines/ollama.js +205 -0
- package/nugget/dist/cjs/adapters/engines/openaiChat.js +312 -0
- package/nugget/dist/cjs/adapters/index.js +22 -0
- package/nugget/dist/cjs/adapters/profiles.js +125 -0
- package/nugget/dist/cjs/agent/index.js +18 -0
- package/nugget/dist/cjs/agent/loop.js +373 -0
- package/nugget/dist/cjs/agent/tools.js +51 -0
- package/nugget/dist/cjs/connect.js +27 -0
- package/nugget/dist/cjs/errors.js +110 -0
- package/nugget/dist/cjs/handler.js +586 -0
- package/nugget/dist/cjs/index.js +28 -0
- package/nugget/dist/cjs/json.js +121 -0
- package/nugget/dist/cjs/keys.js +81 -0
- package/nugget/dist/cjs/package.json +3 -0
- package/nugget/dist/cjs/policy.js +42 -0
- package/nugget/dist/cjs/reasoning.js +159 -0
- package/nugget/dist/cjs/redact.js +78 -0
- package/nugget/dist/cjs/tokens.js +22 -0
- package/nugget/dist/cjs/transport.js +172 -0
- package/nugget/dist/cjs/types.js +6 -0
- package/nugget/dist/cjs/util.js +126 -0
- package/nugget/dist/connect.d.ts +31 -0
- package/nugget/dist/connect.d.ts.map +1 -0
- package/nugget/dist/connect.js +25 -0
- package/nugget/dist/connect.js.map +1 -0
- package/nugget/dist/errors.d.ts +22 -0
- package/nugget/dist/errors.d.ts.map +1 -0
- package/nugget/dist/errors.js +104 -0
- package/nugget/dist/errors.js.map +1 -0
- package/nugget/dist/handler.d.ts +114 -0
- package/nugget/dist/handler.d.ts.map +1 -0
- package/nugget/dist/handler.js +582 -0
- package/nugget/dist/handler.js.map +1 -0
- package/nugget/dist/index.d.ts +13 -0
- package/nugget/dist/index.d.ts.map +1 -0
- package/nugget/dist/index.js +13 -0
- package/nugget/dist/index.js.map +1 -0
- package/nugget/dist/json.d.ts +7 -0
- package/nugget/dist/json.d.ts.map +1 -0
- package/nugget/dist/json.js +114 -0
- package/nugget/dist/json.js.map +1 -0
- package/nugget/dist/keys.d.ts +7 -0
- package/nugget/dist/keys.d.ts.map +1 -0
- package/nugget/dist/keys.js +75 -0
- package/nugget/dist/keys.js.map +1 -0
- package/nugget/dist/policy.d.ts +6 -0
- package/nugget/dist/policy.d.ts.map +1 -0
- package/nugget/dist/policy.js +37 -0
- package/nugget/dist/policy.js.map +1 -0
- package/nugget/dist/reasoning.d.ts +45 -0
- package/nugget/dist/reasoning.d.ts.map +1 -0
- package/nugget/dist/reasoning.js +154 -0
- package/nugget/dist/reasoning.js.map +1 -0
- package/nugget/dist/redact.d.ts +26 -0
- package/nugget/dist/redact.d.ts.map +1 -0
- package/nugget/dist/redact.js +74 -0
- package/nugget/dist/redact.js.map +1 -0
- package/nugget/dist/tokens.d.ts +5 -0
- package/nugget/dist/tokens.d.ts.map +1 -0
- package/nugget/dist/tokens.js +18 -0
- package/nugget/dist/tokens.js.map +1 -0
- package/nugget/dist/transport.d.ts +30 -0
- package/nugget/dist/transport.d.ts.map +1 -0
- package/nugget/dist/transport.js +165 -0
- package/nugget/dist/transport.js.map +1 -0
- package/nugget/dist/types.d.ts +301 -0
- package/nugget/dist/types.d.ts.map +1 -0
- package/nugget/dist/types.js +4 -0
- package/nugget/dist/types.js.map +1 -0
- package/nugget/dist/util.d.ts +31 -0
- package/nugget/dist/util.d.ts.map +1 -0
- package/nugget/dist/util.js +114 -0
- package/nugget/dist/util.js.map +1 -0
- package/nugget/src/adapters/engines/anthropic.ts +78 -37
- package/nugget/src/adapters/engines/base.ts +50 -7
- package/nugget/src/adapters/engines/google.ts +79 -29
- package/nugget/src/adapters/engines/ollama.ts +56 -17
- package/nugget/src/adapters/engines/openaiChat.ts +104 -30
- package/nugget/src/adapters/profiles.ts +53 -3
- package/nugget/src/agent/loop.ts +156 -13
- package/nugget/src/errors.ts +25 -1
- package/nugget/src/handler.ts +308 -59
- package/nugget/src/index.ts +1 -0
- package/nugget/src/reasoning.ts +174 -0
- package/nugget/src/redact.ts +32 -1
- package/nugget/src/transport.ts +20 -1
- package/nugget/src/types.ts +113 -1
- package/nugget/src/util.ts +64 -0
- package/package.json +18 -5
package/dist/redact.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Prefixed secret formats. Each pattern is anchored on a vendor prefix that is
|
|
3
|
+
* distinctive enough that a match is a secret, not a coincidence.
|
|
4
|
+
*/
|
|
5
|
+
export const SECRET_PATTERNS = [
|
|
2
6
|
/sk-[A-Za-z0-9_-]{20,}/g,
|
|
3
7
|
/sk-proj-[A-Za-z0-9_-]{20,}/g,
|
|
4
8
|
/sk-ant-[A-Za-z0-9_-]{20,}/g,
|
|
@@ -20,6 +24,27 @@ const SECRET_PATTERNS = [
|
|
|
20
24
|
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
21
25
|
/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
|
|
22
26
|
];
|
|
27
|
+
/**
|
|
28
|
+
* Unprefixed/opaque secrets — Azure OpenAI `api-key` values, AWS *secret*
|
|
29
|
+
* access keys, generic bearer/session tokens — carry no distinctive prefix, so
|
|
30
|
+
* matching them on shape alone would redact commit SHAs, content hashes, and
|
|
31
|
+
* base64 payloads. These patterns instead anchor on the *label* that precedes
|
|
32
|
+
* the value (`api-key: …`, `"aws_secret_access_key": "…"`, `password=…`) and
|
|
33
|
+
* redact only the value, keeping the label readable in logs.
|
|
34
|
+
*
|
|
35
|
+
* Exact-match registration (`SessionRedactor.addSecret`, which the handler does
|
|
36
|
+
* for every resolved key) remains the only guaranteed catch for a bare,
|
|
37
|
+
* unlabeled, unprefixed secret.
|
|
38
|
+
*/
|
|
39
|
+
export const LABELED_SECRET_PATTERNS = [
|
|
40
|
+
new RegExp(
|
|
41
|
+
// Lookbehind rather than `\b` so an underscore-joined prefix still matches
|
|
42
|
+
// the label (`aws_secret_access_key`, `azure_api_key`).
|
|
43
|
+
String.raw `(?<![A-Za-z0-9])(api[_-]?key|apikey|secret[_-]?access[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|client[_-]?secret|refresh[_-]?token|private[_-]?key|password|passwd)` +
|
|
44
|
+
// Optional closing quote handles JSON keys (`"api_key": "…"`).
|
|
45
|
+
String.raw `(["']?\s*[:=]\s*|\s+)` +
|
|
46
|
+
String.raw `(["']?)([A-Za-z0-9/+_.~-]{16,}={0,2})\3`, 'gi'),
|
|
47
|
+
];
|
|
23
48
|
export function createDefaultRedactor(extraSecrets = []) {
|
|
24
49
|
const secrets = new Set([...extraSecrets].filter((value) => value.length >= 6));
|
|
25
50
|
return {
|
|
@@ -27,6 +52,9 @@ export function createDefaultRedactor(extraSecrets = []) {
|
|
|
27
52
|
let output = text;
|
|
28
53
|
for (const pattern of SECRET_PATTERNS)
|
|
29
54
|
output = output.replace(pattern, '[REDACTED]');
|
|
55
|
+
for (const pattern of LABELED_SECRET_PATTERNS) {
|
|
56
|
+
output = output.replace(pattern, (_match, label, separator, quote) => `${label}${separator}${quote}[REDACTED]${quote}`);
|
|
57
|
+
}
|
|
30
58
|
for (const secret of secrets)
|
|
31
59
|
output = output.split(secret).join('[REDACTED]');
|
|
32
60
|
return output;
|
package/dist/transport.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export declare function withTimeout(ms: number, external?: AbortSignal): {
|
|
1
|
+
export declare function withTimeout(ms: number, external?: AbortSignal, idleMs?: number): {
|
|
2
2
|
signal: AbortSignal;
|
|
3
3
|
done(): void;
|
|
4
4
|
timedOut(): boolean;
|
|
5
|
+
/** Reset the idle timer. No-op unless `idleMs` was supplied. Call on each chunk. */
|
|
6
|
+
bump(): void;
|
|
5
7
|
};
|
|
6
8
|
export declare function fetchJson(url: string, init: RequestInit & {
|
|
7
9
|
timeoutMs: number;
|
package/dist/transport.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { AIError, classify, fromUnknown } from './errors.js';
|
|
2
|
-
export function withTimeout(ms, external) {
|
|
2
|
+
export function withTimeout(ms, external, idleMs) {
|
|
3
3
|
const controller = new AbortController();
|
|
4
4
|
let didTimeOut = false;
|
|
5
5
|
const timer = setTimeout(() => {
|
|
6
6
|
didTimeOut = true;
|
|
7
7
|
controller.abort(new AIError(`Request timed out after ${ms}ms`, { kind: 'timeout' }));
|
|
8
8
|
}, ms);
|
|
9
|
+
// Optional idle timeout: aborts only when no chunk has arrived for `idleMs`,
|
|
10
|
+
// rearmed on every `bump()`. Keeps a long but healthy stream alive while the
|
|
11
|
+
// total `ms` ceiling still bounds a truly stuck call.
|
|
12
|
+
let idleTimer;
|
|
13
|
+
const armIdle = () => {
|
|
14
|
+
if (idleMs === undefined)
|
|
15
|
+
return;
|
|
16
|
+
if (idleTimer)
|
|
17
|
+
clearTimeout(idleTimer);
|
|
18
|
+
idleTimer = setTimeout(() => {
|
|
19
|
+
didTimeOut = true;
|
|
20
|
+
controller.abort(new AIError(`Request idle for ${idleMs}ms`, { kind: 'timeout' }));
|
|
21
|
+
}, idleMs);
|
|
22
|
+
};
|
|
9
23
|
const onAbort = () => controller.abort(external?.reason);
|
|
10
24
|
if (external) {
|
|
11
25
|
if (external.aborted)
|
|
@@ -13,15 +27,21 @@ export function withTimeout(ms, external) {
|
|
|
13
27
|
else
|
|
14
28
|
external.addEventListener('abort', onAbort, { once: true });
|
|
15
29
|
}
|
|
30
|
+
armIdle();
|
|
16
31
|
return {
|
|
17
32
|
signal: controller.signal,
|
|
18
33
|
done() {
|
|
19
34
|
clearTimeout(timer);
|
|
35
|
+
if (idleTimer)
|
|
36
|
+
clearTimeout(idleTimer);
|
|
20
37
|
external?.removeEventListener('abort', onAbort);
|
|
21
38
|
},
|
|
22
39
|
timedOut() {
|
|
23
40
|
return didTimeOut;
|
|
24
41
|
},
|
|
42
|
+
bump() {
|
|
43
|
+
armIdle();
|
|
44
|
+
},
|
|
25
45
|
};
|
|
26
46
|
}
|
|
27
47
|
export async function fetchJson(url, init) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { KnownProvider } from './adapters/profiles.js';
|
|
2
|
+
export type { KnownProvider };
|
|
1
3
|
export type Role = 'system' | 'user' | 'assistant' | 'tool';
|
|
2
4
|
export interface ContentPart {
|
|
3
5
|
type: 'text' | 'image';
|
|
@@ -23,12 +25,28 @@ export interface ToolSchema {
|
|
|
23
25
|
description: string;
|
|
24
26
|
parameters: object;
|
|
25
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* How hard a reasoning-capable model should think before answering. The nugget
|
|
30
|
+
* maps one vocabulary onto each provider's own knob (see `docs/providers.md`,
|
|
31
|
+
* "Reasoning effort"): OpenAI `reasoning_effort`, Anthropic `thinking`
|
|
32
|
+
* (`budget_tokens` tiers), Google `generationConfig.thinkingConfig.thinkingBudget`,
|
|
33
|
+
* Ollama `think`. `'none'` disables reasoning where the provider allows it.
|
|
34
|
+
* Unset means the provider's own default — the nugget never sends the knob
|
|
35
|
+
* unasked, because non-reasoning models reject it.
|
|
36
|
+
*/
|
|
37
|
+
export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high';
|
|
26
38
|
export interface ChatRequest {
|
|
27
39
|
model: string;
|
|
28
40
|
messages: ChatMessage[];
|
|
29
41
|
temperature?: number;
|
|
30
42
|
maxTokens?: number;
|
|
31
43
|
topP?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Reasoning effort for thinking-capable models — see {@link ReasoningEffort}.
|
|
46
|
+
* A provider-native value in `providerOptions` (e.g. `reasoning_effort`,
|
|
47
|
+
* `thinking`, `thinkingConfig`, `think`) wins over this on collision.
|
|
48
|
+
*/
|
|
49
|
+
reasoningEffort?: ReasoningEffort;
|
|
32
50
|
responseFormat?: {
|
|
33
51
|
type: 'text';
|
|
34
52
|
} | {
|
|
@@ -42,14 +60,39 @@ export interface ChatRequest {
|
|
|
42
60
|
stopSequences?: string[];
|
|
43
61
|
signal?: AbortSignal;
|
|
44
62
|
metadata?: Record<string, unknown>;
|
|
63
|
+
/**
|
|
64
|
+
* Provider-native request fields the nugget does not model as first-class
|
|
65
|
+
* options — an escape hatch so a caller can reach a capability without waiting
|
|
66
|
+
* for a library release. Merged into the outgoing provider request body:
|
|
67
|
+
* shallow at the top level, and one level deep into the provider's own nested
|
|
68
|
+
* option container (Ollama `options`, Google `generationConfig`). Examples:
|
|
69
|
+
* `{ options: { num_ctx: 8192 }, keep_alive: '30m' }` (Ollama),
|
|
70
|
+
* `{ reasoning_effort: 'high' }` (OpenAI), `{ thinking: { type: 'enabled' } }`
|
|
71
|
+
* (Anthropic), `{ safetySettings: [...] }` (Google). Values here win over the
|
|
72
|
+
* nugget's own fields on a key collision, so use with care.
|
|
73
|
+
*/
|
|
74
|
+
providerOptions?: Record<string, unknown>;
|
|
45
75
|
}
|
|
46
76
|
export interface Connection {
|
|
47
77
|
id: string;
|
|
48
|
-
|
|
78
|
+
/**
|
|
79
|
+
* A provider with a profile in the table, or any other string — an unknown
|
|
80
|
+
* key with a `baseUrl` resolves through the `openai-compat` escape hatch.
|
|
81
|
+
* The union is there for autocomplete and typo-catching; the `string & {}`
|
|
82
|
+
* arm keeps the escape hatch open.
|
|
83
|
+
*/
|
|
84
|
+
provider: KnownProvider | (string & {});
|
|
49
85
|
baseUrl?: string;
|
|
50
86
|
keyRef?: KeyRef;
|
|
51
87
|
timeoutMs?: number;
|
|
52
88
|
headers?: Record<string, string>;
|
|
89
|
+
/**
|
|
90
|
+
* Idle timeout for streaming calls: aborts the stream only if no bytes arrive
|
|
91
|
+
* for this many milliseconds, resetting on every chunk. Distinct from
|
|
92
|
+
* `timeoutMs`, which bounds the total call lifetime. Set this (and a generous
|
|
93
|
+
* `timeoutMs`) for long local generations that stream slowly but healthily.
|
|
94
|
+
*/
|
|
95
|
+
idleTimeoutMs?: number;
|
|
53
96
|
}
|
|
54
97
|
export type KeyRef = {
|
|
55
98
|
kind: 'none';
|
|
@@ -103,8 +146,27 @@ export interface ModelSource {
|
|
|
103
146
|
connectionId: string;
|
|
104
147
|
baseUrl?: string;
|
|
105
148
|
}
|
|
149
|
+
export interface EmbedRequest {
|
|
150
|
+
model: string;
|
|
151
|
+
/** One string, or a batch of strings embedded in a single call. */
|
|
152
|
+
input: string | string[];
|
|
153
|
+
signal?: AbortSignal;
|
|
154
|
+
metadata?: Record<string, unknown>;
|
|
155
|
+
/** Provider-native passthrough, same contract as {@link ChatRequest.providerOptions}. */
|
|
156
|
+
providerOptions?: Record<string, unknown>;
|
|
157
|
+
}
|
|
158
|
+
export interface EmbedResult {
|
|
159
|
+
/** One vector per input, in input order. */
|
|
160
|
+
embeddings: number[][];
|
|
161
|
+
model: string;
|
|
162
|
+
usage: Usage;
|
|
163
|
+
source: ModelSource;
|
|
164
|
+
raw?: unknown;
|
|
165
|
+
}
|
|
106
166
|
export declare function modelRef(source: ModelSource, model: string): string;
|
|
107
|
-
export type AIErrorKind = 'auth' | 'rate_limit' | 'timeout' | 'network' | 'server' | 'invalid_request' | 'invalid_response'
|
|
167
|
+
export type AIErrorKind = 'auth' | 'rate_limit' | 'timeout' | 'network' | 'server' | 'invalid_request' | 'invalid_response'
|
|
168
|
+
/** 404/410 — endpoint, deployment, or model not found (wrong baseUrl/model, or a misrouted edge). */
|
|
169
|
+
| 'not_found' | 'context_length' | 'canceled' | 'policy_blocked' | 'key_unavailable' | 'tool_error' | 'budget_exceeded';
|
|
108
170
|
export type StreamEvent = {
|
|
109
171
|
type: 'start';
|
|
110
172
|
callId: string;
|
|
@@ -113,6 +175,9 @@ export type StreamEvent = {
|
|
|
113
175
|
} | {
|
|
114
176
|
type: 'delta';
|
|
115
177
|
text: string;
|
|
178
|
+
} | {
|
|
179
|
+
type: 'reasoning';
|
|
180
|
+
text: string;
|
|
116
181
|
} | {
|
|
117
182
|
type: 'tool_call';
|
|
118
183
|
call: ToolCall;
|
|
@@ -141,6 +206,7 @@ export interface ProviderAdapter {
|
|
|
141
206
|
ok: boolean;
|
|
142
207
|
detail?: string;
|
|
143
208
|
}>;
|
|
209
|
+
embed?(conn: ResolvedConnection, req: EmbedRequest): Promise<EmbedResult>;
|
|
144
210
|
}
|
|
145
211
|
export interface ModelInfo {
|
|
146
212
|
id: string;
|
|
@@ -168,6 +234,15 @@ export interface CallInfo {
|
|
|
168
234
|
provider: string;
|
|
169
235
|
model: string;
|
|
170
236
|
metadata?: Record<string, unknown>;
|
|
237
|
+
/**
|
|
238
|
+
* The fully resolved connection for this call — base URL defaulted from the
|
|
239
|
+
* provider profile and auth headers applied. Present whenever `beforeCall`
|
|
240
|
+
* runs after resolution (chat/stream and probes), letting a hook validate the
|
|
241
|
+
* *effective* endpoint (e.g. a request-time SSRF/DNS-rebinding re-check on the
|
|
242
|
+
* resolved `baseUrl`) without duplicating profile logic. The resolved
|
|
243
|
+
* `apiKey` is intentionally not exposed here.
|
|
244
|
+
*/
|
|
245
|
+
resolved?: Omit<ResolvedConnection, 'apiKey'>;
|
|
171
246
|
}
|
|
172
247
|
export interface CallRecord {
|
|
173
248
|
callId: string;
|
|
@@ -187,5 +262,40 @@ export interface CallRecord {
|
|
|
187
262
|
metadata?: Record<string, unknown>;
|
|
188
263
|
promptChars: number;
|
|
189
264
|
responseChars: number;
|
|
265
|
+
/**
|
|
266
|
+
* Estimated cost of this call in USD, computed by the optional `pricing` hook
|
|
267
|
+
* passed to the handler. Undefined when no pricing hook is configured or the
|
|
268
|
+
* hook returns nothing for this provider/model.
|
|
269
|
+
*/
|
|
270
|
+
costUsd?: number;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Minimal [Standard Schema](https://standardschema.dev) validator surface. Any
|
|
274
|
+
* Zod / Valibot / ArkType schema (v1+) satisfies this via its `~standard`
|
|
275
|
+
* property, so `chatParsed` can validate model output against a schema the app
|
|
276
|
+
* already owns — with zero dependency added to this library.
|
|
277
|
+
*/
|
|
278
|
+
export interface StandardSchemaV1<Output = unknown> {
|
|
279
|
+
readonly '~standard': {
|
|
280
|
+
readonly version: 1;
|
|
281
|
+
readonly vendor: string;
|
|
282
|
+
readonly validate: (value: unknown) => StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
export type StandardSchemaResult<Output> = {
|
|
286
|
+
readonly value: Output;
|
|
287
|
+
readonly issues?: undefined;
|
|
288
|
+
} | {
|
|
289
|
+
readonly issues: ReadonlyArray<{
|
|
290
|
+
readonly message: string;
|
|
291
|
+
readonly path?: ReadonlyArray<PropertyKey | {
|
|
292
|
+
readonly key: PropertyKey;
|
|
293
|
+
}>;
|
|
294
|
+
}>;
|
|
295
|
+
};
|
|
296
|
+
/** Output of {@link AIHandler.chatParsed}: the validated value plus the raw chat result. */
|
|
297
|
+
export interface ParsedResult<T> {
|
|
298
|
+
data: T;
|
|
299
|
+
result: ChatResult;
|
|
190
300
|
}
|
|
191
301
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/util.d.ts
CHANGED
|
@@ -5,5 +5,27 @@ export declare function asNumber(value: unknown): number | undefined;
|
|
|
5
5
|
export declare function promptChars(messages: ChatMessage[]): number;
|
|
6
6
|
export declare function textFromMessages(messages: ChatMessage[]): string;
|
|
7
7
|
export declare function globalEnv(): Record<string, string | undefined>;
|
|
8
|
+
/**
|
|
9
|
+
* Merges app-supplied {@link ChatRequest.providerOptions} into a provider
|
|
10
|
+
* request body: shallow at the top level, and one level deep for each key in
|
|
11
|
+
* `nestedKeys` where both sides are plain objects (Ollama `options`, Google
|
|
12
|
+
* `generationConfig`). Values in `providerOptions` win on collision.
|
|
13
|
+
*/
|
|
14
|
+
export declare function applyProviderOptions(body: Record<string, unknown>, providerOptions: Record<string, unknown> | undefined, nestedKeys?: readonly string[]): Record<string, unknown>;
|
|
15
|
+
/** Joins a base URL and path without producing a double slash, even if `base` ends with `/`. */
|
|
16
|
+
export declare function joinUrl(base: string, path: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Runs `fn` over `items` with at most `limit` in flight at once, preserving
|
|
19
|
+
* input order in the returned array. Used to probe many local models
|
|
20
|
+
* concurrently without opening an unbounded number of sockets.
|
|
21
|
+
*/
|
|
22
|
+
export declare function mapWithConcurrency<T, R>(items: readonly T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
|
|
8
23
|
export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Token budgets behind the {@link ReasoningEffort} tiers for providers that
|
|
26
|
+
* express effort as a thinking-token budget (Anthropic `budget_tokens`, Google
|
|
27
|
+
* `thinkingBudget`). `'none'` is 0. Deliberately conservative: they are floors
|
|
28
|
+
* a model may stop under, not ceilings it fills.
|
|
29
|
+
*/
|
|
30
|
+
export declare const REASONING_BUDGET_TOKENS: Record<'none' | 'minimal' | 'low' | 'medium' | 'high', number>;
|
|
9
31
|
//# sourceMappingURL=util.d.ts.map
|
package/dist/util.js
CHANGED
|
@@ -25,6 +25,52 @@ export function globalEnv() {
|
|
|
25
25
|
const maybeProcess = globalThis;
|
|
26
26
|
return maybeProcess.process?.env ?? {};
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Merges app-supplied {@link ChatRequest.providerOptions} into a provider
|
|
30
|
+
* request body: shallow at the top level, and one level deep for each key in
|
|
31
|
+
* `nestedKeys` where both sides are plain objects (Ollama `options`, Google
|
|
32
|
+
* `generationConfig`). Values in `providerOptions` win on collision.
|
|
33
|
+
*/
|
|
34
|
+
export function applyProviderOptions(body, providerOptions, nestedKeys = []) {
|
|
35
|
+
if (!providerOptions)
|
|
36
|
+
return body;
|
|
37
|
+
const merged = { ...body };
|
|
38
|
+
for (const [key, value] of Object.entries(providerOptions)) {
|
|
39
|
+
const base = asRecord(merged[key]);
|
|
40
|
+
if (nestedKeys.includes(key) && base && asRecord(value)) {
|
|
41
|
+
merged[key] = { ...base, ...value };
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
merged[key] = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return merged;
|
|
48
|
+
}
|
|
49
|
+
/** Joins a base URL and path without producing a double slash, even if `base` ends with `/`. */
|
|
50
|
+
export function joinUrl(base, path) {
|
|
51
|
+
return `${base.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Runs `fn` over `items` with at most `limit` in flight at once, preserving
|
|
55
|
+
* input order in the returned array. Used to probe many local models
|
|
56
|
+
* concurrently without opening an unbounded number of sockets.
|
|
57
|
+
*/
|
|
58
|
+
export async function mapWithConcurrency(items, limit, fn) {
|
|
59
|
+
const results = new Array(items.length);
|
|
60
|
+
let next = 0;
|
|
61
|
+
const workerCount = Math.max(1, Math.min(limit, items.length));
|
|
62
|
+
const worker = async () => {
|
|
63
|
+
for (;;) {
|
|
64
|
+
const index = next;
|
|
65
|
+
next += 1;
|
|
66
|
+
if (index >= items.length)
|
|
67
|
+
return;
|
|
68
|
+
results[index] = await fn(items[index], index);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
await Promise.all(Array.from({ length: workerCount }, worker));
|
|
72
|
+
return results;
|
|
73
|
+
}
|
|
28
74
|
export function sleep(ms, signal) {
|
|
29
75
|
if (ms <= 0)
|
|
30
76
|
return Promise.resolve();
|
|
@@ -52,4 +98,17 @@ export function sleep(ms, signal) {
|
|
|
52
98
|
}
|
|
53
99
|
});
|
|
54
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Token budgets behind the {@link ReasoningEffort} tiers for providers that
|
|
103
|
+
* express effort as a thinking-token budget (Anthropic `budget_tokens`, Google
|
|
104
|
+
* `thinkingBudget`). `'none'` is 0. Deliberately conservative: they are floors
|
|
105
|
+
* a model may stop under, not ceilings it fills.
|
|
106
|
+
*/
|
|
107
|
+
export const REASONING_BUDGET_TOKENS = {
|
|
108
|
+
none: 0,
|
|
109
|
+
minimal: 1024,
|
|
110
|
+
low: 2048,
|
|
111
|
+
medium: 8192,
|
|
112
|
+
high: 16384,
|
|
113
|
+
};
|
|
55
114
|
//# sourceMappingURL=util.js.map
|
package/nugget/VERSION.txt
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
0.
|
|
2
|
-
|
|
1
|
+
0.7.0
|
|
2
|
+
e0e4c28d06eb5e7474c628652e1c56fa5f29ce41c24428270895d7af3b8cd75e
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ChatRequest, ChatResult, ModelInfo, ProviderAdapter, ResolvedConnection, StreamEvent } from '../../types.js';
|
|
2
|
+
export declare class AnthropicAdapter implements ProviderAdapter {
|
|
3
|
+
readonly provider: string;
|
|
4
|
+
constructor(provider: string);
|
|
5
|
+
chat(conn: ResolvedConnection, req: ChatRequest): Promise<ChatResult>;
|
|
6
|
+
stream(conn: ResolvedConnection, req: ChatRequest): AsyncIterable<StreamEvent>;
|
|
7
|
+
/**
|
|
8
|
+
* Lists models from Anthropic's `/v1/models` endpoint (auth + version headers
|
|
9
|
+
* already applied to `conn.headers`). The endpoint does not report a context
|
|
10
|
+
* window, so `contextWindow` is left undefined rather than guessed.
|
|
11
|
+
*/
|
|
12
|
+
listModels(conn: ResolvedConnection): Promise<ModelInfo[]>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/adapters/engines/anthropic.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAe,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,WAAW,EAAY,MAAM,gBAAgB,CAAC;AAMlJ,qBAAa,gBAAiB,YAAW,eAAe;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBACd,QAAQ,EAAE,MAAM;IAItB,IAAI,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAUpE,MAAM,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,WAAW,GAAG,aAAa,CAAC,WAAW,CAAC;IA2HrF;;;;OAIG;IACG,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAajE"}
|