@foldrun/core 2.5.0 → 2.6.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 (61) hide show
  1. package/dist/src/agent-import.js +2 -2
  2. package/dist/src/agent-tools.js +2 -2
  3. package/dist/src/agents-md.d.ts +5 -1
  4. package/dist/src/agents-md.js +42 -18
  5. package/dist/src/completions.js +25 -3
  6. package/dist/src/deploy.js +72 -7
  7. package/dist/src/evals.d.ts +22 -1
  8. package/dist/src/evals.js +43 -14
  9. package/dist/src/flow-lint.d.ts +14 -0
  10. package/dist/src/flow-lint.js +35 -0
  11. package/dist/src/flow-patterns.js +29 -14
  12. package/dist/src/frontmatter-fields.d.ts +27 -0
  13. package/dist/src/frontmatter-fields.js +51 -3
  14. package/dist/src/frontmatter-guard.d.ts +19 -0
  15. package/dist/src/frontmatter-guard.js +67 -0
  16. package/dist/src/frontmatter-schema.d.ts +2 -2
  17. package/dist/src/frontmatter-schema.js +30 -2
  18. package/dist/src/frontmatter-text.d.ts +31 -0
  19. package/dist/src/frontmatter-text.js +102 -0
  20. package/dist/src/judge-verdict.d.ts +19 -0
  21. package/dist/src/judge-verdict.js +54 -0
  22. package/dist/src/matter.d.ts +34 -0
  23. package/dist/src/matter.js +104 -0
  24. package/dist/src/network.d.ts +0 -1
  25. package/dist/src/network.js +10 -7
  26. package/dist/src/package.js +9 -2
  27. package/dist/src/provider-health.js +2 -2
  28. package/dist/src/run-container.d.ts +9 -0
  29. package/dist/src/run-container.js +4 -1
  30. package/dist/src/runner.js +119 -36
  31. package/dist/src/scan.d.ts +11 -0
  32. package/dist/src/scan.js +86 -8
  33. package/dist/src/starter.js +23 -0
  34. package/dist/src/step-exec.d.ts +10 -2
  35. package/dist/src/step-exec.js +12 -9
  36. package/dist/src/store.d.ts +17 -3
  37. package/dist/src/store.js +14 -10
  38. package/package.json +1 -1
  39. package/src/agent-import.ts +2 -2
  40. package/src/agent-tools.ts +2 -2
  41. package/src/agents-md.ts +39 -14
  42. package/src/completions.ts +26 -3
  43. package/src/deploy.ts +59 -7
  44. package/src/evals.ts +45 -13
  45. package/src/flow-lint.ts +36 -0
  46. package/src/flow-patterns.ts +26 -13
  47. package/src/frontmatter-fields.ts +74 -3
  48. package/src/frontmatter-guard.ts +70 -0
  49. package/src/frontmatter-schema.ts +30 -4
  50. package/src/frontmatter-text.ts +109 -0
  51. package/src/judge-verdict.ts +52 -0
  52. package/src/matter.ts +112 -0
  53. package/src/network.ts +10 -6
  54. package/src/package.ts +8 -2
  55. package/src/provider-health.ts +2 -2
  56. package/src/run-container.ts +11 -1
  57. package/src/runner.ts +118 -37
  58. package/src/scan.ts +86 -8
  59. package/src/starter.ts +23 -0
  60. package/src/step-exec.ts +21 -8
  61. package/src/store.ts +23 -10
package/src/store.ts CHANGED
@@ -31,7 +31,7 @@ import { platform } from "./platform.ts";
31
31
  import { toLF, asRaw } from "./eol.ts";
32
32
  import type { TestEffect } from "./test-mode.ts";
33
33
  import type { OperatorEvent } from "./operator.ts";
34
- import matter from "./matter.ts";
34
+ import matter, { frontmatterErrorText, configMatter } from "./matter.ts";
35
35
  import { readAgentsMdKeys } from "./agents-md.ts";
36
36
 
37
37
  /**
@@ -44,7 +44,7 @@ import { readAgentsMdKeys } from "./agents-md.ts";
44
44
  * the runtime, and there is nothing to fail to import.
45
45
  */
46
46
  export function readFrontmatter(file: string): Record<string, unknown> {
47
- return matter(fs.readFileSync(file, "utf8")).data as Record<string, unknown>;
47
+ return configMatter(fs.readFileSync(file, "utf8")).data as Record<string, unknown>;
48
48
  }
