@tokagent/tokagentos 2.0.30 → 2.0.32

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": "@tokagent/tokagentos",
3
- "version": "2.0.30",
3
+ "version": "2.0.32",
4
4
  "description": "tokagentOS CLI - Create and upgrade tokagentOS project templates",
5
5
  "type": "module",
6
6
  "bin": {
@@ -71,7 +71,11 @@ LITELLM_LARGE_MODEL=
71
71
  #
72
72
  # Skip these if you have a Google key with paid quota and want to use
73
73
  # Gemini Flash. Or pin to whichever model your account has best rates on.
74
- OPENROUTER_SMALL_MODEL=anthropic/claude-haiku-4-5
74
+ # NOTE: OpenRouter uses dots in version suffixes (4.5, not 4-5). Bad model
75
+ # ids surface as AI_NoOutputGeneratedError because the upstream returns an
76
+ # error event the AI SDK stream parser cannot translate to a message.
77
+ # Verify against https://openrouter.ai/api/v1/models before changing these.
78
+ OPENROUTER_SMALL_MODEL=anthropic/claude-haiku-4.5
75
79
  OPENROUTER_LARGE_MODEL=anthropic/claude-sonnet-4.6
76
80
 
77
81
  # Local LLM endpoints (optional).
@@ -114,9 +114,83 @@ for (const check of CHECKS) {
114
114
  pass(`${check.pkg}@${installedVersion} ✓ (entry=${check.entry}, lines=${lineCount})`);
115
115
  }
116
116
 
117
+ /**
118
+ * Model-id sanity check.
119
+ *
120
+ * Failure mode observed in the field: a user "fixes" `OPENROUTER_SMALL_MODEL`
121
+ * by stripping the `anthropic/` prefix or by using a version that doesn't
122
+ * exist on OpenRouter. The plugin sends the id verbatim, OpenRouter returns
123
+ * an error event the AI SDK can't translate to a message, and the symptom
124
+ * is the opaque `AI_NoOutputGeneratedError: No output generated`. The error
125
+ * never mentions the model id, so users blame the plugin or the API key
126
+ * (both fine) and spend hours debugging.
127
+ *
128
+ * We only inspect the .env — `runtime.getSetting()` is a process.env wrapper,
129
+ * so the .env value is what the plugin will see. We don't hit the network;
130
+ * we just enforce the `<provider>/<model>` shape and warn if a known-bad
131
+ * id is set. If OPENROUTER_API_KEY is empty the user isn't using OpenRouter,
132
+ * so the check is skipped.
133
+ */
134
+ function readDotenv() {
135
+ const dotenvPath = path.join(PROJECT_ROOT, ".env");
136
+ if (!existsSync(dotenvPath)) return {};
137
+ const out = {};
138
+ for (const rawLine of readFileSync(dotenvPath, "utf8").split("\n")) {
139
+ const line = rawLine.trim();
140
+ if (!line || line.startsWith("#")) continue;
141
+ const eq = line.indexOf("=");
142
+ if (eq < 1) continue;
143
+ out[line.slice(0, eq).trim()] = line
144
+ .slice(eq + 1)
145
+ .trim()
146
+ .replace(/^["']|["']$/g, "");
147
+ }
148
+ return out;
149
+ }
150
+
151
+ const env = readDotenv();
152
+ if (env.OPENROUTER_API_KEY) {
153
+ const MODEL_KEYS = [
154
+ "OPENROUTER_SMALL_MODEL",
155
+ "OPENROUTER_LARGE_MODEL",
156
+ "OPENROUTER_IMAGE_MODEL",
157
+ "OPENROUTER_IMAGE_GENERATION_MODEL",
158
+ "OPENROUTER_EMBEDDING_MODEL",
159
+ ];
160
+ // Provider-namespaced model id. OpenRouter ids are `<provider>/<model>`
161
+ // (e.g. anthropic/claude-haiku-4.5, google/gemini-2.0-flash-001).
162
+ const validIdShape = /^[a-z0-9._-]+\/[a-z0-9._-]+(:[a-z0-9._-]+)?$/i;
163
+ for (const key of MODEL_KEYS) {
164
+ const value = env[key];
165
+ if (!value) continue;
166
+ if (!validIdShape.test(value)) {
167
+ fail(
168
+ `${key}=${value} is not a valid OpenRouter model id.\n` +
169
+ ` OpenRouter requires "<provider>/<model>" (e.g. anthropic/claude-haiku-4.5).\n` +
170
+ ` Bad ids surface as AI_NoOutputGeneratedError — the request leaves your machine,\n` +
171
+ ` OpenRouter rejects the model, the AI SDK can't translate the error event, and you\n` +
172
+ ` see "No output generated" with no hint about the model.\n` +
173
+ ` Catalog: https://openrouter.ai/api/v1/models`,
174
+ );
175
+ continue;
176
+ }
177
+ // Catch the specific typo we shipped pre-2.0.31 (claude-haiku-4-5 with
178
+ // a hyphen instead of a dot). OpenRouter uses dotted version suffixes.
179
+ if (/\/claude-(haiku|sonnet|opus)-\d+-\d/i.test(value)) {
180
+ fail(
181
+ `${key}=${value} uses hyphens in the version suffix. OpenRouter uses dots — e.g.\n` +
182
+ ` anthropic/claude-haiku-4.5, anthropic/claude-sonnet-4.6, anthropic/claude-opus-4.1.\n` +
183
+ ` The hyphen form is silently rejected and surfaces as AI_NoOutputGeneratedError.`,
184
+ );
185
+ continue;
186
+ }
187
+ pass(`${key}=${value} ✓ (shape valid)`);
188
+ }
189
+ }
190
+
117
191
  if (hadFailure) {
118
192
  console.error(
119
- "\n\x1b[31m[verify-llm-plugins]\x1b[0m One or more LLM-provider plugin checks failed. Chat will not work until this is resolved.\n",
193
+ "\n\x1b[31m[verify-llm-plugins]\x1b[0m One or more LLM-provider checks failed. Chat will not work until this is resolved.\n",
120
194
  );
121
195
  process.exit(1);
122
196
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "generatedAt": "2026-05-25T17:16:25.028Z",
3
+ "generatedAt": "2026-05-27T08:46:59.428Z",
4
4
  "repoUrl": "https://github.com/elizaos/eliza",
5
5
  "templates": [
6
6
  {