@agentprojectcontext/apx 1.65.3 → 1.66.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentprojectcontext/apx",
3
- "version": "1.65.3",
3
+ "version": "1.66.0",
4
4
  "description": "APX — unified CLI + daemon for the Agent Project Context (APC) standard.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -152,7 +152,7 @@ const DEFAULT_CONFIG = {
152
152
  piper: { bin: "piper", model: "", speaker: "", extra_args: [] },
153
153
  elevenlabs: { api_key: "", model: "eleven_multilingual_v2", voice_id: "", output_format: "mp3_44100_128" },
154
154
  openai: { api_key: "", model: "tts-1", voice: "alloy", format: "mp3" },
155
- gemini: { api_key: "", model: "gemini-2.5-flash-preview-tts", voice: "Kore" },
155
+ gemini: { api_key: "", model: "gemini-2.5-flash-tts", voice: "Kore" },
156
156
  },
157
157
  },
158
158
  };
@@ -0,0 +1,102 @@
1
+ // Curated engine catalog — the SINGLE SOURCE OF TRUTH for the known models,
2
+ // per-engine defaults, base URLs and api-key env vars shown across APX.
3
+ //
4
+ // Who consumes this:
5
+ // • CLI — `apx setup` builds its provider/model menus from here
6
+ // (src/interfaces/cli/commands/setup.js).
7
+ // • Web — the admin panel fetches it via `GET /engines/presets` and hydrates
8
+ // its provider forms (src/interfaces/web/.../providers/typeStyles.ts).
9
+ //
10
+ // This is the OFFLINE / no-key fallback list. When the user has an api_key
11
+ // configured, the daemon's `POST /engines/models` returns the provider's LIVE
12
+ // catalog instead (see ./catalog.js). The model field is ALWAYS free-text, so
13
+ // any id can be typed even if it is not listed here.
14
+ //
15
+ // `ollama` and `custom` are intentionally dynamic — no curated model list.
16
+ // Update model ids in THIS file only; every surface reflects the change.
17
+
18
+ /** @typedef {{ base_url: string, default_model: string, api_key_env: string, known_models: string[] }} EnginePreset */
19
+
20
+ /** @type {Record<string, EnginePreset>} */
21
+ export const ENGINE_PRESETS = {
22
+ anthropic: {
23
+ base_url: "", // empty ⇒ adapter uses the built-in Anthropic endpoint
24
+ default_model: "claude-sonnet-5",
25
+ api_key_env: "ANTHROPIC_API_KEY",
26
+ known_models: [
27
+ "claude-opus-4-8",
28
+ "claude-sonnet-5",
29
+ "claude-haiku-4-5",
30
+ "claude-fable-5",
31
+ ],
32
+ },
33
+ openai: {
34
+ base_url: "https://api.openai.com/v1",
35
+ default_model: "gpt-5.4-mini",
36
+ api_key_env: "OPENAI_API_KEY",
37
+ known_models: [
38
+ "gpt-5.5",
39
+ "gpt-5.4-mini",
40
+ "gpt-5.4-nano",
41
+ "gpt-5.1",
42
+ "gpt-4.1-mini",
43
+ ],
44
+ },
45
+ gemini: {
46
+ base_url: "https://generativelanguage.googleapis.com/v1beta/openai",
47
+ default_model: "gemini-2.5-flash",
48
+ api_key_env: "GEMINI_API_KEY",
49
+ known_models: [
50
+ "gemini-3.5-flash",
51
+ "gemini-3.1-pro-preview",
52
+ "gemini-2.5-pro",
53
+ "gemini-2.5-flash",
54
+ "gemini-2.5-flash-lite",
55
+ ],
56
+ },
57
+ groq: {
58
+ base_url: "https://api.groq.com/openai/v1",
59
+ default_model: "openai/gpt-oss-20b",
60
+ api_key_env: "GROQ_API_KEY",
61
+ known_models: [
62
+ "openai/gpt-oss-120b",
63
+ "openai/gpt-oss-20b",
64
+ "qwen/qwen3.6-27b",
65
+ "groq/compound",
66
+ "groq/compound-mini",
67
+ "whisper-large-v3-turbo",
68
+ ],
69
+ },
70
+ openrouter: {
71
+ base_url: "https://openrouter.ai/api/v1",
72
+ // openrouter/auto = "Auto Router": OpenRouter picks the best model.
73
+ default_model: "openrouter/auto",
74
+ api_key_env: "OPENROUTER_API_KEY",
75
+ known_models: [
76
+ "openrouter/auto",
77
+ "openrouter/free",
78
+ "anthropic/claude-sonnet-5",
79
+ "openai/gpt-5.4-mini",
80
+ "google/gemini-2.5-flash",
81
+ ],
82
+ },
83
+ azure: {
84
+ base_url: "",
85
+ default_model: "", // Azure deployment names are user-defined
86
+ api_key_env: "AZURE_OPENAI_API_KEY",
87
+ known_models: [],
88
+ },
89
+ ollama: {
90
+ base_url: "http://127.0.0.1:11434",
91
+ default_model: "gemma2:9b",
92
+ api_key_env: "",
93
+ known_models: [], // dynamic — fetched live from the local Ollama daemon
94
+ },
95
+ mock: { base_url: "", default_model: "mock", api_key_env: "", known_models: ["mock"] },
96
+ custom: { base_url: "", default_model: "", api_key_env: "", known_models: [] },
97
+ };
98
+
99
+ /** Known models for one engine, or [] if the engine is dynamic/unknown. */
100
+ export function knownModels(engine) {
101
+ return ENGINE_PRESETS[engine]?.known_models ?? [];
102
+ }
@@ -1,12 +1,18 @@
1
1
  // GET /engines — list engine adapter ids known to core/engines.
