@runtypelabs/cli 2.21.5 → 2.22.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.
Files changed (2) hide show
  1. package/dist/index.js +168 -20
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -15128,13 +15128,18 @@ function date4(params) {
15128
15128
  // ../../node_modules/.pnpm/zod@4.4.2/node_modules/zod/v4/classic/external.js
15129
15129
  config(en_default());
15130
15130
 
15131
- // ../shared/dist/chunk-ENDRXULJ.mjs
15131
+ // ../shared/dist/chunk-NUTME5YJ.mjs
15132
15132
  var apiReleaseChannelSchema = external_exports.enum(["staging", "production"]);
15133
15133
  var API_ARTIFACT_SCRIPT_PATTERN = /^api-[a-z0-9][a-z0-9-]{0,62}$/;
15134
15134
  var apiArtifactScriptNameSchema = external_exports.string().regex(
15135
15135
  API_ARTIFACT_SCRIPT_PATTERN,
15136
15136
  "API artifact script names look like api-<sha12> or api-<sha12>-<suffix> (lowercase alphanumeric and dashes)"
15137
15137
  );
15138
+ var RUNTIME_ARTIFACT_SCRIPT_PATTERN = /^rt-[a-z0-9][a-z0-9-]{0,80}$/;
15139
+ var runtimeArtifactScriptNameSchema = external_exports.string().regex(
15140
+ RUNTIME_ARTIFACT_SCRIPT_PATTERN,
15141
+ "Runtime artifact script names look like rt-<namespace>-<flow|agent>-<hash> (lowercase alphanumeric and dashes)"
15142
+ );
15138
15143
  var apiHeaderOverrideModeSchema = external_exports.enum(["open", "token"]);
15139
15144
  var apiArtifactStatusSchema = external_exports.enum([
15140
15145
  "uploaded",
@@ -15163,6 +15168,20 @@ var apiRoutingDocSchema = external_exports.object({
15163
15168
  message: "activeScript may only be null while legacyFallback is true",
15164
15169
  path: ["api", "activeScript"]
15165
15170
  });
15171
+ var edgeContextPayloadSchema = external_exports.object({
15172
+ /** Resolved Runtype user id (`user_…`). */
15173
+ userId: external_exports.string().min(1),
15174
+ /** Resolved org id (`org_…`); null for a personal (no-org) credential. */
15175
+ orgId: external_exports.string().min(1).nullable(),
15176
+ /** Billing tier display name (e.g. `growth`); informational at the edge. */
15177
+ tier: external_exports.string().min(1),
15178
+ /** Effective permission scopes for the credential (e.g. `["*"]`). */
15179
+ scopes: external_exports.array(external_exports.string()),
15180
+ /** Token id (one per mint) — replay/audit handle, never reused as a secret. */
15181
+ jti: external_exports.string().min(1),
15182
+ /** Expiry as epoch MILLISECONDS; the token is rejected once `exp <= now`. */
15183
+ exp: external_exports.number().int().positive()
15184
+ });
15166
15185
 
15167
15186
  // ../shared/dist/chunk-KR4LFVFE.mjs
15168
15187
  function getNestedValue(obj, path18) {
@@ -52721,6 +52740,32 @@ function listForkCandidates(log) {
52721
52740
  return candidates;
52722
52741
  }
52723
52742
 
52743
+ // src/marathon/steering-queue.ts
52744
+ function createSteeringQueue(options = {}) {
52745
+ const items = [];
52746
+ const notify = () => {
52747
+ options.onSizeChange?.(items.length);
52748
+ };
52749
+ return {
52750
+ push(message) {
52751
+ items.push(message);
52752
+ notify();
52753
+ },
52754
+ drain() {
52755
+ if (items.length === 0) return [];
52756
+ const drained = items.splice(0);
52757
+ notify();
52758
+ return drained;
52759
+ },
52760
+ size() {
52761
+ return items.length;
52762
+ },
52763
+ isEmpty() {
52764
+ return items.length === 0;
52765
+ }
52766
+ };
52767
+ }
52768
+
52724
52769
  // src/ink/marathon/CheckpointPrompt.tsx
52725
52770
  import { useState as useState26, useEffect as useEffect21, useRef as useRef8 } from "react";
52726
52771
  import { Box as Box23, Text as Text26 } from "ink";
@@ -55128,14 +55173,12 @@ function MarathonApp({
55128
55173
  getCallbacks: () => callbacks,
55129
55174
  getState: () => getHydratedState(),
55130
55175
  drainSteeringQueue: () => {
55131
- const drained = steeringQueueRef.current.splice(0);
55132
- if (drained.length > 0) setQueuedSteerCount(0);
55176
+ const drained = steeringQueue.drain();
55133
55177
  return drained.length > 0 ? drained : void 0;
55134
55178
  },
55135
- hasQueuedSteering: () => steeringQueueRef.current.length > 0,
55179
+ hasQueuedSteering: () => !steeringQueue.isEmpty(),
55136
55180
  drainFollowUpQueue: () => {
55137
- const drained = followUpQueueRef.current.splice(0);
55138
- if (drained.length > 0) setQueuedFollowUpCount(0);
55181
+ const drained = followUpQueue.drain();
55139
55182
  return drained.length > 0 ? drained : void 0;
55140
55183
  },
55141
55184
  appendSessionSnapshot: (snapshot) => {
@@ -55217,10 +55260,18 @@ function MarathonApp({
55217
55260
  setEscAbortArmed(false);
55218
55261
  }
55219
55262
  }, [isAgentWorkingPhase, escAbortArmed]);
55220
- const steeringQueueRef = useRef9([]);
55221
- const followUpQueueRef = useRef9([]);
55222
55263
  const [queuedSteerCount, setQueuedSteerCount] = useState31(0);
55223
55264
  const [queuedFollowUpCount, setQueuedFollowUpCount] = useState31(0);
55265
+ const steeringQueueHolder = useRef9(null);
55266
+ if (steeringQueueHolder.current === null) {
55267
+ steeringQueueHolder.current = createSteeringQueue({ onSizeChange: setQueuedSteerCount });
55268
+ }
55269
+ const steeringQueue = steeringQueueHolder.current;
55270
+ const followUpQueueHolder = useRef9(null);
55271
+ if (followUpQueueHolder.current === null) {
55272
+ followUpQueueHolder.current = createSteeringQueue({ onSizeChange: setQueuedFollowUpCount });
55273
+ }
55274
+ const followUpQueue = followUpQueueHolder.current;
55224
55275
  const [showSteerComposer, setShowSteerComposer] = useState31(false);
55225
55276
  const [steerDraft, setSteerDraft] = useState31("");
55226
55277
  const [activeScreen, setActiveScreen] = useState31("overview");
@@ -55719,8 +55770,7 @@ function MarathonApp({
55719
55770
  if (escAbortTimeout.current) clearTimeout(escAbortTimeout.current);
55720
55771
  setEscAbortArmed(false);
55721
55772
  if (onAbortTurn?.() && !noCheckpoint) {
55722
- const queued = steeringQueueRef.current.splice(0);
55723
- setQueuedSteerCount(0);
55773
+ const queued = steeringQueue.drain();
55724
55774
  const restored = [...queued, steerDraft].map((text) => text.trim()).filter(Boolean).join("\n\n");
55725
55775
  setSteerDraft("");
55726
55776
  setCheckpointInitialMessage(restored || void 0);
@@ -56452,11 +56502,9 @@ function MarathonApp({
56452
56502
  initialDraft: steerDraft,
56453
56503
  onSubmit: (message, kind) => {
56454
56504
  if (kind === "steer") {
56455
- steeringQueueRef.current.push(message);
56456
- setQueuedSteerCount(steeringQueueRef.current.length);
56505
+ steeringQueue.push(message);
56457
56506
  } else {
56458
- followUpQueueRef.current.push(message);
56459
- setQueuedFollowUpCount(followUpQueueRef.current.length);
56507
+ followUpQueue.push(message);
56460
56508
  }
56461
56509
  setSteerDraft("");
56462
56510
  setShowSteerComposer(false);
@@ -59450,7 +59498,40 @@ function resolveModelForPhase(phase, cliOverrides, milestoneModels) {
59450
59498
  }
59451
59499
  return cliOverrides.defaultModel;
59452
59500
  }
59453
- function resolveErrorHandlingForPhase(phase, cliFallbackModel, milestoneFallbackModels) {
59501
+ function resolveMaxTokensForPhase(phase, cliMaxTokens, milestoneMaxTokens, defaultMaxTokens) {
59502
+ if (phase && milestoneMaxTokens?.[phase] !== void 0) return milestoneMaxTokens[phase];
59503
+ if (cliMaxTokens !== void 0) return cliMaxTokens;
59504
+ return defaultMaxTokens;
59505
+ }
59506
+ function resolveTemperatureForPhase(phase, cliTemperature, milestoneTemperature, defaultTemperature) {
59507
+ if (phase && milestoneTemperature?.[phase] !== void 0) return milestoneTemperature[phase];
59508
+ if (cliTemperature !== void 0) return cliTemperature;
59509
+ return defaultTemperature;
59510
+ }
59511
+ function parseMaxTokensFlag(raw) {
59512
+ if (raw === void 0) return void 0;
59513
+ const value = Number(raw);
59514
+ if (!Number.isInteger(value) || value <= 0) {
59515
+ throw new Error(`Invalid --max-tokens "${raw}": expected a positive integer`);
59516
+ }
59517
+ return value;
59518
+ }
59519
+ function parseTemperatureFlag(raw) {
59520
+ if (raw === void 0) return void 0;
59521
+ const value = Number(raw);
59522
+ if (!Number.isFinite(value) || value < 0 || value > 2) {
59523
+ throw new Error(`Invalid --temperature "${raw}": expected a number between 0 and 2`);
59524
+ }
59525
+ return value;
59526
+ }
59527
+ function resolveFallbackOnEmptyForPhase(phase, milestoneFallbackOnEmpty, defaultFallbackOnEmpty) {
59528
+ if (phase && milestoneFallbackOnEmpty?.[phase] !== void 0) {
59529
+ return milestoneFallbackOnEmpty[phase];
59530
+ }
59531
+ return defaultFallbackOnEmpty ?? false;
59532
+ }
59533
+ function resolveErrorHandlingForPhase(phase, cliFallbackModel, milestoneFallbackModels, fallbackOnEmpty) {
59534
+ const triggers = fallbackOnEmpty ? [{ type: "empty-output" }, { type: "error" }] : void 0;
59454
59535
  const phaseFallbacks = phase ? milestoneFallbackModels?.[phase] : void 0;
59455
59536
  if (phaseFallbacks?.length) {
59456
59537
  return {
@@ -59463,7 +59544,8 @@ function resolveErrorHandlingForPhase(phase, cliFallbackModel, milestoneFallback
59463
59544
  ...fb.temperature !== void 0 ? { temperature: fb.temperature } : {},
59464
59545
  ...fb.maxTokens !== void 0 ? { maxTokens: fb.maxTokens } : {}
59465
59546
  }))
59466
- ]
59547
+ ],
59548
+ ...triggers ? { triggers } : {}
59467
59549
  };
59468
59550
  }
59469
59551
  if (cliFallbackModel) {
@@ -59472,7 +59554,8 @@ function resolveErrorHandlingForPhase(phase, cliFallbackModel, milestoneFallback
59472
59554
  fallbacks: [
59473
59555
  { type: "retry", delay: 5e3 },
59474
59556
  { type: "model", model: cliFallbackModel }
59475
- ]
59557
+ ],
59558
+ ...triggers ? { triggers } : {}
59476
59559
  };
59477
59560
  }
59478
59561
  return void 0;
@@ -59627,6 +59710,15 @@ function collectPlaybookWarnings(config3) {
59627
59710
  );
59628
59711
  }
59629
59712
  }
59713
+ const emptyDefault = config3.fallbackOnEmpty === true;
59714
+ for (const m2 of config3.milestones) {
59715
+ const enabled = m2.fallbackOnEmpty ?? emptyDefault;
59716
+ if (enabled && !m2.fallbackModels?.length) {
59717
+ warnings.push(
59718
+ `Playbook '${config3.name}': milestone '${m2.name}' enables fallbackOnEmpty but defines no fallbackModels \u2014 empty output has nothing to fall back to.`
59719
+ );
59720
+ }
59721
+ }
59630
59722
  return warnings;
59631
59723
  }
59632
59724
  var PLUGIN_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs"]);
@@ -59704,17 +59796,29 @@ async function loadPlaybook(nameOrPath, cwd) {
59704
59796
  });
59705
59797
  const milestoneModels = {};
59706
59798
  const milestoneFallbackModels = {};
59799
+ const milestoneMaxTokens = {};
59800
+ const milestoneTemperature = {};
59801
+ const milestoneFallbackOnEmpty = {};
59707
59802
  for (const m2 of config3.milestones) {
59708
59803
  if (m2.model) milestoneModels[m2.name] = m2.model;
59709
59804
  if (m2.fallbackModels?.length) {
59710
59805
  milestoneFallbackModels[m2.name] = m2.fallbackModels.map(normalizeFallbackModel);
59711
59806
  }
59807
+ if (m2.maxTokens !== void 0) milestoneMaxTokens[m2.name] = m2.maxTokens;
59808
+ if (m2.temperature !== void 0) milestoneTemperature[m2.name] = m2.temperature;
59809
+ if (m2.fallbackOnEmpty !== void 0) milestoneFallbackOnEmpty[m2.name] = m2.fallbackOnEmpty;
59712
59810
  }
59713
59811
  return {
59714
59812
  workflow,
59715
59813
  milestones: config3.milestones.map((m2) => m2.name),
59716
59814
  milestoneModels: Object.keys(milestoneModels).length > 0 ? milestoneModels : void 0,
59717
59815
  milestoneFallbackModels: Object.keys(milestoneFallbackModels).length > 0 ? milestoneFallbackModels : void 0,
59816
+ milestoneMaxTokens: Object.keys(milestoneMaxTokens).length > 0 ? milestoneMaxTokens : void 0,
59817
+ milestoneTemperature: Object.keys(milestoneTemperature).length > 0 ? milestoneTemperature : void 0,
59818
+ milestoneFallbackOnEmpty: Object.keys(milestoneFallbackOnEmpty).length > 0 ? milestoneFallbackOnEmpty : void 0,
59819
+ ...config3.maxTokens !== void 0 ? { defaultMaxTokens: config3.maxTokens } : {},
59820
+ ...config3.temperature !== void 0 ? { defaultTemperature: config3.temperature } : {},
59821
+ ...config3.fallbackOnEmpty !== void 0 ? { defaultFallbackOnEmpty: config3.fallbackOnEmpty } : {},
59718
59822
  verification: config3.verification,
59719
59823
  rules: config3.rules,
59720
59824
  policy: config3.policy,
@@ -60277,6 +60381,12 @@ async function taskAction(agent, options) {
60277
60381
  let playbookMilestones;
60278
60382
  let playbookMilestoneModels;
60279
60383
  let playbookMilestoneFallbackModels;
60384
+ let playbookMilestoneMaxTokens;
60385
+ let playbookMilestoneTemperature;
60386
+ let playbookMilestoneFallbackOnEmpty;
60387
+ let playbookDefaultMaxTokens;
60388
+ let playbookDefaultTemperature;
60389
+ let playbookDefaultFallbackOnEmpty;
60280
60390
  let playbookPolicy;
60281
60391
  if (options.playbook) {
60282
60392
  const result = await loadPlaybook(options.playbook);
@@ -60284,6 +60394,12 @@ async function taskAction(agent, options) {
60284
60394
  playbookMilestones = result.milestones;
60285
60395
  playbookMilestoneModels = result.milestoneModels;
60286
60396
  playbookMilestoneFallbackModels = result.milestoneFallbackModels;
60397
+ playbookMilestoneMaxTokens = result.milestoneMaxTokens;
60398
+ playbookMilestoneTemperature = result.milestoneTemperature;
60399
+ playbookMilestoneFallbackOnEmpty = result.milestoneFallbackOnEmpty;
60400
+ playbookDefaultMaxTokens = result.defaultMaxTokens;
60401
+ playbookDefaultTemperature = result.defaultTemperature;
60402
+ playbookDefaultFallbackOnEmpty = result.defaultFallbackOnEmpty;
60287
60403
  playbookPolicy = result.policy;
60288
60404
  for (const warning of result.warnings) {
60289
60405
  if (useStartupShell) {
@@ -60295,6 +60411,8 @@ async function taskAction(agent, options) {
60295
60411
  } else {
60296
60412
  playbookPolicy = void 0;
60297
60413
  }
60414
+ const cliMaxTokens = parseMaxTokensFlag(options.maxTokens);
60415
+ const cliTemperature = parseTemperatureFlag(options.temperature);
60298
60416
  if (useStartupShell && !options.model?.trim()) {
60299
60417
  if (playbookMilestoneModels && Object.keys(playbookMilestoneModels).length > 0 && startupShellRef.current) {
60300
60418
  let editableModels = { ...playbookMilestoneModels };
@@ -60434,7 +60552,12 @@ ${rulesContext}`;
60434
60552
  const initialErrorHandling = resolveErrorHandlingForPhase(
60435
60553
  currentPhase,
60436
60554
  options.fallbackModel,
60437
- playbookMilestoneFallbackModels
60555
+ playbookMilestoneFallbackModels,
60556
+ resolveFallbackOnEmptyForPhase(
60557
+ currentPhase,
60558
+ playbookMilestoneFallbackOnEmpty,
60559
+ playbookDefaultFallbackOnEmpty
60560
+ )
60438
60561
  );
60439
60562
  if (initialErrorHandling) {
60440
60563
  await client.agents.update(agentId, { config: { errorHandling: initialErrorHandling } }).catch(() => {
@@ -60768,6 +60891,18 @@ Saving state... done. Session saved to ${filePath}`);
60768
60891
  },
60769
60892
  playbookMilestoneModels
60770
60893
  );
60894
+ const phaseMaxTokens = resolveMaxTokensForPhase(
60895
+ resumeState?.workflowPhase,
60896
+ cliMaxTokens,
60897
+ playbookMilestoneMaxTokens,
60898
+ playbookDefaultMaxTokens
60899
+ );
60900
+ const phaseTemperature = resolveTemperatureForPhase(
60901
+ resumeState?.workflowPhase,
60902
+ cliTemperature,
60903
+ playbookMilestoneTemperature,
60904
+ playbookDefaultTemperature
60905
+ );
60771
60906
  const effectiveModelForContext = phaseModel || options.model || agentConfigModel || defaultConfiguredModel;
60772
60907
  const compactStrategy = resolveCompactStrategyForModel(effectiveModelForContext);
60773
60908
  const contextLimitTokens = resolveContextLimitForModel(effectiveModelForContext);
@@ -60782,6 +60917,8 @@ Saving state... done. Session saved to ${filePath}`);
60782
60917
  maxSessions: remainingSessions - accumulatedSessions,
60783
60918
  maxCost: currentRemainingCost,
60784
60919
  model: phaseModel || options.model,
60920
+ ...phaseMaxTokens !== void 0 ? { maxTokens: phaseMaxTokens } : {},
60921
+ ...phaseTemperature !== void 0 ? { temperature: phaseTemperature } : {},
60785
60922
  abortSignal: turnAbortController.signal,
60786
60923
  reasoning: !options.noReasoning,
60787
60924
  debugMode: options.debug ?? true,
@@ -60953,7 +61090,12 @@ Saving state... done. Session saved to ${filePath}`);
60953
61090
  const newErrorHandling = resolveErrorHandlingForPhase(
60954
61091
  resumeState.workflowPhase,
60955
61092
  options.fallbackModel,
60956
- playbookMilestoneFallbackModels
61093
+ playbookMilestoneFallbackModels,
61094
+ resolveFallbackOnEmptyForPhase(
61095
+ resumeState.workflowPhase,
61096
+ playbookMilestoneFallbackOnEmpty,
61097
+ playbookDefaultFallbackOnEmpty
61098
+ )
60957
61099
  );
60958
61100
  client.agents.update(agentId, {
60959
61101
  config: { errorHandling: newErrorHandling ?? null }
@@ -61463,7 +61605,13 @@ function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState)
61463
61605
  };
61464
61606
  }
61465
61607
  function applyTaskOptions(cmd) {
61466
- return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option(
61608
+ return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option(
61609
+ "--max-tokens <n>",
61610
+ "Max output-token budget per session (overrides agent config; playbook milestones can override per phase)"
61611
+ ).option(
61612
+ "--temperature <n>",
61613
+ "Sampling temperature 0-2 per session (overrides agent config; playbook milestones can override per phase)"
61614
+ ).option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option(
61467
61615
  "--state-dir <path>",
61468
61616
  "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)"
61469
61617
  ).option(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtypelabs/cli",
3
- "version": "2.21.5",
3
+ "version": "2.22.0",
4
4
  "description": "Command-line interface for Runtype AI platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,7 +24,7 @@
24
24
  "rosie-skills": "0.8.1",
25
25
  "yaml": "^2.9.0",
26
26
  "@runtypelabs/ink-components": "0.3.2",
27
- "@runtypelabs/sdk": "4.17.1",
27
+ "@runtypelabs/sdk": "4.19.0",
28
28
  "@runtypelabs/terminal-animations": "0.2.1"
29
29
  },
30
30
  "devDependencies": {
@@ -39,7 +39,7 @@
39
39
  "tsx": "^4.7.1",
40
40
  "typescript": "^5.3.3",
41
41
  "vitest": "^4.1.0",
42
- "@runtypelabs/shared": "1.32.0"
42
+ "@runtypelabs/shared": "1.33.1"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=22.0.0"