stable-harness 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +32 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +2 -0
  4. package/dist/compat/agent-harness.d.ts +24 -0
  5. package/dist/compat/agent-harness.js +1 -0
  6. package/dist/index.d.ts +13 -0
  7. package/dist/index.js +1 -0
  8. package/dist/runtime/compat/agent-harness-compat-runner.d.ts +2 -0
  9. package/dist/runtime/compat/agent-harness-compat-runner.js +1 -0
  10. package/dist/runtime/compat/json.d.ts +3 -0
  11. package/dist/runtime/compat/json.js +1 -0
  12. package/dist/runtime/compat/presentation.d.ts +1 -0
  13. package/dist/runtime/compat/presentation.js +1 -0
  14. package/dist/runtime/compat/prompts.d.ts +24 -0
  15. package/dist/runtime/compat/prompts.js +1 -0
  16. package/dist/runtime/compat/tool-registry.d.ts +3 -0
  17. package/dist/runtime/compat/tool-registry.js +1 -0
  18. package/dist/runtime/compat/types.d.ts +38 -0
  19. package/dist/runtime/compat/types.js +1 -0
  20. package/dist/runtime/model/ollama.d.ts +2 -0
  21. package/dist/runtime/model/ollama.js +1 -0
  22. package/dist/runtime/skills/skill-metadata.d.ts +7 -0
  23. package/dist/runtime/skills/skill-metadata.js +1 -0
  24. package/dist/runtime/workspace/types.d.ts +38 -0
  25. package/dist/runtime/workspace/types.js +1 -0
  26. package/dist/tools.d.ts +12 -0
  27. package/dist/tools.js +1 -0
  28. package/dist/workspace/compile.d.ts +2 -0
  29. package/dist/workspace/compile.js +1 -0
  30. package/package.json +94 -0
  31. package/packages/adapter-deepagents/dist/src/adapter.d.ts +8 -0
  32. package/packages/adapter-deepagents/dist/src/adapter.js +1 -0
  33. package/packages/adapter-deepagents/dist/src/builtin-tool-policy.d.ts +18 -0
  34. package/packages/adapter-deepagents/dist/src/builtin-tool-policy.js +1 -0
  35. package/packages/adapter-deepagents/dist/src/index.d.ts +2 -0
  36. package/packages/adapter-deepagents/dist/src/index.js +1 -0
  37. package/packages/adapter-deepagents/dist/src/messages.d.ts +9 -0
  38. package/packages/adapter-deepagents/dist/src/messages.js +1 -0
  39. package/packages/adapter-deepagents/dist/src/retry-policy.d.ts +2 -0
  40. package/packages/adapter-deepagents/dist/src/retry-policy.js +1 -0
  41. package/packages/adapter-deepagents/dist/src/stream-events.d.ts +2 -0
  42. package/packages/adapter-deepagents/dist/src/stream-events.js +1 -0
  43. package/packages/adapter-deepagents/dist/src/types.d.ts +6 -0
  44. package/packages/adapter-deepagents/dist/src/types.js +1 -0
  45. package/packages/adapter-deepagents/package.json +26 -0
  46. package/packages/cli/dist/src/cli.d.ts +2 -0
  47. package/packages/cli/dist/src/cli.js +2 -0
  48. package/packages/cli/dist/src/index.d.ts +1 -0
  49. package/packages/cli/dist/src/index.js +1 -0
  50. package/packages/cli/package.json +22 -0
  51. package/packages/core/dist/artifacts.d.ts +8 -0
  52. package/packages/core/dist/artifacts.js +1 -0
  53. package/packages/core/dist/execution-contract.d.ts +8 -0
  54. package/packages/core/dist/execution-contract.js +1 -0
  55. package/packages/core/dist/index.d.ts +9 -0
  56. package/packages/core/dist/index.js +1 -0
  57. package/packages/core/dist/inspection.d.ts +4 -0
  58. package/packages/core/dist/inspection.js +1 -0
  59. package/packages/core/dist/memory-plugins.d.ts +68 -0
  60. package/packages/core/dist/memory-plugins.js +1 -0
  61. package/packages/core/dist/queue.d.ts +2 -0
  62. package/packages/core/dist/queue.js +1 -0
  63. package/packages/core/dist/runtime.d.ts +12 -0
  64. package/packages/core/dist/runtime.js +1 -0
  65. package/packages/core/dist/stores.d.ts +3 -0
  66. package/packages/core/dist/stores.js +1 -0
  67. package/packages/core/dist/trace.d.ts +15 -0
  68. package/packages/core/dist/trace.js +1 -0
  69. package/packages/core/dist/types.d.ts +526 -0
  70. package/packages/core/dist/types.js +1 -0
  71. package/packages/core/package.json +17 -0
  72. package/packages/evaluation/dist/src/index.d.ts +2 -0
  73. package/packages/evaluation/dist/src/index.js +1 -0
  74. package/packages/evaluation/dist/src/trace.d.ts +16 -0
  75. package/packages/evaluation/dist/src/trace.js +1 -0
  76. package/packages/evaluation/dist/src/types.d.ts +11 -0
  77. package/packages/evaluation/dist/src/types.js +1 -0
  78. package/packages/evaluation/package.json +15 -0
  79. package/packages/governance/dist/src/approval-queue.d.ts +2 -0
  80. package/packages/governance/dist/src/approval-queue.js +1 -0
  81. package/packages/governance/dist/src/index.d.ts +4 -0
  82. package/packages/governance/dist/src/index.js +1 -0
  83. package/packages/governance/dist/src/policy-engine.d.ts +2 -0
  84. package/packages/governance/dist/src/policy-engine.js +1 -0
  85. package/packages/governance/dist/src/skill-candidates.d.ts +2 -0
  86. package/packages/governance/dist/src/skill-candidates.js +1 -0
  87. package/packages/governance/dist/src/types.d.ts +100 -0
  88. package/packages/governance/dist/src/types.js +1 -0
  89. package/packages/governance/package.json +12 -0
  90. package/packages/memory/dist/src/index.d.ts +9 -0
  91. package/packages/memory/dist/src/index.js +1 -0
  92. package/packages/memory/dist/src/langmem-service.d.ts +8 -0
  93. package/packages/memory/dist/src/langmem-service.js +1 -0
  94. package/packages/memory/dist/src/maintenance.d.ts +2 -0
  95. package/packages/memory/dist/src/maintenance.js +1 -0
  96. package/packages/memory/dist/src/persistence.d.ts +4 -0
  97. package/packages/memory/dist/src/persistence.js +1 -0
  98. package/packages/memory/dist/src/policy.d.ts +2 -0
  99. package/packages/memory/dist/src/policy.js +1 -0
  100. package/packages/memory/dist/src/provider.d.ts +50 -0
  101. package/packages/memory/dist/src/provider.js +1 -0
  102. package/packages/memory/dist/src/store.d.ts +5 -0
  103. package/packages/memory/dist/src/store.js +1 -0
  104. package/packages/memory/dist/src/types.d.ts +138 -0
  105. package/packages/memory/dist/src/types.js +1 -0
  106. package/packages/memory/package.json +12 -0
  107. package/packages/protocols/dist/src/http-server.d.ts +3 -0
  108. package/packages/protocols/dist/src/http-server.js +1 -0
  109. package/packages/protocols/dist/src/in-process-client.d.ts +2 -0
  110. package/packages/protocols/dist/src/in-process-client.js +1 -0
  111. package/packages/protocols/dist/src/index.d.ts +4 -0
  112. package/packages/protocols/dist/src/index.js +1 -0
  113. package/packages/protocols/dist/src/openai-compatible.d.ts +9 -0
  114. package/packages/protocols/dist/src/openai-compatible.js +1 -0
  115. package/packages/protocols/package.json +15 -0
  116. package/packages/tool-gateway/dist/src/argument-guard.d.ts +32 -0
  117. package/packages/tool-gateway/dist/src/argument-guard.js +1 -0
  118. package/packages/tool-gateway/dist/src/in-memory.d.ts +4 -0
  119. package/packages/tool-gateway/dist/src/in-memory.js +1 -0
  120. package/packages/tool-gateway/dist/src/index.d.ts +7 -0
  121. package/packages/tool-gateway/dist/src/index.js +1 -0
  122. package/packages/tool-gateway/dist/src/module-loader.d.ts +13 -0
  123. package/packages/tool-gateway/dist/src/module-loader.js +1 -0
  124. package/packages/tool-gateway/dist/src/types.d.ts +65 -0
  125. package/packages/tool-gateway/dist/src/types.js +1 -0
  126. package/packages/tool-gateway/package.json +15 -0
  127. package/packages/workspace-yaml/dist/index.d.ts +1 -0
  128. package/packages/workspace-yaml/dist/index.js +1 -0
  129. package/packages/workspace-yaml/dist/loader.d.ts +2 -0
  130. package/packages/workspace-yaml/dist/loader.js +1 -0
  131. package/packages/workspace-yaml/package.json +16 -0
