@op0ai/sdk 0.3.0 → 0.4.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 (83) hide show
  1. package/LICENSE +38 -38
  2. package/dist/guards.d.ts +1 -61
  3. package/dist/guards.js +1 -88
  4. package/dist/hash.d.ts +1 -6
  5. package/dist/hash.js +1 -18
  6. package/dist/index.d.ts +1 -121
  7. package/dist/index.js +14 -171
  8. package/dist/session.d.ts +1 -47
  9. package/dist/session.js +2 -88
  10. package/dist/{agent.d.ts → types/agent.d.ts} +1 -2
  11. package/dist/{agui.d.ts → types/agui.d.ts} +0 -1
  12. package/dist/{config.d.ts → types/config.d.ts} +0 -1
  13. package/dist/{contract.d.ts → types/contract.d.ts} +0 -1
  14. package/dist/{data.d.ts → types/data.d.ts} +0 -1
  15. package/dist/{define.d.ts → types/define.d.ts} +0 -1
  16. package/dist/{distill.d.ts → types/distill.d.ts} +0 -1
  17. package/dist/{events.d.ts → types/events.d.ts} +0 -1
  18. package/dist/{evlog.d.ts → types/evlog.d.ts} +0 -1
  19. package/dist/types/guards.d.ts +60 -0
  20. package/dist/types/hash.d.ts +5 -0
  21. package/dist/types/index.d.ts +120 -0
  22. package/dist/{platform.d.ts → types/platform.d.ts} +0 -1
  23. package/dist/types/session.d.ts +46 -0
  24. package/dist/{source.d.ts → types/source.d.ts} +0 -1
  25. package/dist/{tool.d.ts → types/tool.d.ts} +0 -1
  26. package/dist/{usectx.d.ts → types/usectx.d.ts} +0 -1
  27. package/dist/types/vault.d.ts +20 -0
  28. package/dist/vault.d.ts +1 -21
  29. package/dist/vault.js +1 -25
  30. package/package.json +4 -3
  31. package/dist/agent.d.ts.map +0 -1
  32. package/dist/agent.js +0 -72
  33. package/dist/agent.js.map +0 -1
  34. package/dist/agui.d.ts.map +0 -1
  35. package/dist/agui.js +0 -22
  36. package/dist/agui.js.map +0 -1
  37. package/dist/config.d.ts.map +0 -1
  38. package/dist/config.js +0 -39
  39. package/dist/config.js.map +0 -1
  40. package/dist/contract.d.ts.map +0 -1
  41. package/dist/contract.js +0 -66
  42. package/dist/contract.js.map +0 -1
  43. package/dist/data.d.ts.map +0 -1
  44. package/dist/data.js +0 -211
  45. package/dist/data.js.map +0 -1
  46. package/dist/define.d.ts.map +0 -1
  47. package/dist/define.js +0 -87
  48. package/dist/define.js.map +0 -1
  49. package/dist/distill.d.ts.map +0 -1
  50. package/dist/distill.js +0 -113
  51. package/dist/distill.js.map +0 -1
  52. package/dist/events.d.ts.map +0 -1
  53. package/dist/events.js +0 -25
  54. package/dist/events.js.map +0 -1
  55. package/dist/evlog.d.ts.map +0 -1
  56. package/dist/evlog.js +0 -124
  57. package/dist/evlog.js.map +0 -1
  58. package/dist/fleet-names.d.ts +0 -11
  59. package/dist/fleet-names.d.ts.map +0 -1
  60. package/dist/fleet-names.js +0 -10
  61. package/dist/fleet-names.js.map +0 -1
  62. package/dist/guards.d.ts.map +0 -1
  63. package/dist/guards.js.map +0 -1
  64. package/dist/hash.d.ts.map +0 -1
  65. package/dist/hash.js.map +0 -1
  66. package/dist/index.d.ts.map +0 -1
  67. package/dist/index.js.map +0 -1
  68. package/dist/platform.d.ts.map +0 -1
  69. package/dist/platform.js +0 -10
  70. package/dist/platform.js.map +0 -1
  71. package/dist/session.d.ts.map +0 -1
  72. package/dist/session.js.map +0 -1
  73. package/dist/source.d.ts.map +0 -1
  74. package/dist/source.js +0 -96
  75. package/dist/source.js.map +0 -1
  76. package/dist/tool.d.ts.map +0 -1
  77. package/dist/tool.js +0 -16
  78. package/dist/tool.js.map +0 -1
  79. package/dist/usectx.d.ts.map +0 -1
  80. package/dist/usectx.js +0 -220
  81. package/dist/usectx.js.map +0 -1
  82. package/dist/vault.d.ts.map +0 -1
  83. package/dist/vault.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,171 +1,14 @@
