heyio 4.2.4 → 4.2.5

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.
@@ -80,7 +80,7 @@ var init_constants = __esm({
80
80
  "packages/shared/dist/constants.js"() {
81
81
  "use strict";
82
82
  APP_NAME = "io";
83
- APP_VERSION = "4.2.4";
83
+ APP_VERSION = "4.2.5";
84
84
  API_PORT = 7777;
85
85
  API_HOST = "0.0.0.0";
86
86
  DEFAULT_MODEL = "gpt-4o";
@@ -67985,6 +67985,10 @@ async function scrapeTokenUnitPricing() {
67985
67985
  const html = await fetchPage(TOKEN_UNIT_COSTS_URL);
67986
67986
  return parseTokenUnitTable(html);
67987
67987
  }
67988
+ async function scrapeCopilotPricing() {
67989
+ const markdown = await fetchMarkdown(COPILOT_PRICING_URL);
67990
+ return parseCopilotPricingMarkdown(markdown);
67991
+ }
67988
67992
  async function scrapePremiumRequestPricing() {
67989
67993
  const html = await fetchPage(PREMIUM_MULTIPLIERS_URL);
67990
67994
  return parsePremiumMultiplierTable(html);
@@ -68002,6 +68006,19 @@ async function fetchPage(url2) {
68002
68006
  }
68003
68007
  return response.text();
68004
68008
  }
68009
+ async function fetchMarkdown(url2) {
68010
+ const response = await fetch(url2, {
68011
+ headers: {
68012
+ Accept: "text/markdown, text/plain, */*",
68013
+ "User-Agent": "IO-Daemon/4.0 (pricing-refresh)"
68014
+ },
68015
+ redirect: "follow"
68016
+ });
68017
+ if (!response.ok) {
68018
+ throw new Error(`Failed to fetch ${url2}: ${response.status} ${response.statusText}`);
68019
+ }
68020
+ return response.text();
68021
+ }
68005
68022
  function parseTokenUnitTable(html) {
68006
68023
  const results = [];
68007
68024
  const tableRowPattern = /<tr[^>]*>\s*<td[^>]*>([^<]+)<\/td>\s*<td[^>]*>([^<]+)<\/td>\s*<td[^>]*>([^<]*)<\/td>\s*<td[^>]*>([^<]+)<\/td>/gi;
@@ -68036,12 +68053,82 @@ function parsePremiumMultiplierTable(html) {
68036
68053
  function cleanCellText(text) {
68037
68054
  return text.replace(/<[^>]*>/g, "").replace(/&[^;]+;/g, " ").trim();
68038
68055
  }
68039
- var TOKEN_UNIT_COSTS_URL, PREMIUM_MULTIPLIERS_URL;
68056
+ function parseCopilotPricingMarkdown(markdown) {
68057
+ const results = [];
68058
+ const seenModels = /* @__PURE__ */ new Set();
68059
+ const lines = markdown.split("\n");
68060
+ let columnIndices = null;
68061
+ for (const line of lines) {
68062
+ const trimmed = line.trim();
68063
+ if (!trimmed.startsWith("|")) continue;
68064
+ if (/\|\s*Model\s/i.test(trimmed)) {
68065
+ columnIndices = parseHeaderColumns(trimmed);
68066
+ continue;
68067
+ }
68068
+ if (/^[\s|:-]+$/.test(trimmed) || !columnIndices) continue;
68069
+ const entry = parseDataRow(trimmed, columnIndices);
68070
+ if (entry && !seenModels.has(entry.modelName.toLowerCase())) {
68071
+ seenModels.add(entry.modelName.toLowerCase());
68072
+ results.push(entry);
68073
+ }
68074
+ }
68075
+ return results;
68076
+ }
68077
+ function parseDataRow(line, columnIndices) {
68078
+ const cells = splitMarkdownRow(line);
68079
+ if (cells.length <= columnIndices.output) return null;
68080
+ const modelName = cells[columnIndices.model].trim();
68081
+ const inputPrice = parseDollarValue(cells[columnIndices.input]);
68082
+ const cachedPrice = columnIndices.cached >= 0 ? parseDollarValue(cells[columnIndices.cached]) : null;
68083
+ const outputPrice = parseDollarValue(cells[columnIndices.output]);
68084
+ if (!modelName || inputPrice === null || outputPrice === null) return null;
68085
+ return {
68086
+ modelName,
68087
+ inputMultiplier: inputPrice * PRICE_TO_MULTIPLIER,
68088
+ cachedInputMultiplier: cachedPrice !== null ? cachedPrice * PRICE_TO_MULTIPLIER : null,
68089
+ outputMultiplier: outputPrice * PRICE_TO_MULTIPLIER
68090
+ };
68091
+ }
68092
+ function parseHeaderColumns(headerLine) {
68093
+ const cells = splitMarkdownRow(headerLine).map((c) => c.trim().toLowerCase());
68094
+ const model = cells.findIndex((c) => c === "model" || c === "model name");
68095
+ const input2 = cells.findIndex(
68096
+ (c) => (c === "input" || c === "input multiplier") && !c.includes("cached")
68097
+ );
68098
+ const cached2 = cells.findIndex(
68099
+ (c) => c.includes("cached input") || c === "cached input multiplier"
68100
+ );
68101
+ const output2 = cells.findIndex(
68102
+ (c) => (c === "output" || c === "output multiplier") && !c.includes("cached")
68103
+ );
68104
+ if (model < 0 || input2 < 0 || output2 < 0) {
68105
+ return null;
68106
+ }
68107
+ return { model, input: input2, cached: cached2 >= 0 ? cached2 : -1, output: output2 };
68108
+ }
68109
+ function splitMarkdownRow(line) {
68110
+ const parts = line.split("|");
68111
+ if (parts[0].trim() === "") parts.shift();
68112
+ if (parts[parts.length - 1]?.trim() === "") parts.pop();
68113
+ return parts;
68114
+ }
68115
+ function parseDollarValue(cell) {
68116
+ if (!cell) return null;
68117
+ const cleaned = cell.trim().replace(/[$,]/g, "");
68118
+ if (cleaned.toLowerCase() === "n/a" || cleaned === "" || cleaned === "-") {
68119
+ return null;
68120
+ }
68121
+ const value = Number.parseFloat(cleaned);
68122
+ return Number.isNaN(value) ? null : value;
68123
+ }
68124
+ var TOKEN_UNIT_COSTS_URL, PREMIUM_MULTIPLIERS_URL, COPILOT_PRICING_URL, PRICE_TO_MULTIPLIER;
68040
68125
  var init_pricing_scraper = __esm({
68041
68126
  "packages/daemon/src/models/pricing-scraper.ts"() {
68042
68127
  "use strict";
68043
68128
  TOKEN_UNIT_COSTS_URL = "https://docs.github.com/en/billing/reference/costs-for-github-models";
68044
68129
  PREMIUM_MULTIPLIERS_URL = "https://docs.github.com/en/copilot/reference/copilot-billing/request-based-billing-legacy/model-multipliers-for-annual-plans";
68130
+ COPILOT_PRICING_URL = "https://docs.github.com/api/article/body?pathname=/en/copilot/reference/copilot-billing/models-and-pricing";
68131
+ PRICE_TO_MULTIPLIER = 0.1;
68045
68132
  }
68046
68133
  });
68047
68134
 
@@ -68075,79 +68162,99 @@ var init_seed = __esm({
68075
68162
  id: "gpt-5-mini",
68076
68163
  displayName: "GPT-5 mini",
68077
68164
  premiumMultiplier: 0.33,
68078
- tokenInputMultiplier: null,
68079
- tokenOutputMultiplier: null,
68080
- cachedInputMultiplier: null,
68165
+ tokenInputMultiplier: 0.025,
68166
+ tokenOutputMultiplier: 0.2,
68167
+ cachedInputMultiplier: 25e-4,
68081
68168
  tier: "trivial",
68082
68169
  available: true
68083
68170
  },
68084
68171
  {
68085
- id: "claude-sonnet-4",
68086
- displayName: "Claude Sonnet 4",
68172
+ id: "gpt-5.3-codex",
68173
+ displayName: "GPT-5.3-Codex",
68087
68174
  premiumMultiplier: 6,
68088
- tokenInputMultiplier: 0.6,
68089
- tokenOutputMultiplier: 2.4,
68090
- cachedInputMultiplier: null,
68175
+ tokenInputMultiplier: 0.175,
68176
+ tokenOutputMultiplier: 1.4,
68177
+ cachedInputMultiplier: 0.0175,
68091
68178
  tier: "premium",
68092
68179
  available: true
68093
68180
  },
68094
68181
  {
68095
- id: "claude-haiku-4.5",
68096
- displayName: "Claude Haiku 4.5",
68097
- premiumMultiplier: 0.33,
68098
- tokenInputMultiplier: null,
68099
- tokenOutputMultiplier: null,
68100
- cachedInputMultiplier: null,
68101
- tier: "trivial",
68182
+ id: "gpt-5.4",
68183
+ displayName: "GPT-5.4",
68184
+ premiumMultiplier: 6,
68185
+ tokenInputMultiplier: 0.25,
68186
+ tokenOutputMultiplier: 1.5,
68187
+ cachedInputMultiplier: 0.025,
68188
+ tier: "premium",
68102
68189
  available: true
68103
68190
  },
68104
68191
  {
68105
- id: "gemini-2.5-pro",
68106
- displayName: "Gemini 2.5 Pro",
68107
- premiumMultiplier: 1,
68108
- tokenInputMultiplier: null,
68109
- tokenOutputMultiplier: null,
68110
- cachedInputMultiplier: null,
68111
- tier: "fast",
68192
+ id: "gpt-5.4-mini",
68193
+ displayName: "GPT-5.4 mini",
68194
+ premiumMultiplier: 6,
68195
+ tokenInputMultiplier: 0.075,
68196
+ tokenOutputMultiplier: 0.45,
68197
+ cachedInputMultiplier: 75e-4,
68198
+ tier: "premium",
68112
68199
  available: true
68113
68200
  },
68114
68201
  {
68115
- id: "gpt-5.1",
68116
- displayName: "GPT-5.1",
68117
- premiumMultiplier: 3,
68118
- tokenInputMultiplier: null,
68119
- tokenOutputMultiplier: null,
68120
- cachedInputMultiplier: null,
68121
- tier: "standard",
68202
+ id: "gpt-5.5",
68203
+ displayName: "GPT-5.5",
68204
+ premiumMultiplier: 57,
68205
+ tokenInputMultiplier: 0.5,
68206
+ tokenOutputMultiplier: 3,
68207
+ cachedInputMultiplier: 0.05,
68208
+ tier: "ultra",
68122
68209
  available: true
68123
68210
  },
68124
68211
  {
68125
- id: "gpt-5.2",
68126
- displayName: "GPT-5.2",
68127
- premiumMultiplier: 3,
68128
- tokenInputMultiplier: null,
68129
- tokenOutputMultiplier: null,
68130
- cachedInputMultiplier: null,
68131
- tier: "standard",
68212
+ id: "claude-sonnet-4",
68213
+ displayName: "Claude Sonnet 4",
68214
+ premiumMultiplier: 6,
68215
+ tokenInputMultiplier: 0.3,
68216
+ tokenOutputMultiplier: 1.5,
68217
+ cachedInputMultiplier: 0.03,
68218
+ tier: "premium",
68132
68219
  available: true
68133
68220
  },
68134
68221
  {
68135
- id: "gpt-5.4",
68136
- displayName: "GPT-5.4",
68222
+ id: "claude-sonnet-4.5",
68223
+ displayName: "Claude Sonnet 4.5",
68137
68224
  premiumMultiplier: 6,
68138
- tokenInputMultiplier: null,
68139
- tokenOutputMultiplier: null,
68140
- cachedInputMultiplier: null,
68225
+ tokenInputMultiplier: 0.3,
68226
+ tokenOutputMultiplier: 1.5,
68227
+ cachedInputMultiplier: 0.03,
68228
+ tier: "premium",
68229
+ available: true
68230
+ },
68231
+ {
68232
+ id: "claude-sonnet-4.6",
68233
+ displayName: "Claude Sonnet 4.6",
68234
+ premiumMultiplier: 9,
68235
+ tokenInputMultiplier: 0.3,
68236
+ tokenOutputMultiplier: 1.5,
68237
+ cachedInputMultiplier: 0.03,
68141
68238
  tier: "premium",
68142
68239
  available: true
68143
68240
  },
68241
+ {
68242
+ id: "claude-haiku-4.5",
68243
+ displayName: "Claude Haiku 4.5",
68244
+ premiumMultiplier: 0.33,
68245
+ tokenInputMultiplier: 0.1,
68246
+ tokenOutputMultiplier: 0.5,
68247
+ cachedInputMultiplier: 0.01,
68248
+ tier: "trivial",
68249
+ available: true
68250
+ },
68144
68251
  {
68145
68252
  id: "claude-opus-4.5",
68146
68253
  displayName: "Claude Opus 4.5",
68147
68254
  premiumMultiplier: 15,
68148
- tokenInputMultiplier: null,
68149
- tokenOutputMultiplier: null,
68150
- cachedInputMultiplier: null,
68255
+ tokenInputMultiplier: 0.5,
68256
+ tokenOutputMultiplier: 2.5,
68257
+ cachedInputMultiplier: 0.05,
68151
68258
  tier: "premium",
68152
68259
  available: true
68153
68260
  },
@@ -68155,9 +68262,9 @@ var init_seed = __esm({
68155
68262
  id: "claude-opus-4.6",
68156
68263
  displayName: "Claude Opus 4.6",
68157
68264
  premiumMultiplier: 27,
68158
- tokenInputMultiplier: null,
68159
- tokenOutputMultiplier: null,
68160
- cachedInputMultiplier: null,
68265
+ tokenInputMultiplier: 0.5,
68266
+ tokenOutputMultiplier: 2.5,
68267
+ cachedInputMultiplier: 0.05,
68161
68268
  tier: "ultra",
68162
68269
  available: true
68163
68270
  },
@@ -68165,21 +68272,81 @@ var init_seed = __esm({
68165
68272
  id: "claude-opus-4.7",
68166
68273
  displayName: "Claude Opus 4.7",
68167
68274
  premiumMultiplier: 27,
68168
- tokenInputMultiplier: null,
68169
- tokenOutputMultiplier: null,
68170
- cachedInputMultiplier: null,
68275
+ tokenInputMultiplier: 0.5,
68276
+ tokenOutputMultiplier: 2.5,
68277
+ cachedInputMultiplier: 0.05,
68171
68278
  tier: "ultra",
68172
68279
  available: true
68173
68280
  },
68174
68281
  {
68175
- id: "gpt-5.5",
68176
- displayName: "GPT-5.5",
68177
- premiumMultiplier: 57,
68178
- tokenInputMultiplier: null,
68179
- tokenOutputMultiplier: null,
68180
- cachedInputMultiplier: null,
68282
+ id: "claude-opus-4.8",
68283
+ displayName: "Claude Opus 4.8",
68284
+ premiumMultiplier: 27,
68285
+ tokenInputMultiplier: 0.5,
68286
+ tokenOutputMultiplier: 2.5,
68287
+ cachedInputMultiplier: 0.05,
68181
68288
  tier: "ultra",
68182
68289
  available: true
68290
+ },
68291
+ {
68292
+ id: "gemini-2.5-pro",
68293
+ displayName: "Gemini 2.5 Pro",
68294
+ premiumMultiplier: 1,
68295
+ tokenInputMultiplier: 0.125,
68296
+ tokenOutputMultiplier: 1,
68297
+ cachedInputMultiplier: 0.0125,
68298
+ tier: "fast",
68299
+ available: true
68300
+ },
68301
+ {
68302
+ id: "gemini-3-flash",
68303
+ displayName: "Gemini 3 Flash",
68304
+ premiumMultiplier: 0.33,
68305
+ tokenInputMultiplier: 0.05,
68306
+ tokenOutputMultiplier: 0.3,
68307
+ cachedInputMultiplier: 5e-3,
68308
+ tier: "trivial",
68309
+ available: true
68310
+ },
68311
+ {
68312
+ id: "gemini-3.1-pro",
68313
+ displayName: "Gemini 3.1 Pro",
68314
+ premiumMultiplier: 6,
68315
+ tokenInputMultiplier: 0.2,
68316
+ tokenOutputMultiplier: 1.2,
68317
+ cachedInputMultiplier: 0.02,
68318
+ tier: "premium",
68319
+ available: true
68320
+ },
68321
+ {
68322
+ id: "gemini-3.5-flash",
68323
+ displayName: "Gemini 3.5 Flash",
68324
+ premiumMultiplier: 14,
68325
+ tokenInputMultiplier: 0.15,
68326
+ tokenOutputMultiplier: 0.9,
68327
+ cachedInputMultiplier: 0.015,
68328
+ tier: "premium",
68329
+ available: true
68330
+ },
68331
+ {
68332
+ id: "raptor-mini",
68333
+ displayName: "Raptor mini",
68334
+ premiumMultiplier: 0.33,
68335
+ tokenInputMultiplier: 0.025,
68336
+ tokenOutputMultiplier: 0.2,
68337
+ cachedInputMultiplier: 25e-4,
68338
+ tier: "trivial",
68339
+ available: true
68340
+ },
68341
+ {
68342
+ id: "mai-code-1-flash",
68343
+ displayName: "MAI-Code-1-Flash",
68344
+ premiumMultiplier: 0.33,
68345
+ tokenInputMultiplier: 0.075,
68346
+ tokenOutputMultiplier: 0.45,
68347
+ cachedInputMultiplier: 75e-4,
68348
+ tier: "trivial",
68349
+ available: true
68183
68350
  }
68184
68351
  ];
68185
68352
  }
@@ -68282,19 +68449,51 @@ async function scrapePremiumPricingIntoMap(modelMap, result, logger2) {
68282
68449
  logger2?.warn(`Premium pricing scrape failed: ${msg}`);
68283
68450
  }
68284
68451
  }
68452
+ async function scrapeCopilotPricingIntoMap(modelMap, result, logger2) {
68453
+ try {
68454
+ const copilotPricing = await scrapeCopilotPricing();
68455
+ result.copilotPricingScraped = true;
68456
+ for (const cp of copilotPricing) {
68457
+ const key = normalizeModelName(cp.modelName);
68458
+ const existing = modelMap.get(key) ?? findClosestKey(modelMap, key);
68459
+ if (existing) {
68460
+ existing.tokenInputMultiplier = cp.inputMultiplier;
68461
+ existing.tokenOutputMultiplier = cp.outputMultiplier;
68462
+ if (cp.cachedInputMultiplier !== null) {
68463
+ existing.cachedInputMultiplier = cp.cachedInputMultiplier;
68464
+ }
68465
+ } else {
68466
+ modelMap.set(key, {
68467
+ id: key,
68468
+ displayName: cp.modelName,
68469
+ tokenInputMultiplier: cp.inputMultiplier,
68470
+ tokenOutputMultiplier: cp.outputMultiplier,
68471
+ cachedInputMultiplier: cp.cachedInputMultiplier,
68472
+ available: true
68473
+ });
68474
+ }
68475
+ }
68476
+ } catch (error51) {
68477
+ const msg = error51 instanceof Error ? error51.message : String(error51);
68478
+ result.errors.push(`Copilot pricing scrape failed: ${msg}`);
68479
+ logger2?.warn(`Copilot pricing scrape failed: ${msg}`);
68480
+ }
68481
+ }
68285
68482
  async function refreshModelPricing(logger2) {
68286
68483
  const result = {
68287
68484
  modelsUpdated: 0,
68288
68485
  catalogFetched: false,
68289
68486
  tokenPricingScraped: false,
68290
68487
  premiumPricingScraped: false,
68488
+ copilotPricingScraped: false,
68291
68489
  errors: []
68292
68490
  };
68293
68491
  const modelMap = /* @__PURE__ */ new Map();
68294
68492
  await fetchCatalogIntoMap(modelMap, result, logger2);
68295
68493
  await scrapeTokenPricingIntoMap(modelMap, result, logger2);
68494
+ await scrapeCopilotPricingIntoMap(modelMap, result, logger2);
68296
68495
  await scrapePremiumPricingIntoMap(modelMap, result, logger2);
68297
- if (!result.catalogFetched && !result.tokenPricingScraped && !result.premiumPricingScraped) {
68496
+ if (!result.catalogFetched && !result.tokenPricingScraped && !result.premiumPricingScraped && !result.copilotPricingScraped) {
68298
68497
  logger2?.warn("All pricing sources failed, using seed data");
68299
68498
  await seedFromFallback();
68300
68499
  result.modelsUpdated = SEED_MODELS.length;
@@ -71048,7 +71247,7 @@ async function handleUpdateSquadMember(rawArgs) {
71048
71247
  member: updated
71049
71248
  };
71050
71249
  }
71051
- function createSquadToolExecutor(config2) {
71250
+ function createSquadToolExecutor(_config) {
71052
71251
  return async (toolName, rawArgs) => {
71053
71252
  switch (toolName) {
71054
71253
  case "create_squad":
@@ -71125,7 +71324,9 @@ var init_squad2 = __esm({
71125
71324
  squadId: external_exports.string().trim().min(1),
71126
71325
  role: external_exports.string().trim().min(1).describe("Slug-style role identifier (e.g. 'senior-frontend-engineer', 'team-lead')"),
71127
71326
  name: external_exports.string().trim().min(1).describe("Display name for the member (e.g. 'Senior Frontend Engineer')"),
71128
- systemPrompt: external_exports.string().min(1).describe("The system prompt defining this member's expertise, responsibilities, and behavior."),
71327
+ systemPrompt: external_exports.string().min(1).describe(
71328
+ "The system prompt defining this member's expertise, responsibilities, and behavior."
71329
+ ),
71129
71330
  model: external_exports.string().optional().describe("Model override for this member. Uses squad default if not provided.")
71130
71331
  });
71131
71332
  removeSquadMemberSchema = external_exports.object({
@@ -79,7 +79,7 @@ var init_constants = __esm({
79
79
  "packages/shared/dist/constants.js"() {
80
80
  "use strict";
81
81
  APP_NAME = "io";
82
- APP_VERSION = "4.2.4";
82
+ APP_VERSION = "4.2.5";
83
83
  API_PORT = 7777;
84
84
  API_HOST = "0.0.0.0";
85
85
  DEFAULT_MODEL = "gpt-4o";
@@ -80828,10 +80828,16 @@ async function fetchModelCatalog() {
80828
80828
  // packages/daemon/src/models/pricing-scraper.ts
80829
80829
  var TOKEN_UNIT_COSTS_URL = "https://docs.github.com/en/billing/reference/costs-for-github-models";
80830
80830
  var PREMIUM_MULTIPLIERS_URL = "https://docs.github.com/en/copilot/reference/copilot-billing/request-based-billing-legacy/model-multipliers-for-annual-plans";
80831
+ var COPILOT_PRICING_URL = "https://docs.github.com/api/article/body?pathname=/en/copilot/reference/copilot-billing/models-and-pricing";
80832
+ var PRICE_TO_MULTIPLIER = 0.1;
80831
80833
  async function scrapeTokenUnitPricing() {
80832
80834
  const html = await fetchPage(TOKEN_UNIT_COSTS_URL);
80833
80835
  return parseTokenUnitTable(html);
80834
80836
  }
80837
+ async function scrapeCopilotPricing() {
80838
+ const markdown = await fetchMarkdown(COPILOT_PRICING_URL);
80839
+ return parseCopilotPricingMarkdown(markdown);
80840
+ }
80835
80841
  async function scrapePremiumRequestPricing() {
80836
80842
  const html = await fetchPage(PREMIUM_MULTIPLIERS_URL);
80837
80843
  return parsePremiumMultiplierTable(html);
@@ -80849,6 +80855,19 @@ async function fetchPage(url2) {
80849
80855
  }
80850
80856
  return response.text();
80851
80857
  }
80858
+ async function fetchMarkdown(url2) {
80859
+ const response = await fetch(url2, {
80860
+ headers: {
80861
+ Accept: "text/markdown, text/plain, */*",
80862
+ "User-Agent": "IO-Daemon/4.0 (pricing-refresh)"
80863
+ },
80864
+ redirect: "follow"
80865
+ });
80866
+ if (!response.ok) {
80867
+ throw new Error(`Failed to fetch ${url2}: ${response.status} ${response.statusText}`);
80868
+ }
80869
+ return response.text();
80870
+ }
80852
80871
  function parseTokenUnitTable(html) {
80853
80872
  const results = [];
80854
80873
  const tableRowPattern = /<tr[^>]*>\s*<td[^>]*>([^<]+)<\/td>\s*<td[^>]*>([^<]+)<\/td>\s*<td[^>]*>([^<]*)<\/td>\s*<td[^>]*>([^<]+)<\/td>/gi;
@@ -80883,6 +80902,74 @@ function parsePremiumMultiplierTable(html) {
80883
80902
  function cleanCellText(text) {
80884
80903
  return text.replace(/<[^>]*>/g, "").replace(/&[^;]+;/g, " ").trim();
80885
80904
  }
80905
+ function parseCopilotPricingMarkdown(markdown) {
80906
+ const results = [];
80907
+ const seenModels = /* @__PURE__ */ new Set();
80908
+ const lines = markdown.split("\n");
80909
+ let columnIndices = null;
80910
+ for (const line of lines) {
80911
+ const trimmed = line.trim();
80912
+ if (!trimmed.startsWith("|")) continue;
80913
+ if (/\|\s*Model\s/i.test(trimmed)) {
80914
+ columnIndices = parseHeaderColumns(trimmed);
80915
+ continue;
80916
+ }
80917
+ if (/^[\s|:-]+$/.test(trimmed) || !columnIndices) continue;
80918
+ const entry = parseDataRow(trimmed, columnIndices);
80919
+ if (entry && !seenModels.has(entry.modelName.toLowerCase())) {
80920
+ seenModels.add(entry.modelName.toLowerCase());
80921
+ results.push(entry);
80922
+ }
80923
+ }
80924
+ return results;
80925
+ }
80926
+ function parseDataRow(line, columnIndices) {
80927
+ const cells = splitMarkdownRow(line);
80928
+ if (cells.length <= columnIndices.output) return null;
80929
+ const modelName = cells[columnIndices.model].trim();
80930
+ const inputPrice = parseDollarValue(cells[columnIndices.input]);
80931
+ const cachedPrice = columnIndices.cached >= 0 ? parseDollarValue(cells[columnIndices.cached]) : null;
80932
+ const outputPrice = parseDollarValue(cells[columnIndices.output]);
80933
+ if (!modelName || inputPrice === null || outputPrice === null) return null;
80934
+ return {
80935
+ modelName,
80936
+ inputMultiplier: inputPrice * PRICE_TO_MULTIPLIER,
80937
+ cachedInputMultiplier: cachedPrice !== null ? cachedPrice * PRICE_TO_MULTIPLIER : null,
80938
+ outputMultiplier: outputPrice * PRICE_TO_MULTIPLIER
80939
+ };
80940
+ }
80941
+ function parseHeaderColumns(headerLine) {
80942
+ const cells = splitMarkdownRow(headerLine).map((c) => c.trim().toLowerCase());
80943
+ const model = cells.findIndex((c) => c === "model" || c === "model name");
80944
+ const input = cells.findIndex(
80945
+ (c) => (c === "input" || c === "input multiplier") && !c.includes("cached")
80946
+ );
80947
+ const cached2 = cells.findIndex(
80948
+ (c) => c.includes("cached input") || c === "cached input multiplier"
80949
+ );
80950
+ const output = cells.findIndex(
80951
+ (c) => (c === "output" || c === "output multiplier") && !c.includes("cached")
80952
+ );
80953
+ if (model < 0 || input < 0 || output < 0) {
80954
+ return null;
80955
+ }
80956
+ return { model, input, cached: cached2 >= 0 ? cached2 : -1, output };
80957
+ }
80958
+ function splitMarkdownRow(line) {
80959
+ const parts = line.split("|");
80960
+ if (parts[0].trim() === "") parts.shift();
80961
+ if (parts[parts.length - 1]?.trim() === "") parts.pop();
80962
+ return parts;
80963
+ }
80964
+ function parseDollarValue(cell) {
80965
+ if (!cell) return null;
80966
+ const cleaned = cell.trim().replace(/[$,]/g, "");
80967
+ if (cleaned.toLowerCase() === "n/a" || cleaned === "" || cleaned === "-") {
80968
+ return null;
80969
+ }
80970
+ const value = Number.parseFloat(cleaned);
80971
+ return Number.isNaN(value) ? null : value;
80972
+ }
80886
80973
 
80887
80974
  // packages/daemon/src/models/seed.ts
80888
80975
  var SEED_MODELS = [
@@ -80910,79 +80997,99 @@ var SEED_MODELS = [
80910
80997
  id: "gpt-5-mini",
80911
80998
  displayName: "GPT-5 mini",
80912
80999
  premiumMultiplier: 0.33,
80913
- tokenInputMultiplier: null,
80914
- tokenOutputMultiplier: null,
80915
- cachedInputMultiplier: null,
81000
+ tokenInputMultiplier: 0.025,
81001
+ tokenOutputMultiplier: 0.2,
81002
+ cachedInputMultiplier: 25e-4,
80916
81003
  tier: "trivial",
80917
81004
  available: true
80918
81005
  },
80919
81006
  {
80920
- id: "claude-sonnet-4",
80921
- displayName: "Claude Sonnet 4",
81007
+ id: "gpt-5.3-codex",
81008
+ displayName: "GPT-5.3-Codex",
80922
81009
  premiumMultiplier: 6,
80923
- tokenInputMultiplier: 0.6,
80924
- tokenOutputMultiplier: 2.4,
80925
- cachedInputMultiplier: null,
81010
+ tokenInputMultiplier: 0.175,
81011
+ tokenOutputMultiplier: 1.4,
81012
+ cachedInputMultiplier: 0.0175,
80926
81013
  tier: "premium",
80927
81014
  available: true
80928
81015
  },
80929
81016
  {
80930
- id: "claude-haiku-4.5",
80931
- displayName: "Claude Haiku 4.5",
80932
- premiumMultiplier: 0.33,
80933
- tokenInputMultiplier: null,
80934
- tokenOutputMultiplier: null,
80935
- cachedInputMultiplier: null,
80936
- tier: "trivial",
81017
+ id: "gpt-5.4",
81018
+ displayName: "GPT-5.4",
81019
+ premiumMultiplier: 6,
81020
+ tokenInputMultiplier: 0.25,
81021
+ tokenOutputMultiplier: 1.5,
81022
+ cachedInputMultiplier: 0.025,
81023
+ tier: "premium",
80937
81024
  available: true
80938
81025
  },
80939
81026
  {
80940
- id: "gemini-2.5-pro",
80941
- displayName: "Gemini 2.5 Pro",
80942
- premiumMultiplier: 1,
80943
- tokenInputMultiplier: null,
80944
- tokenOutputMultiplier: null,
80945
- cachedInputMultiplier: null,
80946
- tier: "fast",
81027
+ id: "gpt-5.4-mini",
81028
+ displayName: "GPT-5.4 mini",
81029
+ premiumMultiplier: 6,
81030
+ tokenInputMultiplier: 0.075,
81031
+ tokenOutputMultiplier: 0.45,
81032
+ cachedInputMultiplier: 75e-4,
81033
+ tier: "premium",
80947
81034
  available: true
80948
81035
  },
80949
81036
  {
80950
- id: "gpt-5.1",
80951
- displayName: "GPT-5.1",
80952
- premiumMultiplier: 3,
80953
- tokenInputMultiplier: null,
80954
- tokenOutputMultiplier: null,
80955
- cachedInputMultiplier: null,
80956
- tier: "standard",
81037
+ id: "gpt-5.5",
81038
+ displayName: "GPT-5.5",
81039
+ premiumMultiplier: 57,
81040
+ tokenInputMultiplier: 0.5,
81041
+ tokenOutputMultiplier: 3,
81042
+ cachedInputMultiplier: 0.05,
81043
+ tier: "ultra",
80957
81044
  available: true
80958
81045
  },
80959
81046
  {
80960
- id: "gpt-5.2",
80961
- displayName: "GPT-5.2",
80962
- premiumMultiplier: 3,
80963
- tokenInputMultiplier: null,
80964
- tokenOutputMultiplier: null,
80965
- cachedInputMultiplier: null,
80966
- tier: "standard",
81047
+ id: "claude-sonnet-4",
81048
+ displayName: "Claude Sonnet 4",
81049
+ premiumMultiplier: 6,
81050
+ tokenInputMultiplier: 0.3,
81051
+ tokenOutputMultiplier: 1.5,
81052
+ cachedInputMultiplier: 0.03,
81053
+ tier: "premium",
80967
81054
  available: true
80968
81055
  },
80969
81056
  {
80970
- id: "gpt-5.4",
80971
- displayName: "GPT-5.4",
81057
+ id: "claude-sonnet-4.5",
81058
+ displayName: "Claude Sonnet 4.5",
80972
81059
  premiumMultiplier: 6,
80973
- tokenInputMultiplier: null,
80974
- tokenOutputMultiplier: null,
80975
- cachedInputMultiplier: null,
81060
+ tokenInputMultiplier: 0.3,
81061
+ tokenOutputMultiplier: 1.5,
81062
+ cachedInputMultiplier: 0.03,
80976
81063
  tier: "premium",
80977
81064
  available: true
80978
81065
  },
81066
+ {
81067
+ id: "claude-sonnet-4.6",
81068
+ displayName: "Claude Sonnet 4.6",
81069
+ premiumMultiplier: 9,
81070
+ tokenInputMultiplier: 0.3,
81071
+ tokenOutputMultiplier: 1.5,
81072
+ cachedInputMultiplier: 0.03,
81073
+ tier: "premium",
81074
+ available: true
81075
+ },
81076
+ {
81077
+ id: "claude-haiku-4.5",
81078
+ displayName: "Claude Haiku 4.5",
81079
+ premiumMultiplier: 0.33,
81080
+ tokenInputMultiplier: 0.1,
81081
+ tokenOutputMultiplier: 0.5,
81082
+ cachedInputMultiplier: 0.01,
81083
+ tier: "trivial",
81084
+ available: true
81085
+ },
80979
81086
  {
80980
81087
  id: "claude-opus-4.5",
80981
81088
  displayName: "Claude Opus 4.5",
80982
81089
  premiumMultiplier: 15,
80983
- tokenInputMultiplier: null,
80984
- tokenOutputMultiplier: null,
80985
- cachedInputMultiplier: null,
81090
+ tokenInputMultiplier: 0.5,
81091
+ tokenOutputMultiplier: 2.5,
81092
+ cachedInputMultiplier: 0.05,
80986
81093
  tier: "premium",
80987
81094
  available: true
80988
81095
  },
@@ -80990,9 +81097,9 @@ var SEED_MODELS = [
80990
81097
  id: "claude-opus-4.6",
80991
81098
  displayName: "Claude Opus 4.6",
80992
81099
  premiumMultiplier: 27,
80993
- tokenInputMultiplier: null,
80994
- tokenOutputMultiplier: null,
80995
- cachedInputMultiplier: null,
81100
+ tokenInputMultiplier: 0.5,
81101
+ tokenOutputMultiplier: 2.5,
81102
+ cachedInputMultiplier: 0.05,
80996
81103
  tier: "ultra",
80997
81104
  available: true
80998
81105
  },
@@ -81000,21 +81107,81 @@ var SEED_MODELS = [
81000
81107
  id: "claude-opus-4.7",
81001
81108
  displayName: "Claude Opus 4.7",
81002
81109
  premiumMultiplier: 27,
81003
- tokenInputMultiplier: null,
81004
- tokenOutputMultiplier: null,
81005
- cachedInputMultiplier: null,
81110
+ tokenInputMultiplier: 0.5,
81111
+ tokenOutputMultiplier: 2.5,
81112
+ cachedInputMultiplier: 0.05,
81006
81113
  tier: "ultra",
81007
81114
  available: true
81008
81115
  },
81009
81116
  {
81010
- id: "gpt-5.5",
81011
- displayName: "GPT-5.5",
81012
- premiumMultiplier: 57,
81013
- tokenInputMultiplier: null,
81014
- tokenOutputMultiplier: null,
81015
- cachedInputMultiplier: null,
81117
+ id: "claude-opus-4.8",
81118
+ displayName: "Claude Opus 4.8",
81119
+ premiumMultiplier: 27,
81120
+ tokenInputMultiplier: 0.5,
81121
+ tokenOutputMultiplier: 2.5,
81122
+ cachedInputMultiplier: 0.05,
81016
81123
  tier: "ultra",
81017
81124
  available: true
81125
+ },
81126
+ {
81127
+ id: "gemini-2.5-pro",
81128
+ displayName: "Gemini 2.5 Pro",
81129
+ premiumMultiplier: 1,
81130
+ tokenInputMultiplier: 0.125,
81131
+ tokenOutputMultiplier: 1,
81132
+ cachedInputMultiplier: 0.0125,
81133
+ tier: "fast",
81134
+ available: true
81135
+ },
81136
+ {
81137
+ id: "gemini-3-flash",
81138
+ displayName: "Gemini 3 Flash",
81139
+ premiumMultiplier: 0.33,
81140
+ tokenInputMultiplier: 0.05,
81141
+ tokenOutputMultiplier: 0.3,
81142
+ cachedInputMultiplier: 5e-3,
81143
+ tier: "trivial",
81144
+ available: true
81145
+ },
81146
+ {
81147
+ id: "gemini-3.1-pro",
81148
+ displayName: "Gemini 3.1 Pro",
81149
+ premiumMultiplier: 6,
81150
+ tokenInputMultiplier: 0.2,
81151
+ tokenOutputMultiplier: 1.2,
81152
+ cachedInputMultiplier: 0.02,
81153
+ tier: "premium",
81154
+ available: true
81155
+ },
81156
+ {
81157
+ id: "gemini-3.5-flash",
81158
+ displayName: "Gemini 3.5 Flash",
81159
+ premiumMultiplier: 14,
81160
+ tokenInputMultiplier: 0.15,
81161
+ tokenOutputMultiplier: 0.9,
81162
+ cachedInputMultiplier: 0.015,
81163
+ tier: "premium",
81164
+ available: true
81165
+ },
81166
+ {
81167
+ id: "raptor-mini",
81168
+ displayName: "Raptor mini",
81169
+ premiumMultiplier: 0.33,
81170
+ tokenInputMultiplier: 0.025,
81171
+ tokenOutputMultiplier: 0.2,
81172
+ cachedInputMultiplier: 25e-4,
81173
+ tier: "trivial",
81174
+ available: true
81175
+ },
81176
+ {
81177
+ id: "mai-code-1-flash",
81178
+ displayName: "MAI-Code-1-Flash",
81179
+ premiumMultiplier: 0.33,
81180
+ tokenInputMultiplier: 0.075,
81181
+ tokenOutputMultiplier: 0.45,
81182
+ cachedInputMultiplier: 75e-4,
81183
+ tier: "trivial",
81184
+ available: true
81018
81185
  }
81019
81186
  ];
81020
81187
 
@@ -81109,19 +81276,51 @@ async function scrapePremiumPricingIntoMap(modelMap, result, logger2) {
81109
81276
  logger2?.warn(`Premium pricing scrape failed: ${msg}`);
81110
81277
  }
81111
81278
  }
81279
+ async function scrapeCopilotPricingIntoMap(modelMap, result, logger2) {
81280
+ try {
81281
+ const copilotPricing = await scrapeCopilotPricing();
81282
+ result.copilotPricingScraped = true;
81283
+ for (const cp of copilotPricing) {
81284
+ const key = normalizeModelName(cp.modelName);
81285
+ const existing = modelMap.get(key) ?? findClosestKey(modelMap, key);
81286
+ if (existing) {
81287
+ existing.tokenInputMultiplier = cp.inputMultiplier;
81288
+ existing.tokenOutputMultiplier = cp.outputMultiplier;
81289
+ if (cp.cachedInputMultiplier !== null) {
81290
+ existing.cachedInputMultiplier = cp.cachedInputMultiplier;
81291
+ }
81292
+ } else {
81293
+ modelMap.set(key, {
81294
+ id: key,
81295
+ displayName: cp.modelName,
81296
+ tokenInputMultiplier: cp.inputMultiplier,
81297
+ tokenOutputMultiplier: cp.outputMultiplier,
81298
+ cachedInputMultiplier: cp.cachedInputMultiplier,
81299
+ available: true
81300
+ });
81301
+ }
81302
+ }
81303
+ } catch (error51) {
81304
+ const msg = error51 instanceof Error ? error51.message : String(error51);
81305
+ result.errors.push(`Copilot pricing scrape failed: ${msg}`);
81306
+ logger2?.warn(`Copilot pricing scrape failed: ${msg}`);
81307
+ }
81308
+ }
81112
81309
  async function refreshModelPricing(logger2) {
81113
81310
  const result = {
81114
81311
  modelsUpdated: 0,
81115
81312
  catalogFetched: false,
81116
81313
  tokenPricingScraped: false,
81117
81314
  premiumPricingScraped: false,
81315
+ copilotPricingScraped: false,
81118
81316
  errors: []
81119
81317
  };
81120
81318
  const modelMap = /* @__PURE__ */ new Map();
81121
81319
  await fetchCatalogIntoMap(modelMap, result, logger2);
81122
81320
  await scrapeTokenPricingIntoMap(modelMap, result, logger2);
81321
+ await scrapeCopilotPricingIntoMap(modelMap, result, logger2);
81123
81322
  await scrapePremiumPricingIntoMap(modelMap, result, logger2);
81124
- if (!result.catalogFetched && !result.tokenPricingScraped && !result.premiumPricingScraped) {
81323
+ if (!result.catalogFetched && !result.tokenPricingScraped && !result.premiumPricingScraped && !result.copilotPricingScraped) {
81125
81324
  logger2?.warn("All pricing sources failed, using seed data");
81126
81325
  await seedFromFallback();
81127
81326
  result.modelsUpdated = SEED_MODELS.length;
@@ -83374,7 +83573,9 @@ var addSquadMemberSchema = external_exports.object({
83374
83573
  squadId: external_exports.string().trim().min(1),
83375
83574
  role: external_exports.string().trim().min(1).describe("Slug-style role identifier (e.g. 'senior-frontend-engineer', 'team-lead')"),
83376
83575
  name: external_exports.string().trim().min(1).describe("Display name for the member (e.g. 'Senior Frontend Engineer')"),
83377
- systemPrompt: external_exports.string().min(1).describe("The system prompt defining this member's expertise, responsibilities, and behavior."),
83576
+ systemPrompt: external_exports.string().min(1).describe(
83577
+ "The system prompt defining this member's expertise, responsibilities, and behavior."
83578
+ ),
83378
83579
  model: external_exports.string().optional().describe("Model override for this member. Uses squad default if not provided.")
83379
83580
  });
83380
83581
  var removeSquadMemberSchema = external_exports.object({
@@ -83840,7 +84041,7 @@ async function handleUpdateSquadMember(rawArgs) {
83840
84041
  member: updated
83841
84042
  };
83842
84043
  }
83843
- function createSquadToolExecutor(config2) {
84044
+ function createSquadToolExecutor(_config) {
83844
84045
  return async (toolName, rawArgs) => {
83845
84046
  switch (toolName) {
83846
84047
  case "create_squad":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyio",
3
- "version": "4.2.4",
3
+ "version": "4.2.5",
4
4
  "description": "AI orchestrator daemon with squad-based team delegation",
5
5
  "type": "module",
6
6
  "license": "MIT",