neoctl 0.2.53 → 0.2.55

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.
Files changed (81) hide show
  1. package/README.md +0 -1
  2. package/dist/agents/agent-activity.js +1 -1
  3. package/dist/agents/agent-activity.js.map +1 -1
  4. package/dist/agents/agent-tool.js +4 -4
  5. package/dist/agents/agent-tool.js.map +1 -1
  6. package/dist/core/context-metrics.js +2 -1
  7. package/dist/core/context-metrics.js.map +1 -1
  8. package/dist/core/query-engine.d.ts +13 -0
  9. package/dist/core/query-engine.js +98 -18
  10. package/dist/core/query-engine.js.map +1 -1
  11. package/dist/core/query.d.ts +1 -0
  12. package/dist/core/query.js +10 -1
  13. package/dist/core/query.js.map +1 -1
  14. package/dist/core/run-agent.js +45 -36
  15. package/dist/core/run-agent.js.map +1 -1
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/model/agent-settings-boundary.d.ts +11 -0
  20. package/dist/model/agent-settings-boundary.js +53 -0
  21. package/dist/model/agent-settings-boundary.js.map +1 -0
  22. package/dist/model/anthropic-adapter.d.ts +24 -0
  23. package/dist/model/anthropic-adapter.js +106 -0
  24. package/dist/model/anthropic-adapter.js.map +1 -0
  25. package/dist/model/anthropic-mapper.d.ts +14 -0
  26. package/dist/model/anthropic-mapper.js +364 -0
  27. package/dist/model/anthropic-mapper.js.map +1 -0
  28. package/dist/model/composition-runtime.d.ts +31 -0
  29. package/dist/model/composition-runtime.js +31 -0
  30. package/dist/model/composition-runtime.js.map +1 -0
  31. package/dist/model/config.d.ts +10 -3
  32. package/dist/model/config.js +26 -10
  33. package/dist/model/config.js.map +1 -1
  34. package/dist/model/context-window.d.ts +16 -1
  35. package/dist/model/context-window.js +171 -5
  36. package/dist/model/context-window.js.map +1 -1
  37. package/dist/model/env.js +0 -1
  38. package/dist/model/env.js.map +1 -1
  39. package/dist/model/model-gateway.d.ts +4 -1
  40. package/dist/model/model-gateway.js +4 -0
  41. package/dist/model/model-gateway.js.map +1 -1
  42. package/dist/model/model-metadata.json +10 -3
  43. package/dist/model/openai-adapter.js +2 -1
  44. package/dist/model/openai-adapter.js.map +1 -1
  45. package/dist/model/provider-factory.js +28 -1
  46. package/dist/model/provider-factory.js.map +1 -1
  47. package/dist/model/settings-files.d.ts +3 -0
  48. package/dist/model/settings-files.js +43 -0
  49. package/dist/model/settings-files.js.map +1 -0
  50. package/dist/model/settings-store.d.ts +85 -0
  51. package/dist/model/settings-store.js +235 -0
  52. package/dist/model/settings-store.js.map +1 -0
  53. package/dist/model/settings-sync.d.ts +31 -0
  54. package/dist/model/settings-sync.js +81 -0
  55. package/dist/model/settings-sync.js.map +1 -0
  56. package/dist/repl/commands.d.ts +1 -1
  57. package/dist/repl/commands.js +3 -2
  58. package/dist/repl/commands.js.map +1 -1
  59. package/dist/repl/index.js +51 -25
  60. package/dist/repl/index.js.map +1 -1
  61. package/dist/session/session-store.d.ts +11 -0
  62. package/dist/session/session-store.js +18 -1
  63. package/dist/session/session-store.js.map +1 -1
  64. package/dist/tasks/task-persistence.js +2 -1
  65. package/dist/tasks/task-persistence.js.map +1 -1
  66. package/dist/tools/builtins/image-generation-tool.js +2 -0
  67. package/dist/tools/builtins/image-generation-tool.js.map +1 -1
  68. package/dist/tools/builtins/search-providers.js +2 -0
  69. package/dist/tools/builtins/search-providers.js.map +1 -1
  70. package/dist/tools/builtins/search-tool.d.ts +2 -0
  71. package/dist/tools/builtins/search-tool.js +2 -2
  72. package/dist/tools/builtins/search-tool.js.map +1 -1
  73. package/dist/types/events.d.ts +1 -0
  74. package/dist/web/index.d.ts +9 -3
  75. package/dist/web/index.js +123 -32
  76. package/dist/web/index.js.map +1 -1
  77. package/dist/web/model-settings-api.d.ts +9 -0
  78. package/dist/web/model-settings-api.js +236 -0
  79. package/dist/web/model-settings-api.js.map +1 -0
  80. package/package.json +2 -2
  81. package/scripts/initialize-model-metadata.mjs +6 -0
