@tekmidian/pai 0.37.0 → 0.38.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.
@@ -131,6 +131,14 @@ var CONFIG_DIR = join(homedir(), ".config", "pai");
131
131
  var CONFIG_FILE = join(CONFIG_DIR, "config.json");
132
132
 
133
133
  // src/workers/config.ts
134
+ var PROVIDER_TAGS = [
135
+ "code",
136
+ "vision",
137
+ "image-gen",
138
+ "long-context",
139
+ "fast",
140
+ "reasoning"
141
+ ];
134
142
  var DEFAULT_LOG_DIR = "~/.claude/logs/workers";
135
143
  var DEFAULT_PANE = {
136
144
  enabled: true,
@@ -147,7 +155,7 @@ function defaultWorkersConfig() {
147
155
  enabled: false,
148
156
  active: null,
149
157
  providers: {},
150
- roles: {},
158
+ classes: {},
151
159
  mcpSets: {},
152
160
  pane: { ...DEFAULT_PANE },
153
161
  logDir: DEFAULT_LOG_DIR,
@@ -210,6 +218,24 @@ function parseProvider(name, raw) {
210
218
  if (protocol === "openai" && !upstreamUrl) {
211
219
  bad(`.providers.${name}.upstreamUrl`, `is required for protocol "openai" (the Chat Completions base, e.g. "https://api.openai.com/v1")`);
212
220
  }
221
+ const costTier = p.costTier === void 0 ? void 0 : p.costTier;
222
+ if (costTier !== void 0) {
223
+ if (typeof costTier !== "number" || !Number.isInteger(costTier) || costTier < 1 || costTier > 5) {
224
+ bad(`.providers.${name}.costTier`, "must be an integer 1 (cheapest) \u2026 5 (most expensive)");
225
+ }
226
+ }
227
+ let tags;
228
+ if (p.tags !== void 0) {
229
+ if (!Array.isArray(p.tags) || p.tags.some((x) => typeof x !== "string")) {
230
+ bad(`.providers.${name}.tags`, `must be an array of tags from: ${PROVIDER_TAGS.join(", ")}`);
231
+ }
232
+ for (const t of p.tags) {
233
+ if (!PROVIDER_TAGS.includes(t)) {
234
+ bad(`.providers.${name}.tags`, `"${t}" is not a tag (from: ${PROVIDER_TAGS.join(", ")})`);
235
+ }
236
+ }
237
+ tags = p.tags;
238
+ }
213
239
  return {
214
240
  enabled: p.enabled === void 0 ? true : p.enabled === true,
215
241
  protocol,
@@ -222,7 +248,9 @@ function parseProvider(name, raw) {
222
248
  ...engine !== "claude" ? { engine } : {},
223
249
  ...str(p.quotaProbe) ? { quotaProbe: str(p.quotaProbe) } : {},
224
250
  ...quotaSkipAt !== void 0 ? { quotaSkipAt } : {},
225
- ...contextWindow !== void 0 ? { contextWindow } : {}
251
+ ...contextWindow !== void 0 ? { contextWindow } : {},
252
+ ...costTier !== void 0 ? { costTier } : {},
253
+ ...tags ? { tags } : {}
226
254
  };
227
255
  }
228
256
  function parseWorkersConfig(raw) {
@@ -241,30 +269,64 @@ function parseWorkersConfig(raw) {
241
269
  providers[name] = parseProvider(name, p);
242
270
  }
243
271
  }
244
- const roles = {};
245
- if (w.roles !== void 0) {
246
- if (typeof w.roles !== "object" || w.roles === null || Array.isArray(w.roles)) {
247
- bad(".roles", "must be an object of role \u2192 provider[/alias] or {provider, mcp}");
272
+ const classes = {};
273
+ const classesRaw = w.classes !== void 0 ? w.classes : w.roles;
274
+ if (classesRaw !== void 0) {
275
+ if (typeof classesRaw !== "object" || classesRaw === null || Array.isArray(classesRaw)) {
276
+ bad(w.classes !== void 0 ? ".classes" : ".roles", "must be an object of class \u2192 provider[/alias] or {provider, mcp, maxCostTier, requireTags, order}");
248
277
  }
249
- for (const [role, target] of Object.entries(w.roles)) {
278
+ for (const [cls, target] of Object.entries(classesRaw)) {
250
279
  if (typeof target === "object" && target !== null && !Array.isArray(target)) {
251
280
  const o = target;
252
281
  const provider = str(o.provider);
253
- if (!provider || provider.includes(" ")) {
254
- bad(`.roles.${role}.provider`, `invalid provider "${provider}"`);
282
+ if (o.provider !== void 0 && (!provider || provider.includes(" "))) {
283
+ bad(`.classes.${cls}.provider`, `invalid provider "${provider}"`);
255
284
  }
256
285
  let mcp;
257
286
  if (o.mcp !== void 0) {
258
287
  if (!Array.isArray(o.mcp) || o.mcp.some((x) => typeof x !== "string")) {
259
- bad(`.roles.${role}.mcp`, "must be an array of MCP server or set names");
288
+ bad(`.classes.${cls}.mcp`, "must be an array of MCP server or set names");
260
289
  }
261
290
  mcp = o.mcp;
262
291
  }
263
- roles[role] = mcp ? { provider, mcp } : { provider };
292
+ let maxCostTier;
293
+ if (o.maxCostTier !== void 0) {
294
+ if (typeof o.maxCostTier !== "number" || !Number.isInteger(o.maxCostTier) || o.maxCostTier < 1 || o.maxCostTier > 5) {
295
+ bad(`.classes.${cls}.maxCostTier`, "must be an integer 1 \u2026 5");
296
+ }
297
+ maxCostTier = o.maxCostTier;
298
+ }
299
+ let requireTags;
300
+ if (o.requireTags !== void 0) {
301
+ if (!Array.isArray(o.requireTags) || o.requireTags.some((x) => typeof x !== "string")) {
302
+ bad(`.classes.${cls}.requireTags`, `must be an array of tags from: ${PROVIDER_TAGS.join(", ")}`);
303
+ }
304
+ for (const t of o.requireTags) {
305
+ if (!PROVIDER_TAGS.includes(t)) {
306
+ bad(`.classes.${cls}.requireTags`, `"${t}" is not a tag (from: ${PROVIDER_TAGS.join(", ")})`);
307
+ }
308
+ }
309
+ requireTags = o.requireTags;
310
+ }
311
+ let order;
312
+ if (o.order !== void 0) {
313
+ if (!Array.isArray(o.order) || o.order.some((x) => typeof x !== "string")) {
314
+ bad(`.classes.${cls}.order`, "must be an array of provider names");
315
+ }
316
+ order = o.order;
317
+ }
318
+ const obj = {
319
+ ...provider ? { provider } : {},
320
+ ...mcp ? { mcp } : {},
321
+ ...maxCostTier !== void 0 ? { maxCostTier } : {},
322
+ ...requireTags ? { requireTags } : {},
323
+ ...order ? { order } : {}
324
+ };
325
+ classes[cls] = Object.keys(obj).length ? obj : {};
264
326
  } else {
265
327
  const t = str(target);
266
- if (!t || t.includes(" ")) bad(`.roles.${role}`, `invalid target "${t}"`);
267
- roles[role] = t;
328
+ if (!t || t.includes(" ")) bad(`.classes.${cls}`, `invalid target "${t}"`);
329
+ classes[cls] = t;
268
330
  }
269
331
  }
270
332
  }
@@ -326,7 +388,7 @@ function parseWorkersConfig(raw) {
326
388
  enabled: w.enabled === void 0 ? d.enabled : w.enabled === true,
327
389
  active,
328
390
  providers,
329
- roles,
391
+ classes,
330
392
  mcpSets,
331
393
  pane,
332
394
  logDir: str(w.logDir) || d.logDir,