@cloc/provider-ai-sdk 0.1.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 (82) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agent.d.ts +93 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +359 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/config.d.ts +85 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +101 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/gateway.d.ts +74 -0
  11. package/dist/gateway.d.ts.map +1 -0
  12. package/dist/gateway.js +96 -0
  13. package/dist/gateway.js.map +1 -0
  14. package/dist/index.d.ts +47 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +46 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/memory-tool.d.ts +63 -0
  19. package/dist/memory-tool.d.ts.map +1 -0
  20. package/dist/memory-tool.js +183 -0
  21. package/dist/memory-tool.js.map +1 -0
  22. package/dist/output.d.ts +49 -0
  23. package/dist/output.d.ts.map +1 -0
  24. package/dist/output.js +41 -0
  25. package/dist/output.js.map +1 -0
  26. package/dist/plugin.d.ts +74 -0
  27. package/dist/plugin.d.ts.map +1 -0
  28. package/dist/plugin.js +86 -0
  29. package/dist/plugin.js.map +1 -0
  30. package/dist/request.d.ts +82 -0
  31. package/dist/request.d.ts.map +1 -0
  32. package/dist/request.js +80 -0
  33. package/dist/request.js.map +1 -0
  34. package/dist/safety.d.ts +54 -0
  35. package/dist/safety.d.ts.map +1 -0
  36. package/dist/safety.js +0 -0
  37. package/dist/safety.js.map +1 -0
  38. package/dist/secrets.d.ts +51 -0
  39. package/dist/secrets.d.ts.map +1 -0
  40. package/dist/secrets.js +47 -0
  41. package/dist/secrets.js.map +1 -0
  42. package/dist/skills-loader.d.ts +76 -0
  43. package/dist/skills-loader.d.ts.map +1 -0
  44. package/dist/skills-loader.js +99 -0
  45. package/dist/skills-loader.js.map +1 -0
  46. package/dist/stream.d.ts +58 -0
  47. package/dist/stream.d.ts.map +1 -0
  48. package/dist/stream.js +59 -0
  49. package/dist/stream.js.map +1 -0
  50. package/dist/tokens.d.ts +17 -0
  51. package/dist/tokens.d.ts.map +1 -0
  52. package/dist/tokens.js +17 -0
  53. package/dist/tokens.js.map +1 -0
  54. package/dist/tool-loop.d.ts +98 -0
  55. package/dist/tool-loop.d.ts.map +1 -0
  56. package/dist/tool-loop.js +210 -0
  57. package/dist/tool-loop.js.map +1 -0
  58. package/dist/trace.d.ts +78 -0
  59. package/dist/trace.d.ts.map +1 -0
  60. package/dist/trace.js +39 -0
  61. package/dist/trace.js.map +1 -0
  62. package/dist/validate.d.ts +54 -0
  63. package/dist/validate.d.ts.map +1 -0
  64. package/dist/validate.js +81 -0
  65. package/dist/validate.js.map +1 -0
  66. package/package.json +55 -0
  67. package/src/agent.ts +487 -0
  68. package/src/config.ts +147 -0
  69. package/src/gateway.ts +126 -0
  70. package/src/index.ts +101 -0
  71. package/src/memory-tool.ts +219 -0
  72. package/src/output.ts +67 -0
  73. package/src/plugin.ts +123 -0
  74. package/src/request.ts +178 -0
  75. package/src/safety.ts +0 -0
  76. package/src/secrets.ts +71 -0
  77. package/src/skills-loader.ts +153 -0
  78. package/src/stream.ts +80 -0
  79. package/src/tokens.ts +82 -0
  80. package/src/tool-loop.ts +268 -0
  81. package/src/trace.ts +87 -0
  82. package/src/validate.ts +118 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · safety.ts — data-not-instructions + provenance pass-through
