omniagent 0.1.16 → 0.1.17

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/dist/cli.js CHANGED
@@ -1484,7 +1484,7 @@ const codexTarget = {
1484
1484
  timeoutMs: 6e4
1485
1485
  },
1486
1486
  extract: async (context) => {
1487
- const { extractCodexUsage } = await import("./codex-DhlBosXm.js");
1487
+ const { extractCodexUsage } = await import("./codex-B4oMrP6y.js");
1488
1488
  return extractCodexUsage(context);
1489
1489
  }
1490
1490
  }
@@ -35,8 +35,18 @@ async function extractCodexUsageFromTui(context) {
35
35
  signal: context.signal,
36
36
  debug: context.debug,
37
37
  steps: [
38
- { waitFor: isCodexPromptReadyOrTrustPrompt, waitForTimeoutMs: 1e4 },
38
+ { waitFor: isCodexPromptReadyOrStartupPrompt, waitForTimeoutMs: 1e4 },
39
+ // Numeric migration choices submit immediately, so do not append Enter.
40
+ { write: dismissCodexModelMigrationPrompt, skipIf: isCodexPromptReady },
41
+ { waitFor: isCodexPromptReadyOrTrustPrompt, waitForTimeoutMs: 1e4, optional: true },
39
42
  { write: enterKey(), skipIf: isCodexPromptReady },
43
+ // Trust onboarding can precede the model-migration dialog.
44
+ {
45
+ waitFor: isCodexPromptReadyOrMigrationPrompt,
46
+ waitForTimeoutMs: 1e4,
47
+ optional: true
48
+ },
49
+ { write: dismissCodexModelMigrationPrompt, skipIf: isCodexPromptReady },
40
50
  { waitFor: isCodexPromptReady, waitForTimeoutMs: 1e4 },
41
51
  ...typeTextSteps("/status", 20),
42
52
  { write: enterKey() },
@@ -98,15 +108,14 @@ function buildCodexApiUsageResult(payload, context) {
98
108
  targetId: context.targetId,
99
109
  scope: "main",
100
110
  rateLimit: usage.rate_limit,
101
- now: context.now,
102
- requireBothWindows: true
111
+ now: context.now
103
112
  }),
104
113
  ...buildCodexApiAdditionalUsageLimits(usage.additional_rate_limits, context)
105
114
  ];
106
- const hasMainHourly = limits.some((limit) => limit.scope === "main" && limit.window === "hourly");
107
- const hasMainWeekly = limits.some((limit) => limit.scope === "main" && limit.window === "weekly");
108
- if (!hasMainHourly || !hasMainWeekly) {
109
- throw new Error("Codex usage API response did not include complete main rate-limit windows.");
115
+ if (!limits.some((limit) => limit.scope === "main")) {
116
+ throw new Error(
117
+ "Codex usage API response did not include any recognized main rate-limit windows."
118
+ );
110
119
  }
111
120
  return {
112
121
  targetId: context.targetId,
@@ -203,8 +212,7 @@ function buildCodexApiAdditionalUsageLimits(additionalRateLimits, context) {
203
212
  scope,
204
213
  rateLimit: entry.rate_limit,
205
214
  now: context.now,
206
- labelPrefix: scope === "spark" ? void 0 : limitName || meteredFeature || scope,
207
- requireBothWindows: false
215
+ labelPrefix: scope === "spark" ? void 0 : limitName || meteredFeature || scope
208
216
  });
209
217
  });
210
218
  }
