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