3
+ * (FR-015, NFR-003, Constitution Principle 5).
4
+ *
5
+ * Grounded facts and EVERY tool result are DATA, never instructions: they are framed as inert
6
+ * data blocks in the prompt and never alter the loop's control flow. An injected string like
7
+ * "ignore previous instructions and …" arriving through grounding or a tool result is rendered
8
+ * as quoted data, not executed. Provenance attached to each fact is carried THROUGH to the
9
+ * Output so nothing ungrounded is ever asserted as fact (NFR-003).
10
+ */
11
+ /** Provenance for one grounded fact — where the asserted value came from (NFR-003). */
12
+ export interface Provenance {
13
+ /** e.g. "jobs.md", a DataSource id, a tool name. */
14
+ source: string;
15
+ /** Data version / blob ref for replay (§10 keys). */
16
+ ref?: string;
17
+ }
18
+ /** One grounded fact: an opaque value plus its provenance. */
19
+ export interface GroundedFact {
20
+ value: unknown;
21
+ provenance: Provenance;
22
+ }
23
+ /** The grounded context handed to a turn — DATA, never instructions (FR-015). */
24
+ export interface GroundedContext {
25
+ facts: ReadonlyArray<GroundedFact>;
26
+ }
27
+ /**
28
+ * Frame grounded facts as an inert, clearly-delimited DATA block for the model prompt. The
29
+ * delimiters + the explicit "treat as data" instruction are the control boundary: content
30
+ * inside is never interpreted as instructions (FR-015, Principle 5). Values are JSON-encoded so
31
+ * embedded prose cannot break out of the block.
32
+ *
33
+ * Hardening: the `source`/`ref` provenance annotations are model-influenced strings (they may flow
34
+ * from a connected source name), so the few characters that could forge a fact delimiter or line
35
+ * break (`[ ] \n \r \\`) are neutralized before interpolation — a `source` like `x] do this [` can
36
+ * no longer break out of its `[fact … source=…]` envelope (defense-in-depth, Principle 5). For a
37
+ * normal identifier like `jobs.md` this is a NO-OP, so existing output is unchanged.
38
+ */
39
+ export declare function frameGroundingAsData(ctx: GroundedContext): string;
40
+ /**
41
+ * Frame a tool RESULT as data before it re-enters the loop (FR-003 feedback path). Same rule:
42
+ * the result is observed as data, it does not steer control flow (FR-015).
43
+ *
44
+ * Hardening: the tool NAME rides in an XML attribute, so it is attribute-escaped — a crafted name
45
+ * like `x"><instruction>` can no longer break out of the `tool="…"` attribute or close the tag
46
+ * early. The result value is JSON-encoded (angle brackets survive only as quoted JSON; Principle 5).
47
+ */
48
+ export declare function frameToolResultAsData(tool: string, result: unknown): string;
49
+ /**
50
+ * The collected provenance to attach to the Output, deduplicated by source+ref so the Output
51
+ * carries the lineage of every grounded fact it drew on (NFR-003, data-model §3).
52
+ */
53
+ export declare function collectProvenance(ctx: GroundedContext): Provenance[];
54
+ //# sourceMappingURL=safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,uFAAuF;AACvF,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAgBjE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAE3E;AAsBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,UAAU,EAAE,CAUpE"}
package/dist/safety.js ADDED
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety.js","sourceRoot":"","sources":["../src/safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAqBH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAoB;IACvD,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG;YAC1B,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YAC1F,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,WAAW,CAAC,GAAG,CAAC,aAAa,GAAG,KAAK,OAAO,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IACH,OAAO;QACL,iBAAiB;QACjB,2EAA2E;QAC3E,sFAAsF;QACtF,GAAG,KAAK;QACR,kBAAkB;KACnB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,MAAe;IACjE,OAAO,sBAAsB,UAAU,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC;AACrF,CAAC;AAED,6FAA6F;AAC7F,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAAa;IACzC,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CACzC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CACnD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAoB;IACpD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+FAA+F;AAC/F,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · secrets.ts — the secrets-by-name boundary (FR-009, NFR-005, §73.2).
3
+ *
4
+ * The gateway credential is referenced BY NAME (`config.secretRef`) and resolved LAZILY through
5
+ * an injected secrets-provider handle — never read from `cloc.yml` / `AgentConfig`. The adapter
6
+ * declares a LEAST-PRIVILEGE `needs` descriptor (the gateway network host + the named secret);
7
+ * the kernel grants only those (Constitution Principle 9).
8
+ *
9
+ * This module owns no secrets-provider implementation — that is a host integration (env/vault/
10
+ * KMS). It mirrors the kernel's `SecretHandle` shape structurally so the kernel-supplied handle
11
+ * satisfies it without a runtime import of @cloc/kernel.
12
+ */
13
+ import type { AgentConfig } from "./config.js";
14
+ /** The gateway host the adapter talks to (the only network egress it `needs`). */
15
+ export declare const GATEWAY_HOST = "ai-gateway.vercel.sh";
16
+ /**
17
+ * A live, by-name handle to ONE secret. Structurally identical to @cloc/kernel's `SecretHandle`
18
+ * — the kernel passes its handle straight in. Resolution is lazy; the value never touches config.
19
+ */
20
+ export interface SecretHandle {
21
+ readonly name: string;
22
+ resolve(): Promise<string | undefined>;
23
+ }
24
+ /**
25
+ * The least-privilege resource needs this plugin declares (FR-009, NFR-005). The kernel reads
26
+ * this off the manifest and grants exactly: egress to the gateway host + the one named secret.
27
+ */
28
+ export interface AgentNeeds {
29
+ /** Network hosts the adapter may reach — hosted-first, gateway only. */
30
+ net: readonly string[];
31
+ /** Secret NAMES the adapter may resolve — exactly the configured `secretRef`. */
32
+ secrets: readonly string[];
33
+ }
34
+ /** Build the least-privilege `needs` descriptor for a given config (gateway host + secretRef). */
35
+ export declare function needsFor(config: AgentConfig): AgentNeeds;
36
+ /**
37
+ * Resolve the gateway credential BY NAME through the injected handle. Returns `undefined` when
38
+ * the handle denies it (undeclared / not present) — callers MUST treat a missing credential as a
39
+ * boot/config error, never fabricate one. The value is read here and nowhere else (FR-009).
40
+ *
41
+ * An empty / whitespace-only resolution is treated as ABSENT (returns `undefined`): a blank env var
42
+ * is a misconfiguration, not a usable key — surfacing it as `undefined` lets the gateway fall back
43
+ * to ambient/OIDC resolution rather than sending an empty Bearer token (defense-in-depth, NFR-005).
44
+ */
45
+ export declare function resolveGatewayKey(handle: SecretHandle): Promise<string | undefined>;
46
+ /**
47
+ * Guard: assert no secret VALUE leaked into the config surface. `parseAgentConfig` already
48
+ * rejects an inlined value in `secretRef`; this is a belt-and-braces check usable at boot.
49
+ */
50
+ export declare function assertNoInlineSecret(config: AgentConfig): void;
51
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,kFAAkF;AAClF,eAAO,MAAM,YAAY,yBAAyB,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IACvB,iFAAiF;IACjF,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAExD;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAKzF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAO9D"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · secrets.ts — the secrets-by-name boundary (FR-009, NFR-005, §73.2).
3
+ *
4
+ * The gateway credential is referenced BY NAME (`config.secretRef`) and resolved LAZILY through
5
+ * an injected secrets-provider handle — never read from `cloc.yml` / `AgentConfig`. The adapter
6
+ * declares a LEAST-PRIVILEGE `needs` descriptor (the gateway network host + the named secret);
7
+ * the kernel grants only those (Constitution Principle 9).
8
+ *
9
+ * This module owns no secrets-provider implementation — that is a host integration (env/vault/
10
+ * KMS). It mirrors the kernel's `SecretHandle` shape structurally so the kernel-supplied handle
11
+ * satisfies it without a runtime import of @cloc/kernel.
12
+ */
13
+ /** The gateway host the adapter talks to (the only network egress it `needs`). */
14
+ export const GATEWAY_HOST = "ai-gateway.vercel.sh";
15
+ /** Build the least-privilege `needs` descriptor for a given config (gateway host + secretRef). */
16
+ export function needsFor(config) {
17
+ return { net: [GATEWAY_HOST], secrets: [config.secretRef] };
18
+ }
19
+ /**
20
+ * Resolve the gateway credential BY NAME through the injected handle. Returns `undefined` when
21
+ * the handle denies it (undeclared / not present) — callers MUST treat a missing credential as a
22
+ * boot/config error, never fabricate one. The value is read here and nowhere else (FR-009).
23
+ *
24
+ * An empty / whitespace-only resolution is treated as ABSENT (returns `undefined`): a blank env var
25
+ * is a misconfiguration, not a usable key — surfacing it as `undefined` lets the gateway fall back
26
+ * to ambient/OIDC resolution rather than sending an empty Bearer token (defense-in-depth, NFR-005).
27
+ */
28
+ export async function resolveGatewayKey(handle) {
29
+ const value = await handle.resolve();
30
+ if (value === undefined || value === null)
31
+ return undefined;
32
+ const trimmed = String(value).trim();
33
+ return trimmed.length > 0 ? trimmed : undefined;
34
+ }
35
+ /**
36
+ * Guard: assert no secret VALUE leaked into the config surface. `parseAgentConfig` already
37
+ * rejects an inlined value in `secretRef`; this is a belt-and-braces check usable at boot.
38
+ */
39
+ export function assertNoInlineSecret(config) {
40
+ // `secretRef` is the ONLY credential field; it is a name (enforced in config.ts). There is no
41
+ // field on AgentConfig that carries a value, so a leaked value is structurally impossible here.
42
+ // Kept as an explicit invariant the conformance suite can assert against (data-model §5 rule).
43
+ if (config.secretRef.length === 0) {
44
+ throw new Error("agent.secretRef is required (the gateway credential NAME) — FR-009");
45
+ }
46
+ }
47
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,kFAAkF;AAClF,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAsBnD,kGAAkG;AAClG,MAAM,UAAU,QAAQ,CAAC,MAAmB;IAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAoB;IAC1D,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACrC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,8FAA8F;IAC9F,gGAAgG;IAChG,+FAA+F;IAC/F,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · skills-loader.ts — the three-level progressive-disclosure loader for
3
+ * `SKILL.md` skills the render Agent activates (027-agentic-primitives §16b.1; FR-004, FR-005,
4
+ * FR-006, FR-014, NFR-008).
5
+ *
6
+ * Skills load by Discovery → Activation → Execution:
7
+ * - level 1 (Discovery): ONLY `manifest.name` + `manifest.description` enter the render prompt;
8
+ * - level 2 (Activation): the full SKILL.md Markdown body loads ONLY when a request matches;
9
+ * - level 3 (Execution): bundled scripts/references/templates are read or run ON DEMAND — the
10
+ * script's SOURCE is NEVER loaded into the model context, and executing a
11
+ * bundled script clears the §58 policy gate FIRST (FR-014).
12
+ *
13
+ * The SKILL.md *recipe* (front-matter + body + references) is a committed FACT under `.cloc/skills/`
14
+ * (§13.1, §45); any CODE a skill bakes is cached OUTSIDE the repo and never committed (FR-006). This
15
+ * loader exposes the recipe and routes bake/exec through a repo-EXTERNAL path, never writing code
16
+ * back into the data repo (Principle 1).
17
+ *
18
+ * Vendor edge: NONE. This module turns the core's vendor-free `SkillRef` shapes (@cloc/core) into
19
+ * the level-1 prompt fragment + the gated activation/execution helpers the loop uses; the model SDK
20
+ * is touched only in tool-loop.ts.
21
+ */
22
+ import type { SkillRef, SkillBody, SkillManifest, BundledResource, PolicyGateHook } from "./tokens.js";
23
+ /** The level-1 metadata that is the ONLY skill surface entering the render prompt by default. */
24
+ export interface SkillMetadataLine {
25
+ readonly id: string;
26
+ readonly name: string;
27
+ readonly description: string;
28
+ }
29
+ /**
30
+ * Render the level-1 (Discovery) skill metadata for the prompt — `name` + `description` ONLY, never
31
+ * the body or bundled bytes (§16b.1, FR-005). This is the "just enough for the model to know when
32
+ * each skill should be used" fragment; it keeps the prompt small (the ~84% token reduction §16b.2).
33
+ */
34
+ export declare function skillMetadata(skills: ReadonlyArray<SkillRef>): SkillMetadataLine[];
35
+ /**
36
+ * Frame the level-1 skill metadata as an inert prompt block. ONLY name+description appear — the
37
+ * body and bundled files are absent until activation/execution (FR-005, NFR-002). Returns "" when
38
+ * no skills are enabled so a baseline render adds nothing to the prompt (FR-002, acceptance #1).
39
+ */
40
+ export declare function frameSkillsForPrompt(skills: ReadonlyArray<SkillRef>): string;
41
+ /** A degrade outcome — a gate denial that proceeds without the capability, attributably (FR-021). */
42
+ export interface SkillGateDenied {
43
+ readonly ok: false;
44
+ readonly reason: string;
45
+ }
46
+ /** Activation succeeded — the level-2 body is now available (the loop may feed it in). */
47
+ export interface SkillActivated {
48
+ readonly ok: true;
49
+ readonly id: string;
50
+ readonly manifest: SkillManifest;
51
+ readonly body: SkillBody;
52
+ }
53
+ export type ActivateResult = SkillActivated | SkillGateDenied;
54
+ /**
55
+ * Level-2 ACTIVATION: load the full `SKILL.md` body for a matched skill, AFTER clearing the §58
56
+ * gate (`kind: 'skill', level: 2`). A denial DEGRADES — it returns `{ ok: false, reason }` so the
57
+ * render proceeds without the skill rather than crashing or bypassing the gate (FR-014, FR-021).
58
+ */
59
+ export declare function activateSkill(skill: SkillRef, gate: PolicyGateHook): Promise<ActivateResult>;
60
+ /** Execution succeeded — the bundled resource's bytes (NOT its source-in-context) are available. */
61
+ export interface BundledOpened {
62
+ readonly ok: true;
63
+ readonly path: string;
64
+ readonly kind: BundledResource["kind"];
65
+ readonly bytes: Uint8Array;
66
+ }
67
+ export type OpenBundledResult = BundledOpened | SkillGateDenied;
68
+ /**
69
+ * Level-3 EXECUTION: read or run a bundled resource ON DEMAND, AFTER clearing the §58 gate
70
+ * (`kind: 'skill', level: 3`). The script's SOURCE is never loaded into the model context — the
71
+ * runner calls `resource.open()` only after the gate clears, holding bundled-script execution to
72
+ * the SAME banned-pattern/allowlist/budget gate as generated code (§58, §16b.1, FR-014). A denial
73
+ * DEGRADES (FR-021).
74
+ */
75
+ export declare function openBundled(skillId: string, resource: BundledResource, gate: PolicyGateHook): Promise<OpenBundledResult>;
76
+ //# sourceMappingURL=skills-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-loader.d.ts","sourceRoot":"","sources":["../src/skills-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,eAAe,EACf,cAAc,EAEf,MAAM,aAAa,CAAC;AAErB,iGAAiG;AACjG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,iBAAiB,EAAE,CAMlF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,MAAM,CAe5E;AAWD,qGAAqG;AACrG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0FAA0F;AAC1F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,eAAe,CAAC;AAE9D;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,cAAc,CAAC,CAOzB;AAED,oGAAoG;AACpG,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,eAAe,CAAC;AAEhE;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAW5B"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · skills-loader.ts — the three-level progressive-disclosure loader for
3
+ * `SKILL.md` skills the render Agent activates (027-agentic-primitives §16b.1; FR-004, FR-005,
4
+ * FR-006, FR-014, NFR-008).
5
+ *
6
+ * Skills load by Discovery → Activation → Execution:
7
+ * - level 1 (Discovery): ONLY `manifest.name` + `manifest.description` enter the render prompt;
8
+ * - level 2 (Activation): the full SKILL.md Markdown body loads ONLY when a request matches;
9
+ * - level 3 (Execution): bundled scripts/references/templates are read or run ON DEMAND — the
10
+ * script's SOURCE is NEVER loaded into the model context, and executing a
11
+ * bundled script clears the §58 policy gate FIRST (FR-014).
12
+ *
13
+ * The SKILL.md *recipe* (front-matter + body + references) is a committed FACT under `.cloc/skills/`
14
+ * (§13.1, §45); any CODE a skill bakes is cached OUTSIDE the repo and never committed (FR-006). This
15
+ * loader exposes the recipe and routes bake/exec through a repo-EXTERNAL path, never writing code
16
+ * back into the data repo (Principle 1).
17
+ *
18
+ * Vendor edge: NONE. This module turns the core's vendor-free `SkillRef` shapes (@cloc/core) into
19
+ * the level-1 prompt fragment + the gated activation/execution helpers the loop uses; the model SDK
20
+ * is touched only in tool-loop.ts.
21
+ */
22
+ /**
23
+ * Render the level-1 (Discovery) skill metadata for the prompt — `name` + `description` ONLY, never
24
+ * the body or bundled bytes (§16b.1, FR-005). This is the "just enough for the model to know when
25
+ * each skill should be used" fragment; it keeps the prompt small (the ~84% token reduction §16b.2).
26
+ */
27
+ export function skillMetadata(skills) {
28
+ return skills.map((s) => ({
29
+ id: s.id,
30
+ name: s.manifest.name,
31
+ description: s.manifest.description,
32
+ }));
33
+ }
34
+ /**
35
+ * Frame the level-1 skill metadata as an inert prompt block. ONLY name+description appear — the
36
+ * body and bundled files are absent until activation/execution (FR-005, NFR-002). Returns "" when
37
+ * no skills are enabled so a baseline render adds nothing to the prompt (FR-002, acceptance #1).
38
+ */
39
+ export function frameSkillsForPrompt(skills) {
40
+ if (skills.length === 0)
41
+ return "";
42
+ const lines = skillMetadata(skills).map(
43
+ // `id`/`name`/`description` come from a SKILL.md manifest (model-influenced bytes), so any line
44
+ // break or `[ ]` is neutralized — a crafted description can't forge a new `[skill …]` envelope
45
+ // or inject a directive line into the prompt block (defense-in-depth, §16b.1; mirrors safety.ts).
46
+ (m) => ` [skill ${neutralize(m.id)}] ${neutralize(m.name)}: ${neutralize(m.description)}`);
47
+ return [
48
+ "<available-skills>",
49
+ "These SKILLs may help. Only their name+description are shown; request a skill by name to load",
50
+ "its full instructions (this is progressive disclosure — the body is NOT loaded yet).",
51
+ ...lines,
52
+ "</available-skills>",
53
+ ].join("\n");
54
+ }
55
+ /**
56
+ * Neutralize the characters in a skill-metadata field that could forge a `[skill …]` envelope or a
57
+ * line break (`[`, `]`, `\n`, `\r`, `\\`) when interpolated into the prompt block. A backslash-escape
58
+ * keeps the value human-readable; NO-OP for normal names/descriptions (mirrors safety.ts framing).
59
+ */
60
+ function neutralize(value) {
61
+ return value.replace(/[\\[\]\r\n]/g, (c) => (c === "\n" ? "\\n" : c === "\r" ? "\\r" : `\\${c}`));
62
+ }
63
+ /**
64
+ * Level-2 ACTIVATION: load the full `SKILL.md` body for a matched skill, AFTER clearing the §58
65
+ * gate (`kind: 'skill', level: 2`). A denial DEGRADES — it returns `{ ok: false, reason }` so the
66
+ * render proceeds without the skill rather than crashing or bypassing the gate (FR-014, FR-021).
67
+ */
68
+ export async function activateSkill(skill, gate) {
69
+ const decision = await gate.check({ kind: "skill", skill: skill.id, level: 2 });
70
+ if (!decision.allow) {
71
+ return { ok: false, reason: gateReason(decision, `skill "${skill.id}" activation denied`) };
72
+ }
73
+ const body = await skill.loadBody();
74
+ return { ok: true, id: skill.id, manifest: skill.manifest, body };
75
+ }
76
+ /**
77
+ * Level-3 EXECUTION: read or run a bundled resource ON DEMAND, AFTER clearing the §58 gate
78
+ * (`kind: 'skill', level: 3`). The script's SOURCE is never loaded into the model context — the
79
+ * runner calls `resource.open()` only after the gate clears, holding bundled-script execution to
80
+ * the SAME banned-pattern/allowlist/budget gate as generated code (§58, §16b.1, FR-014). A denial
81
+ * DEGRADES (FR-021).
82
+ */
83
+ export async function openBundled(skillId, resource, gate) {
84
+ const decision = await gate.check({ kind: "skill", skill: skillId, level: 3 });
85
+ if (!decision.allow) {
86
+ return {
87
+ ok: false,
88
+ reason: gateReason(decision, `skill "${skillId}" bundled "${resource.path}" execution denied`),
89
+ };
90
+ }
91
+ // The gate cleared: only NOW is the resource read/executed (its source never entered context).
92
+ const bytes = await resource.open();
93
+ return { ok: true, path: resource.path, kind: resource.kind, bytes };
94
+ }
95
+ /** A truthy, attributable reason for a degrade (FR-021, NFR-004). */
96
+ function gateReason(decision, fallback) {
97
+ return decision.reason && decision.reason.length > 0 ? decision.reason : fallback;
98
+ }
99
+ //# sourceMappingURL=skills-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-loader.js","sourceRoot":"","sources":["../src/skills-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · stream.ts — the partial-object stream adapter (FR-011, NFR-007, §60).
3
+ *
4
+ * Synthesized regions stream in as the model produces them so the projector renders KNOWN FIELDS
5
+ * of a half-arrived plan without blocking (low TTFB, §60). This maps the AI SDK v6 partial-object
6
+ * stream → the adapter's {@link StreamChunk} (and the core's `Delta`): `partial-object` deltas,
7
+ * interleaved `tool-call`/`tool-result` loop events, ending in a terminal `final` validated Output
8
+ * — or an `error`. On error/exhaustion ANY already-streamed partial is INVALIDATED: the stream
9
+ * ends WITHOUT a `final` the runtime could mistake for completion (edge case, data-model §4).
10
+ *
11
+ * AI SDK v6 surface (verified, not stale memory): `streamText({ ..., output: Output.object(...) })`
12
+ * exposes `result.experimental_partialOutputStream` (async-iterable partial objects) and
13
+ * `result.fullStream` (tool-call/tool-result/finish parts). `result.experimental_output` resolves
14
+ * the final typed object. We do not assume property names beyond these v6 docs shapes.
15
+ */
16
+ import type { Delta, Output, StandardSchema } from "./tokens.js";
17
+ import type { StructuredOutput } from "./output.js";
18
+ import type { LoopEvent } from "./tool-loop.js";
19
+ /** Adapter stream chunk (contracts/agent-provider.ts StreamChunk). `TPlan` is the kit plan type. */
20
+ export type StreamChunk<TPlan = unknown> = {
21
+ kind: "partial-object";
22
+ value: Partial<TPlan>;
23
+ } | {
24
+ kind: "tool-call";
25
+ tool: string;
26
+ args: unknown;
27
+ } | {
28
+ kind: "tool-result";
29
+ tool: string;
30
+ result: unknown;
31
+ } | {
32
+ kind: "final";
33
+ output: StructuredOutput<TPlan>;
34
+ } | {
35
+ kind: "error";
36
+ error: {
37
+ code: string;
38
+ message: string;
39
+ fatal: boolean;
40
+ };
41
+ };
42
+ /** Map a loop event to its stream chunk. */
43
+ export declare function loopEventToChunk<TPlan>(event: LoopEvent): StreamChunk<TPlan>;
44
+ /** Wrap a half-arrived plan snapshot as a `partial-object` chunk (parse-and-heal input, §60). */
45
+ export declare function partialChunk<TPlan>(value: Partial<TPlan>): StreamChunk<TPlan>;
46
+ /**
47
+ * Lower an adapter {@link StreamChunk} to the core's vendor-free `Delta` (the surface
48
+ * `AgentProvider.stream` actually yields). `partial-object` and the loop events become a
49
+ * `{ kind: "partial", patch }`; the terminal validated Output becomes `{ kind: "final", output }`.
50
+ * On `error` we DO NOT emit a `final` — the agent throws/rejects the iterator instead so the
51
+ * runtime never mistakes a failed stream for completion (output.ts §3 rule; core Delta contract).
52
+ *
53
+ * `schema` brands the final payload's `Output` (the core requires the validated schema on it).
54
+ */
55
+ export declare function chunkToDelta<TPlan>(chunk: StreamChunk<TPlan>, schema: StandardSchema<unknown>): Delta | undefined;
56
+ /** Brand a validated {@link StructuredOutput} as the core's `Output` (a typed UI plan, never markup). */
57
+ export declare function toCoreOutput<TPlan>(output: StructuredOutput<TPlan>, schema: StandardSchema<unknown>): Output;
58
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,oGAAoG;AACpG,MAAM,MAAM,WAAW,CAAC,KAAK,GAAG,OAAO,IACnC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,CAAC;AAEhF,4CAA4C;AAC5C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,CAI5E;AAED,iGAAiG;AACjG,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAE7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAChC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EACzB,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,GAC9B,KAAK,GAAG,SAAS,CAcnB;AAED,yGAAyG;AACzG,wBAAgB,YAAY,CAAC,KAAK,EAChC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC/B,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,GAC9B,MAAM,CAMR"}
package/dist/stream.js ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · stream.ts — the partial-object stream adapter (FR-011, NFR-007, §60).
3
+ *
4
+ * Synthesized regions stream in as the model produces them so the projector renders KNOWN FIELDS
5
+ * of a half-arrived plan without blocking (low TTFB, §60). This maps the AI SDK v6 partial-object
6
+ * stream → the adapter's {@link StreamChunk} (and the core's `Delta`): `partial-object` deltas,
7
+ * interleaved `tool-call`/`tool-result` loop events, ending in a terminal `final` validated Output
8
+ * — or an `error`. On error/exhaustion ANY already-streamed partial is INVALIDATED: the stream
9
+ * ends WITHOUT a `final` the runtime could mistake for completion (edge case, data-model §4).
10
+ *
11
+ * AI SDK v6 surface (verified, not stale memory): `streamText({ ..., output: Output.object(...) })`
12
+ * exposes `result.experimental_partialOutputStream` (async-iterable partial objects) and
13
+ * `result.fullStream` (tool-call/tool-result/finish parts). `result.experimental_output` resolves
14
+ * the final typed object. We do not assume property names beyond these v6 docs shapes.
15
+ */
16
+ import { partial as coreDelta, final as coreFinal, makeOutput } from "@cloc/core";
17
+ /** Map a loop event to its stream chunk. */
18
+ export function loopEventToChunk(event) {
19
+ return event.kind === "tool-call"
20
+ ? { kind: "tool-call", tool: event.tool, args: event.args }
21
+ : { kind: "tool-result", tool: event.tool, result: event.result };
22
+ }
23
+ /** Wrap a half-arrived plan snapshot as a `partial-object` chunk (parse-and-heal input, §60). */
24
+ export function partialChunk(value) {
25
+ return { kind: "partial-object", value };
26
+ }
27
+ /**
28
+ * Lower an adapter {@link StreamChunk} to the core's vendor-free `Delta` (the surface
29
+ * `AgentProvider.stream` actually yields). `partial-object` and the loop events become a
30
+ * `{ kind: "partial", patch }`; the terminal validated Output becomes `{ kind: "final", output }`.
31
+ * On `error` we DO NOT emit a `final` — the agent throws/rejects the iterator instead so the
32
+ * runtime never mistakes a failed stream for completion (output.ts §3 rule; core Delta contract).
33
+ *
34
+ * `schema` brands the final payload's `Output` (the core requires the validated schema on it).
35
+ */
36
+ export function chunkToDelta(chunk, schema) {
37
+ switch (chunk.kind) {
38
+ case "partial-object":
39
+ return coreDelta({ partialPlan: chunk.value });
40
+ case "tool-call":
41
+ return coreDelta({ toolCall: { tool: chunk.tool, args: chunk.args } });
42
+ case "tool-result":
43
+ return coreDelta({ toolResult: { tool: chunk.tool, result: chunk.result } });
44
+ case "final":
45
+ return coreFinal(toCoreOutput(chunk.output, schema));
46
+ case "error":
47
+ // The agent surfaces errors by rejecting the iterator (never a fabricated `final`).
48
+ return undefined;
49
+ }
50
+ }
51
+ /** Brand a validated {@link StructuredOutput} as the core's `Output` (a typed UI plan, never markup). */
52
+ export function toCoreOutput(output, schema) {
53
+ return makeOutput({
54
+ // The kit plan IS the UI-plan / IR node tree the RenderEngine later lowers (output.ts §3).
55
+ plan: output.plan,
56
+ schema,
57
+ });
58
+ }
59
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,IAAI,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAalF,4CAA4C;AAC5C,MAAM,UAAU,gBAAgB,CAAQ,KAAgB;IACtD,OAAO,KAAK,CAAC,IAAI,KAAK,WAAW;QAC/B,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;QAC3D,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AACtE,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,YAAY,CAAQ,KAAqB;IACvD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAyB,EACzB,MAA+B;IAE/B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,gBAAgB;YACnB,OAAO,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACjD,KAAK,WAAW;YACd,OAAO,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzE,KAAK,aAAa;YAChB,OAAO,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/E,KAAK,OAAO;YACV,OAAO,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACvD,KAAK,OAAO;YACV,oFAAoF;YACpF,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,YAAY,CAC1B,MAA+B,EAC/B,MAA+B;IAE/B,OAAO,UAAU,CAAC;QAChB,2FAA2F;QAC3F,IAAI,EAAE,MAAM,CAAC,IAAa;QAC1B,MAAM;KACP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · tokens.ts — re-export the AgentProvider ref this adapter answers,
3
+ * and pull in the vendor-free contract TYPES from @cloc/core (FR-002, data-model §1).
4
+ *
5
+ * This is the ONLY seam the adapter binds: `AgentProviderRef` selects exactly one
6
+ * AgentProvider per environment (§32 / §75.3). Downstream modules type-check against the
7
+ * core contract — never against an AI SDK / AI Gateway type — so no vendor type leaks across
8
+ * the public signature (FR-002, Constitution Principle 8).
9
+ *
10
+ * NOTE: the model is a swappable FIELD (`GenOpts.model: ModelRef`), never part of this
11
+ * contract; the token/package/capability names carry no "model" (FR-014).
12
+ */
13
+ export { AgentProviderRef } from "@cloc/core";
14
+ export type { AgentProvider, GenOpts, Prompt, StructuredPrompt, Output, OutputPayload, Delta, PlanNode, ModelRef, StandardSchema, StandardSchemaV1, ProviderRef, } from "@cloc/core";
15
+ export type { SkillRef, SkillManifest, SkillBody, BundledResource, DisclosureLevel, MemoryStore, MemoryBackend, MemoryOp, ToolDef, ToolSet as CoreToolSet, ToolSource, ToolLoop, LoopOpts, StopCondition, StepContext, StepDirective, PrepareStep, PolicyGateHook, PrimitiveAccess, GateDecision, } from "@cloc/core";
16
+ export { isStopTool, validateSkillManifest, isValidSkillName, isValidSkillDescription, stepCountIs as coreStepCountIs, hasToolCall as coreHasToolCall, isLoopFinished as coreIsLoopFinished, defaultStopCondition, DEFAULT_STEP_COUNT, MEMORY_ROLE, ALLOW_ALL_GATE, } from "@cloc/core";
17
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EACV,aAAa,EACb,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,aAAa,EACb,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,WAAW,GACZ,MAAM,YAAY,CAAC;AAUpB,YAAY,EAEV,QAAQ,EACR,aAAa,EACb,SAAS,EACT,eAAe,EACf,eAAe,EAEf,WAAW,EACX,aAAa,EACb,QAAQ,EAER,OAAO,EACP,OAAO,IAAI,WAAW,EACtB,UAAU,EAEV,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,WAAW,EACX,aAAa,EACb,WAAW,EAEX,cAAc,EACd,eAAe,EACf,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,WAAW,IAAI,eAAe,EAC9B,WAAW,IAAI,eAAe,EAC9B,cAAc,IAAI,kBAAkB,EACpC,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC"}
package/dist/tokens.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @cloc/provider-ai-sdk · tokens.ts — re-export the AgentProvider ref this adapter answers,
3
+ * and pull in the vendor-free contract TYPES from @cloc/core (FR-002, data-model §1).
4
+ *
5
+ * This is the ONLY seam the adapter binds: `AgentProviderRef` selects exactly one
6
+ * AgentProvider per environment (§32 / §75.3). Downstream modules type-check against the
7
+ * core contract — never against an AI SDK / AI Gateway type — so no vendor type leaks across
8
+ * the public signature (FR-002, Constitution Principle 8).
9
+ *
10
+ * NOTE: the model is a swappable FIELD (`GenOpts.model: ModelRef`), never part of this
11
+ * contract; the token/package/capability names carry no "model" (FR-014).
12
+ */
13
+ // The token (value) the kernel resolves this plugin against. EXACTLY ONE wins (§32).
14
+ export { AgentProviderRef } from "@cloc/core";
15
+ // Agentic runtime helpers (pure, vendor-free) the runner reuses from the core contract.
16
+ export { isStopTool, validateSkillManifest, isValidSkillName, isValidSkillDescription, stepCountIs as coreStepCountIs, hasToolCall as coreHasToolCall, isLoopFinished as coreIsLoopFinished, defaultStopCondition, DEFAULT_STEP_COUNT, MEMORY_ROLE, ALLOW_ALL_GATE, } from "@cloc/core";
17
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qFAAqF;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAsD9C,wFAAwF;AACxF,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,WAAW,IAAI,eAAe,EAC9B,WAAW,IAAI,eAAe,EAC9B,cAAc,IAAI,kBAAkB,EACpC,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC"}