@@ -7,7 +7,7 @@ const MAX_TEXT_CHARS = 1600;
7
7
  export function createSearchTool(options = {}) {
8
8
  return {
9
9
  name: "web_search",
10
- description: "Search the web for current information. OpenAI Responses web search is the default provider and inherits the configured OpenAI URL and API key. Use Exa's official MCP service only when OpenAI search is unavailable or only partially available for the requested queries. Use file_search for local workspace text lookup. Do not explicitly select Exa unless the user requests it or OpenAI has failed or returned incomplete availability.",
10
+ description: options.description ?? "Search the web for current information. OpenAI Responses web search is the default provider and inherits the configured OpenAI URL and API key. Use Exa's official MCP service only when OpenAI search is unavailable or only partially available for the requested queries. Use file_search for local workspace text lookup. Do not explicitly select Exa unless the user requests it or OpenAI has failed or returned incomplete availability.",
11
11
  inputSchema: {
12
12
  type: "object",
13
13
  properties: {
@@ -73,7 +73,7 @@ export function createSearchTool(options = {}) {
73
73
  async call(input, context, callOptions) {
74
74
  let provider;
75
75
  try {
76
- provider = options.provider ?? createSearchProvider({ provider: input.provider }, process.env);
76
+ provider = options.resolveProvider ? options.resolveProvider(input.provider) : options.provider ?? createSearchProvider({ provider: input.provider }, process.env);
77
77
  }
78
78
  catch (error) {
79
79
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"search-tool.js","sourceRoot":"","sources":["../../../src/tools/builtins/search-tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-tool.js","sourceRoot":"","sources":["../../../src/tools/builtins/search-tool.ts"],"names":[],"mappings":"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"}
@@ -128,6 +128,7 @@ export type AgentEvent = {
128
128
  } | {
129
129
  type: "usage";
130
130
  usage: ModelUsage;
131
+ provisional?: boolean;
131
132
  } | {
132
133
  type: "retrying";
133
134
  attempt: number;
@@ -11,7 +11,7 @@ import { QueryEngine } from "../core/query-engine.js";
11
11
  import { type AppPromptStore } from "../app/app-prompt.js";
12
12
  import { type ModelProviderName } from "../model/config.js";
13
13
  import { CommunicationLogger, LoggingModelGateway } from "../model/communication-logger.js";
14
- import type { ModelUsage, ReasoningConfig, ReasoningEffort } from "../model/model-gateway.js";
14
+ import type { ModelUsage, ReasoningConfig } from "../model/model-gateway.js";
15
15
  import { ToolRegistry } from "../tools/registry.js";
16
16
  import type { Tool, ToolUseContext } from "../tools/tool.js";
17
17
  import { type ToolPresentation } from "../tools/tool-catalog.js";
@@ -451,6 +451,7 @@ export declare class WebRepl {
451
451
  isDemo(engine?: QueryEngine): boolean;
452
452
  startDemo(expectedSessionId: string): Promise<WebActionResult>;
453
453
  private recordDemoInput;
454
+ private readonly settingsListener;
454
455
  constructor(runtime: WebRuntime, demoOptions?: {
455
456
  wait?: DemoWait;
456
457
  });
@@ -726,6 +727,7 @@ export declare class WebRepl {
726
727
  modelSettings: {
727
728
  model: string | undefined;
728
729
  reasoning: ReasoningConfig | null | undefined;
730
+ imageInput: boolean | undefined;
729
731
  };
730
732
  pendingSessionSettings: import("../core/query.js").SessionSettingsPatch & {
731
733
  sessionPrompt?: import("../core/session-settings-prompt.js").SessionPromptState | null;
@@ -735,12 +737,16 @@ export declare class WebRepl {
735
737
  catalog: {
736
738
  commands: import("../repl/commands.js").ReplCommandDefinition[];
737
739
  modelIds: string[];
740
+ modelProtocol: "openai" | "anthropic" | undefined;
738
741
  modelReasoning: {
739
- [k: string]: ReasoningEffort[];
742
+ [k: string]: string[];
743
+ };
744
+ modelReasoningEnabled: {
745
+ [k: string]: boolean;
740
746
  };
741
747
  reasoning: string[];
742
748
  envPath: string;
743
- } | undefined;
749
+ };
744
750
  interactive: {
745
751
  sessions: boolean;
746
752
  login: LoginFormPayload;
package/dist/web/index.js CHANGED
@@ -1,4 +1,11 @@
1
1
  #!/usr/bin/env node
2
+ import { trackSettingsGateway } from "../model/settings-sync.js";
3
+ import { observeModelSettings } from "../model/settings-sync.js";
4
+ import { modelProtocols } from "../model/context-window.js";
5
+ import { isReasoningEffort } from "../model/model-gateway.js";
6
+ import { ModelSettingsStore, compositionModelConfig } from "../model/settings-store.js";
7
+ import { registerCompositionTools } from "../model/composition-runtime.js";
8
+ import { handleModelSettingsRequest } from "./model-settings-api.js";
2
9
  import { paginateSessions, sessionPageOptions } from "../session/session-pagination.js";
3
10
  import { applyToolInputChanges } from "../model/tool-input-stream.js";
4
11
  import { toolActivity } from "./tool-activity.js";
@@ -29,7 +36,7 @@ import { loadDefaultDotEnvFiles } from "../model/env.js";
29
36
  import { readModelProviderConfig } from "../model/config.js";
30
37
  import { findModelMetadata, loadModelCatalog, reasoningEffortsForModel, resolveContextWindowTokens } from "../model/context-window.js";
31
38
  import { CommunicationLogger, LoggingModelGateway } from "../model/communication-logger.js";
32
- import { createModelGatewayFromConfig, createModelGatewayFromProcessEnv } from "../model/provider-factory.js";
39
+ import { createModelGatewayFromConfig } from "../model/provider-factory.js";
33
40
  import { ToolRegistry, isToolEnabledByDefault } from "../tools/registry.js";
34
41
  import { builtinToolPresentation, toolPresentationForSource } from "../tools/tool-catalog.js";
35
42
  import { editTool, writeTool } from "../tools/builtins/edit-tool.js";
@@ -147,9 +154,13 @@ function parseWebArgs(argv) {
147
154
  }
148
155
  export async function createWebRuntime(options = {}) {
149
156
  const envLoad = loadDefaultDotEnvFiles({ override: true });
150
- const modelConfig = readModelProviderConfig(process.env);
157
+ loadModelCatalog();
158
+ const settingsStore = new ModelSettingsStore();
159
+ const appliedSettings = settingsStore.read()?.applied;
160
+ const settingsRevisions = new WeakMap();
161
+ const modelConfig = appliedSettings ? compositionModelConfig(appliedSettings.composition, appliedSettings.connections) : readModelProviderConfig(process.env);
151
162
  const communicationLogger = new CommunicationLogger();
152
- const modelGateway = new LoggingModelGateway(createModelGatewayFromProcessEnv(process.env), communicationLogger);
163
+ const modelGateway = trackSettingsGateway(new LoggingModelGateway(createModelGatewayFromConfig(modelConfig), communicationLogger), appliedSettings?.revision, appliedSettings ? [appliedSettings.composition.main.api, appliedSettings.composition.image.api, appliedSettings.composition.search.api] : []);
153
164
  const taskStore = new TaskStore();
154
165
  const pluginCatalog = normalizeWebRuntimePlugins(options.externalPlugins);
155
166
  const pluginOverrides = normalizePluginOverrides(options.sessionPluginOverrides, pluginCatalog);
@@ -179,6 +190,13 @@ export async function createWebRuntime(options = {}) {
179
190
  registerTool(createLoadImageTool(), { source: "builtin" });
180
191
  if (modelConfig?.provider === "openai")
181
192
  registerTool(createOpenAIImageGenerationTool(), { source: "builtin" });
193
+ if (appliedSettings)
194
+ registerCompositionTools(tools, appliedSettings.composition, appliedSettings.connections);
195
+ for (const name of ["web_search", "image_create"]) {
196
+ const tool = tools.get(name);
197
+ if (tool)
198
+ catalogTool(tool, { source: "builtin" });
199
+ }
182
200
  registerTool(planTool, { source: "builtin" });
183
201
  const frameworkFeedback = new FrameworkFeedbackStore(options.frameworkFeedbackDir);
184
202
  registerTool(createFrameworkFeedbackTool(frameworkFeedback), { source: "builtin" });
@@ -217,6 +235,40 @@ export async function createWebRuntime(options = {}) {
217
235
  tools,
218
236
  contextManagerFactory: (cwd) => new DefaultContextManager({ cwd }),
219
237
  acquireTurnResources: (engine) => acquireWebPluginTurn(runtime, true, engine),
238
+ beforeQuery: (engine) => {
239
+ const applied = settingsStore.read()?.applied;
240
+ const captureTools = () => {
241
+ const snapshot = tools.clone();
242
+ compositionToolSnapshots.set(engine, snapshot);
243
+ const session = engine.snapshot().session?.sessionId;
244
+ if (session)
245
+ sessionCompositionSnapshots.set(session, new WeakRef(engine));
246
+ };
247
+ if (!applied) {
248
+ if (!compositionToolSnapshots.has(engine))
249
+ captureTools();
250
+ return;
251
+ }
252
+ const revision = applied.revision;
253
+ if (settingsRevisions.get(engine) === revision)
254
+ return;
255
+ const config = compositionModelConfig(applied.composition, applied.connections);
256
+ const gateway = trackSettingsGateway(new LoggingModelGateway(createModelGatewayFromConfig(config), communicationLogger), revision, [applied.composition.main.api, applied.composition.image.api, applied.composition.search.api]);
257
+ engine.setModelProvider({ modelGateway: gateway, model: config?.model, reasoning: config?.defaultReasoning });
258
+ if (config)
259
+ effectiveModelProviders.set(engine, config.provider);
260
+ registerCompositionTools(tools, applied.composition, applied.connections);
261
+ for (const name of ["web_search", "image_create"]) {
262
+ const tool = tools.get(name);
263
+ if (tool)
264
+ catalogTool(tool, { source: "builtin" });
265
+ }
266
+ runtime.modelGateway = gateway;
267
+ runtime.agentRuntime.modelGateway = gateway;
268
+ runtime.defaultReasoning = config?.defaultReasoning;
269
+ settingsRevisions.set(engine, revision);
270
+ captureTools();
271
+ },
220
272
  refreshTools: (engine) => {
221
273
  if (runtime)
222
274
  refreshRuntimePlugins(runtime, engine);
@@ -353,6 +405,8 @@ function resolveRuntimePluginOverrides(runtime, engine, sessionId = engine.snaps
353
405
  return support.overrides;
354
406
  }
355
407
  /** Children acquire independent tools/prompts; they never refresh the parent's in-flight context. */
408
+ const compositionToolSnapshots = new WeakMap();
409
+ const sessionCompositionSnapshots = new Map();
356
410
  function acquireWebPluginTurn(runtime, main, engine = runtime.engine, sessionId) {
357
411
  if (main) {
358
412
  refreshRuntimePlugins(runtime, engine);
@@ -364,6 +418,22 @@ function acquireWebPluginTurn(runtime, main, engine = runtime.engine, sessionId)
364
418
  try {
365
419
  const catalog = normalizeWebRuntimePlugins(snapshot?.plugins ?? support?.resolveCatalog?.() ?? support?.catalog);
366
420
  const tools = buildPluginRegistry(runtime, catalog, overrides);
421
+ const owner = sessionId ? sessionCompositionSnapshots.get(sessionId)?.deref() : engine;
422
+ const frozen = owner ? compositionToolSnapshots.get(owner)?.clone() : undefined;
423
+ if (sessionId && !owner)
424
+ sessionCompositionSnapshots.delete(sessionId);
425
+ if (frozen)
426
+ for (const name of ["web_search", "image_create"]) {
427
+ const enabled = tools.isEnabled(name) ?? frozen.isEnabled(name);
428
+ frozen.setEnabled(name, true);
429
+ const tool = frozen.get(name);
430
+ tools.unregister(name);
431
+ if (tool) {
432
+ tools.register(tool);
433
+ if (enabled === false)
434
+ tools.setEnabled(name, false);
435
+ }
436
+ }
367
437
  return { tools, release: snapshot?.release ?? (() => { }),
368
438
  ...(!main ? { promptSections: [...(support?.basePromptSections ?? []), ...activeWebRuntimePlugins(catalog, overrides).flatMap(plugin => plugin.promptSections ?? [])] } : {}) };
369
439
  }
@@ -747,9 +817,17 @@ export class WebRepl {
747
817
  this.demoMessageQueues.delete(engine);
748
818
  }
749
819
  }
820
+ settingsListener = () => {
821
+ if (this.deletingSession)
822
+ return;
823
+ this.runtime.engine.refreshModelConfigurationIfIdle();
824
+ for (const subscriber of this.subscribers)
825
+ this.send(subscriber, "sync", this.snapshot());
826
+ };
750
827
  constructor(runtime, demoOptions = {}) {
751
828
  this.runtime = runtime;
752
829
  this.demoOptions = demoOptions;
830
+ observeModelSettings(this.settingsListener);
753
831
  const lineId = { current: 0 };
754
832
  this.lines = initialLines(runtime, lineId);
755
833
  this.lineId = lineId.current;
@@ -830,6 +908,7 @@ export class WebRepl {
830
908
  }
831
909
  snapshot(includeCatalog = false) {
832
910
  const backgroundTasks = this.backgroundTasks();
911
+ this.runtime.engine.refreshModelConfigurationIfIdle?.();
833
912
  const engineSnapshot = this.runtime.engine.snapshot();
834
913
  const pendingSessionSettings = this.runtime.engine.getPendingSessionSettings?.() ?? {};
835
914
  // Include retained reasoning alongside a queued model. Explicit undefined is
@@ -855,11 +934,11 @@ export class WebRepl {
855
934
  backgroundSessionRunCount: this.backgroundSessionRuns.size,
856
935
  runningSessionIds: this.runningSessionIds(),
857
936
  session: engineSnapshot.session,
858
- modelSettings: { model: engineSnapshot.model, reasoning: engineSnapshot.reasoning },
937
+ modelSettings: { model: engineSnapshot.model, reasoning: engineSnapshot.reasoning, imageInput: findModelMetadata(engineSnapshot.model || "")?.imageInput },
859
938
  pendingSessionSettings,
860
939
  fastMode: this.runtime.engine.isFastMode(),
861
940
  appPrompt: this.runtime.engine.getAppPrompt(),
862
- catalog: includeCatalog ? webCatalog(this.runtime) : undefined,
941
+ catalog: webCatalog(this.runtime),
863
942
  interactive: includeCatalog ? webInteractiveCatalog(this.runtime) : undefined,
864
943
  };
865
944
  }
@@ -1457,11 +1536,15 @@ export class WebRepl {
1457
1536
  if (typeof model !== "string" || !model.trim() || model.length > 256 || /[\s\x00-\x1f]/u.test(model.trim())) {
1458
1537
  return actionFailure("MODEL_INVALID", "invalid model");
1459
1538
  }
1460
- if (reasoning !== undefined && (typeof reasoning !== "string" || !["none", "minimal", "low", "medium", "high", "xhigh", "max", "default", "off"].includes(reasoning))) {
1539
+ if (reasoning !== undefined && (typeof reasoning !== "string" || !(reasoning === "default" || reasoning === "off" || isReasoningEffort(reasoning)))) {
1461
1540
  return actionFailure("MODEL_INVALID", "invalid reasoning effort");
1462
1541
  }
1463
1542
  const engine = this.runtime.engine;
1464
1543
  const nextModel = model.trim();
1544
+ const provider = effectiveModelProviders.get(engine) ?? readModelProviderConfig()?.provider;
1545
+ const metadata = (engine.getActiveModelCatalog?.() ?? loadModelCatalog()).models.find(m => m.modelIds.includes(nextModel));
1546
+ if (metadata && provider && !modelProtocols(metadata).includes(provider))
1547
+ return actionFailure("MODEL_INVALID", "模型不支持当前主连接接口");
1465
1548
  const current = { ...engine.getModelSettings(), ...engine.getPendingSessionSettings() };
1466
1549
  const argument = reasoning;
1467
1550
  const validationError = validateModelReasoningArgument(nextModel, argument);
@@ -1567,9 +1650,10 @@ export class WebRepl {
1567
1650
  async saveLogin(providerValue, values) {
1568
1651
  const provider = parseLoginProvider(providerValue);
1569
1652
  if (!provider)
1570
- return actionFailure("LOGIN_INVALID", "provider must be openai");
1653
+ return actionFailure("LOGIN_INVALID", "provider must be openai or anthropic");
1571
1654
  if (dockerEnabled() && !values.apiKey?.trim()) {
1572
- values = { ...values, apiKey: parseEnvFileSafe(this.runtime.envPath).OPENAI_API_KEY || process.env.OPENAI_API_KEY || "" };
1655
+ const key = provider === "anthropic" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
1656
+ values = { ...values, apiKey: parseEnvFileSafe(this.runtime.envPath)[key] || process.env[key] || "" };
1573
1657
  }
1574
1658
  const payload = { ...createLoginFormPayload(this.runtime.envPath, provider), provider, values };
1575
1659
  const validationError = validateLoginFormPayload(payload);
@@ -1598,7 +1682,7 @@ export class WebRepl {
1598
1682
  run.engine.setModelProvider({ modelGateway: this.runtime.modelGateway, model: config.model, reasoning: config.defaultReasoning });
1599
1683
  }
1600
1684
  syncImageGenerationTool(this.runtime, config.provider);
1601
- this.runtime.defaultReasoning = config.defaultReasoning;
1685
+ this.runtime.defaultReasoning = config?.defaultReasoning;
1602
1686
  const metrics = await this.runtime.engine.contextMetrics();
1603
1687
  this.setStatus({ ...this.status, metrics, activityTick: this.status.activityTick + 1 });
1604
1688
  this.publishRuntimeContext();
@@ -1953,7 +2037,7 @@ export class WebRepl {
1953
2037
  }
1954
2038
  reduce(event) {
1955
2039
  this.status = reduceStatus(this.status, event);
1956
- if (event.type === "usage")
2040
+ if (event.type === "usage" && !event.provisional)
1957
2041
  this.runtime.usage.add(event.usage);
1958
2042
  }
1959
2043
  finalizeLiveLine(id) {
@@ -2963,6 +3047,8 @@ export async function handleWebRequest(req, res, router) {
2963
3047
  }
2964
3048
  if (req.method === "POST" && url.pathname === "/api/sessions/new")
2965
3049
  return sendJson(res, await repl.newSession());
3050
+ if (await handleModelSettingsRequest(req, res, url))
3051
+ return;
2966
3052
  if (req.method === "GET" && url.pathname === "/api/login")
2967
3053
  return sendJson(res, repl.loginForm(url.searchParams.get("provider") ?? undefined));
2968
3054
  if (req.method === "POST" && url.pathname === "/api/login") {
@@ -3083,12 +3169,18 @@ function sanitizeWebAttachments(value) {
3083
3169
  return [];
3084
3170
  });
3085
3171
  }
3172
+ const effectiveModelProviders = new WeakMap();
3086
3173
  function webCatalog(runtime) {
3087
- const modelIds = [...new Set(loadModelCatalog().models.flatMap((model) => model.modelIds.length ? model.modelIds : [model.id]))].sort((left, right) => left.localeCompare(right));
3174
+ const catalog = runtime.engine.getActiveModelCatalog?.() ?? loadModelCatalog();
3175
+ const provider = effectiveModelProviders.get(runtime.engine) ?? readModelProviderConfig()?.provider;
3176
+ const models = catalog.models.filter(model => !provider || modelProtocols(model).includes(provider));
3177
+ const modelIds = [...new Set(models.flatMap(model => model.modelIds.length ? model.modelIds : [model.id]))].sort((left, right) => left.localeCompare(right, "en", { numeric: true }));
3088
3178
  return {
3089
3179
  commands: replCommandDefinitions,
3090
3180
  modelIds,
3091
- modelReasoning: Object.fromEntries(modelIds.map(model => [model, reasoningEffortsForModel(model) ?? []])),
3181
+ modelProtocol: provider,
3182
+ modelReasoning: Object.fromEntries(modelIds.map(model => [model, reasoningEffortsForModel(model, catalog) ?? []])),
3183
+ modelReasoningEnabled: Object.fromEntries(models.flatMap(m => m.modelIds.map(id => [id, m.reasoning !== false]))),
3092
3184
  reasoning: ["none", "minimal", "low", "medium", "high", "xhigh", "max", "default", "off"],
3093
3185
  envPath: runtime.envPath,
3094
3186
  };
@@ -3398,7 +3490,7 @@ async function handleModelCommand(command, runtime) {
3398
3490
  runtime.agentRuntime.modelGateway = runtime.modelGateway;
3399
3491
  runtime.engine.setModelProvider({ modelGateway: runtime.modelGateway, model: config.model, reasoning: config.defaultReasoning });
3400
3492
  syncImageGenerationTool(runtime, config.provider);
3401
- runtime.defaultReasoning = config.defaultReasoning;
3493
+ runtime.defaultReasoning = config?.defaultReasoning;
3402
3494
  }
3403
3495
  }
3404
3496
  }
@@ -3448,28 +3540,32 @@ async function persistModelCommandSettings(runtime, command, reasoningUpdate) {
3448
3540
  return { providerChanged: targetProvider !== currentProvider };
3449
3541
  }
3450
3542
  function currentModelProvider() {
3451
- return "openai";
3543
+ return parseLoginProvider(process.env.MODEL_PROVIDER) ?? "openai";
3452
3544
  }
3453
3545
  function parseLoginProvider(value) {
3454
- if (value === "openai")
3546
+ if (value === "openai" || value === "anthropic")
3455
3547
  return value;
3456
3548
  return undefined;
3457
3549
  }
3458
- const LOGIN_PROVIDERS = ["openai"];
3550
+ const LOGIN_PROVIDERS = ["openai", "anthropic"];
3459
3551
  const SHARED_LOGIN_FIELDS = [
3460
3552
  { key: "reasoningEffort", label: "Reasoning effort", envKey: "MODEL_REASONING_EFFORT", scope: "shared", options: ["", "off", "none", "minimal", "low", "medium", "high", "xhigh", "max"] },
3461
- { key: "reasoningSummary", label: "Reasoning summary", envKey: "MODEL_REASONING_SUMMARY", scope: "shared", options: ["", "auto", "concise", "detailed"] },
3462
- { key: "maxOutputTokens", label: "Max output tokens", envKey: "MODEL_MAX_OUTPUT_TOKENS", scope: "shared" },
3553
+ { key: "maxOutputTokens", label: "Max output tokens", envKey: "MODEL_MAX_OUTPUT_TOKENS", scope: "shared", placeholder: "Leave empty for server default" },
3463
3554
  { key: "timeoutMs", label: "Timeout ms", envKey: "MODEL_TIMEOUT_MS", scope: "shared", placeholder: "120000" },
3464
3555
  { key: "streamIdleTimeoutMs", label: "Stream idle timeout ms", envKey: "MODEL_STREAM_IDLE_TIMEOUT_MS", scope: "shared", placeholder: "120000" },
3465
3556
  { key: "maxRetries", label: "Max retries", envKey: "MODEL_MAX_RETRIES", scope: "shared", placeholder: "2" },
3466
3557
  ];
3467
3558
  const LOGIN_FIELD_DEFINITIONS = {
3559
+ anthropic: [
3560
+ { key: "apiKey", label: "API / CPA key", envKey: "ANTHROPIC_API_KEY", scope: "provider", required: true, secret: true },
3561
+ { key: "baseUrl", label: "Base URL", envKey: "ANTHROPIC_BASE_URL", scope: "provider", placeholder: "https://api.anthropic.com" },
3562
+ { key: "model", label: "Model", envKey: "ANTHROPIC_MODEL", scope: "provider", required: true, placeholder: "claude-sonnet-5-5" },
3563
+ ...SHARED_LOGIN_FIELDS.map(field => field.key === "reasoningEffort" ? { ...field, options: ["", "off", "none", "low", "medium", "high", "xhigh", "max"] } : field.key === "maxOutputTokens" ? { ...field, placeholder: "模型库上限 / 未知模型 64000" } : field),
3564
+ ],
3468
3565
  openai: [
3469
3566
  { key: "apiKey", label: "API key", envKey: "OPENAI_API_KEY", scope: "provider", required: true, secret: true, placeholder: "sk-..." },
3470
3567
  { key: "baseUrl", label: "Base URL", envKey: "OPENAI_BASE_URL", scope: "provider", placeholder: "https://api.openai.com" },
3471
3568
  { key: "model", label: "Model", envKey: "OPENAI_MODEL", scope: "provider", required: true, placeholder: "gpt-5.6" },
3472
- { key: "endpoint", label: "Endpoint", envKey: "OPENAI_ENDPOINT", scope: "provider", placeholder: "auto", options: ["auto", "responses", "chat"] },
3473
3569
  ...SHARED_LOGIN_FIELDS,
3474
3570
  ],
3475
3571
  };
@@ -3496,18 +3592,16 @@ function loginValuesForProvider(provider, env) {
3496
3592
  values.baseUrl = defaultBaseUrlForLoginProvider(provider);
3497
3593
  if (!values.model)
3498
3594
  values.model = defaultModelForLoginProvider(provider);
3499
- if (provider === "openai" && !values.endpoint)
3500
- values.endpoint = "auto";
3501
3595
  return values;
3502
3596
  }
3503
- function guessLoginProvider(_env) {
3504
- return currentModelProvider();
3597
+ function guessLoginProvider(env) {
3598
+ return env.ANTHROPIC_API_KEY && !env.OPENAI_API_KEY ? "anthropic" : currentModelProvider();
3505
3599
  }
3506
- function defaultBaseUrlForLoginProvider(_provider) {
3507
- return "https://api.openai.com";
3600
+ function defaultBaseUrlForLoginProvider(provider) {
3601
+ return provider === "anthropic" ? "https://api.anthropic.com" : "https://api.openai.com";
3508
3602
  }
3509
- function defaultModelForLoginProvider(_provider) {
3510
- return "gpt-5.6";
3603
+ function defaultModelForLoginProvider(provider) {
3604
+ return provider === "anthropic" ? "claude-sonnet-4-6" : "gpt-5.6";
3511
3605
  }
3512
3606
  function validateLoginFormPayload(payload) {
3513
3607
  for (const field of LOGIN_FIELD_DEFINITIONS[payload.provider]) {
@@ -3522,9 +3616,6 @@ function validateLoginFormPayload(payload) {
3522
3616
  if (value && !Number.isFinite(Number(value)))
3523
3617
  return `${fieldKey} must be a number.`;
3524
3618
  }
3525
- if (payload.provider === "openai" && payload.values.endpoint === "chat" && payload.values.reasoningSummary?.trim()) {
3526
- return "Reasoning summary requires the Responses API endpoint.";
3527
- }
3528
3619
  return undefined;
3529
3620
  }
3530
3621
  async function saveLoginPayloadToEnv(payload) {
@@ -3559,8 +3650,8 @@ function stripEnvQuotes(value) {
3559
3650
  return value.slice(1, -1);
3560
3651
  return value;
3561
3652
  }
3562
- function modelEnvKeyForProvider(_provider) {
3563
- return "OPENAI_MODEL";
3653
+ function modelEnvKeyForProvider(provider) {
3654
+ return provider === "anthropic" ? "ANTHROPIC_MODEL" : "OPENAI_MODEL";
3564
3655
  }
3565
3656
  function envValueForReasoning(reasoning) {
3566
3657
  if (reasoning === null)