@@ -212,25 +220,17 @@ function buildCodexApiRateLimitUsageLimits(options) {
212
220
  if (!isRecord(options.rateLimit)) {
213
221
  return [];
214
222
  }
215
- const windows = [
216
- ["primary", options.rateLimit.primary_window],
217
- ["secondary", options.rateLimit.secondary_window]
218
- ];
219
- const limits = windows.flatMap(([kind, window]) => {
223
+ const windows = [options.rateLimit.primary_window, options.rateLimit.secondary_window];
224
+ return windows.flatMap((window) => {
220
225
  const limit = makeCodexApiUsageLimit({
221
226
  targetId: options.targetId,
222
227
  scope: options.scope,
223
- windowKind: kind,
224
228
  window,
225
229
  now: options.now,
226
230
  labelPrefix: options.labelPrefix
227
231
  });
228
232
  return limit == null ? [] : [limit];
229
233
  });
230
- if (options.requireBothWindows && limits.length !== 2) {
231
- return [];
232
- }
233
- return limits;
234
234
  }
235
235
  function makeCodexApiUsageLimit(options) {
236
236
  if (!isRecord(options.window)) {
@@ -240,8 +240,11 @@ function makeCodexApiUsageLimit(options) {
240
240
  if (percentUsed == null) {
241
241
  return null;
242
242
  }
243
+ const window = codexApiWindowName(options.window);
244
+ if (window == null) {
245
+ return null;
246
+ }
243
247
  const resetAt = parseApiEpochSeconds(options.window.reset_at);
244
- const window = codexApiWindowName(options.window, options.windowKind);
245
248
  const percentUsedClamped = clampPercent(percentUsed);
246
249
  const percentRemaining = 100 - percentUsedClamped;
247
250
  const resetText = resetAt == null ? null : `resets ${resetAt}`;
@@ -271,7 +274,7 @@ function codexAdditionalLimitScope(limitName, meteredFeature) {
271
274
  const normalized = source.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
272
275
  return normalized || "additional";
273
276
  }
274
- function codexApiWindowName(window, kind) {
277
+ function codexApiWindowName(window) {
275
278
  const seconds = parseApiNumber(window.limit_window_seconds);
276
279
  if (seconds === 18e3) {
277
280
  return "5h";
@@ -279,7 +282,7 @@ function codexApiWindowName(window, kind) {
279
282
  if (seconds === 604800) {
280
283
  return "weekly";
281
284
  }
282
- return kind === "primary" ? "5h" : "weekly";
285
+ return null;
283
286
  }
284
287
  function formatWindowLabel(window) {
285
288
  return window === "weekly" ? "Weekly" : window === "5h" ? "5h" : window;
@@ -320,10 +323,10 @@ function selectCodexStatus(result) {
320
323
  if (snapshot == null) {
321
324
  continue;
322
325
  }
323
- for (const content of [`${snapshot.screen}
324
- ${snapshot.raw}`, snapshot.screen, snapshot.raw]) {
326
+ for (const content of [snapshot.screen, `${snapshot.screen}
327
+ ${snapshot.raw}`, snapshot.raw]) {
325
328
  const parsed = parseCodexStatus(cleanControlOutput(content));
326
- if (parsed.main5hLimit || parsed.mainWeeklyLimit) {
329
+ if (isCompleteCodexStatus(parsed)) {
327
330
  return parsed;
328
331
  }
329
332
  }
@@ -340,16 +343,32 @@ ${snapshot.raw}`);
340
343
  function isCodexPromptReadyOrTrustPrompt(snapshot) {
341
344
  return isCodexPromptReady(snapshot) || isCodexTrustPrompt(snapshot);
342
345
  }
346
+ function isCodexPromptReadyOrStartupPrompt(snapshot) {
347
+ return isCodexPromptReadyOrTrustPrompt(snapshot) || isCodexModelMigrationPrompt(snapshot);
348
+ }
343
349
  function isCodexTrustPrompt(snapshot) {
344
350
  const cleanedOutput = cleanControlOutput(`${snapshot.screen}
345
351
  ${snapshot.raw}`);
346
352
  return /do you trust the contents of this directory/i.test(cleanedOutput);
347
353
  }
354
+ function isCodexModelMigrationPrompt(snapshot) {
355
+ return codexKeepModelSelection(snapshot) != null;
356
+ }
357
+ function isCodexPromptReadyOrMigrationPrompt(snapshot) {
358
+ return isCodexPromptReady(snapshot) || isCodexModelMigrationPrompt(snapshot);
359
+ }
360
+ function codexKeepModelSelection(snapshot) {
361
+ const cleanedScreen = cleanControlOutput(snapshot.screen);
362
+ const match = /(\d+)\.\s*Use existing model/i.exec(cleanedScreen);
363
+ return match?.[1] ?? null;
364
+ }
365
+ function dismissCodexModelMigrationPrompt(snapshot) {
366
+ return codexKeepModelSelection(snapshot) ?? void 0;
367
+ }
348
368
  function hasCodexStatusLimits(snapshot) {
349
369
  const cleanedOutput = cleanControlOutput(`${snapshot.screen}
350
370
  ${snapshot.raw}`);
351
- const parsed = parseCodexStatus(cleanedOutput);
352
- return Boolean(parsed.main5hLimit && parsed.mainWeeklyLimit);
371
+ return isCompleteCodexStatus(parseCodexStatus(cleanedOutput));
353
372
  }
354
373
  function hasCodexStatusResponse(snapshot) {
355
374
  const cleanedOutput = cleanControlOutput(`${snapshot.screen}
@@ -358,14 +377,12 @@ ${snapshot.raw}`);
358
377
  return Boolean(parsed.main5hLimit || parsed.mainWeeklyLimit) || /refresh requested/i.test(cleanedOutput);
359
378
  }
360
379
  function buildCodexUsageResult(parsed, context) {
361
- assertAnyRequiredCodexLimit(parsed);
362
- const errors = buildCodexUsageErrors(parsed, context);
380
+ assertCompleteCodexStatus(parsed);
363
381
  return {
364
382
  targetId: context.targetId,
365
383
  displayName: context.displayName,
366
384
  command: context.command,
367
- limits: buildCodexUsageLimits(parsed, context),
368
- errors: errors.length > 0 ? errors : void 0
385
+ limits: buildCodexUsageLimits(parsed, context)
369
386
  };
370
387
  }
371
388
  function buildCodexUsageLimits(parsed, context) {
@@ -375,12 +392,15 @@ function buildCodexUsageLimits(parsed, context) {
375
392
  return [];
376
393
  }
377
394
  const percentRemaining = parsePercentRemaining(raw);
395
+ if (percentRemaining == null) {
396
+ return [];
397
+ }
378
398
  return [
379
399
  makeUsageLimit({
380
400
  targetId: context.targetId,
381
401
  scope,
382
402
  window,
383
- percentUsed: percentRemaining == null ? null : 100 - percentRemaining,
403
+ percentUsed: 100 - percentRemaining,
384
404
  percentRemaining,
385
405
  resetText: parseResetText(raw),
386
406
  raw,
@@ -424,13 +444,19 @@ function parseCodexStatus(cleanedOutput) {
424
444
  const label = labelMatch[1].trim();
425
445
  const inlineValue = labelMatch[2].trim();
426
446
  if (isCodexSparkLimitLabel(label)) {
427
- section = "spark";
428
- key = "";
447
+ const sparkKey = sparkLimitKey(label);
448
+ if (sparkKey) {
449
+ key = sparkKey;
450
+ setCodexLabeledValue(values, key, label, inlineValue);
451
+ } else {
452
+ section = "spark";
453
+ key = "";
454
+ }
429
455
  continue;
430
456
  }
431
457
  key = labelToCodexKey(label, section);
432
- if (key && inlineValue) {
433
- setValue(values, key, inlineValue);
458
+ if (key) {
459
+ setCodexLabeledValue(values, key, label, inlineValue);
434
460
  }
435
461
  continue;
436
462
  }
@@ -452,35 +478,36 @@ function parseCodexStatus(cleanedOutput) {
452
478
  sparkWeeklyLimit: values.sparkWeeklyLimit ?? ""
453
479
  };
454
480
  }
455
- function assertAnyRequiredCodexLimit(parsed) {
456
- if (parsed.main5hLimit || parsed.mainWeeklyLimit) {
457
- return;
458
- }
459
- throw new Error("Codex usage output did not include the required 5h and weekly limit rows.");
460
- }
461
- function buildCodexUsageErrors(parsed, context) {
462
- const missing = [];
463
- if (!parsed.main5hLimit) {
464
- missing.push("5h");
481
+ function assertCompleteCodexStatus(parsed) {
482
+ if (!hasParseableCodexMainLimit(parsed)) {
483
+ throw new Error("Codex usage output did not include any parseable main rate-limit rows.");
465
484
  }
466
- if (!parsed.mainWeeklyLimit) {
467
- missing.push("weekly");
468
- }
469
- if (missing.length === 0) {
470
- return [];
485
+ if (!hasOnlyParseableCodexLimits(parsed)) {
486
+ throw new Error("Codex usage output included an incomplete rate-limit row.");
471
487
  }
472
- return [
473
- {
474
- targetId: context.targetId,
475
- displayName: context.displayName,
476
- code: "partial_parse",
477
- message: `Codex usage output did not include the ${missing.join(" and ")} limit row.`
478
- }
479
- ];
488
+ }
489
+ function isCompleteCodexStatus(parsed) {
490
+ return hasParseableCodexMainLimit(parsed) && hasOnlyParseableCodexLimits(parsed);
491
+ }
492
+ function hasParseableCodexMainLimit(parsed) {
493
+ return parsePercentRemaining(parsed.main5hLimit) != null || parsePercentRemaining(parsed.mainWeeklyLimit) != null;
494
+ }
495
+ function hasOnlyParseableCodexLimits(parsed) {
496
+ const limits = CODEX_WINDOWS.map(([, , key]) => parsed[key].trim()).filter(Boolean);
497
+ return limits.every((limit) => parsePercentRemaining(limit) != null);
480
498
  }
481
499
  function isCodexSparkLimitLabel(label) {
482
500
  return /\bspark\b/i.test(label) && /\blimit\b/i.test(label);
483
501
  }
502
+ function sparkLimitKey(label) {
503
+ if (/\b5h limit$/i.test(label)) {
504
+ return "spark5hLimit";
505
+ }
506
+ if (/\bweekly limit$/i.test(label)) {
507
+ return "sparkWeeklyLimit";
508
+ }
509
+ return "";
510
+ }
484
511
  function labelToCodexKey(label, section) {
485
512
  if (label === "Model") return "model";
486
513
  if (label === "Directory") return "directory";
@@ -495,6 +522,13 @@ function labelToCodexKey(label, section) {
495
522
  }
496
523
  return "";
497
524
  }
525
+ function setCodexLabeledValue(values, key, label, inlineValue) {
526
+ if (inlineValue) {
527
+ setValue(values, key, inlineValue);
528
+ } else if (CODEX_WINDOWS.some(([, , limitKey]) => limitKey === key)) {
529
+ setValue(values, key, `${label}:`);
530
+ }
531
+ }
498
532
  function setValue(values, key, value) {
499
533
  const sanitized = sanitizeCodexValue(value);
500
534
  if (!sanitized) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniagent",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "Unified agent configuration CLI that compiles canonical agent configs to multiple runtimes.",
5
5
  "type": "module",
6
6
  "bin": {