@niscorp/signal 0.1.3 → 0.1.4
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 +12 -0
- package/DOCS.md +51 -4
- package/dist/index.cjs +6 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -54
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50,17 +50,11 @@ var providerRegistry = {
|
|
|
50
50
|
endpoint: {
|
|
51
51
|
nativeTools: true,
|
|
52
52
|
nativeJsonMode: true,
|
|
53
|
-
// Groq validates tool args server-side (tool_use_failed 400s).
|
|
54
53
|
validatesToolArgs: true,
|
|
55
54
|
supportsEmbedding: false
|
|
56
55
|
},
|
|
57
56
|
adapter: "openai-compatible",
|
|
58
|
-
// tool_use_failed / json_validate_failed 400s carry the model's
|
|
59
|
-
// attempt in failed_generation — recover and route it.
|
|
60
57
|
wire: ["failed-generation"],
|
|
61
|
-
// Reasoning models stream their trace only when asked to parse it out;
|
|
62
|
-
// `reasoning_format` is rejected on the non-reasoning ones, which is why
|
|
63
|
-
// this is opt-in (see reasoningRequest above).
|
|
64
58
|
reasoningRequest: { reasoning_format: "parsed" }
|
|
65
59
|
},
|
|
66
60
|
openai: {
|
|
@@ -75,8 +69,6 @@ var providerRegistry = {
|
|
|
75
69
|
supportsEmbedding: true
|
|
76
70
|
},
|
|
77
71
|
adapter: "openai-compatible",
|
|
78
|
-
// 4o-era models occasionally emit JSONL where one value was asked
|
|
79
|
-
// for; the acceptance gate decides, so this can never misfire.
|
|
80
72
|
wire: ["jsonl-lines"]
|
|
81
73
|
},
|
|
82
74
|
openrouter: {
|
|
@@ -91,8 +83,6 @@ var providerRegistry = {
|
|
|
91
83
|
supportsEmbedding: false
|
|
92
84
|
},
|
|
93
85
|
adapter: "openai-compatible",
|
|
94
|
-
// OpenRouter unifies reasoning across the models it routes; `enabled` turns
|
|
95
|
-
// the trace on for those that have one and is ignored by those that don't.
|
|
96
86
|
reasoningRequest: { reasoning: { enabled: true } }
|
|
97
87
|
},
|
|
98
88
|
anthropic: {
|
|
@@ -125,97 +115,78 @@ var providerRegistry = {
|
|
|
125
115
|
id: "typesafe",
|
|
126
116
|
baseUrl: "https://api.typesafe.ai/v1",
|
|
127
117
|
envKey: "TYPESAFE_API_KEY",
|
|
128
|
-
// The moving alias. A caller that records calibration against a model pins
|
|
129
|
-
// a version (`jev-1.13.0`) with `.model()`.
|
|
130
118
|
defaultModel: "jev-latest",
|
|
131
119
|
adapter: "systemone"
|
|
132
120
|
}
|
|
133
121
|
};
|
|
134
122
|
var modelRegistry = {
|
|
135
|
-
// ── groq ──
|
|
136
123
|
"groq/qwen/qwen3.8-27b": {
|
|
137
124
|
capabilities: { nativeJsonSchema: false, toolsWithStructuredOutput: false, manglesNestedToolArgs: true, multimodal: true },
|
|
138
|
-
// nested: 3 of 20 trials failed
|
|
139
125
|
reasoningEfforts: ["none", "default", "low", "medium", "high"],
|
|
140
126
|
verified: "2026-09-24"
|
|
141
127
|
},
|
|
142
128
|
"groq/openai/gpt-oss-120b": {
|
|
143
129
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: false, manglesNestedToolArgs: true, multimodal: false },
|
|
144
|
-
// nested: 1 of 20 trials failed
|
|
145
130
|
reasoningEfforts: ["low", "medium", "high"],
|
|
146
131
|
verified: "2026-09-24"
|
|
147
132
|
},
|
|
148
133
|
"groq/openai/gpt-oss-20b": {
|
|
149
134
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: false, manglesNestedToolArgs: true, multimodal: false },
|
|
150
|
-
// nested: 6 of 20 trials failed
|
|
151
135
|
reasoningEfforts: ["low", "medium", "high"],
|
|
152
136
|
verified: "2026-09-24"
|
|
153
137
|
},
|
|
154
|
-
// ── openai ──
|
|
155
138
|
"openai/gpt-4o": {
|
|
156
139
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: true },
|
|
157
|
-
// nested: 0 of 20 trials failed
|
|
158
140
|
reasoningEfforts: [],
|
|
159
141
|
verified: "2026-09-24"
|
|
160
142
|
},
|
|
161
143
|
"openai/gpt-4o-mini": {
|
|
162
144
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: true },
|
|
163
|
-
// nested: 0 of 20 trials failed
|
|
164
145
|
reasoningEfforts: [],
|
|
165
146
|
verified: "2026-09-24"
|
|
166
147
|
},
|
|
167
148
|
"openai/gpt-4.1-mini": {
|
|
168
149
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: true },
|
|
169
|
-
// nested: 0 of 20 trials failed
|
|
170
150
|
reasoningEfforts: [],
|
|
171
151
|
verified: "2026-09-24"
|
|
172
152
|
},
|
|
173
|
-
// ── openrouter ──
|
|
174
153
|
"openrouter/qwen/qwen3.8-27b": {
|
|
175
154
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: true },
|
|
176
|
-
// nested: 0 of 20 trials failed
|
|
177
155
|
reasoningEfforts: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
|
|
178
156
|
verified: "2026-09-24"
|
|
179
157
|
},
|
|
180
158
|
"openrouter/openai/gpt-4o": {
|
|
181
159
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: true },
|
|
182
|
-
// nested: 0 of 20 trials failed
|
|
183
160
|
reasoningEfforts: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
|
|
184
161
|
verified: "2026-09-24"
|
|
185
162
|
},
|
|
186
163
|
"openrouter/openai/gpt-4o-mini": {
|
|
187
164
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: true },
|
|
188
|
-
// nested: 0 of 20 trials failed
|
|
189
165
|
reasoningEfforts: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
|
|
190
166
|
verified: "2026-09-24"
|
|
191
167
|
},
|
|
192
168
|
"openrouter/openai/gpt-oss-120b": {
|
|
193
169
|
capabilities: { nativeJsonSchema: false, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: false },
|
|
194
|
-
// nested: 0 of 20 trials failed
|
|
195
170
|
reasoningEfforts: ["minimal", "low", "medium", "high", "xhigh", "max"],
|
|
196
171
|
verified: "2026-09-24"
|
|
197
172
|
},
|
|
198
173
|
"openrouter/z-ai/glm-5.2": {
|
|
199
174
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: true, multimodal: false },
|
|
200
|
-
// nested: 1 of 20 trials failed
|
|
201
175
|
reasoningEfforts: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
|
|
202
176
|
verified: "2026-09-24"
|
|
203
177
|
},
|
|
204
178
|
"openrouter/openai/gpt-5.6-luna": {
|
|
205
179
|
capabilities: { nativeJsonSchema: true, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: true },
|
|
206
|
-
// nested: 0 of 20 trials failed
|
|
207
180
|
reasoningEfforts: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
|
|
208
181
|
verified: "2026-09-24"
|
|
209
182
|
},
|
|
210
183
|
"openrouter/openai/gpt-oss-20b": {
|
|
211
184
|
capabilities: { nativeJsonSchema: false, toolsWithStructuredOutput: true, manglesNestedToolArgs: false, multimodal: false },
|
|
212
|
-
// nested: 0 of 20 trials failed
|
|
213
185
|
reasoningEfforts: ["minimal", "low", "medium", "high", "xhigh", "max"],
|
|
214
186
|
verified: "2026-09-24"
|
|
215
187
|
},
|
|
216
188
|
"openrouter/meta-llama/llama-3.3-70b-instruct": {
|
|
217
189
|
capabilities: { nativeJsonSchema: false, toolsWithStructuredOutput: true, manglesNestedToolArgs: true, multimodal: false },
|
|
218
|
-
// nested: 9 of 20 trials failed
|
|
219
190
|
reasoningEfforts: ["none", "minimal", "low", "medium", "high", "xhigh", "max"],
|
|
220
191
|
verified: "2026-09-24"
|
|
221
192
|
}
|
|
@@ -379,9 +350,8 @@ var createOpenAICompatibleAdapter = async (config) => {
|
|
|
379
350
|
async function* chatStream(request, options) {
|
|
380
351
|
const streamParams = {
|
|
381
352
|
...buildParams(request),
|
|
382
|
-
//
|
|
383
|
-
//
|
|
384
|
-
// the non-stream `chat` path never sees these, so its content is unmoved.
|
|
353
|
+
// Only when the caller set reasoningEffort: Groq answers `reasoning_format` with a 400
|
|
354
|
+
// on its non-reasoning models.
|
|
385
355
|
...request.options?.reasoningEffort !== void 0 && config.reasoningRequest !== void 0 ? config.reasoningRequest : {},
|
|
386
356
|
stream: true,
|
|
387
357
|
stream_options: { include_usage: true }
|
|
@@ -707,8 +677,6 @@ async function* executeStepStream(config) {
|
|
|
707
677
|
contentBuffer += delta.text;
|
|
708
678
|
yield { type: "text", text: delta.text };
|
|
709
679
|
break;
|
|
710
|
-
// Reasoning is passed straight through and deliberately NOT added to
|
|
711
|
-
// contentBuffer: it is the model thinking, not its answer.
|
|
712
680
|
case "reasoning":
|
|
713
681
|
yield { type: "reasoning", text: delta.text };
|
|
714
682
|
break;
|
|
@@ -1387,10 +1355,7 @@ var buildMessages = (config, input) => {
|
|
|
1387
1355
|
var recoveredStepResult = (recovered, routed, raw, sent) => ({
|
|
1388
1356
|
content: "",
|
|
1389
1357
|
toolCalls: routed.outcome.kind === "tool_calls" ? routed.outcome.calls : [],
|
|
1390
|
-
//
|
|
1391
|
-
// billed for it — and the 400 body carries none. The prompt is known exactly
|
|
1392
|
-
// and the model's attempt is in the rejection, so this is countable rather
|
|
1393
|
-
// than lost. Marked unreported, because it is a reckoning.
|
|
1358
|
+
// The provider bills a rejected generation and its 400 carries no usage.
|
|
1394
1359
|
usage: estimateUsage(sent, recovered.rejection.argsText, routed.outcome.kind === "tool_calls" ? routed.outcome.calls : []),
|
|
1395
1360
|
finishReason: "error_recovered",
|
|
1396
1361
|
raw,
|
|
@@ -1445,10 +1410,6 @@ var createSignalFromConfig = (config) => {
|
|
|
1445
1410
|
...providerTools && { tools: providerTools },
|
|
1446
1411
|
...request.toolChoice !== void 0 && { toolChoice: request.toolChoice },
|
|
1447
1412
|
...request.responseFormat !== void 0 && { responseFormat: request.responseFormat },
|
|
1448
|
-
// The client's own options are the floor; a request may override them
|
|
1449
|
-
// field by field. `complete`/`stream` already run on config.options —
|
|
1450
|
-
// step used to drop them, so a configured client behaved differently
|
|
1451
|
-
// depending on which door the caller came through.
|
|
1452
1413
|
...(config.options !== void 0 || request.options !== void 0) && {
|
|
1453
1414
|
options: { ...config.options, ...request.options }
|
|
1454
1415
|
}
|
|
@@ -1483,8 +1444,7 @@ var createSignalFromConfig = (config) => {
|
|
|
1483
1444
|
const result = {
|
|
1484
1445
|
content: response.content,
|
|
1485
1446
|
toolCalls,
|
|
1486
|
-
//
|
|
1487
|
-
// zero rather than a missing frame.
|
|
1447
|
+
// A non-streaming body always carries usage, so a zero here is a reported zero.
|
|
1488
1448
|
usage: { ...response.usage, reported: true },
|
|
1489
1449
|
finishReason: response.finishReason,
|
|
1490
1450
|
raw: response.raw
|
|
@@ -1580,8 +1540,7 @@ var createSignalFromConfig = (config) => {
|
|
|
1580
1540
|
decisions: acceptUncalibrated(request.questions, result.response, result.meta.provider.raw),
|
|
1581
1541
|
meta: {
|
|
1582
1542
|
model: result.meta.model,
|
|
1583
|
-
// complete()
|
|
1584
|
-
// and does not say which, so this total cannot be vouched for as measured.
|
|
1543
|
+
// complete() adds reported usage to estimated usage and does not say which.
|
|
1585
1544
|
usage: { ...result.meta.usage, reported: false },
|
|
1586
1545
|
durationMs: Date.now() - started,
|
|
1587
1546
|
provider: { raw: result.meta.provider.raw }
|
|
@@ -1589,7 +1548,6 @@ var createSignalFromConfig = (config) => {
|
|
|
1589
1548
|
};
|
|
1590
1549
|
};
|
|
1591
1550
|
return {
|
|
1592
|
-
// Builder methods
|
|
1593
1551
|
apiKey: (key) => fork({ apiKey: key }),
|
|
1594
1552
|
model: (m) => fork({ model: m }),
|
|
1595
1553
|
systemPrompt: (prompt) => fork({ systemPrompt: prompt }),
|
|
@@ -1619,7 +1577,6 @@ var createSignalFromConfig = (config) => {
|
|
|
1619
1577
|
modelKnown: false
|
|
1620
1578
|
};
|
|
1621
1579
|
},
|
|
1622
|
-
// Execution — thin wrappers over the step core (src/complete.ts).
|
|
1623
1580
|
complete: async (input) => runComplete(
|
|
1624
1581
|
{
|
|
1625
1582
|
messages: buildMessages(config, input),
|
|
@@ -1645,10 +1602,8 @@ var createSignalFromConfig = (config) => {
|
|
|
1645
1602
|
},
|
|
1646
1603
|
{ stepStream: stepStreamAs("stream"), model: resolveProvider(config).model, capabilities: resolveCapabilities(config) }
|
|
1647
1604
|
),
|
|
1648
|
-
// ─── Low-level primitives — the execution core itself ────
|
|
1649
1605
|
step,
|
|
1650
1606
|
stepStream,
|
|
1651
|
-
// ─── Embedding ────────────────────────────────────────────
|
|
1652
1607
|
embed: (async (input, options) => {
|
|
1653
1608
|
const adapter = await getChatAdapter("embed");
|
|
1654
1609
|
if (!adapter.embed) {
|
|
@@ -1668,7 +1623,6 @@ var createSignalFromConfig = (config) => {
|
|
|
1668
1623
|
}
|
|
1669
1624
|
return response.embeddings;
|
|
1670
1625
|
}),
|
|
1671
|
-
// ─── Decisions ────────────────────────────────────────────
|
|
1672
1626
|
decide: async (request) => {
|
|
1673
1627
|
assertQuestions(request.questions);
|
|
1674
1628
|
const started = Date.now();
|
|
@@ -1676,7 +1630,6 @@ var createSignalFromConfig = (config) => {
|
|
|
1676
1630
|
const model = resolveProvider(config).model;
|
|
1677
1631
|
return adapter.kind === "decisions" ? decideCalibrated(adapter, model, request, started) : decideEmulated(model, request, started);
|
|
1678
1632
|
},
|
|
1679
|
-
// ─── Low-level: token counting (heuristic) ───────────────
|
|
1680
1633
|
count: async (input) => {
|
|
1681
1634
|
const CHARS_PER_TOKEN2 = 4;
|
|
1682
1635
|
if (typeof input === "string") {
|
|
@@ -1784,8 +1737,7 @@ var resolveTransport = (spec, caps) => {
|
|
|
1784
1737
|
responseMode: spec.responseMode,
|
|
1785
1738
|
responseFormat: {
|
|
1786
1739
|
type: "json_schema",
|
|
1787
|
-
//
|
|
1788
|
-
// keywords; non-strict still constrains and never hard-fails.
|
|
1740
|
+
// Strict mode rejects open records and several keywords; non-strict still constrains.
|
|
1789
1741
|
jsonSchema: { name: "envelope", strict: false, schema: serialized }
|
|
1790
1742
|
},
|
|
1791
1743
|
injectSchemaDoc: injectSchemaDoc2,
|