nuabase 2.3.5 → 2.3.11
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 +5 -5
- package/dist/cjs/chunks/{logger-Co5uZG0A.cjs → strict-json-schema-DUE7RTxG.cjs} +87 -0
- package/dist/cjs/index.cjs +47 -14
- package/dist/cjs/local-agent.cjs +163 -92
- package/dist/esm/chunks/{logger-DnkHzkX_.mjs → strict-json-schema-DI9qiH5h.mjs} +87 -1
- package/dist/esm/index.mjs +44 -11
- package/dist/esm/local-agent.mjs +160 -89
- package/dist/types/nua-llm-core/modules/engine/http/http-engine.d.ts +3 -2
- package/dist/types/nua-llm-core/modules/engine/http/provider-config.d.ts +5 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/adapters/pi.d.ts +2 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/agent-id.d.ts +1 -1
- package/package.json +3 -10
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# nuabase
|
|
2
|
+
|
|
3
|
+
## 2.3.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Ship the changelog in the npm package
|
|
8
|
+
|
|
9
|
+
## 2.3.10
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 0303881: The "fast" model alias now uses `openai/gpt-oss-120b` on Groq instead of the preview `qwen/qwen3.8-27b`. On Groq models that support strict structured outputs, casts now enforce the output schema natively instead of describing it in the prompt.
|
|
14
|
+
|
|
15
|
+
## 2.3.9
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Format the release script with Prettier
|
|
20
|
+
|
|
21
|
+
## 2.3.8
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Publish the packed tarball with npm, so 2FA is approved in the browser
|
|
26
|
+
Release nuabase through changesets and the release train
|
package/README.md
CHANGED
|
@@ -172,7 +172,7 @@ Every call returns a discriminated union. When `success` is `false`, you get an
|
|
|
172
172
|
| `engine` | `'http'` \| `'local-agent'` | Whether an LLM provider's API or a coding agent on this machine answered. |
|
|
173
173
|
| `schemaEnforcement` | `'in-prompt'` \| `'native'` | Whether the schema was described in the prompt or enforced by the engine. Output is validated either way. |
|
|
174
174
|
| `provider` | `string` | `engine: 'http'` only. The LLM provider. |
|
|
175
|
-
| `agent` | `'claude-code'` \| `'codex'` | `engine: 'local-agent'` only. Which coding agent answered. |
|
|
175
|
+
| `agent` | `'claude-code'` \| `'codex'` \| `'pi'` | `engine: 'local-agent'` only. Which coding agent answered. |
|
|
176
176
|
| `costUsdEstimate` | `number \| undefined` | `engine: 'local-agent'` only. The agent's own estimate. On a subscription this is not what you pay. |
|
|
177
177
|
|
|
178
178
|
**Error**
|
|
@@ -233,13 +233,13 @@ const agents = await detectLocalAgents();
|
|
|
233
233
|
// [{ agent: 'claude-code', installed: true, loggedIn: true, version: '...', binaryPath: '...' }, ...]
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
-
This runs a coding-agent CLI already installed and logged in on this machine, in its headless mode (`claude -p` or `
|
|
236
|
+
This runs a coding-agent CLI already installed and logged in on this machine, in its headless mode (`claude -p`, `codex exec`, or `pi --mode json`). Calls use the user's own logged-in subscription or provider login, so no API key is needed. `get()` and `list()` behave as with providers: the output is validated against your schema and typed the same way. Queue operations are not supported. `nuabase/local-agent` is a separate entry point so that browser bundles of `nuabase` never include it.
|
|
237
237
|
|
|
238
238
|
The agent is set up once, when you create it. If you install an agent or log in after that, create a new one.
|
|
239
239
|
|
|
240
240
|
**`localAgent(config)`** sets up a named agent. It throws right away if the agent's executable cannot be found; if the agent is not logged in, the first call fails with that error.
|
|
241
241
|
|
|
242
|
-
- `agent: 'claude-code' | 'codex'`
|
|
242
|
+
- `agent: 'claude-code' | 'codex' | 'pi'`
|
|
243
243
|
- `binaryPath?: string` – Path to the agent executable. Defaults to looking it up on `PATH`. On Windows, point this at a native executable; `.cmd` shims are not supported.
|
|
244
244
|
- and the options below.
|
|
245
245
|
|
|
@@ -247,13 +247,13 @@ The agent is set up once, when you create it. If you install an agent or log in
|
|
|
247
247
|
|
|
248
248
|
Options for both:
|
|
249
249
|
|
|
250
|
-
- `model?: string` – The agent's own model name, e.g. `'haiku'` for Claude Code, for calls that name no model. Defaults to the agent's default. Per-call `model: { alias }` works for aliases the agent understands (`haiku`, `sonnet`, `opus` for Claude Code).
|
|
250
|
+
- `model?: string` – The agent's own model name, e.g. `'haiku'` for Claude Code, for calls that name no model. Defaults to the agent's default. Per-call `model: { alias }` works for aliases the agent understands (`haiku`, `sonnet`, `opus` for Claude Code). Codex and Pi have no aliases: pass one of their own model names, and for Pi a `provider/id` name such as `'openrouter/z-ai/glm-5.2'`.
|
|
251
251
|
- `timeoutMs?: number` – Per-call limit. Defaults to `180000`.
|
|
252
252
|
- `concurrency?: number` – Maximum agent processes at once. Defaults to `2`.
|
|
253
253
|
- `auth?: 'subscription' | 'inherit'` – `subscription` (default) hides `ANTHROPIC_API_KEY`, `OPENAI_API_KEY` and similar variables from the agent so it bills the logged-in plan rather than an API key.
|
|
254
254
|
- `logger?` – An object with `debug`, `info`, `warn` and `error` methods, where calls and retries are logged. Defaults to the console.
|
|
255
255
|
|
|
256
|
-
How it works: each call runs the agent in a fresh, empty temporary directory with its tools, project settings and MCP servers turned off. The schema is wrapped as `{ value: ... }` (the agents require an object at the top level) and passed to the agent's own schema option. Codex only accepts OpenAI strict-mode schemas, so a schema with optional properties or open-ended objects is instead described in the prompt, and the output is validated as usual. If an agent rejects a schema, the call is retried with the schema in the prompt. `maxTokens` has no CLI equivalent and is ignored. Calls count against the user's plan limits; check each vendor's terms before offering this to other users.
|
|
256
|
+
How it works: each call runs the agent in a fresh, empty temporary directory with its tools, project settings and MCP servers turned off. The schema is wrapped as `{ value: ... }` (the agents require an object at the top level) and passed to the agent's own schema option. Codex only accepts OpenAI strict-mode schemas, so a schema with optional properties or open-ended objects is instead described in the prompt, and the output is validated as usual. Pi has no schema flag at all, so its schemas are always described in the prompt. If an agent rejects a schema, the call is retried with the schema in the prompt. `maxTokens` has no CLI equivalent and is ignored. Calls count against the user's plan limits; check each vendor's terms before offering this to other users.
|
|
257
257
|
|
|
258
258
|
### Methods
|
|
259
259
|
|
|
@@ -87,4 +87,91 @@ function requireLogger() {
|
|
|
87
87
|
return logger;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
var strictJsonSchema = {};
|
|
91
|
+
|
|
92
|
+
var hasRequiredStrictJsonSchema;
|
|
93
|
+
function requireStrictJsonSchema() {
|
|
94
|
+
if (hasRequiredStrictJsonSchema) return strictJsonSchema;
|
|
95
|
+
hasRequiredStrictJsonSchema = 1;
|
|
96
|
+
Object.defineProperty(strictJsonSchema, "__esModule", { value: true });
|
|
97
|
+
strictJsonSchema.toStrictSchema = toStrictSchema;
|
|
98
|
+
const STRICT_UNSUPPORTED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
99
|
+
"patternProperties",
|
|
100
|
+
"propertyNames",
|
|
101
|
+
"unevaluatedProperties",
|
|
102
|
+
"dependentRequired",
|
|
103
|
+
"dependentSchemas",
|
|
104
|
+
"if",
|
|
105
|
+
"then",
|
|
106
|
+
"else",
|
|
107
|
+
"not",
|
|
108
|
+
"allOf",
|
|
109
|
+
"oneOf"
|
|
110
|
+
]);
|
|
111
|
+
function toStrictSchema(schema) {
|
|
112
|
+
return strictNode(schema);
|
|
113
|
+
}
|
|
114
|
+
function strictNode(node) {
|
|
115
|
+
if (typeof node !== "object" || node === null || Array.isArray(node)) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const schema = node;
|
|
119
|
+
for (const key of Object.keys(schema)) {
|
|
120
|
+
if (STRICT_UNSUPPORTED_KEYWORDS.has(key))
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const result = { ...schema };
|
|
124
|
+
delete result.$schema;
|
|
125
|
+
const isObject = schema.type === "object" || Array.isArray(schema.type) && schema.type.includes("object") || schema.properties !== void 0;
|
|
126
|
+
if (isObject) {
|
|
127
|
+
const properties = schema.properties ?? {};
|
|
128
|
+
if (schema.additionalProperties !== void 0 && schema.additionalProperties !== false) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const required = new Set(schema.required ?? []);
|
|
132
|
+
const shapedProperties = {};
|
|
133
|
+
for (const [name, child] of Object.entries(properties)) {
|
|
134
|
+
if (!required.has(name))
|
|
135
|
+
return null;
|
|
136
|
+
const shaped = strictNode(child);
|
|
137
|
+
if (!shaped)
|
|
138
|
+
return null;
|
|
139
|
+
shapedProperties[name] = shaped;
|
|
140
|
+
}
|
|
141
|
+
result.properties = shapedProperties;
|
|
142
|
+
result.required = Object.keys(shapedProperties);
|
|
143
|
+
result.additionalProperties = false;
|
|
144
|
+
}
|
|
145
|
+
if (schema.items !== void 0) {
|
|
146
|
+
const shaped = strictNode(schema.items);
|
|
147
|
+
if (!shaped)
|
|
148
|
+
return null;
|
|
149
|
+
result.items = shaped;
|
|
150
|
+
}
|
|
151
|
+
if (schema.prefixItems !== void 0)
|
|
152
|
+
return null;
|
|
153
|
+
if (schema.anyOf !== void 0) {
|
|
154
|
+
const variants = schema.anyOf.map(strictNode);
|
|
155
|
+
if (variants.some((v) => v === null))
|
|
156
|
+
return null;
|
|
157
|
+
result.anyOf = variants;
|
|
158
|
+
}
|
|
159
|
+
for (const defsKey of ["$defs", "definitions"]) {
|
|
160
|
+
if (schema[defsKey] !== void 0) {
|
|
161
|
+
const defs = {};
|
|
162
|
+
for (const [name, child] of Object.entries(schema[defsKey])) {
|
|
163
|
+
const shaped = strictNode(child);
|
|
164
|
+
if (!shaped)
|
|
165
|
+
return null;
|
|
166
|
+
defs[name] = shaped;
|
|
167
|
+
}
|
|
168
|
+
result[defsKey] = defs;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
return strictJsonSchema;
|
|
174
|
+
}
|
|
175
|
+
|
|
90
176
|
exports.requireLogger = requireLogger;
|
|
177
|
+
exports.requireStrictJsonSchema = requireStrictJsonSchema;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var strictJsonSchema = require('./chunks/strict-json-schema-DUE7RTxG.cjs');
|
|
4
4
|
var zod = require('zod');
|
|
5
5
|
|
|
6
6
|
var dist = {};
|
|
@@ -9841,7 +9841,7 @@ function requireProviderConfig() {
|
|
|
9841
9841
|
};
|
|
9842
9842
|
};
|
|
9843
9843
|
exports$1.normalizeGeminiUsage = normalizeGeminiUsage;
|
|
9844
|
-
const buildOpenAiStyleRequest = (baseUrl) => ({ prompt, model, maxTokens, assistantPrefillPrompt }, apiKey) => {
|
|
9844
|
+
const buildOpenAiStyleRequest = (baseUrl) => ({ prompt, model, maxTokens, assistantPrefillPrompt, responseSchema }, apiKey) => {
|
|
9845
9845
|
const messages = [];
|
|
9846
9846
|
messages.push({ role: "user", content: prompt });
|
|
9847
9847
|
if (assistantPrefillPrompt) {
|
|
@@ -9854,7 +9854,13 @@ function requireProviderConfig() {
|
|
|
9854
9854
|
max_completion_tokens: maxTokens,
|
|
9855
9855
|
top_p: 1,
|
|
9856
9856
|
stream: false,
|
|
9857
|
-
stop: null
|
|
9857
|
+
stop: null,
|
|
9858
|
+
...responseSchema && {
|
|
9859
|
+
response_format: {
|
|
9860
|
+
type: "json_schema",
|
|
9861
|
+
json_schema: { name: "response", strict: true, schema: responseSchema }
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9858
9864
|
};
|
|
9859
9865
|
const headers = {
|
|
9860
9866
|
"Content-Type": "application/json",
|
|
@@ -9981,6 +9987,12 @@ function requireProviderConfig() {
|
|
|
9981
9987
|
providerId: "groq",
|
|
9982
9988
|
apiOperation: "chat/completions",
|
|
9983
9989
|
errorLabel: "Groq",
|
|
9990
|
+
// https://console.groq.com/docs/structured-outputs
|
|
9991
|
+
strictSchemaModels: /* @__PURE__ */ new Set([
|
|
9992
|
+
"openai/gpt-oss-120b",
|
|
9993
|
+
"openai/gpt-oss-20b",
|
|
9994
|
+
"qwen/qwen3.8-27b"
|
|
9995
|
+
]),
|
|
9984
9996
|
buildRequest: buildOpenAiStyleRequest("https://api.groq.com/openai/v1/chat/completions"),
|
|
9985
9997
|
parseResponse: parseOpenAiStyleResponse("Groq")
|
|
9986
9998
|
},
|
|
@@ -10028,7 +10040,7 @@ function requireModelInfo() {
|
|
|
10028
10040
|
exports$1.MODEL_ALIASES = {
|
|
10029
10041
|
fast: [
|
|
10030
10042
|
{ provider: "cerebras", model: "qwen-3.8-27b" },
|
|
10031
|
-
{ provider: "groq", model: "
|
|
10043
|
+
{ provider: "groq", model: "openai/gpt-oss-120b" },
|
|
10032
10044
|
{ provider: "openrouter", model: "z-ai/glm-5.2" }
|
|
10033
10045
|
],
|
|
10034
10046
|
gemini: [
|
|
@@ -10128,7 +10140,7 @@ function requireProviderCall() {
|
|
|
10128
10140
|
hasRequiredProviderCall = 1;
|
|
10129
10141
|
Object.defineProperty(providerCall, "__esModule", { value: true });
|
|
10130
10142
|
providerCall.callProvider = callProvider;
|
|
10131
|
-
const logger_1 =
|
|
10143
|
+
const logger_1 = strictJsonSchema.requireLogger();
|
|
10132
10144
|
const provider_config_1 = requireProviderConfig();
|
|
10133
10145
|
async function callProvider(call, logger) {
|
|
10134
10146
|
const { target, apiOperation, request } = call;
|
|
@@ -10181,6 +10193,7 @@ function requireHttpEngine() {
|
|
|
10181
10193
|
hasRequiredHttpEngine = 1;
|
|
10182
10194
|
Object.defineProperty(httpEngine, "__esModule", { value: true });
|
|
10183
10195
|
httpEngine.HttpEngine = void 0;
|
|
10196
|
+
const strict_json_schema_1 = strictJsonSchema.requireStrictJsonSchema();
|
|
10184
10197
|
const provider_call_1 = requireProviderCall();
|
|
10185
10198
|
const provider_config_1 = requireProviderConfig();
|
|
10186
10199
|
const FATAL_HTTP_STATUSES = /* @__PURE__ */ new Set([401, 403, 404]);
|
|
@@ -10189,35 +10202,55 @@ function requireHttpEngine() {
|
|
|
10189
10202
|
this.target = target;
|
|
10190
10203
|
this.logger = logger;
|
|
10191
10204
|
}
|
|
10192
|
-
/**
|
|
10193
|
-
nativeSchema() {
|
|
10194
|
-
|
|
10205
|
+
/** Enforced in strict mode on models whose provider supports it; other models get the schema in the prompt. */
|
|
10206
|
+
nativeSchema(envelopeSchema) {
|
|
10207
|
+
const { provider, model } = this.target;
|
|
10208
|
+
if (!provider_config_1.providerConfigs[provider].strictSchemaModels?.has(model))
|
|
10209
|
+
return null;
|
|
10210
|
+
return (0, strict_json_schema_1.toStrictSchema)(envelopeSchema);
|
|
10195
10211
|
}
|
|
10196
10212
|
async attempt(request) {
|
|
10197
10213
|
const { provider, model, apiKey } = this.target;
|
|
10198
10214
|
const config = provider_config_1.providerConfigs[provider];
|
|
10215
|
+
const responseSchema = request.enforcement.kind === "native" ? request.enforcement.schema : void 0;
|
|
10199
10216
|
const call = await (0, provider_call_1.callProvider)({
|
|
10200
10217
|
target: this.target,
|
|
10201
10218
|
apiOperation: config.apiOperation,
|
|
10202
10219
|
maxTokens: request.maxTokens,
|
|
10203
|
-
request: config.buildRequest({ prompt: request.prompt, model, maxTokens: request.maxTokens }, apiKey),
|
|
10220
|
+
request: config.buildRequest({ prompt: request.prompt, model, maxTokens: request.maxTokens, responseSchema }, apiKey),
|
|
10204
10221
|
parseResponse: config.parseResponse,
|
|
10205
10222
|
responseLength: (reply) => reply.text.length,
|
|
10206
10223
|
usage: (reply) => reply.usage
|
|
10207
10224
|
}, this.logger);
|
|
10208
10225
|
if (call.kind === "failed") {
|
|
10209
|
-
return { kind: "failed", failure: failureForStatus(call.status, call.message) };
|
|
10226
|
+
return { kind: "failed", failure: failureForStatus(call.status, call.message, responseSchema !== void 0) };
|
|
10227
|
+
}
|
|
10228
|
+
const answer = responseSchema ? readEnvelope(call.reply.text) : { kind: "text", text: call.reply.text };
|
|
10229
|
+
if (!answer) {
|
|
10230
|
+
return {
|
|
10231
|
+
kind: "failed",
|
|
10232
|
+
failure: { kind: "transient", message: `Structured output is not valid JSON: ${call.reply.text}` }
|
|
10233
|
+
};
|
|
10210
10234
|
}
|
|
10211
10235
|
return {
|
|
10212
10236
|
kind: "answered",
|
|
10213
|
-
answer
|
|
10237
|
+
answer,
|
|
10214
10238
|
usage: call.reply.usage,
|
|
10215
10239
|
origin: { engine: "http", provider, model }
|
|
10216
10240
|
};
|
|
10217
10241
|
}
|
|
10218
10242
|
}
|
|
10219
10243
|
httpEngine.HttpEngine = HttpEngine;
|
|
10220
|
-
function
|
|
10244
|
+
function readEnvelope(text) {
|
|
10245
|
+
try {
|
|
10246
|
+
return { kind: "structured", envelope: JSON.parse(text) };
|
|
10247
|
+
} catch {
|
|
10248
|
+
return null;
|
|
10249
|
+
}
|
|
10250
|
+
}
|
|
10251
|
+
function failureForStatus(status, message, sentSchema) {
|
|
10252
|
+
if (sentSchema && status === 400)
|
|
10253
|
+
return { kind: "schema-rejected", message };
|
|
10221
10254
|
const fatal = status !== void 0 && FATAL_HTTP_STATUSES.has(status);
|
|
10222
10255
|
return { kind: fatal ? "fatal" : "transient", message };
|
|
10223
10256
|
}
|
|
@@ -10231,7 +10264,7 @@ function requireProviderEngines() {
|
|
|
10231
10264
|
Object.defineProperty(providerEngines, "__esModule", { value: true });
|
|
10232
10265
|
providerEngines.ProviderEngines = void 0;
|
|
10233
10266
|
providerEngines.providerEngines = providerEngines$1;
|
|
10234
|
-
const logger_1 =
|
|
10267
|
+
const logger_1 = strictJsonSchema.requireLogger();
|
|
10235
10268
|
const nua_errors_1 = requireNuaErrors();
|
|
10236
10269
|
const model_info_1 = requireModelInfo();
|
|
10237
10270
|
const http_engine_1 = requireHttpEngine();
|
|
@@ -11178,7 +11211,7 @@ function requireDist() {
|
|
|
11178
11211
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
11179
11212
|
exports$1.runAgentLoop = exports$1.runAgent = exports$1.parseListSchema = exports$1.listSchema = exports$1.stableStringify = exports$1.validateJsonSchema = exports$1.providerEngines = exports$1.providerConfigs = exports$1.normalizedUsageZero = exports$1.LLM_PROVIDER_IDS = void 0;
|
|
11180
11213
|
__exportStar(requireNuaLlmClient(), exports$1);
|
|
11181
|
-
__exportStar(
|
|
11214
|
+
__exportStar(strictJsonSchema.requireLogger(), exports$1);
|
|
11182
11215
|
__exportStar(requireTypes(), exports$1);
|
|
11183
11216
|
__exportStar(requireNuaErrors(), exports$1);
|
|
11184
11217
|
var provider_config_1 = requireProviderConfig();
|
package/dist/cjs/local-agent.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var strictJsonSchema = require('./chunks/strict-json-schema-DUE7RTxG.cjs');
|
|
4
4
|
var node_module = require('node:module');
|
|
5
5
|
|
|
6
6
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -168,99 +168,13 @@ function requireClaudeCode() {
|
|
|
168
168
|
|
|
169
169
|
var codex = {};
|
|
170
170
|
|
|
171
|
-
var strictJsonSchema = {};
|
|
172
|
-
|
|
173
|
-
var hasRequiredStrictJsonSchema;
|
|
174
|
-
function requireStrictJsonSchema() {
|
|
175
|
-
if (hasRequiredStrictJsonSchema) return strictJsonSchema;
|
|
176
|
-
hasRequiredStrictJsonSchema = 1;
|
|
177
|
-
Object.defineProperty(strictJsonSchema, "__esModule", { value: true });
|
|
178
|
-
strictJsonSchema.toStrictSchema = toStrictSchema;
|
|
179
|
-
const STRICT_UNSUPPORTED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
180
|
-
"patternProperties",
|
|
181
|
-
"propertyNames",
|
|
182
|
-
"unevaluatedProperties",
|
|
183
|
-
"dependentRequired",
|
|
184
|
-
"dependentSchemas",
|
|
185
|
-
"if",
|
|
186
|
-
"then",
|
|
187
|
-
"else",
|
|
188
|
-
"not",
|
|
189
|
-
"allOf",
|
|
190
|
-
"oneOf"
|
|
191
|
-
]);
|
|
192
|
-
function toStrictSchema(schema) {
|
|
193
|
-
return strictNode(schema);
|
|
194
|
-
}
|
|
195
|
-
function strictNode(node) {
|
|
196
|
-
if (typeof node !== "object" || node === null || Array.isArray(node)) {
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
const schema = node;
|
|
200
|
-
for (const key of Object.keys(schema)) {
|
|
201
|
-
if (STRICT_UNSUPPORTED_KEYWORDS.has(key))
|
|
202
|
-
return null;
|
|
203
|
-
}
|
|
204
|
-
const result = { ...schema };
|
|
205
|
-
delete result.$schema;
|
|
206
|
-
const isObject = schema.type === "object" || Array.isArray(schema.type) && schema.type.includes("object") || schema.properties !== void 0;
|
|
207
|
-
if (isObject) {
|
|
208
|
-
const properties = schema.properties ?? {};
|
|
209
|
-
if (schema.additionalProperties !== void 0 && schema.additionalProperties !== false) {
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
const required = new Set(schema.required ?? []);
|
|
213
|
-
const shapedProperties = {};
|
|
214
|
-
for (const [name, child] of Object.entries(properties)) {
|
|
215
|
-
if (!required.has(name))
|
|
216
|
-
return null;
|
|
217
|
-
const shaped = strictNode(child);
|
|
218
|
-
if (!shaped)
|
|
219
|
-
return null;
|
|
220
|
-
shapedProperties[name] = shaped;
|
|
221
|
-
}
|
|
222
|
-
result.properties = shapedProperties;
|
|
223
|
-
result.required = Object.keys(shapedProperties);
|
|
224
|
-
result.additionalProperties = false;
|
|
225
|
-
}
|
|
226
|
-
if (schema.items !== void 0) {
|
|
227
|
-
const shaped = strictNode(schema.items);
|
|
228
|
-
if (!shaped)
|
|
229
|
-
return null;
|
|
230
|
-
result.items = shaped;
|
|
231
|
-
}
|
|
232
|
-
if (schema.prefixItems !== void 0)
|
|
233
|
-
return null;
|
|
234
|
-
if (schema.anyOf !== void 0) {
|
|
235
|
-
const variants = schema.anyOf.map(strictNode);
|
|
236
|
-
if (variants.some((v) => v === null))
|
|
237
|
-
return null;
|
|
238
|
-
result.anyOf = variants;
|
|
239
|
-
}
|
|
240
|
-
for (const defsKey of ["$defs", "definitions"]) {
|
|
241
|
-
if (schema[defsKey] !== void 0) {
|
|
242
|
-
const defs = {};
|
|
243
|
-
for (const [name, child] of Object.entries(schema[defsKey])) {
|
|
244
|
-
const shaped = strictNode(child);
|
|
245
|
-
if (!shaped)
|
|
246
|
-
return null;
|
|
247
|
-
defs[name] = shaped;
|
|
248
|
-
}
|
|
249
|
-
result[defsKey] = defs;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return result;
|
|
253
|
-
}
|
|
254
|
-
return strictJsonSchema;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
171
|
var hasRequiredCodex;
|
|
258
172
|
function requireCodex() {
|
|
259
173
|
if (hasRequiredCodex) return codex;
|
|
260
174
|
hasRequiredCodex = 1;
|
|
261
175
|
Object.defineProperty(codex, "__esModule", { value: true });
|
|
262
176
|
codex.codexAdapter = void 0;
|
|
263
|
-
const strict_json_schema_1 = requireStrictJsonSchema();
|
|
177
|
+
const strict_json_schema_1 = strictJsonSchema.requireStrictJsonSchema();
|
|
264
178
|
const failure_classification_1 = requireFailureClassification();
|
|
265
179
|
const SCHEMA_FILE = "output-schema.json";
|
|
266
180
|
const LAST_MESSAGE_FILE = "last-message.txt";
|
|
@@ -367,6 +281,161 @@ ${result.stderr}`.trim();
|
|
|
367
281
|
return codex;
|
|
368
282
|
}
|
|
369
283
|
|
|
284
|
+
var pi = {};
|
|
285
|
+
|
|
286
|
+
var hasRequiredPi;
|
|
287
|
+
function requirePi() {
|
|
288
|
+
if (hasRequiredPi) return pi;
|
|
289
|
+
hasRequiredPi = 1;
|
|
290
|
+
Object.defineProperty(pi, "__esModule", { value: true });
|
|
291
|
+
pi.piAdapter = void 0;
|
|
292
|
+
const failure_classification_1 = requireFailureClassification();
|
|
293
|
+
const SYSTEM_PROMPT = [
|
|
294
|
+
"You are a data transformation function called by a program.",
|
|
295
|
+
"You have no tools. Follow the instructions in the user message exactly",
|
|
296
|
+
"and reply only with the requested JSON."
|
|
297
|
+
].join(" ");
|
|
298
|
+
pi.piAdapter = {
|
|
299
|
+
id: "pi",
|
|
300
|
+
binaryName: "pi",
|
|
301
|
+
// Every environment credential Pi's providers recognize. Under `auth:
|
|
302
|
+
// "subscription"` these are removed so Pi bills its own `auth.json` login.
|
|
303
|
+
apiKeyEnvVars: [
|
|
304
|
+
"AI_GATEWAY_API_KEY",
|
|
305
|
+
"ANT_LING_API_KEY",
|
|
306
|
+
"ANTHROPIC_API_KEY",
|
|
307
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
308
|
+
"ANTHROPIC_OAUTH_TOKEN",
|
|
309
|
+
"AWS_ACCESS_KEY_ID",
|
|
310
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
311
|
+
"AWS_SESSION_TOKEN",
|
|
312
|
+
"AZURE_OPENAI_API_KEY",
|
|
313
|
+
"BASETEN_API_KEY",
|
|
314
|
+
"CEREBRAS_API_KEY",
|
|
315
|
+
"CLOUDFLARE_API_KEY",
|
|
316
|
+
"COPILOT_GITHUB_TOKEN",
|
|
317
|
+
"DEEPSEEK_API_KEY",
|
|
318
|
+
"FIREWORKS_API_KEY",
|
|
319
|
+
"GEMINI_API_KEY",
|
|
320
|
+
"GOOGLE_API_KEY",
|
|
321
|
+
"GOOGLE_CLOUD_API_KEY",
|
|
322
|
+
"GROQ_API_KEY",
|
|
323
|
+
"HF_TOKEN",
|
|
324
|
+
"KIMI_API_KEY",
|
|
325
|
+
"META_API_KEY",
|
|
326
|
+
"MINIMAX_API_KEY",
|
|
327
|
+
"MINIMAX_CN_API_KEY",
|
|
328
|
+
"MISTRAL_API_KEY",
|
|
329
|
+
"MOONSHOT_API_KEY",
|
|
330
|
+
"NVIDIA_API_KEY",
|
|
331
|
+
"OPENAI_API_KEY",
|
|
332
|
+
"OPENCODE_API_KEY",
|
|
333
|
+
"OPENROUTER_API_KEY",
|
|
334
|
+
"QWEN_TOKEN_PLAN_API_KEY",
|
|
335
|
+
"QWEN_TOKEN_PLAN_CN_API_KEY",
|
|
336
|
+
"RADIUS_API_KEY",
|
|
337
|
+
"TOGETHER_API_KEY",
|
|
338
|
+
"XAI_API_KEY",
|
|
339
|
+
"XIAOMI_API_KEY",
|
|
340
|
+
"XIAOMI_TOKEN_PLAN_AMS_API_KEY",
|
|
341
|
+
"XIAOMI_TOKEN_PLAN_CN_API_KEY",
|
|
342
|
+
"XIAOMI_TOKEN_PLAN_SGP_API_KEY",
|
|
343
|
+
"ZAI_API_KEY",
|
|
344
|
+
"ZAI_CODING_CN_API_KEY"
|
|
345
|
+
],
|
|
346
|
+
// Pi uses its own `provider/id` model names; set one with localAgent({ model }).
|
|
347
|
+
modelAliases: {},
|
|
348
|
+
nativeSchema() {
|
|
349
|
+
return null;
|
|
350
|
+
},
|
|
351
|
+
buildInvocation(request, model) {
|
|
352
|
+
const args = [
|
|
353
|
+
"--mode",
|
|
354
|
+
"json",
|
|
355
|
+
"--no-session",
|
|
356
|
+
"--no-tools",
|
|
357
|
+
"--no-builtin-tools",
|
|
358
|
+
"--no-extensions",
|
|
359
|
+
"--no-skills",
|
|
360
|
+
"--no-prompt-templates",
|
|
361
|
+
"--no-themes",
|
|
362
|
+
"--no-context-files",
|
|
363
|
+
"--system-prompt",
|
|
364
|
+
SYSTEM_PROMPT,
|
|
365
|
+
"--offline"
|
|
366
|
+
];
|
|
367
|
+
if (model !== void 0) {
|
|
368
|
+
args.push("--model", model);
|
|
369
|
+
}
|
|
370
|
+
return { args, stdin: request.prompt };
|
|
371
|
+
},
|
|
372
|
+
readResult(result, request) {
|
|
373
|
+
const events = parseEvents(result.stdout);
|
|
374
|
+
const assistant = events.filter((event) => event.type === "message_end" && event.message?.role === "assistant").map((event) => event.message).pop();
|
|
375
|
+
if (assistant && (assistant.stopReason === "error" || assistant.errorMessage)) {
|
|
376
|
+
return failed((0, failure_classification_1.classifyAgentFailure)("pi", assistant.errorMessage ?? "pi stopped with an error"));
|
|
377
|
+
}
|
|
378
|
+
const retryFailed = events.find((event) => event.type === "auto_retry_end" && event.success === false);
|
|
379
|
+
if (retryFailed) {
|
|
380
|
+
return failed((0, failure_classification_1.classifyAgentFailure)("pi", retryFailed.finalError ?? "auto retry failed"));
|
|
381
|
+
}
|
|
382
|
+
if (!assistant) {
|
|
383
|
+
return failed((0, failure_classification_1.classifyAgentFailure)("pi", `exited with code ${result.exitCode} without a reply: ${(0, failure_classification_1.stderrTail)(result)}`));
|
|
384
|
+
}
|
|
385
|
+
const text = (assistant.content ?? []).filter((block) => block.type === "text").map((block) => block.text ?? "").join("");
|
|
386
|
+
const usage = assistant.usage ?? {};
|
|
387
|
+
const promptTokens = (usage.input ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
388
|
+
const completionTokens = usage.output ?? 0;
|
|
389
|
+
const reported = {
|
|
390
|
+
usage: { promptTokens, completionTokens, totalTokens: promptTokens + completionTokens },
|
|
391
|
+
model: assistant.model,
|
|
392
|
+
costUsdEstimate: usage.cost?.total
|
|
393
|
+
};
|
|
394
|
+
if (request.enforcement.kind === "in-prompt") {
|
|
395
|
+
return { kind: "answered", answer: { kind: "text", text }, ...reported };
|
|
396
|
+
}
|
|
397
|
+
let envelope;
|
|
398
|
+
try {
|
|
399
|
+
envelope = JSON.parse(text);
|
|
400
|
+
} catch {
|
|
401
|
+
return failed({ kind: "transient", message: `pi reply is not JSON: ${text}` });
|
|
402
|
+
}
|
|
403
|
+
return { kind: "answered", answer: { kind: "structured", envelope }, ...reported };
|
|
404
|
+
},
|
|
405
|
+
// Pi has no provider-agnostic login check: `pi auth check` requires --provider
|
|
406
|
+
// or --model, and the provider differs per user (it is not known until Pi's
|
|
407
|
+
// settings are read). Report installed Pi as logged in; the first real call
|
|
408
|
+
// surfaces any auth error, which classifyAgentFailure marks fatal.
|
|
409
|
+
loginStatusArgs: ["--version"],
|
|
410
|
+
readLoginStatus(result) {
|
|
411
|
+
return {
|
|
412
|
+
loggedIn: result.exitCode === 0,
|
|
413
|
+
detail: "installed; auth is verified on the first call"
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
function failed(failure) {
|
|
418
|
+
return { kind: "failed", failure };
|
|
419
|
+
}
|
|
420
|
+
function parseEvents(stdout) {
|
|
421
|
+
const events = [];
|
|
422
|
+
for (const line of stdout.split("\n")) {
|
|
423
|
+
const trimmed = line.replace(/\r$/, "").trim();
|
|
424
|
+
if (!trimmed.startsWith("{"))
|
|
425
|
+
continue;
|
|
426
|
+
try {
|
|
427
|
+
const parsed = JSON.parse(trimmed);
|
|
428
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
429
|
+
events.push(parsed);
|
|
430
|
+
}
|
|
431
|
+
} catch {
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return events;
|
|
435
|
+
}
|
|
436
|
+
return pi;
|
|
437
|
+
}
|
|
438
|
+
|
|
370
439
|
var hasRequiredAdapters;
|
|
371
440
|
function requireAdapters() {
|
|
372
441
|
if (hasRequiredAdapters) return adapters;
|
|
@@ -375,9 +444,11 @@ function requireAdapters() {
|
|
|
375
444
|
adapters.AGENT_ADAPTERS = void 0;
|
|
376
445
|
const claude_code_1 = requireClaudeCode();
|
|
377
446
|
const codex_1 = requireCodex();
|
|
447
|
+
const pi_1 = requirePi();
|
|
378
448
|
adapters.AGENT_ADAPTERS = {
|
|
379
449
|
"claude-code": claude_code_1.claudeCodeAdapter,
|
|
380
|
-
codex: codex_1.codexAdapter
|
|
450
|
+
codex: codex_1.codexAdapter,
|
|
451
|
+
pi: pi_1.piAdapter
|
|
381
452
|
};
|
|
382
453
|
return adapters;
|
|
383
454
|
}
|
|
@@ -392,7 +463,7 @@ function requireAgentId() {
|
|
|
392
463
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
393
464
|
exports$1.LOCAL_AGENT_IDS = void 0;
|
|
394
465
|
exports$1.isLocalAgentId = isLocalAgentId;
|
|
395
|
-
exports$1.LOCAL_AGENT_IDS = ["claude-code", "codex"];
|
|
466
|
+
exports$1.LOCAL_AGENT_IDS = ["claude-code", "codex", "pi"];
|
|
396
467
|
const LOCAL_AGENT_ID_SET = new Set(exports$1.LOCAL_AGENT_IDS);
|
|
397
468
|
function isLocalAgentId(value) {
|
|
398
469
|
return typeof value === "string" && LOCAL_AGENT_ID_SET.has(value);
|
|
@@ -624,7 +695,7 @@ function requireLocalAgentEngine() {
|
|
|
624
695
|
hasRequiredLocalAgentEngine = 1;
|
|
625
696
|
Object.defineProperty(localAgentEngine, "__esModule", { value: true });
|
|
626
697
|
localAgentEngine.LocalAgentEngine = void 0;
|
|
627
|
-
const logger_1 =
|
|
698
|
+
const logger_1 = strictJsonSchema.requireLogger();
|
|
628
699
|
const process_runner_1 = requireProcessRunner();
|
|
629
700
|
class LocalAgentEngine {
|
|
630
701
|
constructor(runner, model) {
|
|
@@ -783,7 +854,7 @@ function requireCreateLocalAgent() {
|
|
|
783
854
|
Object.defineProperty(createLocalAgent, "__esModule", { value: true });
|
|
784
855
|
createLocalAgent.localAgent = localAgent;
|
|
785
856
|
createLocalAgent.findLocalAgent = findLocalAgent;
|
|
786
|
-
const logger_1 =
|
|
857
|
+
const logger_1 = strictJsonSchema.requireLogger();
|
|
787
858
|
const adapters_1 = requireAdapters();
|
|
788
859
|
const agent_id_1 = requireAgentId();
|
|
789
860
|
const detect_1 = requireDetect();
|
|
@@ -85,4 +85,90 @@ function requireLogger() {
|
|
|
85
85
|
return logger;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
var strictJsonSchema = {};
|
|
89
|
+
|
|
90
|
+
var hasRequiredStrictJsonSchema;
|
|
91
|
+
function requireStrictJsonSchema() {
|
|
92
|
+
if (hasRequiredStrictJsonSchema) return strictJsonSchema;
|
|
93
|
+
hasRequiredStrictJsonSchema = 1;
|
|
94
|
+
Object.defineProperty(strictJsonSchema, "__esModule", { value: true });
|
|
95
|
+
strictJsonSchema.toStrictSchema = toStrictSchema;
|
|
96
|
+
const STRICT_UNSUPPORTED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
97
|
+
"patternProperties",
|
|
98
|
+
"propertyNames",
|
|
99
|
+
"unevaluatedProperties",
|
|
100
|
+
"dependentRequired",
|
|
101
|
+
"dependentSchemas",
|
|
102
|
+
"if",
|
|
103
|
+
"then",
|
|
104
|
+
"else",
|
|
105
|
+
"not",
|
|
106
|
+
"allOf",
|
|
107
|
+
"oneOf"
|
|
108
|
+
]);
|
|
109
|
+
function toStrictSchema(schema) {
|
|
110
|
+
return strictNode(schema);
|
|
111
|
+
}
|
|
112
|
+
function strictNode(node) {
|
|
113
|
+
if (typeof node !== "object" || node === null || Array.isArray(node)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const schema = node;
|
|
117
|
+
for (const key of Object.keys(schema)) {
|
|
118
|
+
if (STRICT_UNSUPPORTED_KEYWORDS.has(key))
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const result = { ...schema };
|
|
122
|
+
delete result.$schema;
|
|
123
|
+
const isObject = schema.type === "object" || Array.isArray(schema.type) && schema.type.includes("object") || schema.properties !== void 0;
|
|
124
|
+
if (isObject) {
|
|
125
|
+
const properties = schema.properties ?? {};
|
|
126
|
+
if (schema.additionalProperties !== void 0 && schema.additionalProperties !== false) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
const required = new Set(schema.required ?? []);
|
|
130
|
+
const shapedProperties = {};
|
|
131
|
+
for (const [name, child] of Object.entries(properties)) {
|
|
132
|
+
if (!required.has(name))
|
|
133
|
+
return null;
|
|
134
|
+
const shaped = strictNode(child);
|
|
135
|
+
if (!shaped)
|
|
136
|
+
return null;
|
|
137
|
+
shapedProperties[name] = shaped;
|
|
138
|
+
}
|
|
139
|
+
result.properties = shapedProperties;
|
|
140
|
+
result.required = Object.keys(shapedProperties);
|
|
141
|
+
result.additionalProperties = false;
|
|
142
|
+
}
|
|
143
|
+
if (schema.items !== void 0) {
|
|
144
|
+
const shaped = strictNode(schema.items);
|
|
145
|
+
if (!shaped)
|
|
146
|
+
return null;
|
|
147
|
+
result.items = shaped;
|
|
148
|
+
}
|
|
149
|
+
if (schema.prefixItems !== void 0)
|
|
150
|
+
return null;
|
|
151
|
+
if (schema.anyOf !== void 0) {
|
|
152
|
+
const variants = schema.anyOf.map(strictNode);
|
|
153
|
+
if (variants.some((v) => v === null))
|
|
154
|
+
return null;
|
|
155
|
+
result.anyOf = variants;
|
|
156
|
+
}
|
|
157
|
+
for (const defsKey of ["$defs", "definitions"]) {
|
|
158
|
+
if (schema[defsKey] !== void 0) {
|
|
159
|
+
const defs = {};
|
|
160
|
+
for (const [name, child] of Object.entries(schema[defsKey])) {
|
|
161
|
+
const shaped = strictNode(child);
|
|
162
|
+
if (!shaped)
|
|
163
|
+
return null;
|
|
164
|
+
defs[name] = shaped;
|
|
165
|
+
}
|
|
166
|
+
result[defsKey] = defs;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
return strictJsonSchema;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export { requireStrictJsonSchema as a, requireLogger as r };
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireLogger } from './chunks/
|
|
1
|
+
import { r as requireLogger, a as requireStrictJsonSchema } from './chunks/strict-json-schema-DI9qiH5h.mjs';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
export { z } from 'zod';
|
|
4
4
|
|
|
@@ -9840,7 +9840,7 @@ function requireProviderConfig() {
|
|
|
9840
9840
|
};
|
|
9841
9841
|
};
|
|
9842
9842
|
exports$1.normalizeGeminiUsage = normalizeGeminiUsage;
|
|
9843
|
-
const buildOpenAiStyleRequest = (baseUrl) => ({ prompt, model, maxTokens, assistantPrefillPrompt }, apiKey) => {
|
|
9843
|
+
const buildOpenAiStyleRequest = (baseUrl) => ({ prompt, model, maxTokens, assistantPrefillPrompt, responseSchema }, apiKey) => {
|
|
9844
9844
|
const messages = [];
|
|
9845
9845
|
messages.push({ role: "user", content: prompt });
|
|
9846
9846
|
if (assistantPrefillPrompt) {
|
|
@@ -9853,7 +9853,13 @@ function requireProviderConfig() {
|
|
|
9853
9853
|
max_completion_tokens: maxTokens,
|
|
9854
9854
|
top_p: 1,
|
|
9855
9855
|
stream: false,
|
|
9856
|
-
stop: null
|
|
9856
|
+
stop: null,
|
|
9857
|
+
...responseSchema && {
|
|
9858
|
+
response_format: {
|
|
9859
|
+
type: "json_schema",
|
|
9860
|
+
json_schema: { name: "response", strict: true, schema: responseSchema }
|
|
9861
|
+
}
|
|
9862
|
+
}
|
|
9857
9863
|
};
|
|
9858
9864
|
const headers = {
|
|
9859
9865
|
"Content-Type": "application/json",
|
|
@@ -9980,6 +9986,12 @@ function requireProviderConfig() {
|
|
|
9980
9986
|
providerId: "groq",
|
|
9981
9987
|
apiOperation: "chat/completions",
|
|
9982
9988
|
errorLabel: "Groq",
|
|
9989
|
+
// https://console.groq.com/docs/structured-outputs
|
|
9990
|
+
strictSchemaModels: /* @__PURE__ */ new Set([
|
|
9991
|
+
"openai/gpt-oss-120b",
|
|
9992
|
+
"openai/gpt-oss-20b",
|
|
9993
|
+
"qwen/qwen3.8-27b"
|
|
9994
|
+
]),
|
|
9983
9995
|
buildRequest: buildOpenAiStyleRequest("https://api.groq.com/openai/v1/chat/completions"),
|
|
9984
9996
|
parseResponse: parseOpenAiStyleResponse("Groq")
|
|
9985
9997
|
},
|
|
@@ -10027,7 +10039,7 @@ function requireModelInfo() {
|
|
|
10027
10039
|
exports$1.MODEL_ALIASES = {
|
|
10028
10040
|
fast: [
|
|
10029
10041
|
{ provider: "cerebras", model: "qwen-3.8-27b" },
|
|
10030
|
-
{ provider: "groq", model: "
|
|
10042
|
+
{ provider: "groq", model: "openai/gpt-oss-120b" },
|
|
10031
10043
|
{ provider: "openrouter", model: "z-ai/glm-5.2" }
|
|
10032
10044
|
],
|
|
10033
10045
|
gemini: [
|
|
@@ -10180,6 +10192,7 @@ function requireHttpEngine() {
|
|
|
10180
10192
|
hasRequiredHttpEngine = 1;
|
|
10181
10193
|
Object.defineProperty(httpEngine, "__esModule", { value: true });
|
|
10182
10194
|
httpEngine.HttpEngine = void 0;
|
|
10195
|
+
const strict_json_schema_1 = requireStrictJsonSchema();
|
|
10183
10196
|
const provider_call_1 = requireProviderCall();
|
|
10184
10197
|
const provider_config_1 = requireProviderConfig();
|
|
10185
10198
|
const FATAL_HTTP_STATUSES = /* @__PURE__ */ new Set([401, 403, 404]);
|
|
@@ -10188,35 +10201,55 @@ function requireHttpEngine() {
|
|
|
10188
10201
|
this.target = target;
|
|
10189
10202
|
this.logger = logger;
|
|
10190
10203
|
}
|
|
10191
|
-
/**
|
|
10192
|
-
nativeSchema() {
|
|
10193
|
-
|
|
10204
|
+
/** Enforced in strict mode on models whose provider supports it; other models get the schema in the prompt. */
|
|
10205
|
+
nativeSchema(envelopeSchema) {
|
|
10206
|
+
const { provider, model } = this.target;
|
|
10207
|
+
if (!provider_config_1.providerConfigs[provider].strictSchemaModels?.has(model))
|
|
10208
|
+
return null;
|
|
10209
|
+
return (0, strict_json_schema_1.toStrictSchema)(envelopeSchema);
|
|
10194
10210
|
}
|
|
10195
10211
|
async attempt(request) {
|
|
10196
10212
|
const { provider, model, apiKey } = this.target;
|
|
10197
10213
|
const config = provider_config_1.providerConfigs[provider];
|
|
10214
|
+
const responseSchema = request.enforcement.kind === "native" ? request.enforcement.schema : void 0;
|
|
10198
10215
|
const call = await (0, provider_call_1.callProvider)({
|
|
10199
10216
|
target: this.target,
|
|
10200
10217
|
apiOperation: config.apiOperation,
|
|
10201
10218
|
maxTokens: request.maxTokens,
|
|
10202
|
-
request: config.buildRequest({ prompt: request.prompt, model, maxTokens: request.maxTokens }, apiKey),
|
|
10219
|
+
request: config.buildRequest({ prompt: request.prompt, model, maxTokens: request.maxTokens, responseSchema }, apiKey),
|
|
10203
10220
|
parseResponse: config.parseResponse,
|
|
10204
10221
|
responseLength: (reply) => reply.text.length,
|
|
10205
10222
|
usage: (reply) => reply.usage
|
|
10206
10223
|
}, this.logger);
|
|
10207
10224
|
if (call.kind === "failed") {
|
|
10208
|
-
return { kind: "failed", failure: failureForStatus(call.status, call.message) };
|
|
10225
|
+
return { kind: "failed", failure: failureForStatus(call.status, call.message, responseSchema !== void 0) };
|
|
10226
|
+
}
|
|
10227
|
+
const answer = responseSchema ? readEnvelope(call.reply.text) : { kind: "text", text: call.reply.text };
|
|
10228
|
+
if (!answer) {
|
|
10229
|
+
return {
|
|
10230
|
+
kind: "failed",
|
|
10231
|
+
failure: { kind: "transient", message: `Structured output is not valid JSON: ${call.reply.text}` }
|
|
10232
|
+
};
|
|
10209
10233
|
}
|
|
10210
10234
|
return {
|
|
10211
10235
|
kind: "answered",
|
|
10212
|
-
answer
|
|
10236
|
+
answer,
|
|
10213
10237
|
usage: call.reply.usage,
|
|
10214
10238
|
origin: { engine: "http", provider, model }
|
|
10215
10239
|
};
|
|
10216
10240
|
}
|
|
10217
10241
|
}
|
|
10218
10242
|
httpEngine.HttpEngine = HttpEngine;
|
|
10219
|
-
function
|
|
10243
|
+
function readEnvelope(text) {
|
|
10244
|
+
try {
|
|
10245
|
+
return { kind: "structured", envelope: JSON.parse(text) };
|
|
10246
|
+
} catch {
|
|
10247
|
+
return null;
|
|
10248
|
+
}
|
|
10249
|
+
}
|
|
10250
|
+
function failureForStatus(status, message, sentSchema) {
|
|
10251
|
+
if (sentSchema && status === 400)
|
|
10252
|
+
return { kind: "schema-rejected", message };
|
|
10220
10253
|
const fatal = status !== void 0 && FATAL_HTTP_STATUSES.has(status);
|
|
10221
10254
|
return { kind: fatal ? "fatal" : "transient", message };
|
|
10222
10255
|
}
|
package/dist/esm/local-agent.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireLogger } from './chunks/
|
|
1
|
+
import { a as requireStrictJsonSchema, r as requireLogger } from './chunks/strict-json-schema-DI9qiH5h.mjs';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
|
|
4
4
|
var localAgent$1 = {};
|
|
@@ -165,92 +165,6 @@ function requireClaudeCode() {
|
|
|
165
165
|
|
|
166
166
|
var codex = {};
|
|
167
167
|
|
|
168
|
-
var strictJsonSchema = {};
|
|
169
|
-
|
|
170
|
-
var hasRequiredStrictJsonSchema;
|
|
171
|
-
function requireStrictJsonSchema() {
|
|
172
|
-
if (hasRequiredStrictJsonSchema) return strictJsonSchema;
|
|
173
|
-
hasRequiredStrictJsonSchema = 1;
|
|
174
|
-
Object.defineProperty(strictJsonSchema, "__esModule", { value: true });
|
|
175
|
-
strictJsonSchema.toStrictSchema = toStrictSchema;
|
|
176
|
-
const STRICT_UNSUPPORTED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
177
|
-
"patternProperties",
|
|
178
|
-
"propertyNames",
|
|
179
|
-
"unevaluatedProperties",
|
|
180
|
-
"dependentRequired",
|
|
181
|
-
"dependentSchemas",
|
|
182
|
-
"if",
|
|
183
|
-
"then",
|
|
184
|
-
"else",
|
|
185
|
-
"not",
|
|
186
|
-
"allOf",
|
|
187
|
-
"oneOf"
|
|
188
|
-
]);
|
|
189
|
-
function toStrictSchema(schema) {
|
|
190
|
-
return strictNode(schema);
|
|
191
|
-
}
|
|
192
|
-
function strictNode(node) {
|
|
193
|
-
if (typeof node !== "object" || node === null || Array.isArray(node)) {
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
const schema = node;
|
|
197
|
-
for (const key of Object.keys(schema)) {
|
|
198
|
-
if (STRICT_UNSUPPORTED_KEYWORDS.has(key))
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
const result = { ...schema };
|
|
202
|
-
delete result.$schema;
|
|
203
|
-
const isObject = schema.type === "object" || Array.isArray(schema.type) && schema.type.includes("object") || schema.properties !== void 0;
|
|
204
|
-
if (isObject) {
|
|
205
|
-
const properties = schema.properties ?? {};
|
|
206
|
-
if (schema.additionalProperties !== void 0 && schema.additionalProperties !== false) {
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
const required = new Set(schema.required ?? []);
|
|
210
|
-
const shapedProperties = {};
|
|
211
|
-
for (const [name, child] of Object.entries(properties)) {
|
|
212
|
-
if (!required.has(name))
|
|
213
|
-
return null;
|
|
214
|
-
const shaped = strictNode(child);
|
|
215
|
-
if (!shaped)
|
|
216
|
-
return null;
|
|
217
|
-
shapedProperties[name] = shaped;
|
|
218
|
-
}
|
|
219
|
-
result.properties = shapedProperties;
|
|
220
|
-
result.required = Object.keys(shapedProperties);
|
|
221
|
-
result.additionalProperties = false;
|
|
222
|
-
}
|
|
223
|
-
if (schema.items !== void 0) {
|
|
224
|
-
const shaped = strictNode(schema.items);
|
|
225
|
-
if (!shaped)
|
|
226
|
-
return null;
|
|
227
|
-
result.items = shaped;
|
|
228
|
-
}
|
|
229
|
-
if (schema.prefixItems !== void 0)
|
|
230
|
-
return null;
|
|
231
|
-
if (schema.anyOf !== void 0) {
|
|
232
|
-
const variants = schema.anyOf.map(strictNode);
|
|
233
|
-
if (variants.some((v) => v === null))
|
|
234
|
-
return null;
|
|
235
|
-
result.anyOf = variants;
|
|
236
|
-
}
|
|
237
|
-
for (const defsKey of ["$defs", "definitions"]) {
|
|
238
|
-
if (schema[defsKey] !== void 0) {
|
|
239
|
-
const defs = {};
|
|
240
|
-
for (const [name, child] of Object.entries(schema[defsKey])) {
|
|
241
|
-
const shaped = strictNode(child);
|
|
242
|
-
if (!shaped)
|
|
243
|
-
return null;
|
|
244
|
-
defs[name] = shaped;
|
|
245
|
-
}
|
|
246
|
-
result[defsKey] = defs;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
return result;
|
|
250
|
-
}
|
|
251
|
-
return strictJsonSchema;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
168
|
var hasRequiredCodex;
|
|
255
169
|
function requireCodex() {
|
|
256
170
|
if (hasRequiredCodex) return codex;
|
|
@@ -364,6 +278,161 @@ ${result.stderr}`.trim();
|
|
|
364
278
|
return codex;
|
|
365
279
|
}
|
|
366
280
|
|
|
281
|
+
var pi = {};
|
|
282
|
+
|
|
283
|
+
var hasRequiredPi;
|
|
284
|
+
function requirePi() {
|
|
285
|
+
if (hasRequiredPi) return pi;
|
|
286
|
+
hasRequiredPi = 1;
|
|
287
|
+
Object.defineProperty(pi, "__esModule", { value: true });
|
|
288
|
+
pi.piAdapter = void 0;
|
|
289
|
+
const failure_classification_1 = requireFailureClassification();
|
|
290
|
+
const SYSTEM_PROMPT = [
|
|
291
|
+
"You are a data transformation function called by a program.",
|
|
292
|
+
"You have no tools. Follow the instructions in the user message exactly",
|
|
293
|
+
"and reply only with the requested JSON."
|
|
294
|
+
].join(" ");
|
|
295
|
+
pi.piAdapter = {
|
|
296
|
+
id: "pi",
|
|
297
|
+
binaryName: "pi",
|
|
298
|
+
// Every environment credential Pi's providers recognize. Under `auth:
|
|
299
|
+
// "subscription"` these are removed so Pi bills its own `auth.json` login.
|
|
300
|
+
apiKeyEnvVars: [
|
|
301
|
+
"AI_GATEWAY_API_KEY",
|
|
302
|
+
"ANT_LING_API_KEY",
|
|
303
|
+
"ANTHROPIC_API_KEY",
|
|
304
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
305
|
+
"ANTHROPIC_OAUTH_TOKEN",
|
|
306
|
+
"AWS_ACCESS_KEY_ID",
|
|
307
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
308
|
+
"AWS_SESSION_TOKEN",
|
|
309
|
+
"AZURE_OPENAI_API_KEY",
|
|
310
|
+
"BASETEN_API_KEY",
|
|
311
|
+
"CEREBRAS_API_KEY",
|
|
312
|
+
"CLOUDFLARE_API_KEY",
|
|
313
|
+
"COPILOT_GITHUB_TOKEN",
|
|
314
|
+
"DEEPSEEK_API_KEY",
|
|
315
|
+
"FIREWORKS_API_KEY",
|
|
316
|
+
"GEMINI_API_KEY",
|
|
317
|
+
"GOOGLE_API_KEY",
|
|
318
|
+
"GOOGLE_CLOUD_API_KEY",
|
|
319
|
+
"GROQ_API_KEY",
|
|
320
|
+
"HF_TOKEN",
|
|
321
|
+
"KIMI_API_KEY",
|
|
322
|
+
"META_API_KEY",
|
|
323
|
+
"MINIMAX_API_KEY",
|
|
324
|
+
"MINIMAX_CN_API_KEY",
|
|
325
|
+
"MISTRAL_API_KEY",
|
|
326
|
+
"MOONSHOT_API_KEY",
|
|
327
|
+
"NVIDIA_API_KEY",
|
|
328
|
+
"OPENAI_API_KEY",
|
|
329
|
+
"OPENCODE_API_KEY",
|
|
330
|
+
"OPENROUTER_API_KEY",
|
|
331
|
+
"QWEN_TOKEN_PLAN_API_KEY",
|
|
332
|
+
"QWEN_TOKEN_PLAN_CN_API_KEY",
|
|
333
|
+
"RADIUS_API_KEY",
|
|
334
|
+
"TOGETHER_API_KEY",
|
|
335
|
+
"XAI_API_KEY",
|
|
336
|
+
"XIAOMI_API_KEY",
|
|
337
|
+
"XIAOMI_TOKEN_PLAN_AMS_API_KEY",
|
|
338
|
+
"XIAOMI_TOKEN_PLAN_CN_API_KEY",
|
|
339
|
+
"XIAOMI_TOKEN_PLAN_SGP_API_KEY",
|
|
340
|
+
"ZAI_API_KEY",
|
|
341
|
+
"ZAI_CODING_CN_API_KEY"
|
|
342
|
+
],
|
|
343
|
+
// Pi uses its own `provider/id` model names; set one with localAgent({ model }).
|
|
344
|
+
modelAliases: {},
|
|
345
|
+
nativeSchema() {
|
|
346
|
+
return null;
|
|
347
|
+
},
|
|
348
|
+
buildInvocation(request, model) {
|
|
349
|
+
const args = [
|
|
350
|
+
"--mode",
|
|
351
|
+
"json",
|
|
352
|
+
"--no-session",
|
|
353
|
+
"--no-tools",
|
|
354
|
+
"--no-builtin-tools",
|
|
355
|
+
"--no-extensions",
|
|
356
|
+
"--no-skills",
|
|
357
|
+
"--no-prompt-templates",
|
|
358
|
+
"--no-themes",
|
|
359
|
+
"--no-context-files",
|
|
360
|
+
"--system-prompt",
|
|
361
|
+
SYSTEM_PROMPT,
|
|
362
|
+
"--offline"
|
|
363
|
+
];
|
|
364
|
+
if (model !== void 0) {
|
|
365
|
+
args.push("--model", model);
|
|
366
|
+
}
|
|
367
|
+
return { args, stdin: request.prompt };
|
|
368
|
+
},
|
|
369
|
+
readResult(result, request) {
|
|
370
|
+
const events = parseEvents(result.stdout);
|
|
371
|
+
const assistant = events.filter((event) => event.type === "message_end" && event.message?.role === "assistant").map((event) => event.message).pop();
|
|
372
|
+
if (assistant && (assistant.stopReason === "error" || assistant.errorMessage)) {
|
|
373
|
+
return failed((0, failure_classification_1.classifyAgentFailure)("pi", assistant.errorMessage ?? "pi stopped with an error"));
|
|
374
|
+
}
|
|
375
|
+
const retryFailed = events.find((event) => event.type === "auto_retry_end" && event.success === false);
|
|
376
|
+
if (retryFailed) {
|
|
377
|
+
return failed((0, failure_classification_1.classifyAgentFailure)("pi", retryFailed.finalError ?? "auto retry failed"));
|
|
378
|
+
}
|
|
379
|
+
if (!assistant) {
|
|
380
|
+
return failed((0, failure_classification_1.classifyAgentFailure)("pi", `exited with code ${result.exitCode} without a reply: ${(0, failure_classification_1.stderrTail)(result)}`));
|
|
381
|
+
}
|
|
382
|
+
const text = (assistant.content ?? []).filter((block) => block.type === "text").map((block) => block.text ?? "").join("");
|
|
383
|
+
const usage = assistant.usage ?? {};
|
|
384
|
+
const promptTokens = (usage.input ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
385
|
+
const completionTokens = usage.output ?? 0;
|
|
386
|
+
const reported = {
|
|
387
|
+
usage: { promptTokens, completionTokens, totalTokens: promptTokens + completionTokens },
|
|
388
|
+
model: assistant.model,
|
|
389
|
+
costUsdEstimate: usage.cost?.total
|
|
390
|
+
};
|
|
391
|
+
if (request.enforcement.kind === "in-prompt") {
|
|
392
|
+
return { kind: "answered", answer: { kind: "text", text }, ...reported };
|
|
393
|
+
}
|
|
394
|
+
let envelope;
|
|
395
|
+
try {
|
|
396
|
+
envelope = JSON.parse(text);
|
|
397
|
+
} catch {
|
|
398
|
+
return failed({ kind: "transient", message: `pi reply is not JSON: ${text}` });
|
|
399
|
+
}
|
|
400
|
+
return { kind: "answered", answer: { kind: "structured", envelope }, ...reported };
|
|
401
|
+
},
|
|
402
|
+
// Pi has no provider-agnostic login check: `pi auth check` requires --provider
|
|
403
|
+
// or --model, and the provider differs per user (it is not known until Pi's
|
|
404
|
+
// settings are read). Report installed Pi as logged in; the first real call
|
|
405
|
+
// surfaces any auth error, which classifyAgentFailure marks fatal.
|
|
406
|
+
loginStatusArgs: ["--version"],
|
|
407
|
+
readLoginStatus(result) {
|
|
408
|
+
return {
|
|
409
|
+
loggedIn: result.exitCode === 0,
|
|
410
|
+
detail: "installed; auth is verified on the first call"
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
function failed(failure) {
|
|
415
|
+
return { kind: "failed", failure };
|
|
416
|
+
}
|
|
417
|
+
function parseEvents(stdout) {
|
|
418
|
+
const events = [];
|
|
419
|
+
for (const line of stdout.split("\n")) {
|
|
420
|
+
const trimmed = line.replace(/\r$/, "").trim();
|
|
421
|
+
if (!trimmed.startsWith("{"))
|
|
422
|
+
continue;
|
|
423
|
+
try {
|
|
424
|
+
const parsed = JSON.parse(trimmed);
|
|
425
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
426
|
+
events.push(parsed);
|
|
427
|
+
}
|
|
428
|
+
} catch {
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return events;
|
|
432
|
+
}
|
|
433
|
+
return pi;
|
|
434
|
+
}
|
|
435
|
+
|
|
367
436
|
var hasRequiredAdapters;
|
|
368
437
|
function requireAdapters() {
|
|
369
438
|
if (hasRequiredAdapters) return adapters;
|
|
@@ -372,9 +441,11 @@ function requireAdapters() {
|
|
|
372
441
|
adapters.AGENT_ADAPTERS = void 0;
|
|
373
442
|
const claude_code_1 = requireClaudeCode();
|
|
374
443
|
const codex_1 = requireCodex();
|
|
444
|
+
const pi_1 = requirePi();
|
|
375
445
|
adapters.AGENT_ADAPTERS = {
|
|
376
446
|
"claude-code": claude_code_1.claudeCodeAdapter,
|
|
377
|
-
codex: codex_1.codexAdapter
|
|
447
|
+
codex: codex_1.codexAdapter,
|
|
448
|
+
pi: pi_1.piAdapter
|
|
378
449
|
};
|
|
379
450
|
return adapters;
|
|
380
451
|
}
|
|
@@ -389,7 +460,7 @@ function requireAgentId() {
|
|
|
389
460
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
390
461
|
exports$1.LOCAL_AGENT_IDS = void 0;
|
|
391
462
|
exports$1.isLocalAgentId = isLocalAgentId;
|
|
392
|
-
exports$1.LOCAL_AGENT_IDS = ["claude-code", "codex"];
|
|
463
|
+
exports$1.LOCAL_AGENT_IDS = ["claude-code", "codex", "pi"];
|
|
393
464
|
const LOCAL_AGENT_ID_SET = new Set(exports$1.LOCAL_AGENT_IDS);
|
|
394
465
|
function isLocalAgentId(value) {
|
|
395
466
|
return typeof value === "string" && LOCAL_AGENT_ID_SET.has(value);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Logger } from "../../../lib/logger";
|
|
2
|
+
import { JsonSchema } from "../../../lib/schema-utils";
|
|
2
3
|
import { AttemptOutcome, AttemptRequest, LlmEngine } from "../llm-engine";
|
|
3
4
|
import { ProviderTarget } from "./provider-call";
|
|
4
5
|
/** Answers cast attempts on one model of an LLM provider's HTTP API. */
|
|
@@ -6,7 +7,7 @@ export declare class HttpEngine implements LlmEngine {
|
|
|
6
7
|
private readonly target;
|
|
7
8
|
private readonly logger;
|
|
8
9
|
constructor(target: ProviderTarget, logger: Logger);
|
|
9
|
-
/**
|
|
10
|
-
nativeSchema(): null;
|
|
10
|
+
/** Enforced in strict mode on models whose provider supports it; other models get the schema in the prompt. */
|
|
11
|
+
nativeSchema(envelopeSchema: JsonSchema): JsonSchema | null;
|
|
11
12
|
attempt(request: AttemptRequest): Promise<AttemptOutcome>;
|
|
12
13
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { JsonSchema } from "../../../lib/schema-utils";
|
|
1
2
|
export type ProviderRequestBase = {
|
|
2
3
|
url: string;
|
|
3
4
|
method?: string;
|
|
@@ -15,6 +16,8 @@ export interface ProviderRequestOptions {
|
|
|
15
16
|
model: string;
|
|
16
17
|
maxTokens: number;
|
|
17
18
|
assistantPrefillPrompt?: string;
|
|
19
|
+
/** A JSON schema the provider enforces on the reply, in strict mode. */
|
|
20
|
+
responseSchema?: JsonSchema;
|
|
18
21
|
}
|
|
19
22
|
export type NormalizedUsage = {
|
|
20
23
|
promptTokens: number;
|
|
@@ -30,6 +33,8 @@ export interface ProviderConfig {
|
|
|
30
33
|
providerId: LlmProviderId;
|
|
31
34
|
apiOperation: string;
|
|
32
35
|
errorLabel: string;
|
|
36
|
+
/** Models that can enforce a response JSON schema in strict mode. */
|
|
37
|
+
strictSchemaModels?: ReadonlySet<string>;
|
|
33
38
|
buildRequest(options: ProviderRequestOptions, apiKey: string): ProviderRequestBase;
|
|
34
39
|
parseResponse(response: Response): Promise<ProviderParsedResponse>;
|
|
35
40
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Supported coding-agent CLIs, in the order findLocalAgent() tries them. */
|
|
2
|
-
export declare const LOCAL_AGENT_IDS: readonly ["claude-code", "codex"];
|
|
2
|
+
export declare const LOCAL_AGENT_IDS: readonly ["claude-code", "codex", "pi"];
|
|
3
3
|
export type LocalAgentId = (typeof LOCAL_AGENT_IDS)[number];
|
|
4
4
|
export declare function isLocalAgentId(value: unknown): value is LocalAgentId;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuabase",
|
|
3
3
|
"description": "Nuabase TypeScript client to create typed functions from LLM prompts",
|
|
4
|
-
"version": "2.3.
|
|
4
|
+
"version": "2.3.11",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Jasim A Basheer <jasim@nuabase.com>",
|
|
7
7
|
"engines": {
|
|
@@ -59,7 +59,6 @@
|
|
|
59
59
|
"zod": "^4.1.5"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"ajv": "^8.17.1",
|
|
63
62
|
"@eslint/js": "^9.35.0",
|
|
64
63
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
|
|
65
64
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
@@ -70,29 +69,23 @@
|
|
|
70
69
|
"@types/jest": "^30.0.0",
|
|
71
70
|
"@types/node": "^24.3.3",
|
|
72
71
|
"@types/signale": "^1",
|
|
73
|
-
"
|
|
74
|
-
"chalk": "^5.6.2",
|
|
72
|
+
"ajv": "^8.17.1",
|
|
75
73
|
"esbuild": "^0.25.9",
|
|
76
74
|
"eslint": "^9.35.0",
|
|
77
75
|
"eventsource": "^4.0.0",
|
|
78
76
|
"fs-extra": "^11.3.1",
|
|
79
77
|
"jest": "^30.1.3",
|
|
80
78
|
"knip": "^5.63.1",
|
|
81
|
-
"new-github-release-url": "^2.0.0",
|
|
82
|
-
"open": "^10.2.0",
|
|
83
79
|
"prettier": "^3.6.2",
|
|
84
80
|
"rimraf": "^6.0.1",
|
|
85
81
|
"rollup": "^4.50.1",
|
|
86
82
|
"rollup-plugin-esbuild": "^6.2.1",
|
|
87
83
|
"rollup-plugin-node-externals": "^8.1.1",
|
|
88
84
|
"signale": "^1.4.0",
|
|
89
|
-
"simple-git": "^3.28.0",
|
|
90
85
|
"ts-jest": "^29.4.1",
|
|
91
86
|
"tsx": "^4.20.5",
|
|
92
87
|
"typescript": "^5.9.2",
|
|
93
88
|
"typescript-eslint": "^8.43.0",
|
|
94
|
-
"version-next": "^1.0.2",
|
|
95
|
-
"yargs": "^18.0.0",
|
|
96
89
|
"zod": "^4.1.5",
|
|
97
90
|
"zx": "^8.8.1",
|
|
98
91
|
"nua-llm-core": "1.0.0"
|
|
@@ -108,7 +101,7 @@
|
|
|
108
101
|
"lint": "eslint --cache .",
|
|
109
102
|
"jest": "jest",
|
|
110
103
|
"test": "pnpm run prettier:check && pnpm run typecheck && pnpm run lint && pnpm run jest && pnpm run build && pnpm run pack:test",
|
|
111
|
-
"release": "
|
|
104
|
+
"release": "tsx scripts/release",
|
|
112
105
|
"knip": "knip"
|
|
113
106
|
}
|
|
114
107
|
}
|