@directive-run/ai 1.23.0 → 1.23.1

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 (74) hide show
  1. package/dist/anthropic.d.cts +1 -1
  2. package/dist/anthropic.d.ts +1 -1
  3. package/dist/{chunk-ESJQSOKJ.cjs → chunk-2FPL5W2H.cjs} +7 -7
  4. package/dist/{chunk-ESJQSOKJ.cjs.map → chunk-2FPL5W2H.cjs.map} +1 -1
  5. package/dist/{chunk-7KCLEIAG.js → chunk-4VP67W7L.js} +15 -15
  6. package/dist/chunk-4VP67W7L.js.map +1 -0
  7. package/dist/{chunk-CXWHLEBQ.js → chunk-EW77VF5K.js} +3 -3
  8. package/dist/{chunk-CXWHLEBQ.js.map → chunk-EW77VF5K.js.map} +1 -1
  9. package/dist/{chunk-GWWZXJOG.cjs → chunk-F73AKFDB.cjs} +15 -15
  10. package/dist/chunk-F73AKFDB.cjs.map +1 -0
  11. package/dist/{chunk-TEPEQE42.js → chunk-FSSCGRAM.js} +2 -2
  12. package/dist/chunk-FSSCGRAM.js.map +1 -0
  13. package/dist/{chunk-PEM2LPOC.cjs → chunk-JMG5GZAH.cjs} +4 -4
  14. package/dist/{chunk-PEM2LPOC.cjs.map → chunk-JMG5GZAH.cjs.map} +1 -1
  15. package/dist/{chunk-GTB6HTZV.js → chunk-MRKU3UXH.js} +2 -2
  16. package/dist/chunk-MRKU3UXH.js.map +1 -0
  17. package/dist/{chunk-MPMBFW2P.cjs → chunk-QMSLWAMH.cjs} +2 -2
  18. package/dist/chunk-QMSLWAMH.cjs.map +1 -0
  19. package/dist/{chunk-LOHC2KP5.js → chunk-XGOTVPN6.js} +3 -3
  20. package/dist/{chunk-LOHC2KP5.js.map → chunk-XGOTVPN6.js.map} +1 -1
  21. package/dist/{chunk-MDXDPECP.cjs → chunk-Y4A4UJPU.cjs} +2 -2
  22. package/dist/chunk-Y4A4UJPU.cjs.map +1 -0
  23. package/dist/{debug-timeline-L13P-U2I.d.ts → debug-timeline-C5Dzs2r_.d.ts} +1 -1
  24. package/dist/{debug-timeline-DpnRMnLU.d.cts → debug-timeline-Sc9cxgxV.d.cts} +1 -1
  25. package/dist/devtools.d.cts +5 -5
  26. package/dist/devtools.d.ts +5 -5
  27. package/dist/evals.d.cts +2 -2
  28. package/dist/evals.d.ts +2 -2
  29. package/dist/gemini.d.cts +1 -1
  30. package/dist/gemini.d.ts +1 -1
  31. package/dist/{guardrails-export-CxCOi3sd.d.ts → guardrails-export-BL8ozXSj.d.ts} +5 -5
  32. package/dist/{guardrails-export-D3pKHiPp.d.cts → guardrails-export-ByaYNGvG.d.cts} +5 -5
  33. package/dist/guardrails.cjs +1 -1
  34. package/dist/guardrails.d.cts +2 -2
  35. package/dist/guardrails.d.ts +2 -2
  36. package/dist/guardrails.js +1 -1
  37. package/dist/{health-monitor-C6xoXrQz.d.cts → health-monitor-C9v10_tj.d.cts} +1 -1
  38. package/dist/{health-monitor-qL9RNMH3.d.ts → health-monitor-J2eKmP--.d.ts} +1 -1
  39. package/dist/index.cjs +4 -4
  40. package/dist/index.d.cts +8 -8
  41. package/dist/index.d.ts +8 -8
  42. package/dist/index.js +1 -1
  43. package/dist/multi-agent-orchestrator-DUMT67N5.cjs +2 -0
  44. package/dist/{multi-agent-orchestrator-PHDHFCW3.cjs.map → multi-agent-orchestrator-DUMT67N5.cjs.map} +1 -1
  45. package/dist/{multi-agent-orchestrator-FIF4GLVR.js → multi-agent-orchestrator-ZZ63F75F.js} +2 -2
  46. package/dist/{multi-agent-orchestrator-FIF4GLVR.js.map → multi-agent-orchestrator-ZZ63F75F.js.map} +1 -1
  47. package/dist/multi-agent.cjs +1 -1
  48. package/dist/multi-agent.d.cts +6 -6
  49. package/dist/multi-agent.d.ts +6 -6
  50. package/dist/multi-agent.js +1 -1
  51. package/dist/ollama.d.cts +1 -1
  52. package/dist/ollama.d.ts +1 -1
  53. package/dist/openai.d.cts +1 -1
  54. package/dist/openai.d.ts +1 -1
  55. package/dist/{orchestrator-types-DxWn77qo.d.cts → orchestrator-types-BT-NIFOe.d.cts} +3 -3
  56. package/dist/{orchestrator-types-BxOJllSa.d.ts → orchestrator-types-DMuSD8Vq.d.ts} +3 -3
  57. package/dist/predicate.cjs +1 -1
  58. package/dist/predicate.d.cts +2 -2
  59. package/dist/predicate.d.ts +2 -2
  60. package/dist/predicate.js +1 -1
  61. package/dist/testing.cjs +1 -1
  62. package/dist/testing.d.cts +4 -4
  63. package/dist/testing.d.ts +4 -4
  64. package/dist/testing.js +1 -1
  65. package/dist/{types-DJ09LjZX.d.cts → types-6NoeLyrD.d.cts} +1 -0
  66. package/dist/{types-DJ09LjZX.d.ts → types-6NoeLyrD.d.ts} +1 -0
  67. package/package.json +2 -2
  68. package/dist/chunk-7KCLEIAG.js.map +0 -1
  69. package/dist/chunk-GTB6HTZV.js.map +0 -1
  70. package/dist/chunk-GWWZXJOG.cjs.map +0 -1
  71. package/dist/chunk-MDXDPECP.cjs.map +0 -1
  72. package/dist/chunk-MPMBFW2P.cjs.map +0 -1
  73. package/dist/chunk-TEPEQE42.js.map +0 -1
  74. package/dist/multi-agent-orchestrator-PHDHFCW3.cjs +0 -2
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/predicate-from-intent.ts"],"names":["djb2Hash","str","hash","i","hashStringSha256","raw","subtle","enc","buf","bytes","hex","b","PredicateFromIntentError","message","attempts","errors","lastRawOutput","SYSTEM_PROMPT_HEADER","renderKindForPrompt","node","nullableTag","k","v","buildSystemPrompt","kindMap","factPath","lines","path","ops","getOperatorsForKind","buildErrorFeedback","intent","pathsToShow","e","shown","remaining","validateOneAttempt","rawOutput","opts","parsed","extractJsonFromOutput","err","validatePredicate","schemaResult","validatePredicateAgainstSchema","DEFAULT_MAX_RETRIES","DEFAULT_MAX_PREDICATE_BYTES","DEFAULT_MAX_OPERATOR_COUNT","DEFAULT_MAX_ARRAY_OPERAND_LENGTH","predicateFromIntent","result","predicateFromIntentRaw","rawIntent","schema","runner","agent","maxRetries","maxPredicateBytes","maxOperatorCount","maxArrayOperandLength","redact","signal","getSchemaFieldKinds","systemPrompt","baseAgent","promptAgent","attempt","validateOpts","input","runResult","validated","buildSchemaSummary","buildDescription","summary","override","predicateToolSpecOpenAI","name","description","predicateToolSpecAnthropic","predicateToolSpec","predicateFromIntentWithProvenance","sanitizedIntent","model","predicateHashValue","predicateHash","intentHash","provenance"],"mappings":"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","file":"chunk-GTB6HTZV.js","sourcesContent":["/**\n * predicateFromIntent — let an LLM emit a typed FactPredicate as JSON,\n * structurally + semantically validated before it ever reaches your\n * constraint engine.\n *\n * Pipeline per call attempt:\n *\n * 1. Output-size check (reject before JSON.parse for DoS guard)\n * 2. JSON.parse via extractJsonFromOutput (handles surrounding prose)\n * 3. validatePredicate (structural: closed operator set, depth, JSON safety)\n * 4. Operator-count check\n * 5. validatePredicateAgainstSchema (semantic: operator-on-kind matrix)\n *\n * On any failure: a structured error message — including the offending\n * clause's path, the allowed operators for that fact's kind, and the\n * original schema kinds — is fed back to the LLM in the next attempt.\n *\n * Returns the validated FactPredicate. Throws PredicateFromIntentError\n * on retry exhaustion. NEVER returns a partial / unvalidated predicate.\n */\n\nimport {\n type FactPredicate,\n type SchemaKindNode,\n type SchemaValidationError,\n getOperatorsForKind,\n getSchemaFieldKinds,\n predicateHash,\n validatePredicate,\n validatePredicateAgainstSchema,\n} from \"@directive-run/core\";\n\nimport { extractJsonFromOutput } from \"./structured-output.js\";\nimport type { AgentLike, AgentRunner } from \"./types.js\";\n\n// ============================================================================\n// Hashing helpers\n// ============================================================================\n//\n// Provenance hashing has two flavors:\n//\n// - `predicateHash(spec)` — synchronous djb2 of a stable-stringified\n// predicate. Imported from `@directive-run/core` (the supported,\n// semver-stable surface). Two semantically-identical predicates emitted\n// with different whitespace / key-order produce the same hash. (N3)\n//\n// - `hashStringSha256(str)` — async SHA-256 via crypto.subtle when\n// available, djb2 fallback otherwise. Used for `intentHash` —\n// intents are free-form strings, no canonicalization to do.\n//\n\nfunction djb2Hash(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n\n return (hash >>> 0).toString(16);\n}\n\nasync function hashStringSha256(raw: string): Promise<string> {\n // Prefer crypto.subtle SHA-256 when available (browsers, Node 19+, workers).\n // Fall back to a sync djb2 — collision-prone, but adequate for telemetry\n // alongside the persisted predicate.\n try {\n const subtle = (globalThis as { crypto?: { subtle?: SubtleCrypto } }).crypto\n ?.subtle;\n if (subtle && typeof subtle.digest === \"function\") {\n const enc = new TextEncoder();\n const buf = await subtle.digest(\"SHA-256\", enc.encode(raw));\n const bytes = new Uint8Array(buf);\n let hex = \"\";\n for (const b of bytes) {\n hex += b.toString(16).padStart(2, \"0\");\n }\n\n return hex;\n }\n } catch {\n // fall through to djb2\n }\n\n return djb2Hash(raw);\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PredicateFromIntentOptions<_F = Record<string, unknown>> {\n /** Natural-language intent (untrusted user input — sanitize via `redact`). */\n intent: string;\n /**\n * Module schema (must expose builders with `_typeName` or `_kind`).\n * Pass either `{ facts: {...} }` or a bare `Record<string, builder>`.\n */\n schema: unknown;\n /** AgentRunner from `@directive-run/ai` adapters (createOpenAIRunner, etc.). */\n runner: AgentRunner;\n /**\n * Optional agent override. Default is `{ name: \"predicate-emitter\" }`\n * with our system prompt; pass `instructions` to append additional\n * context.\n */\n agent?: AgentLike;\n /**\n * Optional dotted-path namespace; useful for cross-module systems\n * where the LLM should emit a predicate over `auth.token` (default:\n * the schema's root facts).\n */\n factPath?: string;\n /** Max retries on validation failure. Default 3. */\n maxRetries?: number;\n /**\n * Hard byte cap on the LLM's raw output, BEFORE JSON.parse. Defaults\n * to 64 KiB. A larger predicate is rejected outright; protects\n * against multi-MB-payload DoS where the predicate is technically\n * structurally valid.\n */\n maxPredicateBytes?: number;\n /**\n * Hard cap on the number of operator clauses in the predicate.\n * Defaults to 256. Protects against `{ $any: [{ x: 1 }, … x100,000 ] }`\n * style operator-count exhaustion.\n */\n maxOperatorCount?: number;\n /**\n * Optional sanitizer applied to `intent` BEFORE it lands in the\n * system prompt. Useful for stripping or redacting user-controlled\n * content that looks like prompt-injection.\n */\n redact?: (intent: string) => string;\n /**\n * Hard cap on the length of each `$in` / `$nin` array operand the LLM\n * may emit. Defaults to 1000. Forwarded to\n * `validatePredicateAgainstSchema`'s `maxArrayOperandLength`.\n */\n maxArrayOperandLength?: number;\n /**\n * Optional `AbortSignal` for cooperative cancellation. (N6)\n *\n * The retry loop checks `signal.aborted` between attempts AND forwards\n * the signal into the runner call itself (`runner(agent, input, { signal })`).\n * Whether the in-flight LLM call honors the signal depends on the runner:\n * fetch-based adapters (the bundled OpenAI / Anthropic / Ollama runners)\n * thread it through to `fetch`, so the network call aborts mid-stream.\n * A custom runner that ignores the signal still delivers cancellation\n * at the next retry boundary.\n *\n * On abort: throws `Error(\"aborted\")`.\n *\n * NOTE: `predicateFromIntent` does NOT limit in-flight calls — callers\n * MUST wrap with a concurrency limiter (e.g. `p-limit`) to bound\n * fan-out under load.\n */\n signal?: AbortSignal;\n /**\n * When `true`, the {@link PredicateFromIntentProvenance} returned by\n * `predicateFromIntentWithProvenance` omits the raw `intent` string and\n * stores only the SHA-256 `intentHash`. Use this in PII-sensitive\n * contexts where the original intent must not be persisted. (M6)\n *\n * **Default `false` for back-compat.** For PII-sensitive deployments,\n * ALWAYS set `redactIntent: true` — the raw intent may contain\n * user-supplied content (names, emails, medical or financial details,\n * customer messages) that becomes a permanent record in\n * `provenance.intent`. The default is opt-in only because flipping it\n * now would silently strip diagnostic data from existing callers; v2\n * may flip this default (tracked in IDEAS.md).\n *\n * Pair with a `redact:` sanitizer when the intent itself must be\n * scrubbed BEFORE it lands in the LLM prompt — `redactIntent` controls\n * only what enters the provenance record, not what the LLM sees.\n */\n redactIntent?: boolean;\n}\n\nexport interface PredicateFromIntentDiagnostics<F = Record<string, unknown>> {\n /** The validated predicate (`null` if all retries failed). */\n predicate: FactPredicate<F> | null;\n /** Number of LLM calls actually made. */\n attempts: number;\n /** Errors encountered across all attempts (most recent last). */\n errors: ReadonlyArray<{\n attempt: number;\n reason: string;\n details?: readonly SchemaValidationError[];\n }>;\n /** The raw LLM output from the final attempt — useful for debugging. */\n lastRawOutput?: string;\n}\n\n/** Thrown by `predicateFromIntent` on retry exhaustion. `predicateFromIntentRaw` returns these as a diagnostics payload instead. */\nexport class PredicateFromIntentError extends Error {\n override readonly name = \"PredicateFromIntentError\";\n constructor(\n message: string,\n public readonly attempts: number,\n public readonly errors: ReadonlyArray<{\n attempt: number;\n reason: string;\n details?: readonly SchemaValidationError[];\n }>,\n public readonly lastRawOutput: string | undefined,\n ) {\n super(message);\n }\n}\n\n// ============================================================================\n// Prompt builder\n// ============================================================================\n\nconst SYSTEM_PROMPT_HEADER = `You emit ONLY a JSON object describing a Directive FactPredicate — no prose, no markdown fences, no explanation.\n\nA FactPredicate is a JSON tree of fact paths and operators:\n- Object form (preferred): { \"factName\": { \"$op\": operand }, \"otherFact\": { \"$op\": operand } }\n- Combinators: { \"$all\": [predicateA, predicateB] }, { \"$any\": [...] }, { \"$not\": predicate }\n- Bare value (equality shortcut): { \"factName\": value }\n\nOperator set (CLOSED — only these are valid):\n $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $exists, $between,\n $matches, $startsWith, $endsWith, $contains, $changed\nCombinators: $all, $any, $not\n\nEach operator is only valid for certain kinds (see below). Emit ONLY operators valid for the fact's kind.\n`;\n\nfunction renderKindForPrompt(node: SchemaKindNode): string {\n const nullableTag = node.nullable ? \" (nullable)\" : \"\";\n switch (node.kind) {\n case \"literal\":\n return `literal ${JSON.stringify(node.value)} (${node.primitive})${nullableTag}`;\n case \"enum\":\n return `enum ${JSON.stringify(node.values)} (${node.primitive})${nullableTag}`;\n case \"array\":\n return `array of ${renderKindForPrompt(node.element)}${nullableTag}`;\n case \"tuple\":\n return `tuple [${node.elements.map(renderKindForPrompt).join(\", \")}]${nullableTag}`;\n case \"object\":\n return `object { ${Object.entries(node.shape)\n .map(([k, v]) => `${k}: ${renderKindForPrompt(v)}`)\n .join(\", \")} }${nullableTag}`;\n case \"record\":\n return `record<string, ${renderKindForPrompt(node.value)}>${nullableTag}`;\n case \"union\":\n return `union (${node.members.map(renderKindForPrompt).join(\" | \")})${nullableTag}`;\n case \"branded\":\n return `branded(${renderKindForPrompt(node.inner)})${nullableTag}`;\n default:\n return `${node.kind}${nullableTag}`;\n }\n}\n\nfunction buildSystemPrompt(\n kindMap: Map<string, SchemaKindNode>,\n factPath?: string,\n): string {\n const lines: string[] = [SYSTEM_PROMPT_HEADER];\n\n lines.push(\"\\nFacts in this schema (path → kind → allowed operators):\");\n for (const [path, node] of kindMap.entries()) {\n if (factPath && !path.startsWith(factPath)) continue;\n const ops = getOperatorsForKind(node);\n lines.push(\n ` ${path}: ${renderKindForPrompt(node)} — allowed: ${ops.join(\", \")}`,\n );\n }\n if (factPath) {\n lines.push(\n `\\nThe user intent will be over the namespace \"${factPath}\". Use only facts at or below that path.`,\n );\n }\n\n lines.push(\n '\\nRespond with ONLY the JSON predicate object. No prose. No markdown fences. No \"Here is...\".',\n );\n\n return lines.join(\"\\n\");\n}\n\nfunction buildErrorFeedback(\n intent: string,\n kindMap: Map<string, SchemaKindNode>,\n errors: readonly SchemaValidationError[] | string,\n): string {\n const lines: string[] = [];\n lines.push(\n \"Your previous response was rejected. Original intent (still applies):\",\n );\n lines.push(` ${intent}`);\n\n // M16: When we have structured errors, scope the schema reminder to only\n // the offending fact paths instead of dumping the full schema. Falls back\n // to the full schema for non-structural failures (string errors).\n let pathsToShow: Set<string> | null = null;\n\n if (typeof errors === \"string\") {\n lines.push(`\\nReason: ${errors}`);\n } else {\n lines.push(\"\\nValidation errors (fix every one):\");\n pathsToShow = new Set();\n for (const e of errors) {\n lines.push(` - path \"${e.path}\", op \"${e.op}\": ${e.reason}`);\n if (e.allowedOps && e.allowedOps.length > 0) {\n lines.push(\n ` → allowed operators for this fact: ${e.allowedOps.join(\", \")}`,\n );\n }\n // Collect every path mentioned by an error. If a path isn't in the\n // kindMap (unknown fact), the offending key may be a dotted prefix of\n // a real fact — include the closest known ancestor too.\n pathsToShow.add(e.path);\n }\n }\n\n lines.push(\"\\nSchema reminder:\");\n if (pathsToShow && pathsToShow.size > 0) {\n let shown = 0;\n for (const path of pathsToShow) {\n const node = kindMap.get(path);\n if (node) {\n const ops = getOperatorsForKind(node);\n lines.push(\n ` ${path}: ${renderKindForPrompt(node)} — allowed: ${ops.join(\", \")}`,\n );\n shown++;\n } else {\n lines.push(\n ` ${path}: (not in schema — pick from the available facts below)`,\n );\n }\n }\n const remaining = kindMap.size - shown;\n if (remaining > 0) {\n lines.push(\n ` …and ${remaining} more fact(s) available — ask if you need the full list.`,\n );\n }\n } else {\n for (const [path, node] of kindMap.entries()) {\n const ops = getOperatorsForKind(node);\n lines.push(\n ` ${path}: ${renderKindForPrompt(node)} — allowed: ${ops.join(\", \")}`,\n );\n }\n }\n\n lines.push(\"\\nEmit ONLY a corrected JSON FactPredicate object. No prose.\");\n\n return lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Validation pipeline (one attempt)\n// ============================================================================\n\nfunction validateOneAttempt(\n rawOutput: string,\n kindMap: Map<string, SchemaKindNode>,\n opts: {\n maxPredicateBytes: number;\n maxOperatorCount: number;\n maxArrayOperandLength: number;\n },\n):\n | { ok: true; predicate: unknown }\n | { ok: false; reason: string; details?: readonly SchemaValidationError[] } {\n // 1. Byte cap (pre-parse — kills 10MB-payload DoS)\n if (rawOutput.length > opts.maxPredicateBytes) {\n return {\n ok: false,\n reason: `Output exceeded maxPredicateBytes=${opts.maxPredicateBytes} (got ${rawOutput.length}). Emit a smaller predicate.`,\n };\n }\n\n // 2. JSON parse (handles surrounding prose)\n let parsed: unknown;\n try {\n parsed = extractJsonFromOutput(rawOutput);\n } catch (err) {\n return {\n ok: false,\n reason: `Could not extract JSON from output: ${\n err instanceof Error ? err.message : String(err)\n }`,\n };\n }\n\n // 3. Structural validation (closed operator set, depth, JSON-safety)\n try {\n validatePredicate(parsed);\n } catch (err) {\n return {\n ok: false,\n reason: `Structural validation failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n };\n }\n\n // 4 + 5. Operator-count cap + array-operand cap + schema validation\n const schemaResult = validatePredicateAgainstSchema(parsed, kindMap, {\n maxOperatorCount: opts.maxOperatorCount,\n maxArrayOperandLength: opts.maxArrayOperandLength,\n });\n\n if (!schemaResult.ok) {\n return {\n ok: false,\n reason: `Predicate has ${schemaResult.errors.length} schema-validation error(s).`,\n details: schemaResult.errors,\n };\n }\n\n return { ok: true, predicate: parsed };\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_MAX_PREDICATE_BYTES = 65_536; // 64 KiB\nconst DEFAULT_MAX_OPERATOR_COUNT = 256;\nconst DEFAULT_MAX_ARRAY_OPERAND_LENGTH = 1000;\n\n/**\n * Ask an LLM to emit a FactPredicate matching the user's intent, then\n * validate it structurally + semantically before returning. On validation\n * failure, retries with structured error feedback in the next prompt.\n *\n * Throws {@link PredicateFromIntentError} on retry exhaustion. NEVER\n * returns a partial / unvalidated predicate.\n *\n * **Rate limiting:** this function does NOT limit in-flight calls. Wrap\n * with a concurrency limiter (e.g. `p-limit` / `Bottleneck`) before\n * exposing it to user-driven traffic. Pass an `AbortSignal` via `opts.signal`\n * for cooperative cancellation between retry attempts.\n *\n * @example\n * ```ts\n * import { createOpenAIRunner } from \"@directive-run/ai/openai\";\n * import { predicateFromIntent } from \"@directive-run/ai\";\n *\n * const runner = createOpenAIRunner({ apiKey, model: \"gpt-4o-mini\" });\n *\n * const predicate = await predicateFromIntent({\n * intent: \"checkout is unblocked when the cart total is at least 50\",\n * schema: myModule.schema,\n * runner,\n * });\n * // → { cartTotal: { $gte: 50 } }\n * ```\n */\nexport async function predicateFromIntent<F = Record<string, unknown>>(\n opts: PredicateFromIntentOptions<F>,\n): Promise<FactPredicate<F>> {\n const result = await predicateFromIntentRaw(opts);\n if (result.predicate === null) {\n throw new PredicateFromIntentError(\n `[Directive] predicateFromIntent: failed after ${result.attempts} attempt(s). Last error: ${\n result.errors[result.errors.length - 1]?.reason ?? \"unknown\"\n }`,\n result.attempts,\n result.errors,\n result.lastRawOutput,\n );\n }\n\n return result.predicate;\n}\n\n/**\n * Lower-level variant — returns the validated predicate (or null) plus\n * full diagnostics. Use when you want to surface validation telemetry,\n * preview the LLM's last raw output, or display per-attempt errors in\n * a UI.\n */\nexport async function predicateFromIntentRaw<F = Record<string, unknown>>(\n opts: PredicateFromIntentOptions<F>,\n): Promise<PredicateFromIntentDiagnostics<F>> {\n const {\n intent: rawIntent,\n schema,\n runner,\n agent,\n factPath,\n maxRetries = DEFAULT_MAX_RETRIES,\n maxPredicateBytes = DEFAULT_MAX_PREDICATE_BYTES,\n maxOperatorCount = DEFAULT_MAX_OPERATOR_COUNT,\n maxArrayOperandLength = DEFAULT_MAX_ARRAY_OPERAND_LENGTH,\n redact,\n signal,\n } = opts;\n\n if (typeof rawIntent !== \"string\" || rawIntent.length === 0) {\n throw new Error(\n \"[Directive] predicateFromIntent: `intent` must be a non-empty string.\",\n );\n }\n\n const intent = redact ? redact(rawIntent) : rawIntent;\n const kindMap = getSchemaFieldKinds(schema);\n\n if (kindMap.size === 0) {\n throw new Error(\n \"[Directive] predicateFromIntent: schema has no introspectable facts. Pass a module schema or a bare facts record.\",\n );\n }\n\n const systemPrompt = buildSystemPrompt(kindMap, factPath);\n const baseAgent: AgentLike = agent ?? { name: \"predicate-emitter\" };\n const promptAgent: AgentLike = {\n ...baseAgent,\n instructions: `${baseAgent.instructions ?? \"\"}\\n\\n${systemPrompt}`.trim(),\n };\n\n const errors: Array<{\n attempt: number;\n reason: string;\n details?: readonly SchemaValidationError[];\n }> = [];\n\n let lastRawOutput: string | undefined;\n let attempt = 0;\n const validateOpts = {\n maxPredicateBytes,\n maxOperatorCount,\n maxArrayOperandLength,\n };\n\n while (attempt < maxRetries + 1) {\n // M7: cooperative cancellation — bail between attempts when aborted.\n if (signal?.aborted) {\n throw new Error(\"aborted\");\n }\n attempt++;\n const input =\n attempt === 1\n ? `Intent: ${intent}\\n\\nEmit the predicate now.`\n : buildErrorFeedback(\n intent,\n kindMap,\n errors[errors.length - 1]!.details ??\n errors[errors.length - 1]!.reason,\n );\n\n let runResult: Awaited<ReturnType<typeof runner>>;\n try {\n // (N6) Forward the abort signal to the runner so in-flight LLM\n // calls can be cancelled mid-fetch. fetch-based adapters honor\n // this via the underlying fetch's `signal` option. Custom runners\n // that ignore the third arg fall back to between-retry cancellation.\n runResult = await runner(promptAgent, input, { signal });\n } catch (err) {\n // If the abort happened during the in-flight call (and the runner\n // honored it), surface that as a plain `Error(\"aborted\")` rather\n // than burning a retry attempt on a cancellation error.\n if (signal?.aborted) {\n throw new Error(\"aborted\");\n }\n errors.push({\n attempt,\n reason: `LLM runner threw: ${err instanceof Error ? err.message : String(err)}`,\n });\n continue;\n }\n\n const rawOutput =\n typeof runResult.output === \"string\"\n ? runResult.output\n : JSON.stringify(runResult.output);\n lastRawOutput = rawOutput;\n\n const validated = validateOneAttempt(rawOutput, kindMap, validateOpts);\n\n if (validated.ok) {\n return {\n predicate: validated.predicate as FactPredicate<F>,\n attempts: attempt,\n errors,\n lastRawOutput,\n };\n }\n\n errors.push({\n attempt,\n reason: validated.reason,\n details: validated.details,\n });\n }\n\n return {\n predicate: null,\n attempts: attempt,\n errors,\n lastRawOutput,\n };\n}\n\n// ============================================================================\n// Tool-spec presets (OpenAI + Anthropic function-calling)\n// ============================================================================\n\nexport interface PredicateToolSpecOptions {\n /** Tool name. Default `\"emit_predicate\"`. */\n name?: string;\n /** Tool description. Default: a one-liner describing predicate emission. */\n description?: string;\n /** Optional dotted-path namespace to restrict the tool's scope. */\n factPath?: string;\n}\n\n/**\n * Anthropic Messages API tool shape. Drop into the `tools: [...]` array.\n * Anthropic's API expects `input_schema` at the top level of the tool.\n */\nexport interface PredicateToolSpecAnthropic {\n name: string;\n description: string;\n input_schema: {\n type: \"object\";\n properties: { predicate: { type: \"object\" } };\n required: [\"predicate\"];\n };\n /** Human-readable schema description — embed in your tool's \"description\" if your provider concatenates them. */\n schemaSummary: string;\n}\n\n/**\n * OpenAI Chat Completions / Responses API tool shape. Drop into the\n * `tools: [...]` array. OpenAI nests the function payload under\n * `function: { name, description, parameters }`.\n */\nexport interface PredicateToolSpecOpenAI {\n type: \"function\";\n function: {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: { predicate: { type: \"object\" } };\n required: [\"predicate\"];\n };\n };\n /** Human-readable schema description — embed in your tool's \"description\" if your provider concatenates them. */\n schemaSummary: string;\n}\n\n/**\n * @deprecated Use {@link PredicateToolSpecAnthropic} (or\n * {@link PredicateToolSpecOpenAI}) directly. Kept as an alias for the\n * pre-split shape that v1.12.x callers depend on; identical to\n * `PredicateToolSpecAnthropic`.\n */\nexport type PredicateToolSpec = PredicateToolSpecAnthropic;\n\nfunction buildSchemaSummary(\n schema: unknown,\n factPath: string | undefined,\n): string {\n const kindMap = getSchemaFieldKinds(schema);\n const lines: string[] = [];\n for (const [path, node] of kindMap.entries()) {\n if (factPath && !path.startsWith(factPath)) continue;\n const ops = getOperatorsForKind(node);\n lines.push(\n `${path}: ${renderKindForPrompt(node)} — ops: ${ops.join(\", \")}`,\n );\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction buildDescription(summary: string, override?: string): string {\n return (\n override ??\n `Emit a Directive FactPredicate (JSON tree of facts and operators) matching the user's intent. Schema:\\n${summary}`\n );\n}\n\n/**\n * OpenAI Chat Completions / Responses API tool spec for predicate\n * emission. Drop the result into your `tools: [...]` array; the model\n * will be told to emit a predicate matching this schema.\n *\n * @example\n * ```ts\n * const tool = predicateToolSpecOpenAI(myModule.schema, { name: \"set_checkout_rule\" });\n *\n * await openai.chat.completions.create({\n * model: \"gpt-4o-mini\",\n * tools: [tool],\n * messages: [...],\n * });\n * ```\n */\nexport function predicateToolSpecOpenAI(\n schema: unknown,\n opts: PredicateToolSpecOptions = {},\n): PredicateToolSpecOpenAI {\n const summary = buildSchemaSummary(schema, opts.factPath);\n const name = opts.name ?? \"emit_predicate\";\n const description = buildDescription(summary, opts.description);\n\n return {\n type: \"function\",\n function: {\n name,\n description,\n parameters: {\n type: \"object\",\n properties: { predicate: { type: \"object\" } },\n required: [\"predicate\"],\n },\n },\n schemaSummary: summary,\n };\n}\n\n/**\n * Anthropic Messages API tool spec for predicate emission. Drop the\n * result into your `tools: [...]` array; the model will be told to emit\n * a predicate matching this schema.\n *\n * @example\n * ```ts\n * const tool = predicateToolSpecAnthropic(myModule.schema, { name: \"set_checkout_rule\" });\n *\n * await anthropic.messages.create({\n * model: \"claude-3-5-sonnet-latest\",\n * tools: [tool],\n * messages: [...],\n * });\n * ```\n */\nexport function predicateToolSpecAnthropic(\n schema: unknown,\n opts: PredicateToolSpecOptions = {},\n): PredicateToolSpecAnthropic {\n const summary = buildSchemaSummary(schema, opts.factPath);\n const name = opts.name ?? \"emit_predicate\";\n const description = buildDescription(summary, opts.description);\n\n return {\n name,\n description,\n input_schema: {\n type: \"object\",\n properties: { predicate: { type: \"object\" } },\n required: [\"predicate\"],\n },\n schemaSummary: summary,\n };\n}\n\n/**\n * @deprecated Use {@link predicateToolSpecAnthropic} (or\n * {@link predicateToolSpecOpenAI}) directly. Back-compat alias for\n * v1.12.x callers — emits the Anthropic shape, unchanged.\n */\nexport function predicateToolSpec(\n schema: unknown,\n opts: PredicateToolSpecOptions = {},\n): PredicateToolSpec {\n return predicateToolSpecAnthropic(schema, opts);\n}\n\n// ============================================================================\n// Provenance (M24)\n// ============================================================================\n\nexport interface PredicateFromIntentProvenance {\n /**\n * Resolved model name when the caller passes `agent: { model }`,\n * otherwise `\"unknown\"`.\n *\n * NOTE: most callers omit `agent` (the default `predicate-emitter`\n * agent has no model field set), so `model` is `\"unknown\"` by default.\n * v1 does NOT read provider-detected model strings from `RunResult` —\n * that requires every adapter to surface `runResult.model`, which the\n * current `AgentRunner` contract does not. Tracked for v2; callers who\n * need provider attribution today should pass `agent: { name, model: \"...\" }`.\n */\n readonly model: string;\n /**\n * Sanitized intent string actually sent to the LLM (post-redact). When\n * `redactIntent: true` was passed, this field is omitted entirely — only\n * `intentHash` is populated.\n */\n readonly intent?: string;\n /**\n * SHA-256 hex hash of the sanitized intent string (or djb2 fallback\n * when `crypto.subtle` is unavailable). Always present — even when\n * `intent` is omitted via `redactIntent`. (M6)\n */\n readonly intentHash: string;\n /** Number of LLM calls that ran before the final predicate was accepted. */\n readonly attemptCount: number;\n /** ISO timestamp when the predicate was returned. */\n readonly emittedAt: string;\n /**\n * Hash of the VALIDATED predicate (canonicalized via stableStringify\n * before hashing). Two semantically-identical predicates emitted with\n * different whitespace or key order produce the SAME `predicateHash`.\n * Sufficient as a tamper-evident pointer alongside the persisted\n * predicate. (N3)\n *\n * Renamed from `rawOutputHash` in v1.13.x — the old name hashed the\n * raw LLM output string, which made two whitespace-different responses\n * for the same logical predicate hash differently. Callers persisting\n * the old `rawOutputHash` value should re-derive it from the stored\n * predicate using `hashObject(predicate)` from `@directive-run/core/internals`.\n */\n readonly predicateHash: string;\n}\n\nexport interface PredicateFromIntentWithProvenanceResult<\n F = Record<string, unknown>,\n> {\n readonly predicate: FactPredicate<F>;\n readonly provenance: PredicateFromIntentProvenance;\n}\n\n/**\n * Like {@link predicateFromIntent} but additionally returns a structured\n * provenance record — the model name, sanitized intent (or its hash),\n * attempt count, timestamp, and a canonical hash of the validated\n * predicate.\n *\n * **Production deployments MUST persist the provenance record alongside\n * the predicate.** Without it, auditing \"where did this rule come from?\"\n * becomes guesswork.\n *\n * Throws {@link PredicateFromIntentError} on retry exhaustion — same\n * semantics as the un-provenanced variant.\n *\n * **PII guidance (M6):** pass `redactIntent: true` to omit the raw\n * intent from the provenance record and persist only the `intentHash`.\n * Useful when the intent itself is sensitive (medical, financial,\n * customer messages, etc.).\n *\n * **Hash semantics (N3):**\n * - `predicateHash` hashes the VALIDATED predicate object via stable\n * stringification — two whitespace-different LLM outputs that parse to\n * the same predicate produce the same hash.\n * - `intentHash` hashes the sanitized intent STRING (SHA-256 when\n * available, djb2 fallback).\n *\n * @example\n * ```ts\n * const { predicate, provenance } = await predicateFromIntentWithProvenance({\n * intent: \"block checkout when cart > 10k\",\n * schema: checkoutModule.schema,\n * runner,\n * agent: { name: \"predicate-emitter\", model: \"gpt-4o-mini\" },\n * redactIntent: false, // default: store both intent + intentHash\n * });\n *\n * await db.predicates.insert({\n * predicate,\n * model: provenance.model,\n * intent: provenance.intent, // omitted when redactIntent: true\n * intentHash: provenance.intentHash,\n * emittedAt: provenance.emittedAt,\n * predicateHash: provenance.predicateHash,\n * attempts: provenance.attemptCount,\n * });\n * ```\n */\nexport async function predicateFromIntentWithProvenance<\n F = Record<string, unknown>,\n>(\n opts: PredicateFromIntentOptions<F>,\n): Promise<PredicateFromIntentWithProvenanceResult<F>> {\n const raw = await predicateFromIntentRaw(opts);\n if (raw.predicate === null) {\n throw new PredicateFromIntentError(\n `[Directive] predicateFromIntentWithProvenance: failed after ${raw.attempts} attempt(s). Last error: ${\n raw.errors[raw.errors.length - 1]?.reason ?? \"unknown\"\n }`,\n raw.attempts,\n raw.errors,\n raw.lastRawOutput,\n );\n }\n\n const sanitizedIntent = opts.redact ? opts.redact(opts.intent) : opts.intent;\n const model = opts.agent?.model ?? \"unknown\";\n // (N3) Hash the VALIDATED predicate (stable canonical form), not the\n // raw LLM output — two semantically-identical responses with different\n // whitespace / key order produce the same hash. Uses the supported\n // public `predicateHash` helper from `@directive-run/core`.\n const predicateHashValue = predicateHash(raw.predicate);\n // (M6) Always hash the intent; raw intent string is included only when\n // `redactIntent` is not set.\n const intentHash = await hashStringSha256(sanitizedIntent);\n\n const provenance: PredicateFromIntentProvenance = opts.redactIntent\n ? {\n model,\n intentHash,\n attemptCount: raw.attempts,\n emittedAt: new Date().toISOString(),\n predicateHash: predicateHashValue,\n }\n : {\n model,\n intent: sanitizedIntent,\n intentHash,\n attemptCount: raw.attempts,\n emittedAt: new Date().toISOString(),\n predicateHash: predicateHashValue,\n };\n\n return {\n predicate: raw.predicate,\n provenance,\n };\n}\n"]}