@tangleai/models 0.21.1 → 0.24.1
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/CHANGELOG.md +26 -0
- package/README.md +2 -1
- package/package.json +3 -3
- package/src/check.d.ts +9 -10
- package/src/check.js +14 -18
- package/src/client.d.ts +59 -102
- package/src/client.js +307 -351
- package/src/embed.d.ts +54 -36
- package/src/embed.js +202 -287
- package/src/embedding-vector.d.ts +9 -4
- package/src/embedding-vector.js +13 -17
- package/src/errors.d.ts +26 -9
- package/src/errors.js +22 -24
- package/src/grammar.d.ts +6 -7
- package/src/grammar.js +39 -30
- package/src/index.d.ts +10 -9
- package/src/index.js +9 -10
- package/src/providers.d.ts +41 -31
- package/src/providers.js +79 -99
- package/src/replay.d.ts +52 -37
- package/src/replay.js +31 -59
- package/src/retry.d.ts +45 -86
- package/src/retry.js +50 -105
- package/src/routing.d.ts +5 -9
- package/src/routing.js +91 -79
- package/src/sse.d.ts +10 -1
- package/src/sse.js +0 -2
- package/src/structured.d.ts +19 -17
- package/src/structured.js +95 -124
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @tangleai/models
|
|
2
2
|
|
|
3
|
+
## 0.24.1
|
|
4
|
+
|
|
5
|
+
No changes in this release.
|
|
6
|
+
|
|
7
|
+
## 0.24.0
|
|
8
|
+
|
|
9
|
+
No changes in this release.
|
|
10
|
+
|
|
11
|
+
## 0.23.0
|
|
12
|
+
|
|
13
|
+
No changes in this release.
|
|
14
|
+
|
|
15
|
+
## 0.22.0
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Convert the migrated source, tests, benchmarks and hosts to strict TypeScript,
|
|
20
|
+
with JavaScript and declarations emitted through one release build. Move the
|
|
21
|
+
program pen from `@tangleai/jaren/program` and the Jaren integration barrel to
|
|
22
|
+
`@tangleai/linq/program`, preserving its JSON format and phantom binding types.
|
|
23
|
+
The new `@tangleai/linq` root exposes the program namespace and shared build error.
|
|
24
|
+
|
|
25
|
+
Match the embedder declarations to unknown widths before the first response,
|
|
26
|
+
retain precise ledger result variants, and enforce the refinement-pressure
|
|
27
|
+
instrument's stated 60-second deadline through the chat client's abort signal.
|
|
28
|
+
|
|
3
29
|
## 0.21.1
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Injected model clients, provider adapters, embeddings, replay, routing and structured generation.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The implementation and deterministic tests use strict TypeScript. Published
|
|
6
|
+
packages contain ESM JavaScript and declarations emitted from that source. Inject
|
|
6
7
|
fetch, storage and compiler services at the existing seams. The public source
|
|
7
8
|
exports and emitted npm JavaScript share one implementation.
|
|
8
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangleai/models",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "Injected model clients, provider adapters, embeddings, replay, routing and structured generation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
},
|
|
70
70
|
"sideEffects": false,
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@jarenjs/core": "0.
|
|
73
|
-
"@jarenjs/validate": "0.
|
|
72
|
+
"@jarenjs/core": "0.86.0",
|
|
73
|
+
"@jarenjs/validate": "0.86.0"
|
|
74
74
|
},
|
|
75
75
|
"private": false,
|
|
76
76
|
"files": [
|
package/src/check.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/** Model-facing validation feedback over the shared strict check contract. */
|
|
2
|
+
/** Validation errors reported back per rejected write — enough to fix
|
|
3
|
+
* from, few enough to stay readable in a model's context. */
|
|
4
|
+
export declare const MAX_INPUT_ERRORS = 8;
|
|
1
5
|
/**
|
|
2
6
|
* The one rejection shape every schema-guarded boundary in this package
|
|
3
7
|
* answers with: `{ error, errors, inputSchema }`, never a throw. The
|
|
@@ -10,20 +14,15 @@
|
|
|
10
14
|
* (the toolbox's `hint`), then `inputSchema` last, because the schema is
|
|
11
15
|
* the biggest member and a reader scans the message first.
|
|
12
16
|
*
|
|
13
|
-
* @param
|
|
14
|
-
* @param
|
|
15
|
-
* @param
|
|
16
|
-
* @param
|
|
17
|
-
* @returns {{ error: string, errors: any[], inputSchema: any }}
|
|
17
|
+
* @param what - what was being validated (`add`, `memory`, …)
|
|
18
|
+
* @param outcome - a normalized {@link checkOutcome}
|
|
19
|
+
* @param inputSchema - the schema to re-read
|
|
20
|
+
* @param [extra] - boundary-specific members
|
|
18
21
|
*/
|
|
19
|
-
export function invalidInput(what: string, outcome: {
|
|
22
|
+
export declare function invalidInput(what: string, outcome: {
|
|
20
23
|
errors: any[];
|
|
21
24
|
}, inputSchema: any, extra?: Record<string, any>): {
|
|
22
25
|
error: string;
|
|
23
26
|
errors: any[];
|
|
24
27
|
inputSchema: any;
|
|
25
28
|
};
|
|
26
|
-
/** Model-facing validation feedback over the shared strict check contract. */
|
|
27
|
-
/** Validation errors reported back per rejected write — enough to fix
|
|
28
|
-
* from, few enough to stay readable in a model's context. */
|
|
29
|
-
export const MAX_INPUT_ERRORS: 8;
|
package/src/check.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
//@ts-check
|
|
2
1
|
/** Model-facing validation feedback over the shared strict check contract. */
|
|
3
|
-
|
|
4
2
|
/** Validation errors reported back per rejected write — enough to fix
|
|
5
3
|
* from, few enough to stay readable in a model's context. */
|
|
6
4
|
export const MAX_INPUT_ERRORS = 8;
|
|
7
|
-
|
|
8
5
|
/**
|
|
9
6
|
* The one rejection shape every schema-guarded boundary in this package
|
|
10
7
|
* answers with: `{ error, errors, inputSchema }`, never a throw. The
|
|
@@ -17,21 +14,20 @@ export const MAX_INPUT_ERRORS = 8;
|
|
|
17
14
|
* (the toolbox's `hint`), then `inputSchema` last, because the schema is
|
|
18
15
|
* the biggest member and a reader scans the message first.
|
|
19
16
|
*
|
|
20
|
-
* @param
|
|
21
|
-
* @param
|
|
22
|
-
* @param
|
|
23
|
-
* @param
|
|
24
|
-
* @returns {{ error: string, errors: any[], inputSchema: any }}
|
|
17
|
+
* @param what - what was being validated (`add`, `memory`, …)
|
|
18
|
+
* @param outcome - a normalized {@link checkOutcome}
|
|
19
|
+
* @param inputSchema - the schema to re-read
|
|
20
|
+
* @param [extra] - boundary-specific members
|
|
25
21
|
*/
|
|
26
22
|
export function invalidInput(what, outcome, inputSchema, extra = {}) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
23
|
+
return {
|
|
24
|
+
error: `invalid input for ${what}`,
|
|
25
|
+
errors: outcome.errors.slice(0, MAX_INPUT_ERRORS).map((e) => ({
|
|
26
|
+
instancePath: e.instancePath ?? '',
|
|
27
|
+
keyword: e.keyword ?? '',
|
|
28
|
+
message: e.message ?? 'invalid',
|
|
29
|
+
})),
|
|
30
|
+
...extra,
|
|
31
|
+
inputSchema,
|
|
32
|
+
};
|
|
37
33
|
}
|
package/src/client.d.ts
CHANGED
|
@@ -1,63 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chat client: one `complete()` call against any OpenAI-compatible
|
|
3
|
+
* `/chat/completions` endpoint, streaming by default. The host injects
|
|
4
|
+
* `fetch` exactly like every other jarenjs boundary injects its
|
|
5
|
+
* environment, so the client runs identically in the browser, in Node
|
|
6
|
+
* and in tests against a scripted stub.
|
|
7
|
+
*
|
|
8
|
+
* The reply is normalized to `{ message: { role, content, toolCalls },
|
|
9
|
+
* finishReason, usage, model }` whether the server streamed deltas or
|
|
10
|
+
* answered in one JSON document.
|
|
11
|
+
*/
|
|
1
12
|
/**
|
|
2
13
|
* The reasoning text one streamed chunk carries: the OpenRouter/`o`-
|
|
3
14
|
* family `delta.reasoning` string, or the `reasoning_details` text
|
|
4
15
|
* entries some providers emit instead.
|
|
5
|
-
* @param {any} delta
|
|
6
|
-
* @returns {string}
|
|
7
16
|
*/
|
|
8
|
-
export function reasoningOf(delta: any): string;
|
|
17
|
+
export declare function reasoningOf(delta: any): string;
|
|
9
18
|
/**
|
|
10
19
|
* Accumulates OpenAI streaming chunks (`choices[0].delta`) into one
|
|
11
20
|
* normalized assistant message. Tool-call fragments merge by `index`;
|
|
12
21
|
* argument strings concatenate across chunks; reasoning deltas
|
|
13
22
|
* accumulate into `message.reasoning` (absent when the model emitted
|
|
14
23
|
* none) so a reasoning-only turn is distinguishable from an empty one.
|
|
15
|
-
* @returns
|
|
24
|
+
* @returns
|
|
16
25
|
* `push` returns the text delta this chunk contributed (may be '').
|
|
17
26
|
*/
|
|
18
|
-
export function createStreamAccumulator(): {
|
|
27
|
+
export declare function createStreamAccumulator(): {
|
|
19
28
|
push: (chunk: any) => string;
|
|
20
29
|
result: () => any;
|
|
21
30
|
};
|
|
22
31
|
/**
|
|
23
|
-
* @
|
|
24
|
-
* @property {any[]} messages - OpenAI wire-shape messages
|
|
25
|
-
* @property {any[]} [tools] - OpenAI function-tool definitions
|
|
26
|
-
* @property {any} [toolChoice] - `tool_choice` passthrough
|
|
27
|
-
* @property {string} [model] - overrides the client's configured model
|
|
28
|
-
* @property {number} [temperature]
|
|
29
|
-
* @property {number} [maxTokens] - token ceiling for this reply, sent under
|
|
30
|
-
* the client's `maxTokensField`. Overrides the client default; when
|
|
31
|
-
* both are unset, the provider chooses the limit. With
|
|
32
|
-
* `max_completion_tokens`, reasoning tokens share this budget with
|
|
33
|
-
* visible output tokens.
|
|
34
|
-
* @property {boolean} [stream] - default true
|
|
35
|
-
* @property {{ name?: string, schema?: any, strict?: boolean, type?: 'json' }} [responseFormat]
|
|
36
|
-
* - structured output: `{ name, schema, strict? }` emits the OpenAI
|
|
37
|
-
* `response_format: { type: "json_schema", … }` wire shape (strict
|
|
38
|
-
* defaults to true); `{ type: 'json' }` emits `json_object` mode
|
|
39
|
-
* @property {{ effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high',
|
|
40
|
-
* enabled?: boolean, exclude?: boolean, max_tokens?: number }} [reasoning]
|
|
41
|
-
* - the provider-normalized thinking control, forwarded verbatim.
|
|
42
|
-
* `{ effort: 'none' }` (or `{ enabled: false }`) turns a hybrid
|
|
43
|
-
* thinking model OFF: it answers directly, which on a short task is
|
|
44
|
-
* dramatically cheaper and faster. `{ exclude: true }` only HIDES the
|
|
45
|
-
* thinking — the model still thinks and you still pay for it.
|
|
46
|
-
* Overrides the client-level default.
|
|
47
|
-
* @property {AbortSignal} [signal]
|
|
48
|
-
* @property {(text: string) => void} [onDelta] - streamed text callback
|
|
49
|
-
* @property {(text: string) => void} [onReasoning] - streamed reasoning
|
|
50
|
-
* callback (reasoning models emit thinking before/instead of content)
|
|
51
|
-
*/
|
|
52
|
-
/**
|
|
53
|
-
* @param {{ provider?: string, baseUrl?: string, apiKey?: string,
|
|
54
|
-
* model?: string, headers?: Record<string, string>,
|
|
55
|
-
* fetch?: typeof fetch, maxTokens?: number,
|
|
56
|
-
* maxTokensField?: 'max_tokens' | 'max_completion_tokens',
|
|
57
|
-
* reasoning?: { effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high',
|
|
58
|
-
* enabled?: boolean, exclude?: boolean, max_tokens?: number },
|
|
59
|
-
* retry?: import('./retry.js').RetryOptions,
|
|
60
|
-
* cache?: import('./replay.js').ReplayCache }} [options]
|
|
32
|
+
* @param [options]
|
|
61
33
|
* - `maxTokensField` selects the wire field for client and request
|
|
62
34
|
* `maxTokens` budgets (default `'max_tokens'`). Select
|
|
63
35
|
* `'max_completion_tokens'` for OpenAI Chat Completions, including
|
|
@@ -86,11 +58,8 @@ export function createStreamAccumulator(): {
|
|
|
86
58
|
* value it asked for rides the final error as `retryAfterMs` for
|
|
87
59
|
* the caller to honour. `random` and `sleep` exist for deterministic
|
|
88
60
|
* tests.
|
|
89
|
-
* @returns {{ endpoint: { provider: string, base: string, url: string,
|
|
90
|
-
* headers: Record<string, string>, model: string },
|
|
91
|
-
* complete: (request: ChatRequest) => Promise<any> }}
|
|
92
61
|
*/
|
|
93
|
-
export function createChatClient(options?: {
|
|
62
|
+
export declare function createChatClient(options?: {
|
|
94
63
|
provider?: string;
|
|
95
64
|
baseUrl?: string;
|
|
96
65
|
apiKey?: string;
|
|
@@ -98,15 +67,15 @@ export function createChatClient(options?: {
|
|
|
98
67
|
headers?: Record<string, string>;
|
|
99
68
|
fetch?: typeof fetch;
|
|
100
69
|
maxTokens?: number;
|
|
101
|
-
maxTokensField?:
|
|
70
|
+
maxTokensField?: 'max_tokens' | 'max_completion_tokens';
|
|
102
71
|
reasoning?: {
|
|
103
|
-
effort?:
|
|
72
|
+
effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high';
|
|
104
73
|
enabled?: boolean;
|
|
105
74
|
exclude?: boolean;
|
|
106
75
|
max_tokens?: number;
|
|
107
76
|
};
|
|
108
|
-
retry?: import(
|
|
109
|
-
cache?: import(
|
|
77
|
+
retry?: import('./retry.ts').RetryOptions;
|
|
78
|
+
cache?: import('./replay.ts').ReplayCache;
|
|
110
79
|
}): {
|
|
111
80
|
endpoint: {
|
|
112
81
|
provider: string;
|
|
@@ -118,68 +87,56 @@ export function createChatClient(options?: {
|
|
|
118
87
|
complete: (request: ChatRequest) => Promise<any>;
|
|
119
88
|
};
|
|
120
89
|
export type ChatRequest = {
|
|
121
|
-
/**
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
* - `tool_choice` passthrough
|
|
131
|
-
*/
|
|
132
|
-
toolChoice?: any;
|
|
133
|
-
/**
|
|
134
|
-
* - overrides the client's configured model
|
|
135
|
-
*/
|
|
90
|
+
messages: any[]; /**
|
|
91
|
+
* - OpenAI function-tool definitions
|
|
92
|
+
*/
|
|
93
|
+
tools?: any[]; /**
|
|
94
|
+
* - `tool_choice` passthrough
|
|
95
|
+
*/
|
|
96
|
+
toolChoice?: any; /**
|
|
97
|
+
* - overrides the client's configured model
|
|
98
|
+
*/
|
|
136
99
|
model?: string;
|
|
137
|
-
temperature?: number;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
* `response_format: { type: "json_schema", … }` wire shape (strict
|
|
153
|
-
* defaults to true); `{ type: 'json' }` emits `json_object` mode
|
|
154
|
-
*/
|
|
100
|
+
temperature?: number; /**
|
|
101
|
+
* - token ceiling for this reply, sent under
|
|
102
|
+
* the client's `maxTokensField`. Overrides the client default; when
|
|
103
|
+
* both are unset, the provider chooses the limit. With
|
|
104
|
+
* `max_completion_tokens`, reasoning tokens share this budget with
|
|
105
|
+
* visible output tokens.
|
|
106
|
+
*/
|
|
107
|
+
maxTokens?: number; /**
|
|
108
|
+
* - default true
|
|
109
|
+
*/
|
|
110
|
+
stream?: boolean; /**
|
|
111
|
+
* - structured output: `{ name, schema, strict? }` emits the OpenAI
|
|
112
|
+
* `response_format: { type: "json_schema", … }` wire shape (strict
|
|
113
|
+
* defaults to true); `{ type: 'json' }` emits `json_object` mode
|
|
114
|
+
*/
|
|
155
115
|
responseFormat?: {
|
|
156
116
|
name?: string;
|
|
157
117
|
schema?: any;
|
|
158
118
|
strict?: boolean;
|
|
159
119
|
type?: "json";
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
*/
|
|
120
|
+
}; /**
|
|
121
|
+
* - the provider-normalized thinking control, forwarded verbatim.
|
|
122
|
+
* `{ effort: 'none' }` (or `{ enabled: false }`) turns a hybrid
|
|
123
|
+
* thinking model OFF: it answers directly, which on a short task is
|
|
124
|
+
* dramatically cheaper and faster. `{ exclude: true }` only HIDES the
|
|
125
|
+
* thinking — the model still thinks and you still pay for it.
|
|
126
|
+
* Overrides the client-level default.
|
|
127
|
+
*/
|
|
169
128
|
reasoning?: {
|
|
170
129
|
effort?: "none" | "minimal" | "low" | "medium" | "high";
|
|
171
130
|
enabled?: boolean;
|
|
172
131
|
exclude?: boolean;
|
|
173
132
|
max_tokens?: number;
|
|
174
133
|
};
|
|
175
|
-
signal?: AbortSignal;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
* callback (reasoning models emit thinking before/instead of content)
|
|
183
|
-
*/
|
|
134
|
+
signal?: AbortSignal; /**
|
|
135
|
+
* - streamed text callback
|
|
136
|
+
*/
|
|
137
|
+
onDelta?: (text: string) => void; /**
|
|
138
|
+
* - streamed reasoning
|
|
139
|
+
* callback (reasoning models emit thinking before/instead of content)
|
|
140
|
+
*/
|
|
184
141
|
onReasoning?: (text: string) => void;
|
|
185
142
|
};
|