1
- // @op0ai/sdk the op0 SDK. An agent (a cord) is a governed function: a charter + a RunSpec
2
- // (goal, stop rules, verifier) + typed tools, behind typed ports. Pure TS, exactly one dep (zod);
3
- // runs in plain Node and inside a Worker; the core imports no vendor SDK (dep-lint enforced).
4
- //
5
- // THE CONCEPT MAP (one export group per concept — each has one page in /docs):
6
- // the unit config.ts + define.ts defineAgentConfig / defineTool — an AGENT (fleets compose agents)
7
- // the ports platform.ts + vault.ts Kv · Inference · Harness · Sandbox · Vault — swap any
8
- // the contract contract.ts POST /ask: q | messages[] | stream | mode:"agui" — the
9
- // pure laws every op0-hosted agent speaks
10
- // events agui.ts + evlog.ts the typed AgentEvent timeline (UI) + wide events (ops),
11
- // + events.ts joined on runId; the ask-ledger event defined once
12
- // source source.ts the typed, versioned store your agent owns (write side)
13
- // ctx usectx.ts context acquisition + connections (read side) — reach
14
- // arrives via grants, never ambient
15
- // guards guards.ts + hash.ts scope gate, redaction, the hash-chained audit
16
- // composition below use/useRemote sub-agents under one shared RunBudget
17
- // sessions session.ts + distill.ts runs → sessions → distilled skills (the flywheel)
18
- // data data.ts typed query/mutation over an agent-owned store
19
- export * from "./hash.js";
20
- export * from "./vault.js";
21
- export * from "./guards.js";
22
- export * from "./platform.js";
23
- export * from "./agent.js";
24
- export * from "./source.js";
25
- export * from "./agui.js";
26
- export * from "./tool.js";
27
- export * from "./config.js";
28
- export * from "./define.js";
29
- // the chat contract's pure laws (mirrored in the composed host — THE MIRROR LAW lives in contract.ts)
30
- export * from "./contract.js";
31
- // vendor adapters (gatewayModel, toAiTools, runCordChat) live in the cord-ai workspace lib — core stays vendor-free
32
- export * from "./evlog.js";
33
- export * from "./events.js";
34
- export * from "./usectx.js";
35
- export * from "./distill.js";
36
- export * from "./data.js";
37
- import { hashHex, slug, newId } from "./hash.js";
38
- import { makeAuditChain } from "./guards.js";
39
- /** Mount an OWNED sub-cord in-process (deterministic trunk). */
40
- export function use(sc) {
41
- return { id: sc.id, mount: "local", run: sc.run };
42
- }
43
- /** Mount a THIRD-PARTY/registry cord over MCP (the trust boundary; an executor toolkit). */
44
- export function useRemote(sc) {
45
- return { id: sc.id, mount: "registry", run: sc.call };
46
- }
47
- const now = () => (typeof performance !== "undefined" ? performance.now() : Date.now());
48
- const errOf = (e) => ({ code: "cord.run", why: e instanceof Error ? e.message : String(e) });
49
- export function defineAgent(def) {
50
- const guards = def.guards ?? [];
51
- const expose = def.expose ?? { codemode: true };
52
- const manifest = {
53
- id: def.id, version: "0.1.0",
54
- kind: def.kind ?? "agent-ful", inference: def.inference ?? "managed",
55
- ...(def.scope !== undefined ? { scope: def.scope } : {}), expose,
56
- subcords: Object.values(def.subcords ?? {}).map((s) => s.id),
57
- guards: guards.map((g) => g.name),
58
- needs: def.needs ?? [],
59
- };
60
- const runFull = async (input, opts = {}) => {
61
- const runId = newId();
62
- const tenantId = opts.tenantId ?? "local";
63
- const scope = opts.scope ?? def.scope;
64
- const budget = { cap: opts.budget?.cap ?? 64, used: 0, depth: 0, maxDepth: opts.budget?.maxDepth ?? 8 };
65
- const events = [];
66
- const chain = makeAuditChain();
67
- const emit = (e) => { events.push(e); opts.onEvent?.(e); for (const g of guards)
68
- g.onEvent?.(e); };
69
- const span = (kind, name, ms, ok, error, attrs) => ({
70
- ts: new Date().toISOString(), runId, tenantId, cordId: def.id, kind, name, durationMs: Math.round(ms), ok,
71
- ...(scope !== undefined ? { scope } : {}),
72
- ...(error !== undefined ? { error } : {}),
73
- ...(attrs !== undefined ? { attrs } : {}),
74
- });
75
- // H4 — gate: deepsec authorizes the run scope (throws if off-allow-list), then audit the authorization.
76
- // Guards run in the author-declared order (def.guards) and any may throw to refuse the run — sequential
77
- // by design (a later guard should see the run as already vetted by earlier ones, not race them).
78
- const gev = { cord: def.id, ...(scope !== undefined ? { scope } : {}), input };
79
- for (const g of guards) {
80
- // oxlint-disable-next-line no-await-in-loop
81
- await g.onCall?.(gev);
82
- }
83
- chain.append({ actor: "deepsec", action: "run.authorize", scopeId: scope ?? "", payload: { cord: def.id, tenantId } });
84
- // Resolve host-bound resources (the adapter model). opts.vault is a shorthand for resources.vault. A cord
85
- // that declares `needs` fails fast here if the host bound none — a missing binding is a deploy bug, not a
86
- // silent no-op. (Trust boundary: validate, never simplify away — ponytail.)
87
- const res = { ...opts.resources };
88
- if (opts.vault && !res.vault)
89
- res.vault = opts.vault;
90
- for (const need of def.needs ?? []) {
91
- if (!res[need])
92
- throw new Error(`cord ${def.id}: required resource "${need}" not bound by the host`);
93
- }
94
- // H5 — wrap each sub-cord with the cycle-guard (budget + maxDepth) and a per-step wide-event.
95
- const ctx = {};
96
- for (const key of Object.keys(def.subcords ?? {})) {
97
- const sc = def.subcords[key];
98
- if (!sc)
99
- continue;
100
- ctx[key] = async (i) => {
101
- if (budget.depth >= budget.maxDepth)
102
- throw new Error(`cord: cycle-guard tripped (maxDepth ${budget.maxDepth}) at ${sc.id}`);
103
- if (budget.used + 1 > budget.cap)
104
- throw new Error(`cord: run budget exhausted (cap ${budget.cap}) at ${sc.id}`);
105
- budget.used += 1;
106
- budget.depth += 1;
107
- const s0 = now();
108
- try {
109
- const out = await sc.run(i);
110
- emit(span("step", sc.id, now() - s0, true));
111
- return out;
112
- }
113
- catch (e) {
114
- emit(span("step", sc.id, now() - s0, false, errOf(e)));
115
- throw e;
116
- }
117
- finally {
118
- budget.depth -= 1;
119
- }
120
- };
121
- }
122
- // the deterministic trunk
123
- const t0 = now();
124
- let output;
125
- try {
126
- output = await def.run(input, ctx, res);
127
- emit(span("turn", def.id, now() - t0, true, undefined, { used: budget.used }));
128
- }
129
- catch (e) {
130
- emit(span("turn", def.id, now() - t0, false, errOf(e)));
131
- chain.append({ actor: "deepsec", action: "run.error", scopeId: scope ?? "", payload: errOf(e) });
132
- throw e;
133
- }
134
- // H4 — redaction: scrub secrets/PII before the output is persisted or exported.
135
- let safe = output;
136
- for (const g of guards)
137
- if (g.redact)
138
- safe = g.redact(safe);
139
- // H3 — vault write: every assess leaves a versioned deliverable.
140
- let artifact;
141
- if (res.vault) {
142
- // ponytail: key by cord id + runId. Was keyed off input.target (deepeval-specific leaking into the
143
- // generic core) — keying by the cord is correct for every cord.
144
- const key = `reports/${slug(def.id)}/${runId}.json`;
145
- artifact = await res.vault.put(key, JSON.stringify(safe, null, 2), { runId, tenantId, cord: def.id });
146
- chain.append({ actor: "deepsec", action: "artifact.write", scopeId: scope ?? "", payload: { key: artifact.key, version: artifact.version, hash: artifact.hash } });
147
- }
148
- chain.append({ actor: "deepsec", action: "run.settle", scopeId: scope ?? "", payload: { runId, ok: true, used: budget.used } });
149
- return { output: safe, runId, ...(artifact !== undefined ? { artifact } : {}), audit: chain.entries, events, budget };
150
- };
151
- return {
152
- id: def.id,
153
- expose,
154
- manifest,
155
- run: async (input, opts) => (await runFull(input, opts)).output,
156
- runFull,
157
- };
158
- }
159
- // ---- H5: publish/fork — the forkable manifest + the generated discovery endpoint ----
160
- /** /.well-known/op0.json (ADR-18) generated from the cord's `expose`. Host is filled at deploy. */
161
- export const wellKnown = (m, host = "https://host") => ({
162
- mcp: m.expose.mcp ? [`${host}${m.expose.mcp}`] : [],
163
- docs: `${host}/llms.txt`,
164
- ...(m.expose.openapi ? { openapi: `${host}/openapi.json` } : {}),
165
- ...(m.expose.cli ? { cli: `${host}/cli` } : {}),
166
- skills: "/.well-known/agent-skills/",
167
- ...(m.scope ? { auth: { type: "oauth2", scopes: [m.scope] } } : {}),
168
- });
169
- /** Content-address the manifest for skillkit publish/fork lineage (signed → forkOf{atCommit} later, ADR-22). */
170
- export const signManifest = (m) => ({ manifest: m, hash: hashHex(JSON.stringify(m)) });
171
- //# sourceMappingURL=index.js.map
1
+ var h=e=>{let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")},H=e=>e.trim().toLowerCase().replace(/^https?:\/\//,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"target",E=()=>Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,8);var fe=()=>{let e=new Map;return{store:e,async put(t,n,r){let o=(e.get(t)?.version??0)+1;return e.set(t,{body:n,version:o,meta:r}),{key:t,version:String(o),hash:h(n)}},async get(t){return e.get(t)?.body??null},async list(t=""){return[...e.keys()].filter(n=>n.startsWith(t))}}};var W=e=>h([e.seq,e.ts,e.actor,e.action,e.scopeId,e.payloadHash,e.prevHash].join("|")),I=()=>{let e=[];return{entries:e,append({actor:t,action:n,scopeId:r,payload:o}){let s=e.length,i=new Date().toISOString(),u=s===0?"GENESIS":e[s-1]?.hash??"GENESIS",a=h(JSON.stringify(o??null)),d={seq:s,ts:i,actor:t,action:n,scopeId:r,payloadHash:a,prevHash:u},c={...d,hash:W(d)};return e.push(c),c}}},V=e=>{for(let t=0;t<e.length;t++){let n=e[t];if(!n)return!1;let r=t===0?"GENESIS":e[t-1]?.hash??"GENESIS";if(n.prevHash!==r)return!1;let{hash:o,...s}=n;if(o!==W(s))return!1}return!0},X=[/gh[poursa]_[A-Za-z0-9]{20,}/g,/github_pat_[A-Za-z0-9_]{20,}/g,/xox[baprs]-[A-Za-z0-9-]{10,}/g,/AKIA[0-9A-Z]{16}/g,/sk-[A-Za-z0-9]{20,}/g,/-----BEGIN (?:[A-Z ]+ )?PRIVATE KEY-----/g],D=(e,t)=>{if(typeof e=="string"){let n=e;for(let r of t)n=n.replace(r,"[redacted]");return n}if(Array.isArray(e))return e.map(n=>D(n,t));if(e&&typeof e=="object"){let n={};for(let r of Object.keys(e))n[r]=D(e[r],t);return n}return e},we=(e={})=>{let t=e.secrets??X;return{name:"deepsec",onCall:({scope:n})=>{if(e.allow&&n!==void 0&&!e.allow.includes(n))throw new Error(`deepsec: scope "${n}" not in allow-list [${e.allow.join(", ")}]`)},redact:n=>D(n,t)}},be=(e=[])=>({name:"deepeval",onEvent:t=>{e.push(t)}});var ve=()=>{let e=new Map;return{async get(t){return e.get(t)??null},async put(t,n){e.set(t,n)},async incr(t,n=1){let r=Number(e.get(t)??0)+n;return e.set(t,String(r)),r}}};var Se=e=>({async run({instructions:t,input:n,tools:r,maxSteps:o=8}){let s=[{role:"system",content:t},{role:"user",content:n}],i=new Map(r.map(u=>[u.name,u]));for(let u=0;u<o;u++){let a=await e.generate({messages:s,tools:r});if(a.toolCalls&&a.toolCalls.length>0){s.push({role:"assistant",content:a.text??"",toolCalls:a.toolCalls});for(let d of a.toolCalls){let c=i.get(d.name),l=c?await c.run(d.args):{error:`unknown tool: ${d.name}`};s.push({role:"tool",content:JSON.stringify(l),toolCallId:d.id})}continue}return{output:a.text??"",steps:u+1}}throw new Error(`harness: maxSteps ${o} exhausted without a final answer`)}}),Ee=e=>{let t=0;return{async generate(){return e[t++]??{text:"(script exhausted)"}}}},Re=(e,t)=>{let n=[];return e.kv&&n.push({name:"kv_incr",description:"Increment a durable counter by key. args: { key: string, by?: number }",parameters:{type:"object",properties:{key:{type:"string"},by:{type:"number"}},required:["key"]},run:async r=>(t?.("kv_incr",r),{count:await e.kv.incr(String(r.key),typeof r.by=="number"?r.by:1)})}),e.vault&&n.push({name:"vault_put",description:"Persist a deliverable. args: { key: string, body: string }",parameters:{type:"object",properties:{key:{type:"string"},body:{type:"string"}},required:["key","body"]},run:async r=>(t?.("vault_put",r),await e.vault.put(String(r.key),String(r.body)))}),n};var G="pending/";function Te(e){let{store:t,committer:n}=e,r=s=>e.prefix?`${e.prefix}/${s}`:s,o=r(G);return{async read(s){let i=await t.get(r(s));return i?await i.text():null},async stage(s,i){await t.put(r(G+s),i)},async flush(){let s=await t.list({prefix:o}),u=(await Promise.all(s.objects.map(async d=>{let c=await t.get(d.key);if(!c)return null;let l=d.key.slice(o.length),p=await c.text();return await t.put(r(l),p),await t.delete(d.key),{path:l,text:p}}))).filter(d=>d!==null),a=n&&u.length>0?await n.commit(u):"skipped";return{committed:u.length,paths:u.map(d=>d.path),external:a}}}}function Y(e){let t=new TextEncoder().encode(e),n="";for(let r of t)n+=String.fromCharCode(r);return btoa(n)}function Ie(e){let t=e.branch??"main",n=e.base??"cord",r=e.fetch??fetch,o=`https://api.github.com/repos/${e.owner}/${e.repo}/contents`,s={authorization:`Bearer ${e.token}`,accept:"application/vnd.github+json","user-agent":"op0-cord","content-type":"application/json"};return{async commit(i){let u=0;for(let a of i){let d=`${o}/${n}/${a.path}`,c,l=await r(`${d}?ref=${encodeURIComponent(t)}`,{headers:s});l.ok&&(c=(await l.json()).sha),(await r(d,{method:"PUT",headers:s,body:JSON.stringify({message:`cord: commit ${a.path}`,content:Y(a.text),branch:t,...c?{sha:c}:{}})})).ok&&(u+=1)}return{committed:u,total:i.length,target:`${e.owner}/${e.repo}@${t}`}}}}var w=()=>Date.now();function Oe(e,t){let n=r=>t(r);return{runId:e,started:r=>n({type:"RUN_STARTED",runId:e,threadId:r,ts:w()}),text:r=>n({type:"TEXT_MESSAGE_CONTENT",runId:e,delta:r,ts:w()}),toolStart:(r,o,s)=>n({type:"TOOL_CALL_START",runId:e,toolCallId:r,name:o,args:s,ts:w()}),toolResult:r=>n({type:"TOOL_CALL_RESULT",runId:e,...r,ts:w()}),sourceStaged:r=>n({type:"SOURCE_STAGED",runId:e,path:r,ts:w()}),sourceCommitted:(r,o)=>n({type:"SOURCE_COMMITTED",runId:e,paths:r,external:o,ts:w()}),stateDelta:r=>n({type:"STATE_DELTA",runId:e,patch:r,ts:w()}),finished:()=>n({type:"RUN_FINISHED",runId:e,ts:w()}),errored:r=>n({type:"RUN_ERROR",runId:e,error:r,ts:w()})}}function De(e){return{name:e.name,description:e.description,inputSchema:e.input,execute:e.execute}}function Pe(e){return Object.values(e).map(t=>({name:t.name,description:t.description}))}function _e(e){return e}function Ne(e){return(Array.isArray(e)?e:Object.values(e)).map(n=>{let r=n.inputSchema;if(typeof r.toJSONSchema!="function")throw new Error(`tool "${n.name}": inputSchema has no toJSONSchema() \u2014 zod 4.4+ schemas required`);return{type:"function",function:{name:n.name,description:n.description,parameters:r.toJSONSchema()}}})}var P=(e,t)=>console.log(JSON.stringify({evlog:`cord_events.${e}`,error:t instanceof Error?t.message:String(t)})),$=(e,t=200)=>new Response(JSON.stringify(e),{status:t,headers:{"content-type":"application/json"}});function Fe(e){let t=!1;try{e.sql`CREATE TABLE IF NOT EXISTS cord_events (seq INTEGER PRIMARY KEY AUTOINCREMENT, run TEXT, json TEXT)`,t=!0}catch(n){P("init",n)}return{sink:n=>{if(t)try{e.sql`INSERT INTO cord_events (run, json) VALUES (${n.runId}, ${JSON.stringify(n)})`,e.broadcast(JSON.stringify({cordEvent:n}))}catch(r){P("sink",r)}},replay:()=>{if(!t)return[];try{return e.sql`SELECT json FROM cord_events ORDER BY seq`.map(n=>JSON.parse(n.json))}catch(n){return P("replay",n),[]}}}}async function je(e,t){let n;try{n=await e.json()}catch{return $({error:"invalid json"},400)}let r=n.fn??"",o=n.args??{},s={"source.read":async a=>({path:a.path,content:t.source?await t.source.read(String(a.path)):null}),"source.edit":async a=>{if(!t.source)throw new Error("no source bound");return await t.source.stage(String(a.path),String(a.content)),await t.source.flush(),{staged:String(a.path),commitsInSeconds:0}},"kv.get":async a=>({value:t.kv?await t.kv.get(String(a.key)):null}),"kv.put":async a=>{if(!t.kv)throw new Error("no kv bound");return await t.kv.put(String(a.key),String(a.value)),{ok:!0}}},i=t.functions?.[r],u=s[r]??(i?a=>i(a,t):void 0);if(!u)return $({error:`unknown fn: ${r}`},404);try{return $(await u(o))}catch(a){return $({error:a instanceof Error?a.message:String(a)},500)}}var O={maxMessages:40,maxChars:96e3};function He(e,t){if(e==null)return{ok:!0,messages:[{role:"user",content:String(t??"hello")}]};if(!Array.isArray(e)||e.length===0)return{ok:!1,error:"messages: a non-empty array is required"};if(e.length>O.maxMessages)return{ok:!1,error:`messages: ${e.length} exceeds the ${O.maxMessages}-message cap \u2014 trim or summarize the thread client-side`};let n=0,r=[];for(let o of e){let s=o?.role,i=o?.content;if(s!=="user"&&s!=="assistant")return{ok:!1,error:`messages: role '${String(s)}' refused \u2014 only user/assistant (the charter is this cord's system prompt)`};if(typeof i!="string"||i.length===0)return{ok:!1,error:"messages: every content must be a non-empty string"};n+=i.length,r.push({role:s,content:i})}return n>O.maxChars?{ok:!1,error:`messages: the thread is ${n} chars (cap ${O.maxChars}) \u2014 summarize or trim client-side`}:r[r.length-1]?.role!=="user"?{ok:!1,error:"messages: the last message must be from the user"}:{ok:!0,messages:r}}function We(e){for(let t of e.split(`
2
+ `)){if(!t.startsWith("data:"))continue;let n=t.slice(5).trim();if(!(!n||n==="[DONE]"))try{let r=JSON.parse(n)?.choices?.[0]?.delta;if(r?.tool_calls?.length)return"tool";if(typeof r?.content=="string"&&r.content.length)return"content"}catch{}}return"open"}function Ge(e,t){for(let n of t??[]){let r=n.index??0;e[r]??={id:"",name:"",args:""},n.id&&(e[r].id=n.id),typeof n.function?.name=="string"&&(e[r].name+=n.function.name),typeof n.function?.arguments=="string"&&(e[r].args+=n.function.arguments)}return e}function ee(e){return{indexes:[e.cordId],blobs:[e.runId,e.kind,e.name,e.tenantId,e.cordId,e.scope??"",e.error?.code??"",e.error?.why??""],doubles:[e.durationMs,e.ok?1:0]}}function te(e){return t=>{if(e)try{e.writeDataPoint(ee(t))}catch(n){console.log(JSON.stringify({evlog:"evlog.write",error:n instanceof Error?n.message:String(n)}))}}}var z=e=>h([e.seq,e.ts,e.actor,e.action,e.scopeId,e.payloadHash,e.prevHash].join("|")),M=(e,t)=>console.log(JSON.stringify({evlog:`cord_audit.${e}`,error:t instanceof Error?t.message:String(t)}));function ne(e){let t=!1;try{e.sql`CREATE TABLE IF NOT EXISTS cord_audit (seq INTEGER PRIMARY KEY, ts TEXT, actor TEXT, action TEXT, scopeId TEXT, payloadHash TEXT, prevHash TEXT, hash TEXT)`,t=!0}catch(n){M("init",n)}return{append({actor:n,action:r,scopeId:o,payload:s}){if(!t)return null;try{let u=e.sql`SELECT seq, hash FROM cord_audit ORDER BY seq DESC LIMIT 1`[0],a=u?Number(u.seq)+1:0,d=u?u.hash:"GENESIS",c=new Date().toISOString(),l=h(JSON.stringify(s??null)),p={seq:a,ts:c,actor:n,action:r,scopeId:o,payloadHash:l,prevHash:d},m=z(p);return e.sql`INSERT INTO cord_audit (seq, ts, actor, action, scopeId, payloadHash, prevHash, hash) VALUES (${a}, ${c}, ${n}, ${r}, ${o}, ${l}, ${d}, ${m})`,{...p,hash:m}}catch(i){return M("append",i),null}},list(){if(!t)return[];try{return e.sql`SELECT seq, ts, actor, action, scopeId, payloadHash, prevHash, hash FROM cord_audit ORDER BY seq`.map(r=>Object.assign(r,{seq:Number(r.seq)}))}catch(n){return M("list",n),[]}}}}function Je(e){let t="GENESIS";for(let n=0;n<e.length;n++){let r=e[n];if(!r)return{ok:!1,brokenAt:n};let{hash:o,...s}=r;if(s.prevHash!==t||z(s)!==o)return{ok:!1,brokenAt:n};t=o}return{ok:!0}}function Ke(e){let t=te(e.analytics),n=ne(e.host);return{runId:e.runId,audit:n,wide:r=>{let o={...r,runId:e.runId,cordId:e.cordId,tenantId:e.tenantId,ts:new Date().toISOString()};t(o),n.append({actor:e.cordId,action:`${o.kind}:${o.name}`,scopeId:e.runId,payload:{ok:o.ok,durationMs:o.durationMs,scope:o.scope,error:o.error,attrs:o.attrs}})}}}function Be(e){return{kind:"ask",at:e.at??new Date().toISOString(),...e}}function Qe(e){let t=e;return!!t&&t.kind==="ask"&&typeof t.cord=="string"&&t.cord.length>0&&typeof t.run=="string"&&t.run.length>0&&typeof t.ok=="boolean"}var Ve=e=>e.includes("--")?e.split("--")[0]??null:null;var y=e=>e.replace(/^\.?\/+/,"").replace(/\/+$/,"");function re(e){let t=new Map(Object.entries(e).map(([n,r])=>[y(n),r]));return{async exists(n){let r=y(n);if(t.has(r))return!0;for(let o of t.keys())if(o.startsWith(r+"/"))return!0;return!1},async read(n){return t.get(y(n))??null},async paths(){return[...t.keys()]}}}function se(e){let t=e.trim();return t.startsWith("evlog:")?"evlog":t.startsWith("r2:")?"r2":/\.zip($|\?)/i.test(t)?"zip":/^git@github\.com:|github\.com[/:]/.test(t)||/^[\w.-]+\/[\w.-]+$/.test(t)?"repo":/^https?:\/\//.test(t)?"url":/^(\.\/|\/|[a-zA-Z]:\\)/.test(t)||t==="."?"fs":"unknown"}var J=e=>{let t=e.trim().replace(/\.git$/,"").match(/(?:github\.com[/:])?([^/\s]+)\/([^/\s]+)\/?$/),n=t?.[1],r=t?.[2];if(!n||!r)throw new Error(`not a github repo target: ${e}`);return{owner:n,repo:r}},U=async(e,t)=>{let n=await fetch(e,{headers:t});if(n.status===403||n.status===429){let r=n.headers.get("x-ratelimit-remaining");throw new Error(`github ${n.status} for ${e}`+(r==="0"?" \u2014 rate limit exhausted; set a token to lift 60\u21925000/hr (or use executor)":" (forbidden/auth)"))}return{status:n.status,json:n.ok?await n.json():null}},oe=e=>async t=>{let{owner:n,repo:r}=J(t),o={"user-agent":"op0-cord-usectx",accept:"application/vnd.github+json",...e?{authorization:`Bearer ${e}`}:{}},s=await U(`https://api.github.com/repos/${n}/${r}`,o);if(s.status===404)throw new Error(`github repo not found: ${n}/${r}`);let i=s.json?.default_branch??"main",u=await U(`https://api.github.com/repos/${n}/${r}/git/trees/${i}?recursive=1`,o);if(u.status===404)throw new Error(`github tree not found: ${n}/${r}@${i}`);let a=u.json??{tree:[]};if(a.truncated===!0)throw new Error(`github tree truncated for ${n}/${r}@${i} \u2014 needs paged acquisition / a token (use executor)`);let d=new Set,c=new Set;for(let p of a.tree??[])(p.type==="tree"?c:d).add(y(p.path));let l=new Map;return{async exists(p){let m=y(p);return d.has(m)||c.has(m)},async paths(){return[...d]},async read(p){let m=y(p);if(!d.has(m))return null;if(l.has(m))return l.get(m)??null;let b=await fetch(`https://raw.githubusercontent.com/${n}/${r}/${i}/${m}`,{headers:{"user-agent":"op0-cord-usectx"}}).then(R=>R.ok?R.text():null);return l.set(m,b),b}}},ie=e=>async t=>{let{owner:n,repo:r}=J(t),s=(await e.reposGet({owner:n,repo:r})).default_branch??"main",i=await e.gitGetTree({owner:n,repo:r,tree_sha:s,recursive:"1"});if(i.truncated===!0)throw new Error(`github tree truncated for ${n}/${r}@${s} via executor \u2014 needs paged acquisition`);let u=new Set,a=new Set;for(let c of i.tree??[])(c.type==="tree"?a:u).add(y(c.path));let d=new Map;return{async exists(c){let l=y(c);return u.has(l)||a.has(l)},async paths(){return[...u]},async read(c){let l=y(c);if(!u.has(l))return null;if(d.has(l))return d.get(l)??null;let p=await e.reposGetContent({owner:n,repo:r,path:l,ref:s}),m=p?.content?p.encoding==="base64"?atob(p.content.replace(/\n/g,"")):p.content:null;return d.set(l,m),m}}},ae=async e=>{let t=await fetch(e,{headers:{"user-agent":"op0-cord-usectx"}});if(!t.ok)throw new Error(`usectx http ${t.status} for ${e}`);let n=await t.text(),r=y(new URL(e).pathname.split("/").pop()||"index");return re({[r||"index"]:n})},ue=async e=>{let{existsSync:t,readFileSync:n,readdirSync:r}=await import("node:fs"),{join:o,relative:s,sep:i}=await import("node:path"),u=/(^|\/)(\.git|node_modules)(\/|$)/;return{async exists(a){return t(o(e,a))},async read(a){try{return n(o(e,a),"utf8")}catch{return null}},async paths(){try{return r(e,{recursive:!0,withFileTypes:!0}).filter(a=>a.isFile()).map(a=>s(e,o(a.parentPath??a.path,a.name)).split(i).join("/")).filter(a=>!u.test(a))}catch{return[]}}}};function Ye(e={}){let t=e.executor?ie(e.executor):oe(e.github?.token),n=(r,o)=>{let s=e.resolvers?.[r];if(s)return s(o);switch(r){case"repo":return t(o);case"url":if(e.http)return ae(o);break;case"fs":if(e.fs)return ue(o);break;default:break}throw new Error(`usectx: no resolver bound for target kind "${r}" (${o})`)};return async r=>{let o=se(r);e.audit?.({op:"acquire",target:r,kind:o});let s=await n(o,r);return!e.redact&&!e.audit?s:{exists:s.exists.bind(s),paths:s.paths.bind(s),read:async i=>{e.audit?.({op:"read",target:r,kind:o,path:i});let u=await s.read(i);return e.redact?e.redact(u,{target:r,path:i}):u}}}}var K=[{id:"force-push",match:e=>e.kind==="tool_call"&&/\bgit\s+push\b.*--force(?!-with-lease)/.test(e.name),decision:"deny",why:"force-push without --force-with-lease"},{id:"rm-rf",match:e=>e.kind==="tool_call"&&/\brm\s+-rf\b/.test(e.name),decision:"approve",why:"destructive delete \u2014 needs human approval"},{id:"secret-exfil",match:e=>e.kind==="tool_call"&&/(curl|wget)\b.*(\.env|secret|token|key)/i.test(e.name),decision:"approve",why:"possible secret exfiltration"}],ce=(e,t)=>e==="owned"||e==="attached"||e==="streamed"&&t==="proxy",de=(e,t=K)=>{let n=[];for(let r of e.events)for(let o of t)o.match(r)&&n.push({event:r,rule:o,decision:o.decision,enforceable:ce(e.mode,r.vector)});return n},Z=(e,t=K)=>{let n=I();n.append({actor:"deepsec",action:"session.capture",scopeId:e.mode,payload:{harness:e.harness,mode:e.mode}});let r=e.events.map(s=>({ts:s.ts,runId:e.runId,tenantId:"op0",cordId:"@op0/coding-ops",kind:s.kind==="tool_call"||s.kind==="tool_result"?"tool":s.kind==="model"?"model":"step",name:s.name,durationMs:0,ok:!0,attrs:{vector:s.vector,...s.attrs??{}}})),o=de(e,t);for(let s of o)n.append({actor:"deepsec",action:s.enforceable?`intercept.${s.decision}`:"intercept.flag",scopeId:e.mode,payload:{rule:s.rule.id,why:s.rule.why,event:s.event.name,enforceable:s.enforceable}});return n.append({actor:"deepsec",action:"session.settle",scopeId:e.mode,payload:{runId:e.runId,events:r.length,interceptions:o.length}}),{runId:e.runId,harness:e.harness,mode:e.mode,events:r,audit:n.entries,interceptions:o}};var _=e=>new Date(e).toISOString();function ot(e,t,n=[]){let r=[],o=new Map;for(let s of t)if(s.type==="TOOL_CALL_START")o.set(s.toolCallId,{name:s.name,ts:s.ts});else if(s.type==="TOOL_CALL_RESULT"){let i=o.get(s.toolCallId);o.delete(s.toolCallId),r.push({ts:_(s.ts),runId:e,tenantId:"cord",cordId:"cord",kind:"tool",name:s.name,durationMs:i?s.ts-i.ts:0,ok:s.ok,...s.ok?{}:{error:{code:"tool_error",why:s.error??""}}})}else s.type==="SOURCE_COMMITTED"?r.push({ts:_(s.ts),runId:e,tenantId:"cord",cordId:"cord",kind:"tool",name:"source.commit",durationMs:0,ok:!0,attrs:{paths:s.paths}}):s.type==="RUN_ERROR"&&r.push({ts:_(s.ts),runId:e,tenantId:"cord",cordId:"cord",kind:"turn",name:"run",durationMs:0,ok:!1,error:{code:"run_error",why:s.error}});return{runId:e,source:"cord",events:r,audit:n}}function it(e){let t=Z(e);return{runId:t.runId,source:"agent",harness:t.harness,mode:t.mode,events:t.events,audit:t.audit,interceptions:t.interceptions}}function le(e,t,n={}){let r=[],o=[];for(let c of e.events)c.kind==="tool"&&!r.includes(c.name)&&r.push(c.name),c.ok||o.push(`${c.name}: ${c.error?.why??"failed"}`);let s=(e.interceptions??[]).filter(c=>c.decision!=="allow").map(c=>`${c.rule.id} (${c.decision})`),i=o.length===0&&s.every(c=>!c.includes("(deny)")),u=n.name??`${e.source}-${r[0]??"session"}-pattern`,a=e.events.filter(c=>c.kind==="tool").map(c=>c.name),d=[`# ${u}`,"",t?`> ${t}`:`> Distilled from a ${e.source} session (run ${e.runId}).`,"","## Observed pattern",a.length?a.map((c,l)=>`${l+1}. ${c}`).join(`
3
+ `):"_(no tool steps)_","","## Tools",r.length?r.map(c=>`- ${c}`).join(`
4
+ `):"_(none)_",o.length?`
5
+ ## Failures observed
6
+ ${o.map(c=>`- ${c}`).join(`
7
+ `)}`:"",s.length?`
8
+ ## Governance flags
9
+ ${s.map(c=>`- ${c}`).join(`
10
+ `)}`:""].filter(Boolean).join(`
11
+ `);return{name:u,description:`${e.source} session pattern over ${r.length} tool(s): ${r.slice(0,4).join(", ")||"\u2014"}.`,whenToUse:t??`When repeating the ${r[0]??"this"} workflow distilled from run ${e.runId}.`,documentation:d,tags:["distilled",e.source,...n.tags??[]],evidence:{sourceRunId:e.runId,source:e.source,tools:r,steps:e.events.length,ok:i,failures:o,flagged:s,...t!==void 0?{note:t}:{}}}}async function at(e,t,n,r={}){let o=le(e,t,r),s=`You distill agent sessions into reusable skills. Given this evidence, write a crisp, reusable skill.
12
+ Evidence: ${JSON.stringify(o.evidence)}
13
+ Note: ${t??"(none)"}
14
+ Return ONLY JSON: {"name","description","whenToUse","documentation"}.`;try{let u=((await n.generate({messages:[{role:"user",content:s}]})).text??"").match(/\{[\s\S]*\}/);if(u){let a=JSON.parse(u[0]);return{...o,...a}}}catch{}return o}function ut(e){return async t=>(e.push(t),{ok:!0,id:t.name})}var pe=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"skill";function ct(e,t){return async n=>{let r=`${t?.prefix??"skills"}/${pe(n.name)}`;return await e.put(`${r}.md`,n.documentation),await e.put(`${r}.json`,JSON.stringify(n,null,2)),{ok:!0,id:`${r}.md`}}}function pt(e){let t={},n={schema:e,indexes:t,index(r,o){return t[r]=o,n}};return n}function gt(e){return e}function mt(e){return{kind:"query",args:e.args,handler:e.handler}}function ft(e){return{kind:"mutation",args:e.args,handler:e.handler}}function ht(e){return{kind:"action",args:e.args,handler:e.handler}}var B=(e,t)=>`${e}:${t}`,Q=class{constructor(t,n){this.schema=t;this.functions=n;for(let r of Object.keys(t))this.tables.set(r,new Map)}schema;functions;tables=new Map;subs=new Map;version=0;table(t){let n=this.tables.get(t);if(!n)throw new Error(`data: unknown table "${t}"`);return n}readDb(t){let n=this;return{get(r,o){return t?.rows.add(B(r,o)),n.table(r).get(o)??null},query(r){t?.tables.add(r);let o=[],s={withIndex(i,u){let a={eq(d,c){return o.push({col:d,val:c}),a}};return u(a),s},collect(){return[...n.table(r).values()].filter(u=>o.every(a=>u[a.col]===a.val))},first(){return[...n.table(r).values()].find(i=>o.every(u=>i[u.col]===u.val))??null}};return s}}}writeDb(t){let n=this,r=this.readDb(null);return{get:r.get,query:r.query,insert(o,s){n.table(o);let i=typeof s.id=="string"?s.id:E(),u=n.schema[o];if(!u)throw new Error(`data: unknown table "${o}"`);return u.schema.parse({...s,id:i}),n.table(o).set(i,{...s,id:i,_v:n.version}),t.push({table:o,id:i}),i},patch(o,s,i){let u=n.table(o).get(s);if(!u)throw new Error(`data: patch missing ${o}:${s}`);let a={...u,...i,id:s,_v:n.version},d=n.schema[o];if(!d)throw new Error(`data: unknown table "${o}"`);d.schema.parse(a),n.table(o).set(s,a),t.push({table:o,id:s})},delete(o,s){n.table(o).delete(s)&&t.push({table:o,id:s})}}}fn(t,n){let r=this.functions[t];if(!r)throw new Error(`data: unknown function "${t}"`);if(r.kind!==n)throw new Error(`data: "${t}" is a ${r.kind}, not a ${n}`);return r}runQuery(t,n){let r=this.fn(t,"query"),o={rows:new Set,tables:new Set};return{result:r.handler(this.readDb(o),r.args.parse(n)),readSet:o,version:this.version}}runMutation(t,n){let r=this.fn(t,"mutation"),o=[];this.version+=1;let s=r.handler(this.writeDb(o),r.args.parse(n)),i=new Set(o.map(d=>d.table)),u=new Set(o.map(d=>B(d.table,d.id))),a=[];for(let d of this.subs.values()){if(!([...d.readSet.tables].some(p=>i.has(p))||[...d.readSet.rows].some(p=>u.has(p))))continue;let l=this.runQuery(d.name,d.args);d.readSet=l.readSet,a.push({subId:d.subId,connId:d.connId,name:d.name,args:d.args,result:l.result,version:this.version})}return{result:s,version:this.version,transitions:a}}async runAction(t,n,r){let o=this.fn(t,"action"),s={runQuery:(i,u)=>this.runQuery(i,u).result,runMutation:(i,u)=>this.runMutation(i,u).result,...r?.runCordTool!==void 0?{runCordTool:r.runCordTool}:{}};return o.handler(s,o.args.parse(n))}subscribe(t,n,r,o){let{result:s,readSet:i,version:u}=this.runQuery(r,o);return this.subs.set(t,{subId:t,connId:n,name:r,args:o,readSet:i}),{result:s,version:u}}unsubscribe(t){this.subs.delete(t)}unsubscribeConn(t){for(let[n,r]of this.subs)r.connId===t&&this.subs.delete(n)}snapshot(){let t={};for(let[n,r]of this.tables)t[n]=[...r.values()];return{version:this.version,tables:t}}restore(t){this.version=t.version;for(let[n,r]of Object.entries(t.tables)){let o=this.tables.get(n)??new Map;o.clear();for(let s of r)o.set(s.id,s);this.tables.set(n,o)}}};async function yt(e,t,n="rpc"){try{switch(t.op){case"query":return{ok:!0,...e.runQuery(t.name,t.args)};case"subscribe":return{ok:!0,...e.subscribe(t.subId,n,t.name,t.args)};case"unsubscribe":return e.unsubscribe(t.subId),{ok:!0};case"mutation":return{ok:!0,...e.runMutation(t.name,t.args)};case"action":return{ok:!0,result:await e.runAction(t.name,t.args)};default:return{ok:!1,error:"unknown op"}}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}function vt(e){return{id:e.id,mount:"local",run:e.run}}function xt(e){return{id:e.id,mount:"registry",run:e.call}}var S=()=>typeof performance<"u"?performance.now():Date.now(),N=e=>({code:"cord.run",why:e instanceof Error?e.message:String(e)});function St(e){let t=e.guards??[],n=e.expose??{codemode:!0},r={id:e.id,version:"0.1.0",kind:e.kind??"agent-ful",inference:e.inference??"managed",...e.scope!==void 0?{scope:e.scope}:{},expose:n,subcords:Object.values(e.subcords??{}).map(s=>s.id),guards:t.map(s=>s.name),needs:e.needs??[]},o=async(s,i={})=>{let u=E(),a=i.tenantId??"local",d=i.scope??e.scope,c={cap:i.budget?.cap??64,used:0,depth:0,maxDepth:i.budget?.maxDepth??8},l=[],p=I(),m=g=>{l.push(g),i.onEvent?.(g);for(let f of t)f.onEvent?.(g)},b=(g,f,C,T,k,L)=>({ts:new Date().toISOString(),runId:u,tenantId:a,cordId:e.id,kind:g,name:f,durationMs:Math.round(C),ok:T,...d!==void 0?{scope:d}:{},...k!==void 0?{error:k}:{},...L!==void 0?{attrs:L}:{}}),R={cord:e.id,...d!==void 0?{scope:d}:{},input:s};for(let g of t)await g.onCall?.(R);p.append({actor:"deepsec",action:"run.authorize",scopeId:d??"",payload:{cord:e.id,tenantId:a}});let v={...i.resources};i.vault&&!v.vault&&(v.vault=i.vault);for(let g of e.needs??[])if(!v[g])throw new Error(`cord ${e.id}: required resource "${g}" not bound by the host`);let q={};for(let g of Object.keys(e.subcords??{})){let f=e.subcords[g];f&&(q[g]=async C=>{if(c.depth>=c.maxDepth)throw new Error(`cord: cycle-guard tripped (maxDepth ${c.maxDepth}) at ${f.id}`);if(c.used+1>c.cap)throw new Error(`cord: run budget exhausted (cap ${c.cap}) at ${f.id}`);c.used+=1,c.depth+=1;let T=S();try{let k=await f.run(C);return m(b("step",f.id,S()-T,!0)),k}catch(k){throw m(b("step",f.id,S()-T,!1,N(k))),k}finally{c.depth-=1}})}let F=S(),j;try{j=await e.run(s,q,v),m(b("turn",e.id,S()-F,!0,void 0,{used:c.used}))}catch(g){throw m(b("turn",e.id,S()-F,!1,N(g))),p.append({actor:"deepsec",action:"run.error",scopeId:d??"",payload:N(g)}),g}let A=j;for(let g of t)g.redact&&(A=g.redact(A));let x;if(v.vault){let g=`reports/${H(e.id)}/${u}.json`;x=await v.vault.put(g,JSON.stringify(A,null,2),{runId:u,tenantId:a,cord:e.id}),p.append({actor:"deepsec",action:"artifact.write",scopeId:d??"",payload:{key:x.key,version:x.version,hash:x.hash}})}return p.append({actor:"deepsec",action:"run.settle",scopeId:d??"",payload:{runId:u,ok:!0,used:c.used}}),{output:A,runId:u,...x!==void 0?{artifact:x}:{},audit:p.entries,events:l,budget:c}};return{id:e.id,expose:n,manifest:r,run:async(s,i)=>(await o(s,i)).output,runFull:o}}var Et=(e,t="https://host")=>({mcp:e.expose.mcp?[`${t}${e.expose.mcp}`]:[],docs:`${t}/llms.txt`,...e.expose.openapi?{openapi:`${t}/openapi.json`}:{},...e.expose.cli?{cli:`${t}/cli`}:{},skills:"/.well-known/agent-skills/",...e.scope?{auth:{type:"oauth2",scopes:[e.scope]}}:{}}),Rt=e=>({manifest:e,hash:h(JSON.stringify(e))});export{O as CHAT_CAPS,Q as DataEngine,Ge as accumToolCalls,ie as acquireExecutor,ue as acquireFs,oe as acquireGitHub,ae as acquireHttp,ht as action,Fe as agentEventStore,Ke as agentObserver,it as agentSession,ot as agentSessionFromEvents,te as analyticsEvlog,Be as askLedgerEvent,ne as auditStore,Te as bidirectionalSource,se as classifyTarget,ut as collectSink,je as cordRpc,Oe as createEmitter,yt as dataPlaneRpc,be as deepeval,we as deepsec,St as defineAgent,_e as defineAgentConfig,gt as defineSchema,pt as defineTable,De as defineTool,le as distill,at as distillWithModel,Ee as fakeInference,re as fileSetOf,Ie as githubCommitter,h as hashHex,Qe as isAskLedgerEvent,I as makeAuditChain,ve as memKv,fe as memVault,Se as minimalHarness,ft as mutation,E as newId,Re as portsAsTools,mt as query,Rt as signManifest,H as slug,We as sniffTurn,ct as storeSkillSink,Ve as tenantOfAgent,Y as toBase64,Pe as toolManifest,Ne as toolsToOpenAI,vt as use,xt as useRemote,Ye as usectx,He as validateMessages,Je as verifyAuditChain,V as verifyChain,Et as wellKnown,ee as wideEventToDataPoint};
package/dist/session.d.ts CHANGED
@@ -1,47 +1 @@
1
- import { verifyChain, type WideEvent, type AuditEntry } from "./guards.ts";
2
- export type SessionMode = "owned" | "attached" | "streamed";
3
- export type CaptureVector = "hook" | "proxy" | "watcher" | "backfill";
4
- /** A normalized coding-session event (mirrors lapdog/trajectory capture). */
5
- export type SessionEvent = {
6
- ts: string;
7
- kind: "lifecycle" | "prompt" | "model" | "tool_call" | "tool_result" | "permission";
8
- name: string;
9
- vector: CaptureVector;
10
- attrs?: Record<string, unknown>;
11
- tokensIn?: number;
12
- tokensOut?: number;
13
- costUsd?: number;
14
- };
15
- export type SessionStream = {
16
- mode: SessionMode;
17
- harness: string;
18
- runId: string;
19
- events: SessionEvent[];
20
- };
21
- export type Decision = "allow" | "deny" | "approve";
22
- export type Rule = {
23
- id: string;
24
- match: (e: SessionEvent) => boolean;
25
- decision: Decision;
26
- why: string;
27
- };
28
- export declare const DEFAULT_RULES: Rule[];
29
- export type Interception = {
30
- event: SessionEvent;
31
- rule: Rule;
32
- decision: Decision;
33
- enforceable: boolean;
34
- };
35
- export declare const intercept: (stream: SessionStream, rules?: Rule[]) => Interception[];
36
- export type SessionTrace = {
37
- runId: string;
38
- harness: string;
39
- mode: SessionMode;
40
- events: WideEvent[];
41
- audit: AuditEntry[];
42
- interceptions: Interception[];
43
- };
44
- export declare const ingestSession: (stream: SessionStream, rules?: Rule[]) => SessionTrace;
45
- export declare const fromTrajectoryJsonl: (jsonl: string, harness: string, mode?: SessionMode) => SessionStream;
46
- export { verifyChain };
47
- //# sourceMappingURL=session.d.ts.map
1
+ export * from "./types/session.js";
package/dist/session.js CHANGED
@@ -1,88 +1,2 @@
1
- // session.ts the Session seam (ADR-30): coding-ops over harness-agnostic LIVE sessions.
2
- //
3
- // Parallel to the Source seam (source.ts = static repos; this = live coding sessions). Three modes:
4
- // owned — op0 creates the session in our runtime (WfP/Sandbox): full control + full intercept.
5
- // attached — op0 drives an EXISTING session via the session-connector (local daemon, ADR-4d): partial.
6
- // streamed — op0 observes + intercepts a session it does NOT run, via the lapdog/trajectory pattern:
7
- // HOOKS = observe (fail-open, fire-and-forget) · model-PROXY = in-path = INTERCEPTABLE.
8
- // This is how we "audit work we're not controlling" AND keep a governance gate (deepsec)
9
- // on the proxy path even for sessions we didn't launch.
10
- //
11
- // Harness-agnostic (Claude Code / Codex / Cursor / Gemini / opencode / Copilot / Factory / Pi): MINE the
12
- // OSS reference `datadog-labs/trajectory` (per-client hook/proxy/watcher/backfill instrumentation) rather
13
- // than hand-rolling — the "check for an existing OSS framework first" lesson. *Verify its license before
14
- // adapting code; otherwise inspiration-only and build our thin capture on the same vectors.* Observability
15
- // is commoditized by Datadog (lapdog/trajectory) — our moat is the ACT half: govern · intercept · turn the
16
- // session into a governed onloop run · the flywheel. evlog ingests these traces as just another Source.
17
- //
18
- // Pure TS, zero deps (Node + Worker). Reuses the @op0-ai/cord guards so a streamed session yields the SAME
19
- // evlog WideEvents + tamper-evident audit as an owned cord run.
20
- import { makeAuditChain, verifyChain } from "./guards.js";
21
- import { newId } from "./hash.js";
22
- export const DEFAULT_RULES = [
23
- { id: "force-push", match: (e) => e.kind === "tool_call" && /\bgit\s+push\b.*--force(?!-with-lease)/.test(e.name), decision: "deny", why: "force-push without --force-with-lease" },
24
- { id: "rm-rf", match: (e) => e.kind === "tool_call" && /\brm\s+-rf\b/.test(e.name), decision: "approve", why: "destructive delete — needs human approval" },
25
- { id: "secret-exfil", match: (e) => e.kind === "tool_call" && /(curl|wget)\b.*(\.env|secret|token|key)/i.test(e.name), decision: "approve", why: "possible secret exfiltration" },
26
- ];
27
- // enforceable ONLY when the event is actionable: owned/attached (we drive it) or streamed-via-PROXY (in-path).
28
- // streamed-via-hook is observe-only (fail-open) → we can flag/audit but not block.
29
- const canEnforce = (mode, vector) => mode === "owned" || mode === "attached" || (mode === "streamed" && vector === "proxy");
30
- export const intercept = (stream, rules = DEFAULT_RULES) => {
31
- const out = [];
32
- for (const e of stream.events) {
33
- for (const r of rules) {
34
- if (r.match(e))
35
- out.push({ event: e, rule: r, decision: r.decision, enforceable: canEnforce(stream.mode, e.vector) });
36
- }
37
- }
38
- return out;
39
- };
40
- export const ingestSession = (stream, rules = DEFAULT_RULES) => {
41
- const chain = makeAuditChain();
42
- chain.append({ actor: "deepsec", action: "session.capture", scopeId: stream.mode, payload: { harness: stream.harness, mode: stream.mode } });
43
- const events = stream.events.map((e) => ({
44
- ts: e.ts, runId: stream.runId, tenantId: "op0", cordId: "@op0/coding-ops",
45
- kind: e.kind === "tool_call" || e.kind === "tool_result" ? "tool" : e.kind === "model" ? "model" : "step",
46
- name: e.name, durationMs: 0, ok: true,
47
- attrs: { vector: e.vector, ...(e.attrs ?? {}) },
48
- }));
49
- const interceptions = intercept(stream, rules);
50
- for (const i of interceptions) {
51
- chain.append({
52
- actor: "deepsec",
53
- action: i.enforceable ? `intercept.${i.decision}` : "intercept.flag",
54
- scopeId: stream.mode,
55
- payload: { rule: i.rule.id, why: i.rule.why, event: i.event.name, enforceable: i.enforceable },
56
- });
57
- }
58
- chain.append({ actor: "deepsec", action: "session.settle", scopeId: stream.mode, payload: { runId: stream.runId, events: events.length, interceptions: interceptions.length } });
59
- return { runId: stream.runId, harness: stream.harness, mode: stream.mode, events, audit: chain.entries, interceptions };
60
- };
61
- // --- streamed adapter: parse a lapdog/trajectory-style JSONL capture into a SessionStream ---
62
- // (lapdog hooks POST one JSON per event; trajectory writes JSONL timelines. This is a minimal normalized
63
- // subset for the spike; the real adapter maps each harness's hook/proxy schema — mine trajectory's.)
64
- export const fromTrajectoryJsonl = (jsonl, harness, mode = "streamed") => {
65
- const events = [];
66
- for (const line of jsonl.split("\n")) {
67
- const t = line.trim();
68
- if (!t)
69
- continue;
70
- let o;
71
- try {
72
- o = JSON.parse(t);
73
- }
74
- catch {
75
- continue;
76
- }
77
- events.push({
78
- ts: o.ts ?? new Date().toISOString(),
79
- kind: o.kind ?? "lifecycle",
80
- name: o.name ?? o.tool ?? o.event ?? "event",
81
- vector: o.vector ?? "hook",
82
- attrs: o.attrs, tokensIn: o.tokensIn, tokensOut: o.tokensOut, costUsd: o.costUsd,
83
- });
84
- }
85
- return { mode, harness, runId: newId(), events };
86
- };
87
- export { verifyChain };
88
- //# sourceMappingURL=session.js.map
1
+ var a=e=>{let n=2166136261;for(let o=0;o<e.length;o++)n^=e.charCodeAt(o),n=Math.imul(n,16777619);return(n>>>0).toString(16).padStart(8,"0")};var p=()=>Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,8);var l=e=>a([e.seq,e.ts,e.actor,e.action,e.scopeId,e.payloadHash,e.prevHash].join("|")),u=()=>{let e=[];return{entries:e,append({actor:n,action:o,scopeId:r,payload:s}){let t=e.length,i=new Date().toISOString(),g=t===0?"GENESIS":e[t-1]?.hash??"GENESIS",y=a(JSON.stringify(s??null)),c={seq:t,ts:i,actor:n,action:o,scopeId:r,payloadHash:y,prevHash:g},d={...c,hash:l(c)};return e.push(d),d}}},f=e=>{for(let n=0;n<e.length;n++){let o=e[n];if(!o)return!1;let r=n===0?"GENESIS":e[n-1]?.hash??"GENESIS";if(o.prevHash!==r)return!1;let{hash:s,...t}=o;if(s!==l(t))return!1}return!0};var h=[{id:"force-push",match:e=>e.kind==="tool_call"&&/\bgit\s+push\b.*--force(?!-with-lease)/.test(e.name),decision:"deny",why:"force-push without --force-with-lease"},{id:"rm-rf",match:e=>e.kind==="tool_call"&&/\brm\s+-rf\b/.test(e.name),decision:"approve",why:"destructive delete \u2014 needs human approval"},{id:"secret-exfil",match:e=>e.kind==="tool_call"&&/(curl|wget)\b.*(\.env|secret|token|key)/i.test(e.name),decision:"approve",why:"possible secret exfiltration"}],m=(e,n)=>e==="owned"||e==="attached"||e==="streamed"&&n==="proxy",v=(e,n=h)=>{let o=[];for(let r of e.events)for(let s of n)s.match(r)&&o.push({event:r,rule:s,decision:s.decision,enforceable:m(e.mode,r.vector)});return o},I=(e,n=h)=>{let o=u();o.append({actor:"deepsec",action:"session.capture",scopeId:e.mode,payload:{harness:e.harness,mode:e.mode}});let r=e.events.map(t=>({ts:t.ts,runId:e.runId,tenantId:"op0",cordId:"@op0/coding-ops",kind:t.kind==="tool_call"||t.kind==="tool_result"?"tool":t.kind==="model"?"model":"step",name:t.name,durationMs:0,ok:!0,attrs:{vector:t.vector,...t.attrs??{}}})),s=v(e,n);for(let t of s)o.append({actor:"deepsec",action:t.enforceable?`intercept.${t.decision}`:"intercept.flag",scopeId:e.mode,payload:{rule:t.rule.id,why:t.rule.why,event:t.event.name,enforceable:t.enforceable}});return o.append({actor:"deepsec",action:"session.settle",scopeId:e.mode,payload:{runId:e.runId,events:r.length,interceptions:s.length}}),{runId:e.runId,harness:e.harness,mode:e.mode,events:r,audit:o.entries,interceptions:s}},b=(e,n,o="streamed")=>{let r=[];for(let s of e.split(`
2
+ `)){let t=s.trim();if(!t)continue;let i;try{i=JSON.parse(t)}catch{continue}r.push({ts:i.ts??new Date().toISOString(),kind:i.kind??"lifecycle",name:i.name??i.tool??i.event??"event",vector:i.vector??"hook",attrs:i.attrs,tokensIn:i.tokensIn,tokensOut:i.tokensOut,costUsd:i.costUsd})}return{mode:o,harness:n,runId:p(),events:r}};export{h as DEFAULT_RULES,b as fromTrajectoryJsonl,I as ingestSession,v as intercept,f as verifyChain};
@@ -17,7 +17,6 @@ export declare const fakeInference: (script: Array<{
17
17
  /**
18
18
  * portsAsTools — expose selected resource ports to the agent as callable tools. THIS is governed-tools = ports:
19
19
  * the agent can only act through capabilities the cord declared + the host bound. `onTool` lets the cord audit
20
- * every call (one wide-event per action). ponytail: only the ports you pass become tools — nothing else.
20
+ * every call (one wide-event per action). Only the ports you pass become tools — nothing else.
21
21
  */
22
22
  export declare const portsAsTools: (res: Resources, onTool?: (name: string, args: Record<string, unknown>) => void) => ToolSpec[];
23
- //# sourceMappingURL=agent.d.ts.map
@@ -84,4 +84,3 @@ export interface Emitter {
84
84
  errored(error: string): void;
85
85
  }
86
86
  export declare function createEmitter(runId: string, sink: AgentEventSink): Emitter;
87
- //# sourceMappingURL=agui.d.ts.map
@@ -75,4 +75,3 @@ export declare function toolsToOpenAI(tools: readonly Tool[] | ToolSet): Array<{
75
75
  parameters: unknown;
76
76
  };
77
77
  }>;
78
- //# sourceMappingURL=config.d.ts.map
@@ -39,4 +39,3 @@ export declare function accumToolCalls(acc: Record<number, ToolCallAccum>, delta
39
39
  arguments?: string;
40
40
  };
41
41
  }>): Record<number, ToolCallAccum>;
42
- //# sourceMappingURL=contract.d.ts.map
@@ -165,4 +165,3 @@ export type DataResponse = {
165
165
  */
166
166
  export declare function dataPlaneRpc(engine: DataEngine, req: DataRequest, connId?: string): Promise<DataResponse>;
167
167
  export {};
168
- //# sourceMappingURL=data.d.ts.map
@@ -27,4 +27,3 @@ export interface AgentRpcContext {
27
27
  * This is the server half of the thin typed client (client.tsx). RPC edits commit immediately (no debounce).
28
28
  */
29
29
  export declare function cordRpc(request: Request, ctx: AgentRpcContext): Promise<Response>;
30
- //# sourceMappingURL=define.d.ts.map
@@ -65,4 +65,3 @@ export interface SkillStore {
65
65
  export declare function storeSkillSink(store: SkillStore, opts?: {
66
66
  prefix?: string;
67
67
  }): SkillSink;
68
- //# sourceMappingURL=distill.d.ts.map
@@ -36,4 +36,3 @@ export declare function askLedgerEvent(fields: Omit<AskLedgerEvent, "kind" | "at
36
36
  export declare function isAskLedgerEvent(r: unknown): r is AskLedgerEvent;
37
37
  /** The tenant a cord addr belongs to under the LOCKED `<team>--<name>` scheme; null = solo/untenanted. */
38
38
  export declare const tenantOfAgent: (cord: string) => string | null;
39
- //# sourceMappingURL=events.d.ts.map
@@ -68,4 +68,3 @@ export declare function agentObserver(opts: {
68
68
  host: SqlHost;
69
69
  analytics?: AnalyticsSink;
70
70
  }): AgentObserver;
71
- //# sourceMappingURL=evlog.d.ts.map
@@ -0,0 +1,60 @@
1
+ export type GuardEvent = {
2
+ cord: string;
3
+ tool?: string;
4
+ scope?: string;
5
+ input: unknown;
6
+ };
7
+ export type WideEvent = {
8
+ ts: string;
9
+ runId: string;
10
+ tenantId: string;
11
+ cordId: string;
12
+ kind: "turn" | "step" | "model" | "tool" | "eval";
13
+ name: string;
14
+ durationMs: number;
15
+ ok: boolean;
16
+ scope?: string;
17
+ error?: {
18
+ code: string;
19
+ why: string;
20
+ };
21
+ attrs?: Record<string, unknown>;
22
+ };
23
+ export type AuditEntry = {
24
+ seq: number;
25
+ ts: string;
26
+ actor: string;
27
+ action: string;
28
+ scopeId: string;
29
+ payloadHash: string;
30
+ prevHash: string;
31
+ hash: string;
32
+ };
33
+ export type Guard = {
34
+ name: string;
35
+ /** Gate hook: deny by throwing (deepsec scope check), or instrument by side-effect. */
36
+ onCall?: (ev: GuardEvent) => void | Promise<void>;
37
+ /** Output transform applied before persist/export (deepsec redaction). */
38
+ redact?: <T>(value: T) => T;
39
+ /** Wide-event sink (deepeval instrumentation). */
40
+ onEvent?: (e: WideEvent) => void;
41
+ };
42
+ export type AuditChain = {
43
+ entries: AuditEntry[];
44
+ append(e: {
45
+ actor: string;
46
+ action: string;
47
+ scopeId: string;
48
+ payload: unknown;
49
+ }): AuditEntry;
50
+ };
51
+ export declare const makeAuditChain: () => AuditChain;
52
+ /** Re-derive every hash; any insert/edit/delete breaks the chain → returns false. (The S7 red test.) */
53
+ export declare const verifyChain: (entries: AuditEntry[]) => boolean;
54
+ /** deepsec — scope gate + redaction (ADR-10). The runtime also drives an audit chain tagged actor="deepsec". */
55
+ export declare const deepsec: (opts?: {
56
+ allow?: string[];
57
+ secrets?: RegExp[];
58
+ }) => Guard;
59
+ /** deepeval — instruments every run (ADR-24). Collects wide-events; prod forwards to evlog (OTLP + PostHog). */
60
+ export declare const deepeval: (sink?: WideEvent[]) => Guard;
@@ -0,0 +1,5 @@
1
+ export declare const hashHex: (s: string) => string;
2
+ /** A url-safe slug for vault keys (target → reports/<slug>/<runId>.json). */
3
+ export declare const slug: (s: string) => string;
4
+ /** A short, sortable-ish run id (timestamp + entropy). No node: deps. */
5
+ export declare const newId: () => string;