2
+ // GET /engines/presets — curated catalog (known models, defaults) per engine.
2
3
  // POST /engines/models — live model catalog from a provider.
3
4
  // GET /engines/models — legacy (Ollama only, no auth).
4
5
  import { ENGINE_IDS } from "#core/engines/index.js";
5
6
  import { listModels } from "#core/engines/catalog.js";
7
+ import { ENGINE_PRESETS } from "#core/engines/presets.js";
6
8
 
7
9
  export function register(app, { config }) {
8
10
  app.get("/engines", (_req, res) => res.json({ engines: ENGINE_IDS }));
9
11
 
12
+ // Curated fallback catalog shared with the CLI wizard. The web hydrates its
13
+ // provider forms from here so model lists never drift between surfaces.
14
+ app.get("/engines/presets", (_req, res) => res.json({ presets: ENGINE_PRESETS }));
15
+
10
16
  app.post("/engines/models", async (req, res) => {
11
17
  const b = req.body || {};
12
18
  const engine = String(b.engine || "").toLowerCase();
@@ -8,6 +8,7 @@ import http from "node:http";
8
8
  import readline from "node:readline";
9
9
  import { spawnSync } from "node:child_process";
10
10
  import { readConfig, writeConfig } from "#core/config/index.js";
11
+ import { ENGINE_PRESETS } from "#core/engines/presets.js";
11
12
  import { mascot } from "#core/mascot.js";
12
13
  import { setupClaudePermissions } from "../claude-permissions.js";
13
14
  import { PERMISSION_MODES, DEFAULT_PERMISSION_MODE } from "#core/constants/permissions.js";
@@ -59,6 +60,8 @@ async function fetchOllamaModels(baseUrl) {
59
60
  }
60
61
 
61
62
  // ── Provider definitions ──────────────────────────────────────────────────────
63
+ // Model lists come from the shared catalog (#core/engines/presets.js) so the CLI
64
+ // and the web admin panel never drift. Ollama stays dynamic (fetched at runtime).
62
65
  const PROVIDERS = [
63
66
  {
64
67
  id: "anthropic",
@@ -66,7 +69,7 @@ const PROVIDERS = [
66
69
  needsKey: true,
67
70
  keyLabel: "Anthropic API key",
68
71
  keyHint: "sk-ant-...",
69
- models: ["claude-sonnet-4-5", "claude-haiku-4-5", "claude-opus-4-5"],
72
+ models: ENGINE_PRESETS.anthropic.known_models,
70
73
  },
71
74
  {
72
75
  id: "openai",
@@ -74,7 +77,7 @@ const PROVIDERS = [
74
77
  needsKey: true,
75
78
  keyLabel: "OpenAI API key",
76
79
  keyHint: "sk-...",
77
- models: ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo"],
80
+ models: ENGINE_PRESETS.openai.known_models,
78
81
  },
79
82
  {
80
83
  id: "ollama",
@@ -88,7 +91,7 @@ const PROVIDERS = [
88
91
  needsKey: true,
89
92
  keyLabel: "Gemini API key",
90
93
  keyHint: "AIza...",
91
- models: ["gemini-3.5-flash", "gemini-3.1-pro-preview", "gemini-2.5-flash"],
94
+ models: ENGINE_PRESETS.gemini.known_models,
92
95
  },
93
96
  ];
94
97