49
49
  import { ownToolNames, legacyUseNames, retiredToolNames } from "./tool-names.ts";
50
50
  import { refNames } from "./refs.ts";
@@ -1602,7 +1602,7 @@ export function listAgents(tenant: string, workspace: string): AgentInfo[] {
1602
1602
  let data: Record<string, any> = {};
1603
1603
  let frontmatterError: string | undefined;
1604
1604
  try {
1605
- ({ data } = matter(fs.readFileSync(path.join(dir, name, "agent.md"), "utf8")));
1605
+ ({ data } = configMatter(fs.readFileSync(path.join(dir, name, "agent.md"), "utf8")));
1606
1606
  } catch (err) {
1607
1607
  frontmatterError = frontmatterErrorText(err);
1608
1608
  }
@@ -1652,12 +1652,9 @@ export function listAgents(tenant: string, workspace: string): AgentInfo[] {
1652
1652
  });
1653
1653
  }
1654
1654
 
1655
- /** The first line of a YAML parse error, with where it is: what a person
1656
- * needs to fix the file, without the parser's excerpt. */
1657
- export function frontmatterErrorText(err: unknown): string {
1658
- const msg = err instanceof Error ? err.message : String(err);
1659
- return `frontmatter does not parse — ${msg.split("\n")[0].trim()}. Quote a value that contains a colon followed by a space.`;
1660
- }
1655
+ // Kept here for callers that import it from the store; it lives in matter.ts
1656
+ // so the scanner can use it without the store.
1657
+ export { frontmatterErrorText };
1661
1658
 
1662
1659
  /** The body of a file whose frontmatter would not parse: what follows the
1663
1660
  * closing fence, so a flow's steps can still be read and shown. */
@@ -1839,7 +1836,7 @@ export function parseFlow(file: string, raw: string): FlowInfo {
1839
1836
  let content: string;
1840
1837
  let frontError: string | null = null;
1841
1838
  try {
1842
- ({ data, content } = matter(raw));
1839
+ ({ data, content } = configMatter(raw));
1843
1840
  } catch (err) {
1844
1841
  frontError = frontmatterErrorText(err);
1845
1842
  content = bodyAfterFrontmatter(raw);
@@ -3297,6 +3294,15 @@ export function sumAttempts(tries: StepAttempt[]): Pick<StepAttempt, "costUsd" |
3297
3294
  export { type TokenUsage, type PromptLayerRecord, tokensOf, sumTokens, cacheHitRate, measuredHitRate, runTokens, promptLayersChanged, promptCacheNote } from "./tokens.ts";
3298
3295
  import { sumTokens, type TokenUsage, type PromptLayerRecord } from "./tokens.ts";
3299
3296
 
3297
+ /** The marker rescueStep puts in a rescue's instruction; how a rescue record
3298
+ * written before `rescueOf` existed is still recognised. */
3299
+ export const RESCUE_MARKER = "<rescue>\nYou are taking this step over:";
3300
+
3301
+ /** Is this record an on-fail rescue rather than a step of the flow? */
3302
+ export function isRescueRecord(step: { rescueOf?: string; instruction?: string | null }): boolean {
3303
+ return !!step.rescueOf || (step.instruction ?? "").includes(RESCUE_MARKER);
3304
+ }
3305
+
3300
3306
  export interface StepRecord {
3301
3307
  agent: string;
3302
3308
  instruction: string;
@@ -3450,6 +3456,13 @@ export interface StepRecord {
3450
3456
  * actually executed in. Carried steps provide context and are never
3451
3457
  * billed again — the original run's ledger line already paid for them. */
3452
3458
  carriedFrom?: string;
3459
+ /** Set on an on-fail rescue record (runner.ts rescueStep): the agent of the
3460
+ * failed step it took over. A rescue is not a step of the flow: a resumed
3461
+ * drive must not launch it as one of its group, and a re-run must not
3462
+ * copy it as work (21 Oct 2026: one rerun carried 77 fixers as pending
3463
+ * steps). Records written before this field are recognised by their
3464
+ * instruction's `<rescue>` block instead — see isRescueRecord. */
3465
+ rescueOf?: string;
3453
3466
  /**
3454
3467
  * Sandbox seconds this step rented, and how many of them were cold start.
3455
3468
  * Set only on the isolated path — an in-process step rents nothing, so