@@ -0,0 +1,8 @@
1
+ import type { RuntimeArtifactRecord, RuntimeArtifactStore } from "./types.js";
2
+ type ArtifactState = {
3
+ records: RuntimeArtifactRecord[];
4
+ contents: Record<string, unknown>;
5
+ };
6
+ export declare function createInMemoryArtifactStore(initial?: ArtifactState): RuntimeArtifactStore;
7
+ export declare function createJsonFileArtifactStore(filePath: string): RuntimeArtifactStore;
8
+ export {};
@@ -0,0 +1 @@
1
+ import{existsSync as t,mkdirSync as e,readFileSync as r,writeFileSync as n}from"node:fs";import i from"node:path";export function createInMemoryArtifactStore(t){const e=new Map((t?.records??[]).map(t=>[t.id,s(t)])),r=new Map(Object.entries(t?.contents??{}).map(([t,e])=>[t,structuredClone(e)]));return{createArtifact(t){const n=function(t){return{id:t.id,kind:t.kind,uri:t.uri,metadata:t.metadata,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agentId,contentType:t.contentType,createdAt:t.createdAt??(new Date).toISOString(),size:(e=t.content,Buffer.byteLength(JSON.stringify(e??null),"utf8"))};var e}(t);return e.set(n.id,n),r.set(n.id,structuredClone(t.content??null)),s(n)},listArtifacts:t=>[...e.values()].filter(e=>function(t,e){return!e||!(e.requestId&&e.requestId!==t.requestId||e.sessionId&&e.sessionId!==t.sessionId||e.agentId&&e.agentId!==t.agentId)}(e,t)).map(s),readArtifact(t){if(!r.has(t))throw new Error(`Artifact not found: ${t}`);return structuredClone(r.get(t))}}}export function createJsonFileArtifactStore(s){const o=i.resolve(s),c=createInMemoryArtifactStore(function(e){if(!t(e))return{records:[],contents:{}};const n=JSON.parse(r(e,"utf8"));if("object"!=typeof(i=n)||null===i||!Array.isArray(i.records)||"object"!=typeof i.contents)throw new Error(`Invalid artifact store file: ${e}`);var i;return n}(o));return{createArtifact(t){const r=c.createArtifact(t);return function(t,r){e(i.dirname(t),{recursive:!0}),n(t,`${JSON.stringify({version:1,...r},null,2)}\n`)}(o,function(t){const e=t.listArtifacts(),r=Object.fromEntries(e.map(e=>[e.id,t.readArtifact(e.id)]));return{records:e,contents:r}}(c)),r},listArtifacts:t=>c.listArtifacts(t),readArtifact:t=>c.readArtifact(t)}}function s(t){return structuredClone(t)}
@@ -0,0 +1,8 @@
1
+ import type { RuntimeEmit, RuntimeStore, WorkspaceAgent } from "./types.js";
2
+ export declare function assertExecutionContract(input: {
3
+ store: RuntimeStore;
4
+ emit: RuntimeEmit;
5
+ requestId: string;
6
+ sessionId: string;
7
+ agent: WorkspaceAgent;
8
+ }): void;
@@ -0,0 +1 @@
1
+ export function assertExecutionContract(n){!function(n){if(!e(n.agent).requiresPlan)return;const o=n.store.getRun(n.requestId);if(!(o?.events??[]).flatMap(t).includes("write_todos"))throw n.emit({type:"execution.contract.failed",requestId:n.requestId,sessionId:n.sessionId,agentId:n.agent.id,reason:"missing_plan"}),new Error("Execution contract requires a planning checkpoint: write_todos")}(n),function(n){const o=function(t){const n=e(t).requiredEvidenceTools;return Array.isArray(n)?n.filter(e=>"string"==typeof e):[]}(n.agent);if(0===o.length)return;const r=n.store.getRun(n.requestId),i=new Set((r?.events??[]).flatMap(t)),s=o.filter(e=>!i.has(e));if(0!==s.length)throw n.emit({type:"execution.contract.failed",requestId:n.requestId,sessionId:n.sessionId,agentId:n.agent.id,reason:"missing_required_evidence",missingEvidenceTools:s}),new Error(`Execution contract missing required evidence tools: ${s.join(", ")}`)}(n)}function e(e){return n(e.config.executionContract)?e.config.executionContract:{}}function t(e){return"tool.completed"===e.type?[e.toolId]:"adapter.event"===e.type&&n(e.event)&&"tool.result"===e.event.phase&&"string"==typeof e.event.toolId?[e.event.toolId]:[]}function n(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -0,0 +1,9 @@
1
+ export * from "./artifacts.js";
2
+ export * from "./execution-contract.js";
3
+ export * from "./inspection.js";
4
+ export * from "./memory-plugins.js";
5
+ export * from "./queue.js";
6
+ export * from "./runtime.js";
7
+ export * from "./stores.js";
8
+ export * from "./trace.js";
9
+ export * from "./types.js";
@@ -0,0 +1 @@
1
+ export*from"./artifacts.js";export*from"./execution-contract.js";export*from"./inspection.js";export*from"./memory-plugins.js";export*from"./queue.js";export*from"./runtime.js";export*from"./stores.js";export*from"./trace.js";export*from"./types.js";
@@ -0,0 +1,4 @@
1
+ import type { CompiledWorkspace, RuntimeRequestInspection, RuntimeRequestSummary, RuntimeRunRecord, RuntimeSessionSummary } from "./types.js";
2
+ export declare function projectRequestSummary(run: RuntimeRunRecord): RuntimeRequestSummary;
3
+ export declare function projectSessionSummaries(runs: RuntimeRunRecord[]): RuntimeSessionSummary[];
4
+ export declare function projectRequestInspection(workspace: CompiledWorkspace, run: RuntimeRunRecord): RuntimeRequestInspection;
@@ -0,0 +1 @@
1
+ export function projectRequestSummary(t){return{requestId:t.requestId,sessionId:t.sessionId,agentId:t.agentId,parentRunId:t.parentRunId,state:t.state,startedAt:t.startedAt,completedAt:t.completedAt,eventCount:t.events.length,artifactCount:t.artifacts.length}}export function projectSessionSummaries(t){const e=new Map;for(const n of t)e.set(n.sessionId,[...e.get(n.sessionId)??[],n]);return[...e.entries()].map(([t,e])=>function(t,e){const r=[...e].sort((t,e)=>t.startedAt.localeCompare(e.startedAt));return{sessionId:t,requestCount:e.length,agentIds:[...new Set(e.map(t=>t.agentId))].sort(),states:n(e),startedAt:r[0]?.startedAt??"",updatedAt:s(e)}}(t,e)).sort((t,e)=>e.updatedAt.localeCompare(t.updatedAt))}export function projectRequestInspection(n,s){return{summary:projectRequestSummary(s),input:s.input,output:s.output,error:s.error,metadata:s.metadata,artifacts:s.artifacts,runtimeSnapshot:t(n,s.agentId),timeline:e(s)}}function t(t,e){const n=t.agents.get(e);return{workspaceRoot:t.root,agentId:e,backend:n?.backend??"unknown",modelRef:n?.modelRef,tools:[...n?.tools??[]],skills:[...n?.skills??[]],subagents:[...n?.subagents??[]]}}function e(t){return t.events.map((t,e)=>({index:e,type:t.type,event:t}))}function n(t){return t.reduce((t,e)=>(t[e.state]=(t[e.state]??0)+1,t),{})}function s(t){return t.map(t=>t.completedAt??t.startedAt).sort((t,e)=>e.localeCompare(t))[0]??""}
@@ -0,0 +1,68 @@
1
+ import type { MemoryMaintenanceOperation, MemoryProvider, MemoryRecord } from "@stable-harness/memory";
2
+ import type { ApprovalQueue, SkillCandidateStore } from "@stable-harness/governance";
3
+ import type { CompiledWorkspace, RuntimeEmit, RuntimeOutput, RuntimeRequest, WorkspaceAgent, WorkspaceMemory } from "./types.js";
4
+ export type MemoryMaintenanceTarget = {
5
+ name: string;
6
+ run(input: MemoryMaintenanceTargetInput): Promise<MemoryMaintenanceResult>;
7
+ };
8
+ export type MemoryMaintenanceTargetInput = {
9
+ emit: RuntimeEmit;
10
+ requestId: string;
11
+ sessionId: string;
12
+ agent: WorkspaceAgent;
13
+ workspace: CompiledWorkspace;
14
+ prompt: string;
15
+ };
16
+ export type MemoryMaintenanceResult = {
17
+ operations?: MemoryMaintenanceOperation[];
18
+ metadata?: Record<string, unknown>;
19
+ };
20
+ export type MemoryMaintenanceDaemon = {
21
+ runOnce(input?: Partial<Pick<MemoryMaintenanceTargetInput, "requestId" | "sessionId" | "agent">>): Promise<MemoryMaintenanceResult[]>;
22
+ start(): void;
23
+ stop(): void;
24
+ };
25
+ export declare function runMemoryPlugins(input: {
26
+ providers: MemoryProvider[] | undefined;
27
+ emit: RuntimeEmit;
28
+ request: RuntimeRequest;
29
+ requestId: string;
30
+ sessionId: string;
31
+ agent: WorkspaceAgent;
32
+ workspace: CompiledWorkspace;
33
+ result: RuntimeOutput;
34
+ }): Promise<void>;
35
+ export declare function recallMemoryPlugins(input: {
36
+ providers: MemoryProvider[] | undefined;
37
+ request: RuntimeRequest;
38
+ agent: WorkspaceAgent;
39
+ workspace: CompiledWorkspace;
40
+ }): Promise<Array<{
41
+ namespace: string;
42
+ records: MemoryRecord[];
43
+ context: string;
44
+ }>>;
45
+ export declare function resolveEnabledMemories(workspace: CompiledWorkspace, phase?: "all" | "recall" | "write"): WorkspaceMemory[];
46
+ export declare function resolveDeepAgentsNativeMemories(workspace: CompiledWorkspace): WorkspaceMemory[];
47
+ export declare function createMemoryMaintenanceDaemon(input: {
48
+ workspace: CompiledWorkspace;
49
+ emit?: RuntimeEmit;
50
+ targets: MemoryMaintenanceTarget[];
51
+ intervalMs?: number;
52
+ prompt?: string;
53
+ defaultAgentId?: string;
54
+ }): MemoryMaintenanceDaemon;
55
+ export declare function createLangMemMaintenanceTarget(input: {
56
+ providers: MemoryProvider[] | undefined;
57
+ limit?: number;
58
+ }): MemoryMaintenanceTarget;
59
+ export declare function createDeepAgentsMemoryMaintenanceTarget(input?: {
60
+ run?: (context: MemoryMaintenanceTargetInput) => Promise<MemoryMaintenanceResult>;
61
+ }): MemoryMaintenanceTarget;
62
+ export declare function createSkillCandidateMinerTarget(input: {
63
+ providers: MemoryProvider[] | undefined;
64
+ store: SkillCandidateStore;
65
+ approvals?: ApprovalQueue;
66
+ minEvidenceCount?: number;
67
+ }): MemoryMaintenanceTarget;
68
+ export declare function resolvePluginNamespace(workspace: CompiledWorkspace, agent: WorkspaceAgent, request: RuntimeRequest, memory: WorkspaceMemory): string;
@@ -0,0 +1 @@
1
+ export async function runMemoryPlugins(n){const t=resolveEnabledMemories(n.workspace,"write");if(n.providers?.length&&0!==t.length&&!1!==n.request.metadata?.memoryWrite)for(const r of t)await e(n,r)}export async function recallMemoryPlugins(e){const t=resolveEnabledMemories(e.workspace,"recall");if(!e.providers?.length||0===t.length)return[];const o=await Promise.all(t.map(async t=>async function(e,t){const o=n(e.providers??[],t.provider);if(!o)return;const s=resolvePluginNamespace(e.workspace,e.agent,e.request,t),i=await o.search({namespace:s,query:r(e),limit:a(e.workspace)});return{namespace:s,records:i,context:i.map(e=>`- ${e.summary??e.content}\n ${e.content}`).join("\n")}}(e,t)));return o.filter(e=>Boolean(e?.context))}export function resolveEnabledMemories(e,n="all"){const t=e.runtime.memory??{};if(!function(e,n){return!1!==e.enabled&&("recall"!==n||!1!==e.recall&&!1!==e.read&&!1!==m(e,"LangMem","read"))&&("write"!==n||!1!==e.write&&!1!==m(e,"LangMem","write"))}(t,n))return[];const r=Array.isArray(t.refs)?t.refs.filter(e=>"string"==typeof e):[];return(r.length>0?r:[...e.memories.keys()]).map(n=>e.memories.get(n)).filter(e=>Boolean(e?.enabled))}export function resolveDeepAgentsNativeMemories(e){return!1===m(e.runtime.memory??{},"deepagentsMem","read")?[]:resolveEnabledMemories(e,"all")}export function createMemoryMaintenanceDaemon(e){let n;const r=e.emit??(()=>{});return{async runOnce(n={}){const a=n.agent??function(e,n){const t=e.agents.get(n??e.runtime.defaultAgentId);if(!t)throw new Error("Memory maintenance requires a configured default agent");return t}(e.workspace,e.defaultAgentId),o={emit:r,requestId:n.requestId??`memory-maintenance-${Date.now()}`,sessionId:n.sessionId??"memory-maintenance",agent:a,workspace:e.workspace,prompt:e.prompt??d(e.workspace)},s=[];for(const n of e.targets)s.push(await t(o,n));return s},start(){e.intervalMs&&!n&&(n=setInterval(()=>{this.runOnce()},e.intervalMs))},stop(){n&&(clearInterval(n),n=void 0)}}}export function createLangMemMaintenanceTarget(e){return{name:"LangMem",async run(t){const r=[];for(const a of resolveEnabledMemories(t.workspace,"write")){const s=n(e.providers??[],a.provider);if(!s)continue;const i=resolvePluginNamespace(t.workspace,t.agent,{input:"",sessionId:t.sessionId},a),c=o(await s.search({namespace:i,query:t.prompt,limit:e.limit??100}),await s.search({namespace:i,query:"",limit:e.limit??100}));r.push(...await s.consolidate({records:c}))}return{operations:r}}}}export function createDeepAgentsMemoryMaintenanceTarget(e={}){return{name:"deepagentsMem",run:async n=>e.run?e.run(n):{operations:[],metadata:{skipped:!0,reason:"No DeepAgents memory maintainer configured"}}}}export function createSkillCandidateMinerTarget(e){return{name:"skillCandidateMiner",async run(t){const r=await async function(e,t){const r=[];for(const a of resolveEnabledMemories(t.workspace,"all")){const s=n(e??[],a.provider);if(!s)continue;const i=resolvePluginNamespace(t.workspace,t.agent,{input:"",sessionId:t.sessionId},a);r.push(...o(await s.search({namespace:i,query:t.prompt,limit:100}),await s.search({namespace:i,query:"",limit:100})))}return o(r,[])}(e.providers,t),a=function(e){const n=new Map;for(const t of e){const e=s(t);e&&n.set(e,[...n.get(e)??[],t])}return n}(r),c=[];for(const[n,r]of a){if(r.length<(e.minEvidenceCount??3))continue;const a=await e.store.upsert(i(t.workspace,n,r));c.push(a),t.emit({type:"skill.candidate.created",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,candidateId:a.id,name:a.name,confidence:a.confidence,evidenceCount:a.evidenceCount,status:a.status,proposedPath:a.proposedPath}),await(e.approvals?.create({kind:"skill_candidate",reason:`Review mined skill candidate ${a.name}`,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,subject:{candidate:a}}))}return{operations:[],metadata:{candidateCount:c.length}}}}}export function resolvePluginNamespace(e,n,t,r){const a=p(e),o=r.profile??r.id;return"agent"===o?`${a}:agent:${n.id}:${r.id}`:"user"===o?`${a}:user:${function(e){return e.metadata?.userId??"local"}(t)}:${r.id}`:"session"===o?`${a}:session:${t.sessionId??"default"}:${r.id}`:`${a}:${o}:${r.id}`}async function e(e,t){const r=n(e.providers??[],t.provider);if(!r)return;const a=resolvePluginNamespace(e.workspace,e.agent,e.request,t);e.emit({type:"memory.plugin.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,memoryId:t.id,provider:r.name,namespace:a});try{const n=await r.propose(function(e,n,t){return{namespace:t,content:[`User input:\n${e.request.input}`,`Agent output:\n${e.result.text}`].join("\n\n"),sourceType:"runtime-run",sourceRef:e.requestId,metadata:{memoryId:n.id,provider:n.provider,profile:n.profile,mode:n.mode,prompts:n.prompts,workspaceRoot:e.workspace.root,agentId:e.agent.id,sessionId:e.sessionId,requestMetadata:e.request.metadata}}}(e,t,a));e.emit({type:"memory.plugin.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,memoryId:t.id,provider:r.name,namespace:a,candidateCount:n.length})}catch(n){e.emit({type:"memory.plugin.failed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,memoryId:t.id,provider:r.name,namespace:a,error:l(n)})}}function n(e,n){return e.find(e=>e.name===n||e.name===`${n}-service`)}async function t(e,n){e.emit({type:"memory.maintenance.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,target:n.name});try{const t=await n.run(e);return e.emit({type:"memory.maintenance.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,target:n.name,operationCount:t.operations?.length??0}),t}catch(t){return e.emit({type:"memory.maintenance.failed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,target:n.name,error:l(t)}),{operations:[],metadata:{error:l(t)}}}}function r(e){const n=[`task: ${e.request.input}`,`workspace: ${p(e.workspace)}`,`agent: ${e.agent.id}`,"memory_needed: durable preferences, workspace facts, reusable procedures, prior corrections"],t=(r=e.request.metadata,"string"==typeof r?.recentContext?r.recentContext.slice(0,3e3):Array.isArray(r?.recentTurns)?r.recentTurns.filter(e=>"string"==typeof e).slice(-6).join("\n").slice(0,3e3):void 0);var r;return t?[...n,`recent_context: ${t}`].join("\n"):n.join("\n")}function a(e){const n=u(e.runtime.memory?.LangMem),t=u(n?.recall),r=t?.topK??t?.limit;return"number"==typeof r&&Number.isFinite(r)?r:10}function o(e,n){const t=new Map;for(const r of[...e,...n])t.set(r.id,r);return[...t.values()]}function s(e){const n=u(e.metadata?.skillCandidate),t=u(u(e.metadata?.requestMetadata)?.skillCandidate),r=n?.name??t?.name;return"string"==typeof r&&r.trim()?function(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"")}(r):void 0}function i(e,n,t){const r=function(e){return e.split("-").filter(Boolean).map(e=>`${e[0]?.toUpperCase()??""}${e.slice(1)}`).join(" ")}(n);return{workspaceId:p(e),name:n,status:"review_required",confidence:Math.min(.95,.55+.1*t.length),proposedPath:`resources/skills/${n}/SKILL.md`,title:r,summary:`Repeated stable workflow mined from ${t.length} memory records.`,draftMarkdown:c(r,t),evidence:t.map(e=>({evidenceType:"memory_record",evidenceRef:e.id,summary:e.summary??e.content.slice(0,160),weight:e.confidence}))}}function c(e,n){return[`# ${e}`,"","## Purpose","","Apply this stable workflow when the task matches the evidence.","","## Evidence","",n.map(e=>`- ${e.summary??e.content}`).join("\n")].join("\n")}function d(e){const n=u(e.runtime.memory?.maintenance);return"string"==typeof n?.prompt?n.prompt:"durable preferences workspace facts reusable procedures prior corrections stale duplicated contradicted memories"}function u(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function m(e,n,t){const r=u(e[n])??u(e[n.toLowerCase()]);return"boolean"==typeof r?.[t]?r[t]:void 0}function p(e){return e.runtime.workspaceId??e.runtime.profile??e.root}function l(e){return e instanceof Error?e.message:String(e)}
@@ -0,0 +1,2 @@
1
+ import type { RuntimeQueueStore } from "./types.js";
2
+ export declare function createInMemoryRuntimeQueueStore(): RuntimeQueueStore;
@@ -0,0 +1 @@
1
+ export function createInMemoryRuntimeQueueStore(){const s=new Map,a=new Map,o=new Map;return{enqueue(e){const t=e.enqueuedAt??(new Date).toISOString(),n=r({...e,enqueuedAt:t,attemptCount:e.attemptCount??0});return s.set(n.requestId,n),r(n)},listQueue:()=>e([...s.values()]).map(r),getQueuedRequest:e=>t(s.get(e),r),claimNext(t){const n=function(t,r){const n=Date.parse(r.now??(new Date).toISOString());return e(t).find(e=>{const t=Date.parse(e.availableAt)<=n,u=!r.queueKey||e.queueKey===r.queueKey,s=!e.leaseExpiresAt||Date.parse(e.leaseExpiresAt)<=n;return t&&u&&s})}([...s.values()],t);if(!n)return;const u=t.now??(new Date).toISOString(),o=function(e,t,r,n){return{...e,claimedBy:t,claimedAt:r,leaseExpiresAt:new Date(Date.parse(r)+n).toISOString(),attemptCount:e.attemptCount+1}}(n,t.workerId,u,t.leaseMs);return s.set(o.requestId,o),a.set(o.requestId,{requestId:o.requestId,cancelRequested:a.get(o.requestId)?.cancelRequested??!1,workerId:t.workerId,workerStartedAt:a.get(o.requestId)?.workerStartedAt??u,heartbeatAt:u}),r(o)},heartbeat(e){const t=a.get(e.requestId);if(!t||t.workerId!==e.workerId)return;const r={...t,heartbeatAt:e.now??(new Date).toISOString()};return a.set(e.requestId,r),n(r)},requestCancel(e){const t={...a.get(e.requestId),requestId:e.requestId,cancelRequested:!0,cancelReason:e.reason,cancelRequestedAt:e.now??(new Date).toISOString()};return a.set(e.requestId,t),n(t)},getControl:e=>t(a.get(e),n),listStuck(e){const t=Date.parse(e.now??(new Date).toISOString());return[...s.values()].filter(r=>function(e,t,r,n){if(!e.claimedAt)return!1;const u=Date.parse(t?.heartbeatAt??e.claimedAt);return!!e.leaseExpiresAt&&Date.parse(e.leaseExpiresAt)<r||r-u>n}(r,a.get(r.requestId),t,e.staleAfterMs)).map(r)},saveRecoveryIntent:e=>(o.set(e.requestId,u(e)),u(e)),getRecoveryIntent:e=>t(o.get(e),u),clearRecoveryIntent:e=>o.delete(e)}}function e(e){return[...e].sort((e,t)=>{const r=t.priority-e.priority;return 0===r?e.enqueuedAt.localeCompare(t.enqueuedAt):r})}function t(e,t){return e?t(e):void 0}function r(e){return structuredClone(e)}function n(e){return structuredClone(e)}function u(e){return structuredClone(e)}
@@ -0,0 +1,12 @@
1
+ import type { ApprovalQueue } from "@stable-harness/governance";
2
+ import type { MemoryProvider, RuntimeMemoryStore } from "@stable-harness/memory";
3
+ import type { CompiledWorkspace, RuntimeToolGateway, RuntimeAdapter, RuntimeStore, StableHarnessRuntime } from "./types.js";
4
+ export declare function createStableHarnessRuntime(input: {
5
+ workspace: CompiledWorkspace;
6
+ adapters: RuntimeAdapter[];
7
+ memory?: RuntimeMemoryStore;
8
+ memoryProviders?: MemoryProvider[];
9
+ approvals?: ApprovalQueue;
10
+ toolGateway?: RuntimeToolGateway;
11
+ store?: RuntimeStore;
12
+ }): StableHarnessRuntime;
@@ -0,0 +1 @@
1
+ import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{projectRequestInspection as s,projectRequestSummary as r,projectSessionSummaries as o}from"./inspection.js";import{recallMemoryPlugins as n,runMemoryPlugins as a}from"./memory-plugins.js";import{createInMemoryRuntimeStore as d}from"./stores.js";export function createStableHarnessRuntime(I){const m=new Set,l=I.store??d(),p=e=>{l.appendEvent(e);for(const t of m)t(e)};return{async request(s){const{agent:r,adapter:o}=function(e,t){const s=t.agentId??e.workspace.runtime.defaultAgentId,r=e.workspace.agents.get(s);if(!r)throw new Error(`Agent ${s} is not defined in the workspace`);if(t.toolCall)return{agent:r,adapter:void 0};const o=e.adapters.find(e=>e.canRun(r));if(!o)throw new Error(`No runtime adapter can run backend ${r.backend} for agent ${r.id}`);return{agent:r,adapter:o}}(I,s),d=s.requestId??e(),m=s.sessionId??e();l.createRun(function(e,t,s,r){return{requestId:t,sessionId:s,agentId:r.id,input:e.input,state:"running",parentRunId:e.parentRunId,metadata:e.metadata,artifacts:[],startedAt:(new Date).toISOString(),events:[]}}(s,d,m,r)),p({type:"request.started",requestId:d,sessionId:m,agentId:r.id});try{if(s.toolCall){const e=await async function(e){const t=e.request.toolCall;if(!t)throw new Error("Direct tool call request is missing");if(!e.gateway)throw new Error("Runtime tool gateway is not configured");const s=await async function(e){if(e.agent.tools.includes(e.toolId)&&e.gateway.get(e.toolId))return{toolId:e.toolId,args:e.args};const t=await(e.gateway.repairToolCall?.({toolId:e.toolId,args:e.args,allowedToolIds:e.agent.tools,context:{workspaceRoot:e.workspace.root,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id}}));if(t&&e.agent.tools.includes(t.toolId)&&e.gateway.get(t.toolId))return t;if(!e.agent.tools.includes(e.toolId))throw new Error(`Tool ${e.toolId} is not assigned to agent ${e.agent.id}`);throw new Error(`Tool is not registered: ${e.toolId}`)}({gateway:e.gateway,workspace:e.workspace,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,toolId:t.toolId,args:t.args});e.emit({type:"tool.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,toolId:s.toolId});const r=await e.gateway.invoke({toolId:s.toolId,args:s.args,context:{workspaceRoot:e.workspace.root,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id}});return e.emit({type:"tool.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,toolId:r.toolId,output:r.output}),{text:(o=r.output,"string"==typeof o?o:JSON.stringify(o)),metadata:{toolCall:{toolId:r.toolId}}};var o}({gateway:I.toolGateway,workspace:I.workspace,emit:p,request:s,requestId:d,sessionId:m,agent:r});return c({store:l,emit:p,requestId:d,sessionId:m,agent:r,result:e})}return await async function(e){if(!e.adapter)throw new Error(`No runtime adapter can run backend ${e.agent.backend} for agent ${e.agent.id}`);const s=await async function(e){if(!e.memory)return;if(i(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-plan"),!1===e.request.memory?.recall)return;const t=u(e.workspace,e.agent,e.request),s=e.request.memory?.recall?.query??e.request.input,r=await e.memory.recall({namespace:t,query:s,limit:e.request.memory?.recall?.limit});return e.emit({type:"memory.recall.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,namespace:t,recordIds:r.records.map(e=>e.id),context:r.context}),{namespace:t,records:r.records,context:r.context}}({memory:e.input.memory,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.input.workspace}),r=await n({providers:e.input.memoryProviders,request:e.request,agent:e.agent,workspace:e.input.workspace}),o=function(e){return"string"==typeof e?{text:e}:e}(await e.adapter.run({workspace:e.input.workspace,agent:e.agent,request:e.request,requestId:e.requestId,sessionId:e.sessionId,memory:s,pluginMemories:r,toolGateway:e.input.toolGateway,emit:e.emit}));i(e.input.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-finalize"),await async function(e){if(!e.memory||!e.request.memory?.candidates?.length)return;i(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"write-after-run");const t=u(e.workspace,e.agent,e.request);for(const s of e.request.memory.candidates){const r={...s,namespace:s.namespace??t},o=await e.memory.submitCandidate(r);if(e.emit({type:"memory.candidate.submitted",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,candidate:o.candidate,decision:o.decision,record:o.record}),"review"===o.decision.action&&e.approvals){const t=await e.approvals.create({kind:"memory_write",reason:o.decision.reason,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,subject:{candidate:o.candidate,decision:o.decision}});e.emit({type:"memory.approval.requested",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,approval:t})}}}({memory:e.input.memory,approvals:e.input.approvals,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.input.workspace}),t({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent});const d=c({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,result:o});return await a({providers:e.input.memoryProviders,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.input.workspace,result:o}),d}({input:I,store:l,emit:p,adapter:o,request:s,requestId:d,sessionId:m,agent:r})}catch(e){return function(e){const t=e.error instanceof Error?e.error.message:String(e.error);return e.store.getRun(e.requestId)&&e.store.updateRun(e.requestId,{state:"failed",error:t,completedAt:(new Date).toISOString()}),e.emit({type:"request.failed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,error:t}),{requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,state:"failed",output:t}}({store:l,emit:p,requestId:d,sessionId:m,agent:r,error:e})}},subscribe:e=>(m.add(e),()=>m.delete(e)),inspect:()=>({workspaceRoot:I.workspace.root,agents:[...I.workspace.agents.keys()].sort(),models:[...I.workspace.models.keys()].sort(),tools:[...I.workspace.tools.keys()].sort(),runs:l.listRuns()}),getRun:e=>l.getRun(e),listRequests:e=>l.listRuns(e).map(r),listSessions:()=>o(l.listRuns()),inspectRequest(e){const t=l.getRun(e);return t?s(I.workspace,t):void 0},cancel(e,t){const s=l.getRun(e);s&&"running"===s.state&&(l.updateRun(e,{state:"cancelled",completedAt:(new Date).toISOString()}),p({type:"request.cancelled",requestId:e,sessionId:s.sessionId,agentId:s.agentId,reason:t}))},async stop(){m.clear()}}}function i(e,t,s,r,o,n){e&&t({type:"memory.lifecycle",requestId:s,sessionId:r,agentId:o,hook:n})}function u(e,t,s){return s.memory?.namespace??`${e.root}:${t.id}`}function c(e){const t=e.store.getRun(e.requestId);if("cancelled"===t?.state)return I(e,"cancelled");t&&e.store.updateRun(e.requestId,{state:"completed",output:e.result.text,metadata:{...t.metadata,...e.result.metadata},artifacts:[...t.artifacts,...e.result.artifacts??[]],completedAt:(new Date).toISOString()});for(const t of e.result.artifacts??[])e.emit({type:"artifact.created",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,artifact:t});return e.emit({type:"request.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,output:e.result.text}),I(e,"completed")}function I(e,t){return{requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,state:t,output:e.result.text,metadata:e.result.metadata,artifacts:e.result.artifacts}}
@@ -0,0 +1,3 @@
1
+ import type { RuntimeRunRecord, RuntimeStore } from "./types.js";
2
+ export declare function createInMemoryRuntimeStore(initialRuns?: RuntimeRunRecord[]): RuntimeStore;
3
+ export declare function createJsonFileRuntimeStore(filePath: string): RuntimeStore;
@@ -0,0 +1 @@
1
+ import{existsSync as e,mkdirSync as n,readFileSync as t,writeFileSync as r}from"node:fs";import u from"node:path";export function createInMemoryRuntimeStore(e=[]){const n=new Map(e.map(e=>[e.requestId,o(e)]));return{createRun(e){n.set(e.requestId,o(e))},updateRun(e,t){const r=n.get(e);if(r)return Object.assign(r,function(e){return structuredClone(e)}(t)),o(r)},appendEvent(e){const t=n.get(e.requestId);if(t)return t.events.push(function(e){return structuredClone(e)}(e)),o(t)},getRun(e){return(t=n.get(e))?o(t):void 0;var t},listRuns:e=>[...n.values()].filter(n=>function(e,n){return!n||!(n.agentId&&n.agentId!==e.agentId||n.sessionId&&n.sessionId!==e.sessionId||n.state&&n.state!==e.state)}(n,e)).map(o)}}export function createJsonFileRuntimeStore(n){const r=u.resolve(n),o=createInMemoryRuntimeStore(function(n){if(!e(n))return[];const r=JSON.parse(t(n,"utf8"));if(!a(r)||!Array.isArray(r.runs))throw new Error(`Invalid runtime store file: ${n}`);return r.runs.map(i)}(r));return{createRun(e){o.createRun(e),s(r,o.listRuns())},updateRun(e,n){const t=o.updateRun(e,n);return s(r,o.listRuns()),t},appendEvent(e){const n=o.appendEvent(e);return s(r,o.listRuns()),n},getRun:e=>o.getRun(e),listRuns:e=>o.listRuns(e)}}function s(e,t){n(u.dirname(e),{recursive:!0}),r(e,`${JSON.stringify({version:1,runs:t},null,2)}\n`)}function i(e){if(!a(e)||"string"!=typeof e.requestId)throw new Error("Invalid runtime run record in store file");return o(e)}function o(e){return structuredClone(e)}function a(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -0,0 +1,15 @@
1
+ import type { RuntimeEvent, RuntimeRunRecord } from "./types.js";
2
+ export type PlanTodoItem = {
3
+ content: string;
4
+ status: string;
5
+ };
6
+ export type RuntimeTraceEntry = {
7
+ type: "request" | "tool" | "adapter" | "memory" | "artifact" | "plan" | "delegation";
8
+ label: string;
9
+ agentId: string;
10
+ requestId: string;
11
+ detail?: Record<string, unknown>;
12
+ };
13
+ export declare function projectRuntimeTrace(run: RuntimeRunRecord): RuntimeTraceEntry[];
14
+ export declare function projectEvent(event: RuntimeEvent): RuntimeTraceEntry | undefined;
15
+ export declare function readPlanTodos(output: unknown): PlanTodoItem[];
@@ -0,0 +1 @@
1
+ export function projectRuntimeTrace(t){return t.events.map(projectEvent).filter(r)}export function projectEvent(t){return"request.started"===t.type||"request.completed"===t.type||"request.failed"===t.type?o(t,"request",t.type):"request.cancelled"===t.type?o(t,"request",t.type,{reason:t.reason}):"execution.contract.failed"===t.type?o(t,"request",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):"tool.started"===t.type?o(t,"tool","tool.started",{toolId:t.toolId}):"tool.completed"===t.type?"write_todos"===t.toolId?o(t,"plan","plan.updated",{toolId:t.toolId,todos:readPlanTodos(t.output)}):o(t,"tool","tool.completed",{toolId:t.toolId}):"adapter.event"===t.type?function(t){const e=t.event;if(n(e)&&"string"==typeof e.phase){if("tool.result"===e.phase&&"write_todos"===e.toolId)return o(t,"plan","plan.updated",e);const r=function(t,e){if("task"!==e.toolId)return;const r=function(t){const e=n(t.args)?t.args:void 0,o=n(t.output)?t.output:void 0;return a(e?.subagent_type)??a(e?.subagentType)??a(o?.subagent_type)??a(o?.subagentType)}(e);return"tool.start"===e.phase?o(t,"delegation","delegation.start",{...e,subagentType:r}):"tool.result"===e.phase?o(t,"delegation","delegation.completed",{...e,subagentType:r}):void 0}(t,e);return r||o(t,"adapter",`adapter.${e.phase}`,e)}return o(t,"adapter","adapter.event",{event:e})}(t):"artifact.created"===t.type?o(t,"artifact","artifact.created",{artifact:t.artifact}):t.type.startsWith("memory.")?o(t,"memory",t.type):void 0}export function readPlanTodos(o){const r=function(t){if(n(t))return t;if("string"==typeof t)try{const e=JSON.parse(t);return n(e)?e:void 0}catch{return}}(o),a=function(t){const e=n(t?.args)?t.args:void 0;return Array.isArray(t?.todos)?t.todos:Array.isArray(e?.todos)?e.todos:[]}(r);return a.map(t).filter(e)}function t(t){if(n(t)&&"string"==typeof t.content)return{content:t.content,status:"string"==typeof t.status?t.status:"pending"}}function e(t){return void 0!==t}function o(t,e,o,r){return{type:e,label:o,agentId:t.agentId,requestId:t.requestId,detail:r}}function r(t){return void 0!==t}function n(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function a(t){return"string"==typeof t&&t.trim()?t:void 0}