neoctl 0.2.52 → 0.2.54
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 +0 -1
- package/dist/agents/agent-tool.js +4 -4
- package/dist/agents/agent-tool.js.map +1 -1
- package/dist/core/query-engine.d.ts +10 -0
- package/dist/core/query-engine.js +72 -16
- package/dist/core/query-engine.js.map +1 -1
- package/dist/core/query.d.ts +1 -0
- package/dist/core/query.js +5 -0
- package/dist/core/query.js.map +1 -1
- package/dist/core/run-agent.js +45 -36
- package/dist/core/run-agent.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/model/agent-settings-boundary.d.ts +11 -0
- package/dist/model/agent-settings-boundary.js +52 -0
- package/dist/model/agent-settings-boundary.js.map +1 -0
- package/dist/model/anthropic-adapter.d.ts +24 -0
- package/dist/model/anthropic-adapter.js +106 -0
- package/dist/model/anthropic-adapter.js.map +1 -0
- package/dist/model/anthropic-mapper.d.ts +14 -0
- package/dist/model/anthropic-mapper.js +340 -0
- package/dist/model/anthropic-mapper.js.map +1 -0
- package/dist/model/composition-runtime.d.ts +31 -0
- package/dist/model/composition-runtime.js +31 -0
- package/dist/model/composition-runtime.js.map +1 -0
- package/dist/model/config.d.ts +10 -3
- package/dist/model/config.js +26 -10
- package/dist/model/config.js.map +1 -1
- package/dist/model/context-window.d.ts +16 -1
- package/dist/model/context-window.js +171 -5
- package/dist/model/context-window.js.map +1 -1
- package/dist/model/env.js +0 -1
- package/dist/model/env.js.map +1 -1
- package/dist/model/model-gateway.d.ts +3 -1
- package/dist/model/model-gateway.js +4 -0
- package/dist/model/model-gateway.js.map +1 -1
- package/dist/model/model-metadata.json +9 -3
- package/dist/model/openai-adapter.js +2 -1
- package/dist/model/openai-adapter.js.map +1 -1
- package/dist/model/provider-factory.js +28 -1
- package/dist/model/provider-factory.js.map +1 -1
- package/dist/model/settings-files.d.ts +3 -0
- package/dist/model/settings-files.js +43 -0
- package/dist/model/settings-files.js.map +1 -0
- package/dist/model/settings-store.d.ts +84 -0
- package/dist/model/settings-store.js +191 -0
- package/dist/model/settings-store.js.map +1 -0
- package/dist/model/settings-sync.d.ts +23 -0
- package/dist/model/settings-sync.js +68 -0
- package/dist/model/settings-sync.js.map +1 -0
- package/dist/repl/commands.d.ts +1 -1
- package/dist/repl/commands.js +3 -2
- package/dist/repl/commands.js.map +1 -1
- package/dist/repl/index.js +50 -22
- package/dist/repl/index.js.map +1 -1
- package/dist/session/session-store.d.ts +2 -0
- package/dist/session/session-store.js +7 -1
- package/dist/session/session-store.js.map +1 -1
- package/dist/tasks/task-persistence.js +2 -1
- package/dist/tasks/task-persistence.js.map +1 -1
- package/dist/tools/builtins/image-generation-tool.js +2 -0
- package/dist/tools/builtins/image-generation-tool.js.map +1 -1
- package/dist/tools/builtins/search-providers.js +2 -0
- package/dist/tools/builtins/search-providers.js.map +1 -1
- package/dist/tools/builtins/search-tool.d.ts +2 -0
- package/dist/tools/builtins/search-tool.js +2 -2
- package/dist/tools/builtins/search-tool.js.map +1 -1
- package/dist/web/index.d.ts +10 -3
- package/dist/web/index.js +126 -33
- package/dist/web/index.js.map +1 -1
- package/dist/web/model-settings-api.d.ts +9 -0
- package/dist/web/model-settings-api.js +221 -0
- package/dist/web/model-settings-api.js.map +1 -0
- package/package.json +2 -2
- package/scripts/initialize-model-metadata.mjs +6 -0
package/dist/repl/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { trackSettingsGateway } from "../model/settings-sync.js";
|
|
3
|
+
import { ModelSettingsStore, compositionModelConfig } from "../model/settings-store.js";
|
|
4
|
+
import { registerCompositionTools } from "../model/composition-runtime.js";
|
|
2
5
|
import fs from "node:fs/promises";
|
|
3
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
7
|
import path from "node:path";
|
|
@@ -12,7 +15,7 @@ import { getUserDotEnvPath, loadDefaultDotEnvFiles } from "../model/env.js";
|
|
|
12
15
|
import { readModelProviderConfig } from "../model/config.js";
|
|
13
16
|
import { findModelMetadata, loadModelCatalog, reasoningEffortsForModel, resolveContextWindowTokens } from "../model/context-window.js";
|
|
14
17
|
import { CommunicationLogger, LoggingModelGateway } from "../model/communication-logger.js";
|
|
15
|
-
import { createModelGatewayFromConfig
|
|
18
|
+
import { createModelGatewayFromConfig } from "../model/provider-factory.js";
|
|
16
19
|
import { ToolRegistry } from "../tools/registry.js";
|
|
17
20
|
import { editTool, writeTool } from "../tools/builtins/edit-tool.js";
|
|
18
21
|
import { createExecTool, createWriteStdinTool } from "../tools/builtins/exec-tool.js";
|
|
@@ -233,9 +236,13 @@ async function buildSkillCatalogPromptSection(catalog) {
|
|
|
233
236
|
}
|
|
234
237
|
async function createRuntime(options = {}) {
|
|
235
238
|
const envLoad = loadDefaultDotEnvFiles({ override: true });
|
|
236
|
-
|
|
239
|
+
loadModelCatalog();
|
|
240
|
+
const settingsStore = new ModelSettingsStore();
|
|
241
|
+
const appliedSettings = settingsStore.read()?.applied;
|
|
242
|
+
const settingsRevisions = new WeakMap();
|
|
243
|
+
const modelConfig = appliedSettings ? compositionModelConfig(appliedSettings.composition, appliedSettings.connections) : readModelProviderConfig(process.env);
|
|
237
244
|
const communicationLogger = new CommunicationLogger();
|
|
238
|
-
const modelGateway = new LoggingModelGateway(
|
|
245
|
+
const modelGateway = trackSettingsGateway(new LoggingModelGateway(createModelGatewayFromConfig(modelConfig), communicationLogger), appliedSettings?.revision);
|
|
239
246
|
const taskStore = new TaskStore();
|
|
240
247
|
const agentActivityStore = new AgentActivityStore();
|
|
241
248
|
const secretStore = await SecretStore.open();
|
|
@@ -261,6 +268,8 @@ async function createRuntime(options = {}) {
|
|
|
261
268
|
tools.register(createLoadImageTool());
|
|
262
269
|
if (modelConfig?.provider === "openai")
|
|
263
270
|
tools.register(createOpenAIImageGenerationTool());
|
|
271
|
+
if (appliedSettings)
|
|
272
|
+
registerCompositionTools(tools, appliedSettings.composition, appliedSettings.connections);
|
|
264
273
|
tools.register(planTool);
|
|
265
274
|
tools.register(createFrameworkFeedbackTool());
|
|
266
275
|
for (const tool of createSecretTools())
|
|
@@ -289,6 +298,24 @@ async function createRuntime(options = {}) {
|
|
|
289
298
|
reasoning: modelConfig?.defaultReasoning,
|
|
290
299
|
modelGateway,
|
|
291
300
|
tools,
|
|
301
|
+
beforeQuery: (engine) => {
|
|
302
|
+
const applied = settingsStore.read()?.applied;
|
|
303
|
+
if (!applied)
|
|
304
|
+
return;
|
|
305
|
+
const revision = applied.revision;
|
|
306
|
+
if (settingsRevisions.get(engine) === revision)
|
|
307
|
+
return;
|
|
308
|
+
const config = compositionModelConfig(applied.composition, applied.connections);
|
|
309
|
+
if (!config)
|
|
310
|
+
return;
|
|
311
|
+
const gateway = trackSettingsGateway(new LoggingModelGateway(createModelGatewayFromConfig(config), communicationLogger), revision);
|
|
312
|
+
engine.setModelProvider({ modelGateway: gateway, model: config.model, reasoning: config.defaultReasoning });
|
|
313
|
+
registerCompositionTools(tools, applied.composition, applied.connections);
|
|
314
|
+
runtime.modelGateway = gateway;
|
|
315
|
+
runtime.agentRuntime.modelGateway = gateway;
|
|
316
|
+
runtime.defaultReasoning = config.defaultReasoning;
|
|
317
|
+
settingsRevisions.set(engine, revision);
|
|
318
|
+
},
|
|
292
319
|
contextManager: new SkillCatalogContextManager(skills),
|
|
293
320
|
canUseTool: createSkillAwareCanUseTool(skills),
|
|
294
321
|
secrets: secretStore,
|
|
@@ -2712,10 +2739,10 @@ async function persistModelCommandSettings(runtime, command, reasoningUpdate) {
|
|
|
2712
2739
|
return { providerChanged: targetProvider !== currentProvider };
|
|
2713
2740
|
}
|
|
2714
2741
|
function currentModelProvider() {
|
|
2715
|
-
return "openai";
|
|
2742
|
+
return parseLoginProvider(process.env.MODEL_PROVIDER) ?? "openai";
|
|
2716
2743
|
}
|
|
2717
|
-
function modelEnvKeyForProvider(
|
|
2718
|
-
return "OPENAI_MODEL";
|
|
2744
|
+
function modelEnvKeyForProvider(provider) {
|
|
2745
|
+
return provider === "anthropic" ? "ANTHROPIC_MODEL" : "OPENAI_MODEL";
|
|
2719
2746
|
}
|
|
2720
2747
|
function envValueForReasoning(reasoning) {
|
|
2721
2748
|
if (reasoning === null)
|
|
@@ -3055,21 +3082,25 @@ function restoredHistoryLines(runtime) {
|
|
|
3055
3082
|
}
|
|
3056
3083
|
return lines;
|
|
3057
3084
|
}
|
|
3058
|
-
const LOGIN_PROVIDERS = ["openai"];
|
|
3085
|
+
const LOGIN_PROVIDERS = ["openai", "anthropic"];
|
|
3059
3086
|
const SHARED_LOGIN_FIELDS = [
|
|
3060
3087
|
{ key: "reasoningEffort", label: "Reasoning effort", envKey: "MODEL_REASONING_EFFORT", scope: "shared", options: ["", "off", "none", "minimal", "low", "medium", "high", "xhigh", "max"] },
|
|
3061
|
-
{ key: "
|
|
3062
|
-
{ key: "maxOutputTokens", label: "Max output tokens", envKey: "MODEL_MAX_OUTPUT_TOKENS", scope: "shared" },
|
|
3088
|
+
{ key: "maxOutputTokens", label: "Max output tokens", envKey: "MODEL_MAX_OUTPUT_TOKENS", scope: "shared", placeholder: "Leave empty for server default" },
|
|
3063
3089
|
{ key: "timeoutMs", label: "Timeout ms", envKey: "MODEL_TIMEOUT_MS", scope: "shared", placeholder: "120000" },
|
|
3064
3090
|
{ key: "streamIdleTimeoutMs", label: "Stream idle timeout ms", envKey: "MODEL_STREAM_IDLE_TIMEOUT_MS", scope: "shared", placeholder: "120000" },
|
|
3065
3091
|
{ key: "maxRetries", label: "Max retries", envKey: "MODEL_MAX_RETRIES", scope: "shared", placeholder: "2" },
|
|
3066
3092
|
];
|
|
3067
3093
|
const LOGIN_FIELD_DEFINITIONS = {
|
|
3094
|
+
anthropic: [
|
|
3095
|
+
{ key: "apiKey", label: "API / CPA key", envKey: "ANTHROPIC_API_KEY", scope: "provider", required: true, secret: true },
|
|
3096
|
+
{ key: "baseUrl", label: "Base URL", envKey: "ANTHROPIC_BASE_URL", scope: "provider", placeholder: "https://api.anthropic.com" },
|
|
3097
|
+
{ key: "model", label: "Model", envKey: "ANTHROPIC_MODEL", scope: "provider", required: true, placeholder: "claude-sonnet-4-6" },
|
|
3098
|
+
...SHARED_LOGIN_FIELDS.map(field => field.key === "reasoningEffort" ? { ...field, options: ["", "off", "none", "low", "medium", "high", "xhigh", "max"] } : field.key === "maxOutputTokens" ? { ...field, placeholder: "8192" } : field),
|
|
3099
|
+
],
|
|
3068
3100
|
openai: [
|
|
3069
3101
|
{ key: "apiKey", label: "API key", envKey: "OPENAI_API_KEY", scope: "provider", required: true, secret: true, placeholder: "sk-..." },
|
|
3070
3102
|
{ key: "baseUrl", label: "Base URL", envKey: "OPENAI_BASE_URL", scope: "provider", placeholder: "https://api.openai.com" },
|
|
3071
3103
|
{ key: "model", label: "Model", envKey: "OPENAI_MODEL", scope: "provider", required: true, placeholder: "gpt-5.6" },
|
|
3072
|
-
{ key: "endpoint", label: "Endpoint", envKey: "OPENAI_ENDPOINT", scope: "provider", placeholder: "auto", options: ["auto", "responses", "chat"] },
|
|
3073
3104
|
...SHARED_LOGIN_FIELDS,
|
|
3074
3105
|
],
|
|
3075
3106
|
};
|
|
@@ -3341,9 +3372,6 @@ function validateLoginForm(state) {
|
|
|
3341
3372
|
if (value && !Number.isFinite(Number(value)))
|
|
3342
3373
|
return `${fieldKey} must be a number.`;
|
|
3343
3374
|
}
|
|
3344
|
-
if (state.provider === "openai" && state.values.endpoint === "chat" && state.values.reasoningSummary?.trim()) {
|
|
3345
|
-
return "Reasoning summary requires the Responses API endpoint.";
|
|
3346
|
-
}
|
|
3347
3375
|
return undefined;
|
|
3348
3376
|
}
|
|
3349
3377
|
function createLoginFormState(envPath = getUserDotEnvPath()) {
|
|
@@ -3373,23 +3401,21 @@ function loginValuesForProvider(provider, env) {
|
|
|
3373
3401
|
values.baseUrl = defaultBaseUrlForLoginProvider(provider);
|
|
3374
3402
|
if (!values.model)
|
|
3375
3403
|
values.model = defaultModelForLoginProvider(provider);
|
|
3376
|
-
if (provider === "openai" && !values.endpoint)
|
|
3377
|
-
values.endpoint = "auto";
|
|
3378
3404
|
return values;
|
|
3379
3405
|
}
|
|
3380
3406
|
function parseLoginProvider(value) {
|
|
3381
|
-
if (value === "openai")
|
|
3407
|
+
if (value === "openai" || value === "anthropic")
|
|
3382
3408
|
return value;
|
|
3383
3409
|
return undefined;
|
|
3384
3410
|
}
|
|
3385
|
-
function guessLoginProvider(
|
|
3386
|
-
return "
|
|
3411
|
+
function guessLoginProvider(env) {
|
|
3412
|
+
return env.ANTHROPIC_API_KEY && !env.OPENAI_API_KEY ? "anthropic" : currentModelProvider();
|
|
3387
3413
|
}
|
|
3388
|
-
function defaultBaseUrlForLoginProvider(
|
|
3389
|
-
return "https://api.openai.com";
|
|
3414
|
+
function defaultBaseUrlForLoginProvider(provider) {
|
|
3415
|
+
return provider === "anthropic" ? "https://api.anthropic.com" : "https://api.openai.com";
|
|
3390
3416
|
}
|
|
3391
|
-
function defaultModelForLoginProvider(
|
|
3392
|
-
return "gpt-5.6";
|
|
3417
|
+
function defaultModelForLoginProvider(provider) {
|
|
3418
|
+
return provider === "anthropic" ? "claude-sonnet-4-6" : "gpt-5.6";
|
|
3393
3419
|
}
|
|
3394
3420
|
function loginFormViewHeight(state) {
|
|
3395
3421
|
return state.step === "provider" ? state.providers.length + 3 : LOGIN_FIELD_DEFINITIONS[state.provider].length + 4;
|
|
@@ -3459,6 +3485,7 @@ function updateEnvContent(content, updates, removeKeys = []) {
|
|
|
3459
3485
|
const grouped = groupLoginEnvEntries(missing);
|
|
3460
3486
|
appendEnvGroup(updatedLines, "# Neo active provider", grouped.active);
|
|
3461
3487
|
appendEnvGroup(updatedLines, "# OpenAI provider settings", grouped.openai);
|
|
3488
|
+
appendEnvGroup(updatedLines, "# Anthropic provider settings", grouped.anthropic);
|
|
3462
3489
|
appendEnvGroup(updatedLines, "# Shared model runtime settings", grouped.shared);
|
|
3463
3490
|
}
|
|
3464
3491
|
return `${updatedLines.join("\n").replace(/\n*$/u, "")}\n`;
|
|
@@ -3467,6 +3494,7 @@ function groupLoginEnvEntries(entries) {
|
|
|
3467
3494
|
return {
|
|
3468
3495
|
active: entries.filter(([key]) => key === "MODEL_PROVIDER"),
|
|
3469
3496
|
openai: entries.filter(([key]) => key.startsWith("OPENAI_")),
|
|
3497
|
+
anthropic: entries.filter(([key]) => key.startsWith("ANTHROPIC_")),
|
|
3470
3498
|
shared: entries.filter(([key]) => key.startsWith("MODEL_") && key !== "MODEL_PROVIDER"),
|
|
3471
3499
|
};
|
|
3472
3500
|
}
|