stable-harness 0.0.54 → 0.0.55

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 (53) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +1 -1
  3. package/docs/guides/integration-guide.md +12 -0
  4. package/docs/protocols/http-runtime.md +10 -0
  5. package/node_modules/@stable-harness/adapter-deepagents/dist/src/adapter.js +1 -1
  6. package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/substrate/checkpoint.d.ts +10 -0
  7. package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/substrate/checkpoint.js +1 -0
  8. package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/substrate/runtime.d.ts +11 -0
  9. package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/substrate/runtime.js +1 -0
  10. package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/substrate/store.d.ts +10 -0
  11. package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/substrate/store.js +1 -0
  12. package/node_modules/@stable-harness/core/dist/runtime/admin/administration.d.ts +9 -0
  13. package/node_modules/@stable-harness/core/dist/runtime/admin/administration.js +1 -0
  14. package/node_modules/@stable-harness/core/dist/runtime/admin/memory.d.ts +10 -0
  15. package/node_modules/@stable-harness/core/dist/runtime/admin/memory.js +1 -0
  16. package/node_modules/@stable-harness/core/dist/runtime/events.d.ts +11 -0
  17. package/node_modules/@stable-harness/core/dist/runtime/persistence/stores.js +1 -1
  18. package/node_modules/@stable-harness/core/dist/runtime/types.d.ts +6 -0
  19. package/node_modules/@stable-harness/core/dist/runtime.js +1 -1
  20. package/node_modules/@stable-harness/core/dist/types.d.ts +13 -4
  21. package/node_modules/@stable-harness/memory/dist/src/index.d.ts +1 -1
  22. package/node_modules/@stable-harness/memory/dist/src/index.js +1 -1
  23. package/node_modules/@stable-harness/memory/dist/src/persistence.js +1 -1
  24. package/node_modules/@stable-harness/memory/dist/src/store.d.ts +3 -0
  25. package/node_modules/@stable-harness/memory/dist/src/store.js +1 -1
  26. package/node_modules/@stable-harness/memory/dist/src/types.d.ts +1 -1
  27. package/node_modules/@stable-harness/protocols/dist/src/http-server.js +1 -1
  28. package/node_modules/@stable-harness/protocols/dist/src/in-process-client.js +1 -1
  29. package/package.json +1 -1
  30. package/packages/adapter-deepagents/dist/src/adapter.js +1 -1
  31. package/packages/adapter-deepagents/dist/src/internal/substrate/checkpoint.d.ts +10 -0
  32. package/packages/adapter-deepagents/dist/src/internal/substrate/checkpoint.js +1 -0
  33. package/packages/adapter-deepagents/dist/src/internal/substrate/runtime.d.ts +11 -0
  34. package/packages/adapter-deepagents/dist/src/internal/substrate/runtime.js +1 -0
  35. package/packages/adapter-deepagents/dist/src/internal/substrate/store.d.ts +10 -0
  36. package/packages/adapter-deepagents/dist/src/internal/substrate/store.js +1 -0
  37. package/packages/core/dist/runtime/admin/administration.d.ts +9 -0
  38. package/packages/core/dist/runtime/admin/administration.js +1 -0
  39. package/packages/core/dist/runtime/admin/memory.d.ts +10 -0
  40. package/packages/core/dist/runtime/admin/memory.js +1 -0
  41. package/packages/core/dist/runtime/events.d.ts +11 -0
  42. package/packages/core/dist/runtime/persistence/stores.js +1 -1
  43. package/packages/core/dist/runtime/types.d.ts +6 -0
  44. package/packages/core/dist/runtime.js +1 -1
  45. package/packages/core/dist/types.d.ts +13 -4
  46. package/packages/memory/dist/src/index.d.ts +1 -1
  47. package/packages/memory/dist/src/index.js +1 -1
  48. package/packages/memory/dist/src/persistence.js +1 -1
  49. package/packages/memory/dist/src/store.d.ts +3 -0
  50. package/packages/memory/dist/src/store.js +1 -1
  51. package/packages/memory/dist/src/types.d.ts +1 -1
  52. package/packages/protocols/dist/src/http-server.js +1 -1
  53. package/packages/protocols/dist/src/in-process-client.js +1 -1
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { createStableHarnessRuntime as createCoreStableHarnessRuntime } from "@stable-harness/core";
2
2
  import type { CompiledWorkspace, RuntimeAdapter, RuntimeRequest, RuntimeToolGateway, RuntimeWorkflowAdapter, StableHarnessRuntime, WorkspaceAdapterPolicy } from "@stable-harness/core";
3
+ import type { RuntimeMemoryStore } from "@stable-harness/memory";
3
4
  export { createDeepAgentsAdapter, createDeepAgentsMemoryMaintenanceTarget } from "@stable-harness/adapter-deepagents";
4
5
  export { createDeepAgentsMiddlewareSkillProvider, createLangGraphRuntimeAdapter, createLangGraphWorkflowAdapter, createRegistrySkillResolverProvider, } from "@stable-harness/adapter-langgraph";
5
6
  export type { LangGraphNodeHandler, LangGraphNodeHandlerInput, LangGraphNodeResolver, LangGraphNodeResolverInput, LangGraphSkillMiddlewareProvider, LangGraphSkillMiddlewareProviderInput, LangGraphSkillResolverProvider, LangGraphWorkflowAdapterOptions, LangGraphWorkflowState, LangGraphWorkflowTraceEntry, } from "@stable-harness/adapter-langgraph";
6
7
  export type { LangGraphRegistrySkillOutput } from "@stable-harness/adapter-langgraph";
7
8
  export { createLangMemServiceProvider } from "@stable-harness/memory";
9
+ export { createInMemoryRuntimeMemoryStore, createJsonFileRuntimeMemoryStore } from "@stable-harness/memory";
8
10
  export { applySpecDrivenPhaseTransition, containsRecoverableResultOutput, createSpecDrivenArtifact, createSpecDrivenArtifactEvent, createSpecDrivenPhaseEvent, createSpecDrivenWorkflowPolicy, createSpecDrivenWorkflowState, projectRuntimeTrace, resolveEnabledMemories, } from "@stable-harness/core";
9
11
  export type { CompiledWorkspace, RuntimeAdapter, RuntimeEvent, RuntimeWorkflowAdapter, RuntimeRequest, RuntimeResponse, RuntimeRunRecord, RuntimeTraceEntry, StableHarnessRuntime, SpecDrivenPhaseRecord, SpecDrivenPhaseStatus, SpecDrivenPhaseTransition, SpecDrivenWorkflowState, WorkspaceAgent, WorkspaceModel, WorkspaceRuntimePolicy, WorkspaceSpecDrivenPhase, WorkspaceSpecDrivenWorkflowPolicy, WorkspaceTool, } from "@stable-harness/core";
10
12
  export { loadWorkspaceFromYaml } from "@stable-harness/workspace-yaml";
@@ -18,6 +20,7 @@ type RuntimeAssemblyInput = {
18
20
  workflowAdapterFactories?: Record<string, RuntimeWorkflowAdapterFactory>;
19
21
  workflowAdapterOptions?: Record<string, unknown>;
20
22
  toolGateway?: RuntimeToolGateway;
23
+ memory?: RuntimeMemoryStore;
21
24
  };
22
25
  type RuntimeAdapterFactory = (input: {
23
26
  policy: WorkspaceAdapterPolicy;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{createBackendModel as e,createDeepAgentsAdapter as r}from"@stable-harness/adapter-deepagents";import{createLangGraphRuntimeAdapter as t,createLangGraphWorkflowAdapter as a,createRegistrySkillResolverProvider as o}from"@stable-harness/adapter-langgraph";import{createStableHarnessRuntime as n}from"@stable-harness/core";import{createModuleToolGateway as i}from"@stable-harness/tool-gateway";import{loadWorkspaceFromYaml as s}from"@stable-harness/workspace-yaml";export{createDeepAgentsAdapter,createDeepAgentsMemoryMaintenanceTarget}from"@stable-harness/adapter-deepagents";export{createDeepAgentsMiddlewareSkillProvider,createLangGraphRuntimeAdapter,createLangGraphWorkflowAdapter,createRegistrySkillResolverProvider}from"@stable-harness/adapter-langgraph";export{createLangMemServiceProvider}from"@stable-harness/memory";export{applySpecDrivenPhaseTransition,containsRecoverableResultOutput,createSpecDrivenArtifact,createSpecDrivenArtifactEvent,createSpecDrivenPhaseEvent,createSpecDrivenWorkflowPolicy,createSpecDrivenWorkflowState,projectRuntimeTrace,resolveEnabledMemories}from"@stable-harness/core";export{loadWorkspaceFromYaml}from"@stable-harness/workspace-yaml";export{createInMemoryToolGateway,createModuleToolGateway}from"@stable-harness/tool-gateway";export function createStableHarnessRuntime(e){return"string"==typeof e?createStableRuntime({workspaceRoot:e}):"workspaceRoot"in e?createStableRuntime(e):n(e)}export async function createStableRuntime(e){const r=await s(e.workspaceRoot),t=e.toolGateway??await i({tools:r.tools.values()});return n({workspace:r,toolGateway:t,qualityReviewModel:createQualityReviewModel(r),adapters:e.adapters??createRuntimeAdapters(r,e),workflowAdapters:e.workflowAdapters??createWorkflowAdapters(r,e)})}function createQualityReviewModel(r){const t=function readQualityModelRef(e){const r=isRecord(e)?e:{};return readString((isRecord(r.reviewer)?r.reviewer:r).modelRef)}(r.runtime.quality),a=t?r.models.get(t):void 0,o=a?e(a):void 0;return function isQualityReviewModel(e){return isRecord(e)&&"function"==typeof e.invoke}(o)?o:void 0}export async function requestStableRuntime(e,r){return e.request(r)}function createRuntimeAdapters(e,a){const o={deepagents:({policy:e})=>r(e.config?{config:e.config}:{}),langgraph:({policy:e})=>t({...readLangGraphOptions(e.config),name:e.name}),...a.adapterFactories},n=function runtimeAdapterPolicies(e){const r=e.runtime.adapters?.filter(e=>!1!==e.enabled);return r&&r.length>0?r:[...new Set([...e.agents.values()].map(e=>e.backend))].map(e=>({name:e}))}(e);return n.map(r=>{const t=o[r.name];if(t)return t({policy:r,workspace:e});throw new Error(`Unsupported runtime adapter: ${r.name}`)})}function createWorkflowAdapters(e,r){const t={langgraph:({name:e,options:r})=>a({...readLangGraphOptions(r),name:e}),...r.workflowAdapterFactories};return[...new Set([...e.workflows.values()].map(e=>e.adapter??"").filter(Boolean))].map(a=>{const o=t[a];return o?.({name:a,workspace:e,options:readWorkflowAdapterOptions(r,a)})}).filter(e=>Boolean(e))}function readWorkflowAdapterOptions(e,r){return e.workflowAdapterOptions?.[r]??{}}function readLangGraphOptions(e){return isRecord(e)?{...e,...void 0!==readLangGraphSkillProvider(e)?{skillProvider:readLangGraphSkillProvider(e)}:{}}:{}}function readLangGraphSkillProvider(e){if(!1===e.skillProvider)return!1;const r=function readSkillProviderConfig(e){return isRecord(e.skills)?e.skills:isRecord(e.skillProvider)?e.skillProvider:void 0}(e);if(!r)return;const t=readString(r.provider)??readString(r.name)??"registry-resolver";if(["none","disabled","false"].includes(t))return!1;if("registry-resolver"!==t)throw new Error(`Unsupported LangGraph skill provider: ${t}`);return o({..."boolean"==typeof r.includeContent?{includeContent:r.includeContent}:{},..."number"==typeof r.maxBytes&&Number.isFinite(r.maxBytes)?{maxBytes:r.maxBytes}:{}})}function readString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
1
+ import{createBackendModel as e,createDeepAgentsAdapter as r}from"@stable-harness/adapter-deepagents";import{createLangGraphRuntimeAdapter as t,createLangGraphWorkflowAdapter as a,createRegistrySkillResolverProvider as o}from"@stable-harness/adapter-langgraph";import{createStableHarnessRuntime as n}from"@stable-harness/core";import{createModuleToolGateway as i}from"@stable-harness/tool-gateway";import{loadWorkspaceFromYaml as s}from"@stable-harness/workspace-yaml";export{createDeepAgentsAdapter,createDeepAgentsMemoryMaintenanceTarget}from"@stable-harness/adapter-deepagents";export{createDeepAgentsMiddlewareSkillProvider,createLangGraphRuntimeAdapter,createLangGraphWorkflowAdapter,createRegistrySkillResolverProvider}from"@stable-harness/adapter-langgraph";export{createLangMemServiceProvider}from"@stable-harness/memory";export{createInMemoryRuntimeMemoryStore,createJsonFileRuntimeMemoryStore}from"@stable-harness/memory";export{applySpecDrivenPhaseTransition,containsRecoverableResultOutput,createSpecDrivenArtifact,createSpecDrivenArtifactEvent,createSpecDrivenPhaseEvent,createSpecDrivenWorkflowPolicy,createSpecDrivenWorkflowState,projectRuntimeTrace,resolveEnabledMemories}from"@stable-harness/core";export{loadWorkspaceFromYaml}from"@stable-harness/workspace-yaml";export{createInMemoryToolGateway,createModuleToolGateway}from"@stable-harness/tool-gateway";export function createStableHarnessRuntime(e){return"string"==typeof e?createStableRuntime({workspaceRoot:e}):"workspaceRoot"in e?createStableRuntime(e):n(e)}export async function createStableRuntime(e){const r=await s(e.workspaceRoot),t=e.toolGateway??await i({tools:r.tools.values()});return n({workspace:r,toolGateway:t,memory:e.memory,qualityReviewModel:createQualityReviewModel(r),adapters:e.adapters??createRuntimeAdapters(r,e),workflowAdapters:e.workflowAdapters??createWorkflowAdapters(r,e)})}function createQualityReviewModel(r){const t=function readQualityModelRef(e){const r=isRecord(e)?e:{};return readString((isRecord(r.reviewer)?r.reviewer:r).modelRef)}(r.runtime.quality),a=t?r.models.get(t):void 0,o=a?e(a):void 0;return function isQualityReviewModel(e){return isRecord(e)&&"function"==typeof e.invoke}(o)?o:void 0}export async function requestStableRuntime(e,r){return e.request(r)}function createRuntimeAdapters(e,a){const o={deepagents:({policy:e})=>r(e.config?{config:e.config}:{}),langgraph:({policy:e})=>t({...readLangGraphOptions(e.config),name:e.name}),...a.adapterFactories},n=function runtimeAdapterPolicies(e){const r=e.runtime.adapters?.filter(e=>!1!==e.enabled);return r&&r.length>0?r:[...new Set([...e.agents.values()].map(e=>e.backend))].map(e=>({name:e}))}(e);return n.map(r=>{const t=o[r.name];if(t)return t({policy:r,workspace:e});throw new Error(`Unsupported runtime adapter: ${r.name}`)})}function createWorkflowAdapters(e,r){const t={langgraph:({name:e,options:r})=>a({...readLangGraphOptions(r),name:e}),...r.workflowAdapterFactories};return[...new Set([...e.workflows.values()].map(e=>e.adapter??"").filter(Boolean))].map(a=>{const o=t[a];return o?.({name:a,workspace:e,options:readWorkflowAdapterOptions(r,a)})}).filter(e=>Boolean(e))}function readWorkflowAdapterOptions(e,r){return e.workflowAdapterOptions?.[r]??{}}function readLangGraphOptions(e){return isRecord(e)?{...e,...void 0!==readLangGraphSkillProvider(e)?{skillProvider:readLangGraphSkillProvider(e)}:{}}:{}}function readLangGraphSkillProvider(e){if(!1===e.skillProvider)return!1;const r=function readSkillProviderConfig(e){return isRecord(e.skills)?e.skills:isRecord(e.skillProvider)?e.skillProvider:void 0}(e);if(!r)return;const t=readString(r.provider)??readString(r.name)??"registry-resolver";if(["none","disabled","false"].includes(t))return!1;if("registry-resolver"!==t)throw new Error(`Unsupported LangGraph skill provider: ${t}`);return o({..."boolean"==typeof r.includeContent?{includeContent:r.includeContent}:{},..."number"==typeof r.maxBytes&&Number.isFinite(r.maxBytes)?{maxBytes:r.maxBytes}:{}})}function readString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -52,12 +52,24 @@ single final answer:
52
52
  - `listRequests`: list historical or active requests
53
53
  - `listSessions`: inspect session state
54
54
  - `inspectRequest`: inspect one request lifecycle
55
+ - `deleteRequest`: remove a persisted request record
56
+ - `deleteSession`: remove all persisted requests in a session
57
+ - `memorize`: write a runtime memory record
58
+ - `recallMemories`: recall memory records by namespace and query
59
+ - `listMemories`: list runtime memory records
60
+ - `updateMemory`: update runtime memory metadata or content
61
+ - `archiveMemory`: archive a runtime memory record
55
62
  - `cancel`: stop active work
56
63
  - `stop`: close the runtime
57
64
 
58
65
  Use those surfaces to build product UI around requests, approvals, event traces,
59
66
  artifacts, and memory lifecycle.
60
67
 
68
+ Do not import removed compatibility facades or package internals. The supported
69
+ workspace loader is `loadWorkspaceFromYaml`, and the supported runtime surface
70
+ is the native `StableHarnessRuntime` object returned by
71
+ `createStableHarnessRuntime`.
72
+
61
73
  ## OpenAI-Compatible Facade
62
74
 
63
75
  Start the server:
@@ -24,13 +24,23 @@ Inspection endpoints expose normalized runtime state:
24
24
  - `GET /inspect`
25
25
  - `GET /requests`
26
26
  - `GET /requests/:id`
27
+ - `DELETE /requests/:id`
27
28
  - `GET /runs/:id/trace`
28
29
  - `GET /runs/:id/spans`
29
30
  - `GET /sessions`
31
+ - `DELETE /sessions/:id`
30
32
  - `GET /workflows`
31
33
  - `GET /workflows/:id/mermaid`
32
34
  - `GET /workflows/:id/plan`
33
35
 
36
+ Memory endpoints expose the native runtime memory store when one is configured:
37
+
38
+ - `POST /memories`
39
+ - `GET /memories?namespace=...`
40
+ - `POST /memories/recall`
41
+ - `PATCH /memories/:id`
42
+ - `POST /memories/:id/archive`
43
+
34
44
  When the workspace enables `specDrivenWorkflow`, `GET /inspect` exposes the
35
45
  configured spec-driven policy summary, and `GET /requests/:id` includes the
36
46
  run-derived `specDrivenWorkflow` phase state. That state is projected from
@@ -1 +1 @@
1
- import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as c}from"./memory.js";import{buildDeepAgentRequest as d}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){if(t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.handoff",modelRef:t.agent.modelRef,tools:t.agent.tools,skills:t.agent.skills,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=e.createDeepAgent?void 0:await async function loadDeepAgentsModule(){try{return await async function importOptionalPackage(e){return import(e)}("deepagents")}catch(e){throw new Error(`DeepAgents package is required for the default adapter path: ${function formatError(e){return e instanceof Error?e.message:String(e)}(e)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o=n(function buildDeepAgentParams(e,t,r){const n={...readDeepAgentsConfig(t),...readDeepAgentsConfig(e.agent.config.deepagents)},o=resolveDeepAgentsSkills(e,e.agent),a=n.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:n.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:n.backend??resolveDeepAgentsBackend(e,r,o),checkpointer:n.checkpointer,store:n.store,middleware:mergeMiddleware(e,e.agent,n.middleware,p),responseFormat:n.responseFormat,contextSchema:n.contextSchema,interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(0,e.agent,n),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=requestScopedRepeatState(e,t);return pruneUndefined({name:t,description:r?.description??readString(r?.config.description)??r?.id,systemPrompt:buildSystemPrompt(e,r),model:n.model??(r?resolveAgentModel(e,r):void 0),middleware:mergeMiddleware(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(0,0,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,e.config,r)),a=d(t),c=function buildDeepAgentInvokeConfig(e){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit)})}(t.agent);if(!0===t.request.metadata?.openaiStream&&o.streamEvents){const e=await o.streamEvents(a,{version:"v3",...c});return g(t,e,p)}const l=await o.invoke(a,c);return p(l)}}}function buildSystemPrompt(e,t){const n=t?.systemPrompt??readString(t?.config.systemPrompt);return r({workspace:e.workspace,request:e.request,agent:t},n)}function resolveDeepAgentsMemory(e,t){const r=readDeepAgentsStringArray(t?.config,"memory");if(r)return r;const n=[...readAgentMemorySources(e.workspace.root,t),...c(e.workspace).map(e=>`/memories/${e.id}.md`)],o=[...new Set(n)];return o.length>0?o:void 0}function readAgentMemorySources(e,t){return(t?.memory??[]).flatMap(t=>"string"==typeof t&&t.trim()?[backendMemorySourcePath(e,t.trim())]:isRecord(t)&&"string"==typeof t.path&&t.path.trim()?[backendMemorySourcePath(e,t.path.trim())]:[])}function backendMemorySourcePath(e,r){if(r.startsWith("/"))return r;if(t.isAbsolute(r)){const n=t.relative(e,r);return n&&!n.startsWith("..")?`/${n.split(t.sep).join("/")}`:canonicalPath(r)}const n=r.split(t.sep).join("/");return n.startsWith("/")?n:`/${n}`}function resolveDeepAgentsSkills(e,r){const n=readDeepAgentsStringArray(r?.config,"skills");if(n)return n;const o=[...new Set((r?.skills??[]).map(t=>e.workspace.skills.get(t)?.path).filter(e=>"string"==typeof e&&e.trim().length>0).map(r=>function backendSkillSourcePath(e,r){const n=t.dirname(t.dirname(r)),o=t.relative(e,n);return!o||o.startsWith("..")||t.isAbsolute(o)?""===o?"/":canonicalPath(n):`/${o.split(t.sep).join("/")}`}(e.workspace.root,r)))];return o.length>0?o:void 0}function resolveDeepAgentsBackend(e,t,r){if(t?.FilesystemBackend&&r&&0!==r.length)return()=>new t.FilesystemBackend({rootDir:e.workspace.root})}function mergeMiddleware(e,t,r,s=a(e.workspace.runtime.toolGateway)){const i=Array.isArray(r)?r:[],p=scopedInput(e,t),c=new Set,d=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:c,repeatState:s,repairModel:resolveAgentRepairModel(0,0,d)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}function requestScopedRepeatState(e,t){const r=`deepagents.repeat.${t}`,n=e.requestState?.get(r);if(n)return n;const o=a(e.workspace.runtime.toolGateway);return e.requestState&&o&&e.requestState.set(r,o),o}function scopedInput(e,t){return t?{...e,agent:t}:e}function resolveAgentModel(e,t){const r=t.modelRef?e.workspace.models.get(t.modelRef):void 0;return r?u(r):void 0}function resolveAgentRepairModel(e,t,r){const n=r.model;return function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}(n)?n:void 0}function readDeepAgentsConfig(e){return isRecord(e)?e:{}}function readDeepAgentsStringArray(e,t){const r=isRecord(e)?e:{},n=readDeepAgentsConfig(r.deepagents),o="memory"===t?["memory","memorySources"]:["skills","skillSources"];for(const e of o){const t=readStringArray(n[e]);if(t)return t}return readStringArray(r[t])}function pruneUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0}function canonicalPath(t){try{return e.native(t)}catch{return t}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
1
+ import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";import{cleanupDeepAgentsRuntimeSubstrate as f,resolveDeepAgentsRuntimeSubstrate as y}from"./internal/substrate/runtime.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){if(t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.handoff",modelRef:t.agent.modelRef,tools:t.agent.tools,skills:t.agent.skills,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=e.createDeepAgent?void 0:await async function loadDeepAgentsModule(){try{return await async function importOptionalPackage(e){return import(e)}("deepagents")}catch(e){throw new Error(`DeepAgents package is required for the default adapter path: ${function formatError(e){return e instanceof Error?e.message:String(e)}(e)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o={...readDeepAgentsConfig(e.config),...readDeepAgentsConfig(t.agent.config.deepagents)},a=y(t,o),d=n(function buildDeepAgentParams(e,t,r,n){const o=resolveDeepAgentsSkills(e,e.agent),a=t.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:t.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:t.backend??resolveDeepAgentsBackend(e,n,o),checkpointer:r.checkpointer,store:r.store,middleware:mergeMiddleware(e,e.agent,t.middleware,p),responseFormat:t.responseFormat,contextSchema:t.contextSchema,interruptOn:t.interruptOn,generalPurposeAgent:readBoolean(t.generalPurposeAgent),taskDescription:readString(t.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(0,e.agent,t),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=requestScopedRepeatState(e,t);return pruneUndefined({name:t,description:r?.description??readString(r?.config.description)??r?.id,systemPrompt:buildSystemPrompt(e,r),model:n.model??(r?resolveAgentModel(e,r):void 0),middleware:mergeMiddleware(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(0,0,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,o,a,r)),l=c(t),u=function buildDeepAgentInvokeConfig(e,t){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit),configurable:{thread_id:t}})}(t.agent,a.threadId);if(!0===t.request.metadata?.openaiStream&&d.streamEvents){const e=await d.streamEvents(l,{version:"v3",...u}),r=await g(t,e,p);return await f(a),r}const m=await d.invoke(l,u),A=p(m);return await f(a),A}}}function buildSystemPrompt(e,t){const n=t?.systemPrompt??readString(t?.config.systemPrompt);return r({workspace:e.workspace,request:e.request,agent:t},n)}function resolveDeepAgentsMemory(e,t){const r=readDeepAgentsStringArray(t?.config,"memory");if(r)return r;const n=[...readAgentMemorySources(e.workspace.root,t),...d(e.workspace).map(e=>`/memories/${e.id}.md`)],o=[...new Set(n)];return o.length>0?o:void 0}function readAgentMemorySources(e,t){return(t?.memory??[]).flatMap(t=>"string"==typeof t&&t.trim()?[backendMemorySourcePath(e,t.trim())]:isRecord(t)&&"string"==typeof t.path&&t.path.trim()?[backendMemorySourcePath(e,t.path.trim())]:[])}function backendMemorySourcePath(e,r){if(r.startsWith("/"))return r;if(t.isAbsolute(r)){const n=t.relative(e,r);return n&&!n.startsWith("..")?`/${n.split(t.sep).join("/")}`:canonicalPath(r)}const n=r.split(t.sep).join("/");return n.startsWith("/")?n:`/${n}`}function resolveDeepAgentsSkills(e,r){const n=readDeepAgentsStringArray(r?.config,"skills");if(n)return n;const o=[...new Set((r?.skills??[]).map(t=>e.workspace.skills.get(t)?.path).filter(e=>"string"==typeof e&&e.trim().length>0).map(r=>function backendSkillSourcePath(e,r){const n=t.dirname(t.dirname(r)),o=t.relative(e,n);return!o||o.startsWith("..")||t.isAbsolute(o)?""===o?"/":canonicalPath(n):`/${o.split(t.sep).join("/")}`}(e.workspace.root,r)))];return o.length>0?o:void 0}function resolveDeepAgentsBackend(e,t,r){if(t?.FilesystemBackend&&r&&0!==r.length)return()=>new t.FilesystemBackend({rootDir:e.workspace.root})}function mergeMiddleware(e,t,r,s=a(e.workspace.runtime.toolGateway)){const i=Array.isArray(r)?r:[],p=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(0,0,c)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}function requestScopedRepeatState(e,t){const r=`deepagents.repeat.${t}`,n=e.requestState?.get(r);if(n)return n;const o=a(e.workspace.runtime.toolGateway);return e.requestState&&o&&e.requestState.set(r,o),o}function scopedInput(e,t){return t?{...e,agent:t}:e}function resolveAgentModel(e,t){const r=t.modelRef?e.workspace.models.get(t.modelRef):void 0;return r?u(r):void 0}function resolveAgentRepairModel(e,t,r){const n=r.model;return function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}(n)?n:void 0}function readDeepAgentsConfig(e){return isRecord(e)?e:{}}function readDeepAgentsStringArray(e,t){const r=isRecord(e)?e:{},n=readDeepAgentsConfig(r.deepagents),o="memory"===t?["memory","memorySources"]:["skills","skillSources"];for(const e of o){const t=readStringArray(n[e]);if(t)return t}return readStringArray(r[t])}function pruneUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0}function canonicalPath(t){try{return e.native(t)}catch{return t}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -0,0 +1,10 @@
1
+ import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
2
+ export type DeepAgentsCheckpointProvider = "sqlite" | "file";
3
+ export type DeepAgentsCheckpointOptions = {
4
+ provider: DeepAgentsCheckpointProvider;
5
+ path: string;
6
+ busyTimeoutMs?: number;
7
+ wal?: boolean;
8
+ synchronous?: "off" | "normal" | "full";
9
+ };
10
+ export declare function createDeepAgentsCheckpointer(options: DeepAgentsCheckpointOptions): BaseCheckpointSaver;
@@ -0,0 +1 @@
1
+ import{existsSync as e,mkdirSync as t,readFileSync as i,writeFileSync as a}from"node:fs";import c from"node:path";import{DatabaseSync as n}from"node:sqlite";import{BaseCheckpointSaver as r,WRITES_IDX_MAP as s,copyCheckpoint as d,getCheckpointId as o}from"@langchain/langgraph-checkpoint";export function createDeepAgentsCheckpointer(e){return"file"===e.provider?new JsonFileCheckpointSaver(e.path):new SqliteCheckpointSaver(e)}class JsonFileCheckpointSaver extends r{filePath;constructor(e){super(),this.filePath=e}async getTuple(e){return tupleFromState(this.state(),e,this)}async*list(e,t){for(const i of listCheckpoints(this.state(),e,t))yield hydrateTuple(i,this.state().writes,this)}async put(e,t,i){const a=requiredThreadId(e,"put checkpoint"),c=checkpointNamespace(e),n=checkpointConfig(a,c,t.id),r=this.state(),s={threadId:a,namespace:c,checkpointId:t.id,checkpoint:await dump(this,d(t)),metadata:await dump(this,i),parentCheckpointId:o(e)||void 0};return r.checkpoints=r.checkpoints.filter(e=>!function sameCheckpoint(e,t){return e.threadId===t.threadId&&e.namespace===t.namespace&&e.checkpointId===t.checkpointId}(e,s)),r.checkpoints.push(s),this.write(r),n}async putWrites(e,t,i){const a=requiredThreadId(e,"put writes"),c=requiredCheckpointId(e),n=checkpointNamespace(e),r=this.state();for(let e=0;e<t.length;e+=1){const[d,o]=t[e],h=s[d]??e,p=r.writes.some(e=>sameWrite(e,{threadId:a,namespace:n,checkpointId:c,taskId:i,idx:h}));h>=0&&p||(r.writes=r.writes.filter(e=>!sameWrite(e,{threadId:a,namespace:n,checkpointId:c,taskId:i,idx:h})),r.writes.push({threadId:a,namespace:n,checkpointId:c,taskId:i,idx:h,channel:d,value:await dump(this,o)}))}this.write(r)}async deleteThread(e){const t=this.state();this.write({checkpoints:t.checkpoints.filter(t=>t.threadId!==e),writes:t.writes.filter(t=>t.threadId!==e)})}state(){if(!e(this.filePath))return{checkpoints:[],writes:[]};const t=JSON.parse(i(this.filePath,"utf8"));return{checkpoints:t.checkpoints??[],writes:t.writes??[]}}write(e){t(c.dirname(this.filePath),{recursive:!0}),a(this.filePath,`${JSON.stringify(e,null,2)}\n`)}}class SqliteCheckpointSaver extends r{db;constructor(e){super(),t(c.dirname(e.path),{recursive:!0}),this.db=new n(e.path),this.db.exec(`PRAGMA busy_timeout = ${e.busyTimeoutMs??5e3}`),!1!==e.wal&&this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec(`PRAGMA synchronous = ${e.synchronous?.toUpperCase()??"NORMAL"}`),this.db.exec(["CREATE TABLE IF NOT EXISTS checkpoints (thread_id TEXT NOT NULL, namespace TEXT NOT NULL, checkpoint_id TEXT NOT NULL, checkpoint TEXT NOT NULL, metadata TEXT NOT NULL, parent_checkpoint_id TEXT, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(thread_id, namespace, checkpoint_id))","CREATE TABLE IF NOT EXISTS writes (thread_id TEXT NOT NULL, namespace TEXT NOT NULL, checkpoint_id TEXT NOT NULL, task_id TEXT NOT NULL, idx INTEGER NOT NULL, channel TEXT NOT NULL, value TEXT NOT NULL, PRIMARY KEY(thread_id, namespace, checkpoint_id, task_id, idx))","CREATE INDEX IF NOT EXISTS idx_checkpoints_thread ON checkpoints(thread_id, namespace, checkpoint_id DESC)"].join(";"))}async getTuple(e){return tupleFromState(this.state(),e,this)}async*list(e,t){const i=this.state();for(const a of listCheckpoints(i,e,t))yield hydrateTuple(a,i.writes,this)}async put(e,t,i){const a=requiredThreadId(e,"put checkpoint"),c=checkpointNamespace(e);return this.db.prepare("INSERT OR REPLACE INTO checkpoints(thread_id, namespace, checkpoint_id, checkpoint, metadata, parent_checkpoint_id) VALUES (?, ?, ?, ?, ?, ?)").run(a,c,t.id,await dump(this,d(t)),await dump(this,i),o(e)||null),checkpointConfig(a,c,t.id)}async putWrites(e,t,i){const a=requiredThreadId(e,"put writes"),c=checkpointNamespace(e),n=requiredCheckpointId(e),r=this.db.prepare("INSERT OR REPLACE INTO writes(thread_id, namespace, checkpoint_id, task_id, idx, channel, value) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let e=0;e<t.length;e+=1){const[d,o]=t[e],h=s[d]??e;r.run(a,c,n,i,h,d,await dump(this,o))}}async deleteThread(e){this.db.prepare("DELETE FROM writes WHERE thread_id = ?").run(e),this.db.prepare("DELETE FROM checkpoints WHERE thread_id = ?").run(e)}state(){return{checkpoints:this.db.prepare("SELECT thread_id AS threadId, namespace, checkpoint_id AS checkpointId, checkpoint, metadata, parent_checkpoint_id AS parentCheckpointId FROM checkpoints").all(),writes:this.db.prepare("SELECT thread_id AS threadId, namespace, checkpoint_id AS checkpointId, task_id AS taskId, idx, channel, value FROM writes").all()}}}async function tupleFromState(e,t,i){const a=t.configurable?.thread_id;if(!a)return;const c=checkpointNamespace(t),n=o(t),r=e.checkpoints.filter(e=>e.threadId===a&&e.namespace===c),s=n?r.find(e=>e.checkpointId===n):r.sort((e,t)=>t.checkpointId.localeCompare(e.checkpointId))[0];return s?hydrateTuple(s,e.writes,i):void 0}function listCheckpoints(e,t,i){const a=t.configurable?.thread_id,c=t.configurable?.checkpoint_ns,n=o(t);let r=e.checkpoints.filter(e=>!(a&&e.threadId!==a||void 0!==c&&e.namespace!==c));return r=r.filter(e=>!n||e.checkpointId===n),r=r.filter(e=>!i?.before?.configurable?.checkpoint_id||e.checkpointId<String(i.before.configurable.checkpoint_id)),r=r.sort((e,t)=>t.checkpointId.localeCompare(e.checkpointId)),i?.filter&&(r=r.filter(e=>function metadataMatches(e,t){const i=JSON.parse(Buffer.from(e,"base64").toString("utf8"));return Object.entries(t).every(([e,t])=>i[e]===t)}(e.metadata,i.filter??{}))),"number"==typeof i?.limit?r.slice(0,i.limit):r}async function hydrateTuple(e,t,i){const a=await Promise.all(t.filter(t=>t.threadId===e.threadId&&t.namespace===e.namespace&&t.checkpointId===e.checkpointId).sort((e,t)=>e.idx-t.idx).map(async e=>[e.taskId,e.channel,await load(i,e.value)]));return{config:checkpointConfig(e.threadId,e.namespace,e.checkpointId),checkpoint:await load(i,e.checkpoint),metadata:await load(i,e.metadata),pendingWrites:a,...e.parentCheckpointId?{parentConfig:checkpointConfig(e.threadId,e.namespace,e.parentCheckpointId)}:{}}}async function dump(e,t){const[,i]=await e.serde.dumpsTyped(t);return Buffer.from(i).toString("base64")}async function load(e,t){return e.serde.loadsTyped("json",Buffer.from(t,"base64"))}function requiredThreadId(e,t){const i=e.configurable?.thread_id;if("string"!=typeof i||!i)throw new Error(`Failed to ${t}: missing configurable.thread_id.`);return i}function requiredCheckpointId(e){const t=o(e);if(!t)throw new Error("Failed to put writes: missing configurable.checkpoint_id.");return t}function checkpointNamespace(e){return String(e.configurable?.checkpoint_ns??"")}function checkpointConfig(e,t,i){return{configurable:{thread_id:e,checkpoint_ns:t,checkpoint_id:i}}}function sameWrite(e,t){return e.threadId===t.threadId&&e.namespace===t.namespace&&e.checkpointId===t.checkpointId&&e.taskId===t.taskId&&e.idx===t.idx}
@@ -0,0 +1,11 @@
1
+ import type { BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
2
+ import type { RuntimeAdapterContext } from "@stable-harness/core";
3
+ export type DeepAgentsRuntimeSubstrate = {
4
+ checkpointer?: BaseCheckpointSaver;
5
+ store?: BaseStore;
6
+ threadId: string;
7
+ cleanupOnCompleted: boolean;
8
+ };
9
+ export declare function resolveDeepAgentsRuntimeSubstrate(input: RuntimeAdapterContext, deepagents: Record<string, unknown>): DeepAgentsRuntimeSubstrate;
10
+ declare function cleanupDeepAgentsRuntimeSubstrate(substrate: DeepAgentsRuntimeSubstrate): Promise<void>;
11
+ export { cleanupDeepAgentsRuntimeSubstrate };
@@ -0,0 +1 @@
1
+ import e from"node:path";import{createDeepAgentsCheckpointer as r}from"./checkpoint.js";import{createDeepAgentsStore as o}from"./store.js";export function resolveDeepAgentsRuntimeSubstrate(e,r){const o=function readSubstrateConfig(e){const r=readRecord(e.workspace.runtime.checkpoint)??{},o=readRecord(r.deepagents)??r;return{...o,performance:readRecord(o.performance),cleanup:readRecord(o.cleanup),checkpointer:readRecord(o.checkpointer),store:readRecord(o.store)}}(e),n=!1!==o.enabled,t=readProvider(o.provider)??"sqlite",i=o.performance??{},a=o.checkpointer??{},c=o.store??{};return{checkpointer:resolveCheckpointer({input:e,configured:r.checkpointer,enabled:n,provider:t,performance:i,config:o,checkpointerConfig:a}),store:resolveStore({input:e,configured:r.store,enabled:n,provider:t,performance:i,storeConfig:c}),threadId:`${workspaceId(e)}:${e.sessionId}:${e.requestId}`,cleanupOnCompleted:readCleanupOnCompleted(o)}}async function cleanupDeepAgentsRuntimeSubstrate(e){e.cleanupOnCompleted&&await(e.checkpointer?.deleteThread?.(e.threadId))}export{cleanupDeepAgentsRuntimeSubstrate};function resolveSubstratePath(r,o,n,t){const i="string"==typeof o&&o.trim()?o.trim():void 0;if(i)return e.isAbsolute(i)?i:e.resolve(r.workspace.root,i);const a="file"===n?"json":"sqlite";return e.resolve(r.workspace.root,function dataRoot(e){const r=e.workspace.runtime.dataRoot;return"string"==typeof r&&r.trim()?r.trim():".stable-harness"}(r),`${t}.${a}`)}function workspaceId(r){return(r.workspace.runtime.workspaceId??e.basename(r.workspace.root))||"workspace"}function resolveCheckpointer(e){return void 0!==e.configured?e.configured:e.enabled&&!1!==e.checkpointerConfig.enabled?r({provider:readProvider(e.checkpointerConfig.provider)??e.provider,path:resolveSubstratePath(e.input,e.checkpointerConfig.path??e.config.path,e.provider,"checkpoints/deepagents"),busyTimeoutMs:readNumber(e.performance.busyTimeoutMs)??readNumber(e.checkpointerConfig.busyTimeoutMs),wal:readBoolean(e.performance.wal)??readBoolean(e.checkpointerConfig.wal),synchronous:readSynchronous(e.performance.synchronous)??readSynchronous(e.checkpointerConfig.synchronous)}):void 0}function resolveStore(e){if(void 0!==e.configured)return e.configured;if(!e.enabled||!1===e.storeConfig.enabled)return;const r=function readStoreProvider(e){return readProvider(e)}(e.storeConfig.provider)??e.provider;return o({provider:r,path:resolveSubstratePath(e.input,e.storeConfig.path,r,"store/deepagents"),busyTimeoutMs:readNumber(e.performance.busyTimeoutMs)??readNumber(e.storeConfig.busyTimeoutMs),wal:readBoolean(e.performance.wal)??readBoolean(e.storeConfig.wal),synchronous:readSynchronous(e.performance.synchronous)??readSynchronous(e.storeConfig.synchronous)})}function readCleanupOnCompleted(e){const r=e.cleanup?.onCompleted;return!1!==r&&"keep"!==r}function readProvider(e){return"file"===e||"json"===e?"file":"sqlite"===e?"sqlite":void 0}function readSynchronous(e){return"off"===e||"normal"===e||"full"===e?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}
@@ -0,0 +1,10 @@
1
+ import { BaseStore } from "@langchain/langgraph-checkpoint";
2
+ export type DeepAgentsStoreProvider = "sqlite" | "file";
3
+ export type DeepAgentsStoreOptions = {
4
+ provider: DeepAgentsStoreProvider;
5
+ path: string;
6
+ busyTimeoutMs?: number;
7
+ wal?: boolean;
8
+ synchronous?: "off" | "normal" | "full";
9
+ };
10
+ export declare function createDeepAgentsStore(options: DeepAgentsStoreOptions): BaseStore;
@@ -0,0 +1 @@
1
+ import{existsSync as e,mkdirSync as t,readFileSync as a,writeFileSync as n}from"node:fs";import s from"node:path";import{DatabaseSync as i}from"node:sqlite";import{BaseStore as r}from"@langchain/langgraph-checkpoint";export function createDeepAgentsStore(e){return"file"===e.provider?new JsonFileStore(e.path):new SqliteStore(e)}class JsonFileStore extends r{filePath;constructor(e){super(),this.filePath=e}async batch(e){const t=this.state(),a=e.map(e=>applyOperation(t,e));return this.write(t),a}state(){return e(this.filePath)?{items:JSON.parse(a(this.filePath,"utf8")).items??[]}:{items:[]}}write(e){t(s.dirname(this.filePath),{recursive:!0}),n(this.filePath,`${JSON.stringify(e,null,2)}\n`)}}class SqliteStore extends r{db;constructor(e){super(),t(s.dirname(e.path),{recursive:!0}),this.db=new i(e.path),this.db.exec(`PRAGMA busy_timeout = ${e.busyTimeoutMs??5e3}`),!1!==e.wal&&this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec(`PRAGMA synchronous = ${e.synchronous?.toUpperCase()??"NORMAL"}`),this.db.exec(["CREATE TABLE IF NOT EXISTS items (namespace TEXT NOT NULL, key TEXT NOT NULL, value TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, PRIMARY KEY(namespace, key))","CREATE INDEX IF NOT EXISTS idx_items_namespace ON items(namespace)"].join(";"))}async batch(e){const t=this.state(),a=e.map(e=>applyOperation(t,e));return this.replace(t),a}state(){return{items:this.db.prepare("SELECT namespace, key, value, created_at AS createdAt, updated_at AS updatedAt FROM items").all().map(e=>({namespace:JSON.parse(e.namespace),key:e.key,value:JSON.parse(e.value),createdAt:e.createdAt,updatedAt:e.updatedAt}))}}replace(e){const t=this.db.prepare("DELETE FROM items"),a=this.db.prepare("INSERT INTO items(namespace, key, value, created_at, updated_at) VALUES (?, ?, ?, ?, ?)");this.db.exec("BEGIN");try{t.run();for(const t of e.items)a.run(JSON.stringify(t.namespace),t.key,JSON.stringify(t.value),t.createdAt,t.updatedAt);this.db.exec("COMMIT")}catch(e){throw this.db.exec("ROLLBACK"),e}}}function applyOperation(e,t){return"key"in t&&"namespace"in t&&!("value"in t)?function toItem(e){return e?toStoredItem(e):null}(e.items.find(e=>sameKey(e,t.namespace,t.key))??null):"value"in t?void function putItem(e,t,a,n){const s=e.items.find(e=>sameKey(e,t,a));if(null===n)return void(e.items=e.items.filter(e=>!sameKey(e,t,a)));const i=(new Date).toISOString();if(s)return s.value=n,void(s.updatedAt=i);e.items.push({namespace:t,key:a,value:n,createdAt:i,updatedAt:i})}(e,t.namespace,t.key,t.value):"namespacePrefix"in t?function searchItems(e,t,a,n,s){return e.items.filter(e=>function startsWithNamespace(e,t){return t.length<=e.length&&t.every((t,a)=>e[a]===t)}(e.namespace,t)).filter(e=>function matchesFilter(e,t){return!t||Object.entries(t).every(([t,a])=>e[t]===a)}(e.value,a)).sort((e,t)=>e.namespace.join("/").localeCompare(t.namespace.join("/"))||e.key.localeCompare(t.key)).slice(n,n+s).map(e=>({...toStoredItem(e),score:0}))}(e,t.namespacePrefix,t.filter,t.offset??0,t.limit??10):"matchConditions"in t?function listNamespaces(e,t){let a=[...new Map(e.items.map(e=>[e.namespace.join("\0"),e.namespace])).values()];const n=t.matchConditions??[];return a=a.filter(e=>n.every(t=>function namespaceMatches(e,t){const a=(Array.isArray(t.path)?t.path:[]).filter(e=>"string"==typeof e);return"suffix"===t.matchType?a.length<=e.length&&a.every((t,n)=>"*"===t||e[e.length-a.length+n]===t):a.length<=e.length&&a.every((t,a)=>"*"===t||e[a]===t)}(e,t))),void 0!==t.maxDepth&&(a=[...new Map(a.map(e=>{const a=e.slice(0,t.maxDepth);return[a.join("\0"),a]})).values()]),a.sort((e,t)=>e.join("/").localeCompare(t.join("/"))).slice(t.offset,t.offset+t.limit)}(e,t):void 0}function toStoredItem(e){return{value:e.value,key:e.key,namespace:e.namespace,createdAt:new Date(e.createdAt),updatedAt:new Date(e.updatedAt)}}function sameKey(e,t,a){return e.key===a&&e.namespace.length===t.length&&e.namespace.every((e,a)=>e===t[a])}
@@ -0,0 +1,9 @@
1
+ import type { RuntimeEvent } from "../events.js";
2
+ import type { RuntimeDeletionResult, RuntimeStore } from "../types.js";
3
+ export declare function createRuntimeAdministrationMethods(input: {
4
+ store: RuntimeStore;
5
+ emit: (event: RuntimeEvent) => void;
6
+ }): {
7
+ deleteRequest(requestId: string): RuntimeDeletionResult;
8
+ deleteSession(sessionId: string): RuntimeDeletionResult;
9
+ };
@@ -0,0 +1 @@
1
+ export function createRuntimeAdministrationMethods(e){return{deleteRequest(t){const s=e.store.getRun(t);return s?(e.emit({type:"runtime.request.deleted",requestId:t,sessionId:s.sessionId,agentId:s.agentId}),e.store.deleteRun(t),{deletedRequestIds:[t],deletedCount:1}):{deletedRequestIds:[],deletedCount:0}},deleteSession(t){const s=e.store.listRuns({sessionId:t});if(0===s.length)return{deletedRequestIds:[],deletedCount:0};const d=s.map(e=>e.requestId);return e.emit({type:"runtime.session.deleted",requestId:s[0]?.requestId??"",sessionId:t,agentId:s[0]?.agentId??"",deletedRequestIds:d}),e.store.deleteSession(t)}}}
@@ -0,0 +1,10 @@
1
+ import type { ListMemoriesInput, MemorizeInput, RecallInput, RuntimeMemoryStore, UpdateMemoryInput } from "@stable-harness/memory";
2
+ export declare function createRuntimeMemoryAdministration(input: {
3
+ memory?: RuntimeMemoryStore;
4
+ }): {
5
+ memorize(inputValue: MemorizeInput): Promise<import("@stable-harness/memory").MemoryRecord>;
6
+ recallMemories(inputValue: RecallInput): Promise<import("@stable-harness/memory").MemoryRecallResult>;
7
+ listMemories(inputValue: ListMemoriesInput): Promise<import("@stable-harness/memory").MemoryRecord[]>;
8
+ updateMemory(inputValue: UpdateMemoryInput): Promise<import("@stable-harness/memory").MemoryRecord | undefined>;
9
+ archiveMemory(id: string, reason?: string): Promise<import("@stable-harness/memory").MemoryRecord | undefined>;
10
+ };
@@ -0,0 +1 @@
1
+ export function createRuntimeMemoryAdministration(e){return{memorize:r=>requireMemory(e.memory).memorize(r),recallMemories:r=>requireMemory(e.memory).recall(r),listMemories:r=>requireMemory(e.memory).list(r),updateMemory:r=>requireMemory(e.memory).update(r),archiveMemory:(r,m)=>requireMemory(e.memory).archive(r,m)}}function requireMemory(e){if(!e)throw new Error("Runtime memory store is not configured");return e}
@@ -45,6 +45,17 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
45
45
  sessionId: string;
46
46
  agentId: string;
47
47
  reason?: string;
48
+ } | {
49
+ type: "runtime.request.deleted";
50
+ requestId: string;
51
+ sessionId: string;
52
+ agentId: string;
53
+ } | {
54
+ type: "runtime.session.deleted";
55
+ requestId: string;
56
+ sessionId: string;
57
+ agentId: string;
58
+ deletedRequestIds: string[];
48
59
  } | {
49
60
  type: "runtime.artifact.created";
50
61
  requestId: string;
@@ -1 +1 @@
1
- import{existsSync as e,mkdirSync as t,readFileSync as n,writeFileSync as r}from"node:fs";import u from"node:path";export function createInMemoryRuntimeStore(e=[]){const t=new Map(e.map(e=>[e.requestId,cloneRun(e)]));return{createRun(e){t.set(e.requestId,cloneRun(e))},updateRun(e,n){const r=t.get(e);if(r)return Object.assign(r,function clonePatch(e){return structuredClone(e)}(n)),cloneRun(r)},appendEvent(e){const n=t.get(e.requestId);if(!n)return;const r=function eventArtifact(e){return"artifact"in e&&e.artifact?e.artifact:void 0}(e);return r&&!n.artifacts.some(e=>e.id===r.id)&&n.artifacts.push(structuredClone(r)),n.events.push(function cloneEvent(e){return structuredClone(e)}(e)),cloneRun(n)},getRun:e=>function cloneOptionalRun(e){return e?cloneRun(e):void 0}(t.get(e)),listRuns:e=>[...t.values()].filter(t=>function matchesFilter(e,t){return!t||!(t.agentId&&t.agentId!==e.agentId||t.sessionId&&t.sessionId!==e.sessionId||t.state&&t.state!==e.state)}(t,e)).map(cloneRun)}}export function createJsonFileRuntimeStore(t){const r=u.resolve(t),i=createInMemoryRuntimeStore(function readStoreFile(t){if(!e(t))return[];const r=JSON.parse(n(t,"utf8"));if(!isRecord(r)||!Array.isArray(r.runs))throw new Error(`Invalid runtime store file: ${t}`);return r.runs.map(assertRunRecord)}(r));return{createRun(e){i.createRun(e),writeStoreFile(r,i.listRuns())},updateRun(e,t){const n=i.updateRun(e,t);return writeStoreFile(r,i.listRuns()),n},appendEvent(e){const t=i.appendEvent(e);return writeStoreFile(r,i.listRuns()),t},getRun:e=>i.getRun(e),listRuns:e=>i.listRuns(e)}}function writeStoreFile(e,n){t(u.dirname(e),{recursive:!0}),r(e,`${JSON.stringify({version:1,runs:n},null,2)}\n`)}function assertRunRecord(e){if(!isRecord(e)||"string"!=typeof e.requestId)throw new Error("Invalid runtime run record in store file");return cloneRun(e)}function cloneRun(e){return structuredClone(e)}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
1
+ import{existsSync as e,mkdirSync as t,readFileSync as n,writeFileSync as r}from"node:fs";import s from"node:path";export function createInMemoryRuntimeStore(e=[]){const t=new Map(e.map(e=>[e.requestId,cloneRun(e)]));return{createRun(e){t.set(e.requestId,cloneRun(e))},updateRun(e,n){const r=t.get(e);if(r)return Object.assign(r,function clonePatch(e){return structuredClone(e)}(n)),cloneRun(r)},appendEvent(e){const n=t.get(e.requestId);if(!n)return;const r=function eventArtifact(e){return"artifact"in e&&e.artifact?e.artifact:void 0}(e);return r&&!n.artifacts.some(e=>e.id===r.id)&&n.artifacts.push(structuredClone(r)),n.events.push(function cloneEvent(e){return structuredClone(e)}(e)),cloneRun(n)},getRun:e=>function cloneOptionalRun(e){return e?cloneRun(e):void 0}(t.get(e)),listRuns:e=>[...t.values()].filter(t=>function matchesFilter(e,t){return!t||!(t.agentId&&t.agentId!==e.agentId||t.sessionId&&t.sessionId!==e.sessionId||t.state&&t.state!==e.state)}(t,e)).map(cloneRun),deleteRun(e){const n=t.get(e);if(n)return t.delete(e),cloneRun(n)},deleteSession(e){const n=[...t.values()].filter(t=>t.sessionId===e).map(e=>e.requestId);for(const e of n)t.delete(e);return{deletedRequestIds:n,deletedCount:n.length}}}}export function createJsonFileRuntimeStore(t){const r=s.resolve(t),u=createInMemoryRuntimeStore(function readStoreFile(t){if(!e(t))return[];const r=JSON.parse(n(t,"utf8"));if(!isRecord(r)||!Array.isArray(r.runs))throw new Error(`Invalid runtime store file: ${t}`);return r.runs.map(assertRunRecord)}(r));return{createRun(e){u.createRun(e),writeStoreFile(r,u.listRuns())},updateRun(e,t){const n=u.updateRun(e,t);return writeStoreFile(r,u.listRuns()),n},appendEvent(e){const t=u.appendEvent(e);return writeStoreFile(r,u.listRuns()),t},getRun:e=>u.getRun(e),listRuns:e=>u.listRuns(e),deleteRun(e){const t=u.deleteRun(e);return writeStoreFile(r,u.listRuns()),t},deleteSession(e){const t=u.deleteSession(e);return writeStoreFile(r,u.listRuns()),t}}}function writeStoreFile(e,n){t(s.dirname(e),{recursive:!0}),r(e,`${JSON.stringify({version:1,runs:n},null,2)}\n`)}function assertRunRecord(e){if(!isRecord(e)||"string"!=typeof e.requestId)throw new Error("Invalid runtime run record in store file");return cloneRun(e)}function cloneRun(e){return structuredClone(e)}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -115,12 +115,18 @@ export type RuntimeRunFilter = {
115
115
  sessionId?: string;
116
116
  state?: RuntimeRecordState;
117
117
  };
118
+ export type RuntimeDeletionResult = {
119
+ deletedRequestIds: string[];
120
+ deletedCount: number;
121
+ };
118
122
  export type RuntimeStore = {
119
123
  createRun(record: RuntimeRunRecord): void;
120
124
  updateRun(requestId: string, patch: RuntimeStoreRunPatch): RuntimeRunRecord | undefined;
121
125
  appendEvent(event: RuntimeEvent): RuntimeRunRecord | undefined;
122
126
  getRun(requestId: string): RuntimeRunRecord | undefined;
123
127
  listRuns(filter?: RuntimeRunFilter): RuntimeRunRecord[];
128
+ deleteRun(requestId: string): RuntimeRunRecord | undefined;
129
+ deleteSession(sessionId: string): RuntimeDeletionResult;
124
130
  };
125
131
  export type RuntimeQueueRecord = {
126
132
  requestId: string;
@@ -1 +1 @@
1
- import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{buildAdapterErrorRecoveryPrompt as r,buildExecutionContractRecoveryRequest as a,isRecoverableAdapterError as s}from"./recovery/tool-call.js";import{recoverQualityReview as n,resolveQualityPolicy as o}from"./quality/index.js";import{recoverAdapterResultOutput as i}from"./runtime/recovery/adapter-result.js";import{completeRun as u,failRun as c}from"./runtime/completion.js";import{runDirectToolCall as p}from"./runtime/direct-tool-call.js";import{createApprovalGatedToolGateway as d}from"./runtime/governance/approval-gate.js";import{createSandboxedToolGateway as m}from"./runtime/governance/sandbox.js";import{createRuntimeInspectionMethods as l}from"./runtime/inspection/methods.js";import{createRuntimeCapabilityRegistry as w,normalizeAdapterResult as f}from"./runtime/capabilities.js";import{createMemoryRuntimeCapability as g}from"./runtime/memory.js";import{createInMemoryRuntimeStore as I}from"./runtime/persistence/stores.js";import{createProgressNarrationCapability as y}from"./runtime/progress-narration.js";import{repairRuntimeSelection as q}from"./runtime/selection-repair.js";import{createLangSmithTracingCapability as R}from"./runtime/tracing/langsmith.js";import{createToolFailureTracker as k}from"./runtime/tool-failure.js";import{runWorkflowRequest as v}from"./workflows/runtime.js";export function createStableHarnessRuntime(t){const f=new Set,b=t.store??I(),A=w([g(t),y({options:t.progressNarration,policy:t.workspace.runtime}),R({policy:t.workspace.runtime,store:b,options:t.langSmithTracing}),...t.capabilities??[]]),emitBase=t=>{const r=function enrichRuntimeEvent(t){return{...t,eventId:t.eventId??e(),emittedAt:t.emittedAt??(new Date).toISOString()}}(t);b.appendEvent(r);for(const e of f)e(r)},emit=e=>{emitBase(e),A.emitSideEffects(e,emitBase)},C=m({gateway:d({gateway:t.toolGateway,approvals:t.approvals,workspace:t.workspace,emit:emit}),workspace:t.workspace,sandbox:t.sandbox,emit:emit}),h={...t,toolGateway:C},x=k(function readToolFailurePolicy(e){if("object"!=typeof e||null===e||Array.isArray(e))return;const t=e.failurePolicy;return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}(t.workspace.runtime.toolGateway));return{request:async t=>async function runRuntimeRequest(t){const d=t.request.requestId??e(),m=t.request.sessionId??e(),l=[],{agent:w,adapter:f}=await async function resolveExecution(e,t,r){const a=t.agentId?await async function resolveRequestedAgentId(e,t,r){if(e.agents.has(t))return t;const a=await q({id:t,candidates:[...e.agents.values()].map(e=>({id:e.id,description:e.description})),trace:{...r,agentId:t,layer:"agent",owner:"stable_runtime_policy"}});return a.ok?a.id:t}(e.workspace,t.agentId,r):function resolveRoutedAgentId(e,t){for(const r of e.runtime.routes??[])if(routeMatches(r,t))return r.agentId;return e.runtime.defaultAgentId}(e.workspace,t.input),s=e.workspace.agents.get(a);if(!s)throw new Error(`Agent ${a} is not defined in the workspace`);if(t.toolCall||t.workflow)return{agent:s,adapter:void 0};const n=e.adapters.find(e=>e.canRun(s));if(!n)throw new Error(`No runtime adapter can run backend ${s.backend} for agent ${s.id}`);return{agent:s,adapter:n}}(t.input,t.request,{requestId:d,sessionId:m,emit:e=>l.push(e)});t.store.createRun(function createRunRecord(e,t,r,a){return{requestId:t,sessionId:r,agentId:a.id,input:e.input,state:"running",parentRunId:e.parentRunId,metadata:e.metadata,artifacts:[],startedAt:(new Date).toISOString(),events:[]}}(t.request,d,m,w)),l.forEach(t.emit),t.emit({type:"runtime.request.started",requestId:d,sessionId:m,agentId:w.id,input:t.request.input});try{if(t.request.workflow){const e=await v({workspace:t.input.workspace,adapters:t.input.workflowAdapters??[],toolGateway:t.input.toolGateway,request:{input:t.request.input,...t.request.workflow},requestId:d,sessionId:m,agentId:w.id,emit:t.emit});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}if(t.request.toolCall){const e=await p({gateway:t.input.toolGateway,workspace:t.input.workspace,emit:t.emit,request:t.request,requestId:d,sessionId:m,agent:w,toolFailureTracker:t.toolFailureTracker});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}return await async function runAdapterRequest(e){if(!e.adapter)throw new Error(`No runtime adapter can run backend ${e.agent.backend} for agent ${e.agent.id}`);const t=e.adapter,c=await e.capabilities.beforeAdapterRun(createCapabilityContext(e)),p=c.memory,d=c.pluginMemories??[],m=e.input.workspace.runtime,l=o(e.input.workspace.runtime,e.agent),w=new Map;let f;try{f=await runAdapterOnce(e,t,e.request,p,d,w)}catch(a){if(!s(a,m))throw a;e.emit(repairStarted(e,"adapter_error",1,errorMessage(a))),f=await runAdapterOnce(e,t,r(e.request,a,m),p,d,w),e.emit(repairCompleted(e,"adapter_error","retried",1,errorMessage(a)))}f=await i({...e,request:e.request,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),e.request,f,l),await e.capabilities.beforeAdapterResultContract({...createCapabilityContext(e),result:f});try{assertRequestExecutionContract(e)}catch(r){const s=a({request:e.request,events:e.store.getRun(e.requestId)?.events??[],policy:m});if(!s)throw r;e.emit(repairStarted(e,"execution_contract",1,errorMessage(r))),f=await runAdapterOnce(e,t,s,p,d,w),f=await i({...e,request:s,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),s,f,l),assertRequestExecutionContract(e),e.emit(repairCompleted(e,"execution_contract","retried",1,errorMessage(r)))}const g=u({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,result:f,artifacts:e.input.artifacts});return await e.capabilities.afterAdapterResponse({...createCapabilityContext(e),result:f,response:g}),g}({...t,adapter:f,requestId:d,sessionId:m,agent:w})}catch(e){return c({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,error:e})}}({input:h,capabilities:A,store:b,emit:emit,request:t,toolFailureTracker:x}),subscribe:e=>(f.add(e),()=>f.delete(e)),...l({workspace:t.workspace,store:b,artifacts:t.artifacts,approvals:t.approvals,emit:emit}),cancel(e,t){const r=b.getRun(e);r&&"running"===r.state&&(b.updateRun(e,{state:"cancelled",completedAt:(new Date).toISOString()}),emit({type:"runtime.request.cancelled",requestId:e,sessionId:r.sessionId,agentId:r.agentId,reason:t}))},async stop(){await A.stop(),f.clear()}}}function createCapabilityContext(e){return{workspace:e.input.workspace,store:e.store,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent}}function createQualityRuntimeInput(e,t,r,a){return{workspace:e.input.workspace,agent:e.agent,request:e.request,requestId:e.requestId,sessionId:e.sessionId,events:e.store.getRun(e.requestId)?.events??[],emit:e.emit,getEvents:()=>e.store.getRun(e.requestId)?.events??[],runAdapter:s=>runAdapterOnce(e,e.adapter,s,t,r,a),reviewModel:e.input.qualityReviewModel,memory:t,pluginMemories:r}}function assertRequestExecutionContract(e){t({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,metadata:e.request.metadata})}async function runAdapterOnce(e,t,r,a,s,n){return f(await t.run({workspace:e.input.workspace,agent:e.agent,request:r,requestId:e.requestId,sessionId:e.sessionId,memory:a,pluginMemories:s,toolGateway:e.input.toolGateway,toolFailureTracker:e.input.toolFailureTracker,requestState:n,getEvents:()=>e.store.getRun(e.requestId)?.events??[],emit:e.emit}))}function repairStarted(e,t,r,a){return{type:"runtime.repair.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,attempt:r,reason:a}}function repairCompleted(e,t,r,a,s){return{type:"runtime.repair.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,outcome:r,attempt:a,reason:s}}function errorMessage(e){return e instanceof Error?e.message:String(e)}function routeMatches(e,t){if(e.pattern)try{if(new RegExp(e.pattern,"iu").test(t))return!0}catch{return!1}const r=t.toLowerCase();return(e.keywords??[]).some(e=>r.includes(e.toLowerCase()))}
1
+ import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{buildAdapterErrorRecoveryPrompt as r,buildExecutionContractRecoveryRequest as a,isRecoverableAdapterError as s}from"./recovery/tool-call.js";import{recoverQualityReview as n,resolveQualityPolicy as o}from"./quality/index.js";import{recoverAdapterResultOutput as i}from"./runtime/recovery/adapter-result.js";import{completeRun as u,failRun as c}from"./runtime/completion.js";import{createRuntimeAdministrationMethods as p}from"./runtime/admin/administration.js";import{runDirectToolCall as d}from"./runtime/direct-tool-call.js";import{createApprovalGatedToolGateway as m}from"./runtime/governance/approval-gate.js";import{createSandboxedToolGateway as l}from"./runtime/governance/sandbox.js";import{createRuntimeInspectionMethods as w}from"./runtime/inspection/methods.js";import{createRuntimeCapabilityRegistry as f,normalizeAdapterResult as g}from"./runtime/capabilities.js";import{createMemoryRuntimeCapability as I}from"./runtime/memory.js";import{createRuntimeMemoryAdministration as y}from"./runtime/admin/memory.js";import{createInMemoryRuntimeStore as q}from"./runtime/persistence/stores.js";import{createProgressNarrationCapability as R}from"./runtime/progress-narration.js";import{repairRuntimeSelection as k}from"./runtime/selection-repair.js";import{createLangSmithTracingCapability as v}from"./runtime/tracing/langsmith.js";import{createToolFailureTracker as A}from"./runtime/tool-failure.js";import{runWorkflowRequest as b}from"./workflows/runtime.js";export function createStableHarnessRuntime(t){const g=new Set,C=t.store??q(),h=f([I(t),R({options:t.progressNarration,policy:t.workspace.runtime}),v({policy:t.workspace.runtime,store:C,options:t.langSmithTracing}),...t.capabilities??[]]),emitBase=t=>{const r=function enrichRuntimeEvent(t){return{...t,eventId:t.eventId??e(),emittedAt:t.emittedAt??(new Date).toISOString()}}(t);C.appendEvent(r);for(const e of g)e(r)},emit=e=>{emitBase(e),h.emitSideEffects(e,emitBase)},j=l({gateway:m({gateway:t.toolGateway,approvals:t.approvals,workspace:t.workspace,emit:emit}),workspace:t.workspace,sandbox:t.sandbox,emit:emit}),x={...t,toolGateway:j},E=A(function readToolFailurePolicy(e){if("object"!=typeof e||null===e||Array.isArray(e))return;const t=e.failurePolicy;return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}(t.workspace.runtime.toolGateway));return{request:async t=>async function runRuntimeRequest(t){const p=t.request.requestId??e(),m=t.request.sessionId??e(),l=[],{agent:w,adapter:f}=await async function resolveExecution(e,t,r){const a=t.agentId?await async function resolveRequestedAgentId(e,t,r){if(e.agents.has(t))return t;const a=await k({id:t,candidates:[...e.agents.values()].map(e=>({id:e.id,description:e.description})),trace:{...r,agentId:t,layer:"agent",owner:"stable_runtime_policy"}});return a.ok?a.id:t}(e.workspace,t.agentId,r):function resolveRoutedAgentId(e,t){for(const r of e.runtime.routes??[])if(routeMatches(r,t))return r.agentId;return e.runtime.defaultAgentId}(e.workspace,t.input),s=e.workspace.agents.get(a);if(!s)throw new Error(`Agent ${a} is not defined in the workspace`);if(t.toolCall||t.workflow)return{agent:s,adapter:void 0};const n=e.adapters.find(e=>e.canRun(s));if(!n)throw new Error(`No runtime adapter can run backend ${s.backend} for agent ${s.id}`);return{agent:s,adapter:n}}(t.input,t.request,{requestId:p,sessionId:m,emit:e=>l.push(e)});t.store.createRun(function createRunRecord(e,t,r,a){return{requestId:t,sessionId:r,agentId:a.id,input:e.input,state:"running",parentRunId:e.parentRunId,metadata:e.metadata,artifacts:[],startedAt:(new Date).toISOString(),events:[]}}(t.request,p,m,w)),l.forEach(t.emit),t.emit({type:"runtime.request.started",requestId:p,sessionId:m,agentId:w.id,input:t.request.input});try{if(t.request.workflow){const e=await b({workspace:t.input.workspace,adapters:t.input.workflowAdapters??[],toolGateway:t.input.toolGateway,request:{input:t.request.input,...t.request.workflow},requestId:p,sessionId:m,agentId:w.id,emit:t.emit});return u({store:t.store,emit:t.emit,requestId:p,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}if(t.request.toolCall){const e=await d({gateway:t.input.toolGateway,workspace:t.input.workspace,emit:t.emit,request:t.request,requestId:p,sessionId:m,agent:w,toolFailureTracker:t.toolFailureTracker});return u({store:t.store,emit:t.emit,requestId:p,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}return await async function runAdapterRequest(e){if(!e.adapter)throw new Error(`No runtime adapter can run backend ${e.agent.backend} for agent ${e.agent.id}`);const t=e.adapter,c=await e.capabilities.beforeAdapterRun(createCapabilityContext(e)),p=c.memory,d=c.pluginMemories??[],m=e.input.workspace.runtime,l=o(e.input.workspace.runtime,e.agent),w=new Map;let f;try{f=await runAdapterOnce(e,t,e.request,p,d,w)}catch(a){if(!s(a,m))throw a;e.emit(repairStarted(e,"adapter_error",1,errorMessage(a))),f=await runAdapterOnce(e,t,r(e.request,a,m),p,d,w),e.emit(repairCompleted(e,"adapter_error","retried",1,errorMessage(a)))}f=await i({...e,request:e.request,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),e.request,f,l),await e.capabilities.beforeAdapterResultContract({...createCapabilityContext(e),result:f});try{assertRequestExecutionContract(e)}catch(r){const s=a({request:e.request,events:e.store.getRun(e.requestId)?.events??[],policy:m});if(!s)throw r;e.emit(repairStarted(e,"execution_contract",1,errorMessage(r))),f=await runAdapterOnce(e,t,s,p,d,w),f=await i({...e,request:s,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),s,f,l),assertRequestExecutionContract(e),e.emit(repairCompleted(e,"execution_contract","retried",1,errorMessage(r)))}const g=u({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,result:f,artifacts:e.input.artifacts});return await e.capabilities.afterAdapterResponse({...createCapabilityContext(e),result:f,response:g}),g}({...t,adapter:f,requestId:p,sessionId:m,agent:w})}catch(e){return c({store:t.store,emit:t.emit,requestId:p,sessionId:m,agent:w,error:e})}}({input:x,capabilities:h,store:C,emit:emit,request:t,toolFailureTracker:E}),subscribe:e=>(g.add(e),()=>g.delete(e)),...w({workspace:t.workspace,store:C,artifacts:t.artifacts,approvals:t.approvals,emit:emit}),...p({store:C,emit:emit}),...y({memory:t.memory}),cancel(e,t){const r=C.getRun(e);r&&"running"===r.state&&(C.updateRun(e,{state:"cancelled",completedAt:(new Date).toISOString()}),emit({type:"runtime.request.cancelled",requestId:e,sessionId:r.sessionId,agentId:r.agentId,reason:t}))},async stop(){await h.stop(),g.clear()}}}function createCapabilityContext(e){return{workspace:e.input.workspace,store:e.store,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent}}function createQualityRuntimeInput(e,t,r,a){return{workspace:e.input.workspace,agent:e.agent,request:e.request,requestId:e.requestId,sessionId:e.sessionId,events:e.store.getRun(e.requestId)?.events??[],emit:e.emit,getEvents:()=>e.store.getRun(e.requestId)?.events??[],runAdapter:s=>runAdapterOnce(e,e.adapter,s,t,r,a),reviewModel:e.input.qualityReviewModel,memory:t,pluginMemories:r}}function assertRequestExecutionContract(e){t({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,metadata:e.request.metadata})}async function runAdapterOnce(e,t,r,a,s,n){return g(await t.run({workspace:e.input.workspace,agent:e.agent,request:r,requestId:e.requestId,sessionId:e.sessionId,memory:a,pluginMemories:s,toolGateway:e.input.toolGateway,toolFailureTracker:e.input.toolFailureTracker,requestState:n,getEvents:()=>e.store.getRun(e.requestId)?.events??[],emit:e.emit}))}function repairStarted(e,t,r,a){return{type:"runtime.repair.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,attempt:r,reason:a}}function repairCompleted(e,t,r,a,s){return{type:"runtime.repair.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,outcome:r,attempt:a,reason:s}}function errorMessage(e){return e instanceof Error?e.message:String(e)}function routeMatches(e,t){if(e.pattern)try{if(new RegExp(e.pattern,"iu").test(t))return!0}catch{return!1}const r=t.toLowerCase();return(e.keywords??[]).some(e=>r.includes(e.toLowerCase()))}
@@ -1,17 +1,17 @@
1
- import type { MemoryProvider, MemoryRecord, RuntimeMemoryStore } from "@stable-harness/memory";
1
+ import type { ListMemoriesInput, MemorizeInput, MemoryProvider, MemoryRecord, MemoryRecallResult, RecallInput, RuntimeMemoryStore, UpdateMemoryInput } from "@stable-harness/memory";
2
2
  import type { ApprovalQueue, ApprovalRequest, ApprovalRequestStatus } from "@stable-harness/governance";
3
3
  import type { RuntimeWorkflowAdapter, RuntimeWorkflowRequest, WorkspaceWorkflow } from "./workflows/index.js";
4
4
  import type { SpecDrivenWorkflowState } from "./spec-driven/index.js";
5
5
  import type { RuntimeEvent, RuntimeEventListener, RuntimeEmit } from "./runtime/events.js";
6
6
  import type { RuntimeToolFailureTracker } from "./runtime/tool-failure.js";
7
- import type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactRecord, RuntimeOutput, RuntimeRecordState, RuntimeRequest, RuntimeResponse, RuntimeReplayBundle, RuntimeRunFilter, RuntimeRunRecord } from "./runtime/types.js";
7
+ import type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactRecord, RuntimeOutput, RuntimeRecordState, RuntimeRequest, RuntimeResponse, RuntimeReplayBundle, RuntimeDeletionResult, RuntimeRunFilter, RuntimeRunRecord } from "./runtime/types.js";
8
8
  import type { RuntimeToolGateway } from "./runtime/tool-gateway.js";
9
9
  import type { CompiledWorkspace, WorkspaceAgent, WorkspaceRuntimePolicy } from "./workspace/types.js";
10
10
  export type { RuntimeEvent, RuntimeMemoryHook, RuntimeEventListener, RuntimeEmit } from "./runtime/events.js";
11
11
  export type { BoundaryScanFinding, BoundaryScanLayer, BoundaryScanLayerResult, BoundaryScanResource, BoundaryScanResult } from "./boundary-scan.js";
12
12
  export type { RuntimeCapabilityContext, RuntimeCapabilityModule, RuntimeCapabilityRegistry, RuntimeCapabilityState } from "./runtime/capabilities.js";
13
13
  export type { RuntimeProgressNarrationOptions, RuntimeProgressNarrationProvider } from "./runtime/progress-narration.js";
14
- export type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactInput, RuntimeArtifactRecord, RuntimeArtifactStore, RuntimeOutputArtifact, RuntimeCancelIntentInput, RuntimeHeartbeatInput, RuntimeMemoryCandidateInput, RuntimeOutput, RuntimeQueueClaimInput, RuntimeQueueRecord, RuntimeQueueStore, RuntimeRecoveryIntent, RuntimeRecordState, RuntimeRequest, RuntimeRequestControlRecord, RuntimeRequestMemory, RuntimeResponse, RuntimeReplayBundle, RuntimeReplayBundleIntegrity, RuntimeRunFilter, RuntimeRunRecord, RuntimeStore, RuntimeStoreRunPatch, RuntimeStuckRequestInput, } from "./runtime/types.js";
14
+ export type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactInput, RuntimeArtifactRecord, RuntimeArtifactStore, RuntimeOutputArtifact, RuntimeCancelIntentInput, RuntimeHeartbeatInput, RuntimeMemoryCandidateInput, RuntimeOutput, RuntimeQueueClaimInput, RuntimeQueueRecord, RuntimeQueueStore, RuntimeRecoveryIntent, RuntimeRecordState, RuntimeRequest, RuntimeRequestControlRecord, RuntimeRequestMemory, RuntimeResponse, RuntimeDeletionResult, RuntimeReplayBundle, RuntimeReplayBundleIntegrity, RuntimeRunFilter, RuntimeRunRecord, RuntimeStore, RuntimeStoreRunPatch, RuntimeStuckRequestInput, } from "./runtime/types.js";
15
15
  export type { CompiledWorkspace, WorkspaceAdapterPolicy, WorkspaceAgent, WorkspaceBoundaryDiagnostic, WorkspaceBoundaryDiagnosticCode, WorkspaceBoundaryScanPolicy, WorkspaceMemory, WorkspaceModel, WorkspaceRetryPolicy, WorkspaceRetryReason, WorkspaceRetryTargetPolicy, WorkspaceRuntimePolicy, WorkspaceSkill, WorkspaceTool, WorkspaceToolRetryPolicy, WorkspaceValidationPolicy, } from "./workspace/types.js";
16
16
  export type { WorkspaceToolQualityDiagnostic, WorkspaceToolQualityDiagnosticCode, WorkspaceToolQualityPolicy, } from "./workspace/tool-quality.js";
17
17
  export type { WorkspaceEvaluation, WorkspaceEvaluationCase, } from "./evaluations/index.js";
@@ -140,6 +140,15 @@ export type RuntimeInspector = {
140
140
  };
141
141
  export type RuntimeLifecycle = {
142
142
  cancel(requestId: string, reason?: string): void;
143
+ deleteRequest(requestId: string): RuntimeDeletionResult;
144
+ deleteSession(sessionId: string): RuntimeDeletionResult;
143
145
  stop(): Promise<void>;
144
146
  };
145
- export type StableHarnessRuntime = RuntimeClient & RuntimeEventSource & RuntimeInspector & RuntimeLifecycle;
147
+ export type RuntimeMemoryAdministration = {
148
+ memorize(input: MemorizeInput): Promise<MemoryRecord>;
149
+ recallMemories(input: RecallInput): Promise<MemoryRecallResult>;
150
+ listMemories(input: ListMemoriesInput): Promise<MemoryRecord[]>;
151
+ updateMemory(input: UpdateMemoryInput): Promise<MemoryRecord | undefined>;
152
+ archiveMemory(id: string, reason?: string): Promise<MemoryRecord | undefined>;
153
+ };
154
+ export type StableHarnessRuntime = RuntimeClient & RuntimeEventSource & RuntimeInspector & RuntimeLifecycle & RuntimeMemoryAdministration;
@@ -5,5 +5,5 @@ export type { LangMemServiceProviderOptions, } from "./langmem-service.js";
5
5
  export type { MemoryProvider, MemoryProviderApprovalConfig, MemoryProviderConfig, MemoryProviderConsolidateInput, MemoryProviderDefaults, MemoryProviderMode, MemoryProviderProposeInput, MemoryProviderSearchInput, MemoryProviderTypeConfig, } from "./provider.js";
6
6
  export { cloneRecords, createInMemoryMemoryPersistenceAdapter, createMemorySnapshot, } from "./persistence.js";
7
7
  export { createDefaultMemoryPolicy } from "./policy.js";
8
- export { createInMemoryRuntimeMemoryStore } from "./store.js";
8
+ export { createInMemoryRuntimeMemoryStore, createJsonFileRuntimeMemoryStore } from "./store.js";
9
9
  export type { ListMemoriesInput, MemorizeInput, MemoryCandidate, MemoryDecision, MemoryDecisionAction, MemoryKind, MemoryMaintenanceAction, MemoryMaintenanceOperation, MemoryMaintenanceResult, MemoryPolicy, MemoryPersistenceAdapter, MemoryRecallResult, MemoryRecord, MemoryRecordStatus, MemoryScope, MemorySensitivity, MemoryStoreSnapshot, MemorySubmitResult, RecallInput, RuntimeMemoryStore, UpdateMemoryInput, } from "./types.js";
@@ -1 +1 @@
1
- export{applyMemoryMaintenance}from"./maintenance.js";export{createEmbeddedMemoryProvider}from"./provider.js";export{createLangMemServiceProvider}from"./langmem-service.js";export{cloneRecords,createInMemoryMemoryPersistenceAdapter,createMemorySnapshot}from"./persistence.js";export{createDefaultMemoryPolicy}from"./policy.js";export{createInMemoryRuntimeMemoryStore}from"./store.js";
1
+ export{applyMemoryMaintenance}from"./maintenance.js";export{createEmbeddedMemoryProvider}from"./provider.js";export{createLangMemServiceProvider}from"./langmem-service.js";export{cloneRecords,createInMemoryMemoryPersistenceAdapter,createMemorySnapshot}from"./persistence.js";export{createDefaultMemoryPolicy}from"./policy.js";export{createInMemoryRuntimeMemoryStore,createJsonFileRuntimeMemoryStore}from"./store.js";
@@ -1 +1 @@
1
- export async function createMemorySnapshot(e,t){return{namespace:t.namespace,records:await e.list(t),exportedAt:(new Date).toISOString()}}export function createInMemoryMemoryPersistenceAdapter(){const e=new Map;return{load:async t=>cloneRecords(e.get(t)??[]),async save(t){e.set(t.namespace,cloneRecords(t.records))}}}export function cloneRecords(e){return e.map(e=>({...e,sourceRefs:[...e.sourceRefs],tags:[...e.tags],metadata:{...e.metadata},provenance:{...e.provenance},supersedes:[...e.supersedes],conflictsWith:[...e.conflictsWith]}))}
1
+ export async function createMemorySnapshot(e,t){return{namespace:t.namespace??"",records:await e.list(t),exportedAt:(new Date).toISOString()}}export function createInMemoryMemoryPersistenceAdapter(){const e=new Map;return{load:async t=>cloneRecords(e.get(t)??[]),async save(t){e.set(t.namespace,cloneRecords(t.records))}}}export function cloneRecords(e){return e.map(e=>({...e,sourceRefs:[...e.sourceRefs],tags:[...e.tags],metadata:{...e.metadata},provenance:{...e.provenance},supersedes:[...e.supersedes],conflictsWith:[...e.conflictsWith]}))}
@@ -3,3 +3,6 @@ export declare function createInMemoryRuntimeMemoryStore(options?: {
3
3
  policy?: MemoryPolicy;
4
4
  records?: MemoryRecord[];
5
5
  }): RuntimeMemoryStore;
6
+ export declare function createJsonFileRuntimeMemoryStore(filePath: string, options?: {
7
+ policy?: MemoryPolicy;
8
+ }): RuntimeMemoryStore;
@@ -1 +1 @@
1
- import{randomUUID as e}from"node:crypto";import{createDefaultMemoryPolicy as t}from"./policy.js";import{cloneRecords as n}from"./persistence.js";export function createInMemoryRuntimeMemoryStore(e={}){const r=e.policy??t(),o=n(e.records??[]);return{async submitCandidate(e){const t=r.decide(e);if("store"!==t.action)return{candidate:e,decision:t};const n=createRecord({namespace:e.namespace,content:e.content,kind:t.kind,scope:t.scope,summary:e.summary,confidence:t.confidence,tags:e.tags,sensitivity:e.sensitivity,sourceType:e.sourceType,sourceRef:e.sourceRef,metadata:e.metadata,provenance:e.provenance,observedAt:e.observedAt,retrievalPriority:t.retrievalPriority});return o.push(n),{candidate:e,decision:{...t,recordId:n.id},record:cloneRecord(n)}},async memorize(e){const t=createRecord(e);return o.push(t),cloneRecord(t)},async recall(e){const t=e.query.toLowerCase(),n=filterRecords(o,e).filter(e=>function matchesQuery(e,t){return[e.canonicalKey,e.content,e.summary??"",...e.tags].join("\n").toLowerCase().includes(t)}(e,t)).sort(compareRecallPriority).slice(0,e.limit??10);return{records:n,context:buildMemoryContext(n)}},list:async e=>n(filterRecords(o,e)),async update(e){const t=o.find(t=>t.id===e.id);if(t)return function applyUpdate(e,t){e.content=t.content??e.content,e.summary=t.summary??e.summary,e.status=t.status??e.status,e.confidence=normalizeConfidence(t.confidence??e.confidence),e.tags=t.tags??e.tags,e.metadata=t.metadata?{...e.metadata,...t.metadata}:e.metadata,e.lastConfirmedAt=(new Date).toISOString(),e.revision+=1}(t,e),cloneRecord(t)},async archive(e,t){const n=o.find(t=>t.id===e);if(n)return n.status="archived",n.metadata={...n.metadata,archiveReason:t},n.revision+=1,cloneRecord(n)}}}function cloneRecord(e){return n([e])[0]}function createRecord(t){const n=(new Date).toISOString();return{id:e(),namespace:t.namespace,canonicalKey:(r=t.namespace,o=t.content,`${r}:${o.trim().toLowerCase().replace(/\s+/gu," ").slice(0,120)}`),kind:t.kind??"semantic",scope:t.scope??"workspace",status:"active",content:t.content,summary:t.summary,confidence:normalizeConfidence(t.confidence),sourceType:t.sourceType,sourceRefs:t.sourceRef?[t.sourceRef]:[],tags:t.tags??[],sensitivity:t.sensitivity??"internal",metadata:t.metadata??{},createdAt:n,observedAt:t.observedAt??n,lastConfirmedAt:n,provenance:t.provenance??{},revision:1,supersedes:[],conflictsWith:[],retrievalPriority:t.retrievalPriority??0};var r,o}function filterRecords(e,t){return e.filter(e=>e.namespace===t.namespace).filter(e=>!t.kinds||t.kinds.includes(e.kind)).filter(e=>!t.scopes||t.scopes.includes(e.scope)).filter(e=>(t.statuses??["active"]).includes(e.status))}function compareRecallPriority(e,t){return t.retrievalPriority-e.retrievalPriority||t.confidence-e.confidence||t.lastConfirmedAt.localeCompare(e.lastConfirmedAt)}function buildMemoryContext(e){return e.map(e=>`- [${e.kind}/${e.scope}] ${e.summary??e.content}`).join("\n")}function normalizeConfidence(e){return void 0===e||Number.isNaN(e)?.6:Math.min(1,Math.max(0,e))}
1
+ import{existsSync as e,mkdirSync as r,readFileSync as t,writeFileSync as n}from"node:fs";import{randomUUID as o}from"node:crypto";import i from"node:path";import{createDefaultMemoryPolicy as a}from"./policy.js";import{cloneRecords as c}from"./persistence.js";export function createInMemoryRuntimeMemoryStore(e={}){const r=e.policy??a(),t=c(e.records??[]);return{async submitCandidate(e){const n=r.decide(e);if("store"!==n.action)return{candidate:e,decision:n};const o=createRecord({namespace:e.namespace,content:e.content,kind:n.kind,scope:n.scope,summary:e.summary,confidence:n.confidence,tags:e.tags,sensitivity:e.sensitivity,sourceType:e.sourceType,sourceRef:e.sourceRef,metadata:e.metadata,provenance:e.provenance,observedAt:e.observedAt,retrievalPriority:n.retrievalPriority});return t.push(o),{candidate:e,decision:{...n,recordId:o.id},record:cloneRecord(o)}},async memorize(e){const r=createRecord(e);return t.push(r),cloneRecord(r)},async recall(e){const r=e.query.toLowerCase(),n=filterRecords(t,e).filter(e=>function matchesQuery(e,r){return[e.canonicalKey,e.content,e.summary??"",...e.tags].join("\n").toLowerCase().includes(r)}(e,r)).sort(compareRecallPriority).slice(0,e.limit??10);return{records:n,context:buildMemoryContext(n)}},list:async e=>c(filterRecords(t,e)),async update(e){const r=t.find(r=>r.id===e.id);if(r)return function applyUpdate(e,r){e.content=r.content??e.content,e.summary=r.summary??e.summary,e.status=r.status??e.status,e.confidence=normalizeConfidence(r.confidence??e.confidence),e.tags=r.tags??e.tags,e.metadata=r.metadata?{...e.metadata,...r.metadata}:e.metadata,e.lastConfirmedAt=(new Date).toISOString(),e.revision+=1}(r,e),cloneRecord(r)},async archive(e,r){const n=t.find(r=>r.id===e);if(n)return n.status="archived",n.metadata={...n.metadata,archiveReason:r},n.revision+=1,cloneRecord(n)}}}export function createJsonFileRuntimeMemoryStore(e,r={}){const t=i.resolve(e),n=createInMemoryRuntimeMemoryStore({policy:r.policy,records:readStoreFile(t)});return{async submitCandidate(e){const r=await n.submitCandidate(e);return await persistMemoryStore(t,n),r},async memorize(e){const r=await n.memorize(e);return await persistMemoryStore(t,n),r},recall:e=>n.recall(e),list:e=>n.list(e),async update(e){const r=await n.update(e);return await persistMemoryStore(t,n),r},async archive(e,r){const o=await n.archive(e,r);return await persistMemoryStore(t,n),o}}}function cloneRecord(e){return c([e])[0]}async function persistMemoryStore(e,t){!function writeStoreFile(e,t){r(i.dirname(e),{recursive:!0}),n(e,`${JSON.stringify({version:1,records:t},null,2)}\n`)}(e,await t.list({statuses:["active","stale","conflicted","archived","pending_review"]}))}function readStoreFile(r){if(!e(r))return[];const n=JSON.parse(t(r,"utf8"));if(!isRecord(n)||!Array.isArray(n.records))throw new Error(`Invalid runtime memory store file: ${r}`);return c(n.records.map(assertMemoryRecord))}function assertMemoryRecord(e){if(!isRecord(e)||"string"!=typeof e.id||"string"!=typeof e.namespace)throw new Error("Invalid memory record in store file");return e}function createRecord(e){const r=(new Date).toISOString();return{id:o(),namespace:e.namespace,canonicalKey:(t=e.namespace,n=e.content,`${t}:${n.trim().toLowerCase().replace(/\s+/gu," ").slice(0,120)}`),kind:e.kind??"semantic",scope:e.scope??"workspace",status:"active",content:e.content,summary:e.summary,confidence:normalizeConfidence(e.confidence),sourceType:e.sourceType,sourceRefs:e.sourceRef?[e.sourceRef]:[],tags:e.tags??[],sensitivity:e.sensitivity??"internal",metadata:e.metadata??{},createdAt:r,observedAt:e.observedAt??r,lastConfirmedAt:r,provenance:e.provenance??{},revision:1,supersedes:[],conflictsWith:[],retrievalPriority:e.retrievalPriority??0};var t,n}function filterRecords(e,r){return e.filter(e=>!r.namespace||e.namespace===r.namespace).filter(e=>!r.kinds||r.kinds.includes(e.kind)).filter(e=>!r.scopes||r.scopes.includes(e.scope)).filter(e=>(r.statuses??["active"]).includes(e.status))}function compareRecallPriority(e,r){return r.retrievalPriority-e.retrievalPriority||r.confidence-e.confidence||r.lastConfirmedAt.localeCompare(e.lastConfirmedAt)}function buildMemoryContext(e){return e.map(e=>`- [${e.kind}/${e.scope}] ${e.summary??e.content}`).join("\n")}function normalizeConfidence(e){return void 0===e||Number.isNaN(e)?.6:Math.min(1,Math.max(0,e))}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -111,7 +111,7 @@ export type MemoryMaintenanceResult = {
111
111
  reason: string;
112
112
  };
113
113
  export type ListMemoriesInput = {
114
- namespace: string;
114
+ namespace?: string;
115
115
  kinds?: MemoryKind[];
116
116
  scopes?: MemoryScope[];
117
117
  statuses?: MemoryRecordStatus[];
@@ -1 +1 @@
1
- import{createServer as t}from"node:http";import{compileWorkflowPlan as e,projectRuntimeTrace as r,projectRuntimeTraceSpans as o,renderWorkflowMermaid as n}from"@stable-harness/core";export function createHttpServer(s){return t(async(t,a)=>{try{if("GET"===t.method&&"/health"===t.url)return void sendJson(a,200,{ok:!0});if("GET"===t.method&&"/inspect"===t.url)return void sendJson(a,200,s.inspect());if("GET"===t.method&&"/requests"===t.url)return void sendJson(a,200,s.listRequests());if("GET"===t.method&&"/sessions"===t.url)return void sendJson(a,200,s.listSessions());const d=function readArtifactList(t){if(!t?.startsWith("/artifacts"))return;const e=new URL(t,"http://stable-harness.local");return"/artifacts"===e.pathname?{...e.searchParams.get("requestId")?{requestId:e.searchParams.get("requestId")}:{},...e.searchParams.get("sessionId")?{sessionId:e.searchParams.get("sessionId")}:{},...e.searchParams.get("agentId")?{agentId:e.searchParams.get("agentId")}:{}}:void 0}(t.url);if("GET"===t.method&&d)return void sendJson(a,200,s.listArtifacts(d));const i=function readArtifactContentId(t){const e=(t??"").match(/^\/artifacts\/([^/]+)\/content$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&i){const t=s.getArtifact(i),e=s.readArtifact(i);return void sendJson(a,t&&void 0!==e?200:404,t&&void 0!==e?{artifact:t,content:e}:{error:"artifact_content_not_found"})}const u=function readArtifactId(t){const e=(t??"").match(/^\/artifacts\/([^/]+)$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&u){const t=s.getArtifact(u);return void sendJson(a,t?200:404,t??{error:"artifact_not_found"})}const c=function readApprovalList(t){if(!t?.startsWith("/approvals"))return;const e=new URL(t,"http://stable-harness.local");if("/approvals"!==e.pathname)return;const r=e.searchParams.get("status");return{status:"pending"===r||"approved"===r||"rejected"===r?r:void 0}}(t.url);if("GET"===t.method&&c)return void sendJson(a,200,await s.listApprovals(c.status));const f=function readApprovalDecision(t){const e=(t??"").match(/^\/approvals\/([^/]+)\/(approve|reject)$/u);if(e?.[1]&&e[2])return{id:decodeURIComponent(e[1]),status:"approve"===e[2]?"approved":"rejected"}}(t.url);if("POST"===t.method&&f){const t=await s.resolveApproval(f.id,f.status);return void sendJson(a,t?200:404,t??{error:"approval_not_found"})}if("GET"===t.method&&"/workflows"===t.url)return void sendJson(a,200,s.inspect().workflows);const l=function readWorkflowMermaidId(t){const e=(t??"").match(/^\/workflows\/([^/]+)\/mermaid$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&l){const t=s.getWorkflow(l);return void sendJson(a,t?200:404,t?{mermaid:n(t)}:{error:"workflow_not_found"})}const p=function readWorkflowPlanId(t){const e=(t??"").match(/^\/workflows\/([^/]+)\/plan$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&p){const t=s.getWorkflow(p);return void sendJson(a,t?200:404,t?e(t):{error:"workflow_not_found"})}const m=function readRequestInspectionId(t){const e=(t??"").match(/^\/requests\/([^/]+)$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&m){const t=s.inspectRequest(m);return void sendJson(a,t?200:404,t??{error:"request_not_found"})}const h=function readTraceRequestId(t){const e=(t??"").match(/^\/runs\/([^/]+)\/trace$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&h){const t=s.getRun(h);return void sendJson(a,t?200:404,t?r(t):{error:"run_not_found"})}const I=function readSpanRequestId(t){const e=(t??"").match(/^\/runs\/([^/]+)\/spans$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&I){const t=s.getRun(I);return void sendJson(a,t?200:404,t?o(t):{error:"run_not_found"})}const v=function readReplayRequestId(t){const e=(t??"").match(/^\/requests\/([^/]+)\/replay$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&v){const t=s.exportReplayBundle(v);return void sendJson(a,t?200:404,t??{error:"run_not_found"})}if("POST"===t.method&&"/requests"===t.url){const e=await async function readJson(t){const e=[];for await(const r of t)e.push(Buffer.isBuffer(r)?r:Buffer.from(r));return 0===e.length?{}:JSON.parse(Buffer.concat(e).toString("utf8"))}(t);return void sendJson(a,200,await s.request(function readRuntimeRequest(t){const e=function readToolCall(t){if("object"!=typeof t||null===t)return;const e=t;return"string"==typeof e.toolId?{toolId:e.toolId,args:e.args}:void 0}(t.toolCall),r=function readWorkflow(t){const e=readRecord(t);if(e)return{..."string"==typeof e.workflowId?{workflowId:e.workflowId}:{},..."string"==typeof e.routeId?{routeId:e.routeId}:{},...void 0!==e.input?{input:e.input}:{},..."object"==typeof e.metadata&&e.metadata?{metadata:e.metadata}:{}}}(t.workflow),o=function readMemory(t){const e=readRecord(t);if(e)return{..."string"==typeof e.namespace?{namespace:e.namespace}:{},...!1===e.recall||readRecord(e.recall)?{recall:e.recall}:{},...Array.isArray(e.candidates)?{candidates:e.candidates}:{}}}(t.memory),n=readRecord(t.metadata);return{input:"string"==typeof t.input?t.input:"",..."string"==typeof t.agentId?{agentId:t.agentId}:{},..."string"==typeof t.sessionId?{sessionId:t.sessionId}:{},..."string"==typeof t.requestId?{requestId:t.requestId}:{},..."string"==typeof t.parentRunId?{parentRunId:t.parentRunId}:{},...e?{toolCall:e}:{},...r?{workflow:r}:{},...o?{memory:o}:{},...n?{metadata:n}:{}}}(e)))}sendJson(a,404,{error:"not_found"})}catch(t){sendJson(a,500,{error:t instanceof Error?t.message:String(t)})}})}function readRecord(t){return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}function sendJson(t,e,r){t.writeHead(e,{"content-type":"application/json"}),t.end(JSON.stringify(r))}
1
+ import{createServer as e}from"node:http";import{compileWorkflowPlan as t,projectRuntimeTrace as r,projectRuntimeTraceSpans as o,renderWorkflowMermaid as n}from"@stable-harness/core";export function createHttpServer(s){return e((e,a)=>{!async function handleHttpRequest(e,s,a){try{await async function routeHttpRequest(e,s,a){if("GET"===s.method&&"/health"===s.url)return void sendJson(a,200,{ok:!0});if("GET"===s.method&&"/inspect"===s.url)return void sendJson(a,200,e.inspect());if("GET"===s.method&&"/requests"===s.url)return void sendJson(a,200,e.listRequests());if(await async function handleAdministrationRoutes(e){const{runtime:t,request:r,response:o}=e;if("GET"===r.method&&"/sessions"===r.url)return sendJson(o,200,t.listSessions()),!0;const n=function readSessionDeleteId(e){const t=(e??"").match(/^\/sessions\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);if("DELETE"===r.method&&n)return sendJson(o,200,t.deleteSession(n)),!0;const s=function readRequestDeleteId(e){const t=(e??"").match(/^\/requests\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);if("DELETE"===r.method&&s)return sendJson(o,200,t.deleteRequest(s)),!0;if("GET"===r.method&&r.url?.startsWith("/memories"))return sendJson(o,200,await t.listMemories(function readMemoryList(e){const t=new URL(e??"/memories","http://stable-harness.local"),r=t.searchParams.getAll("status").filter(e=>"active"===e||"stale"===e||"conflicted"===e||"archived"===e||"pending_review"===e);return{...t.searchParams.get("namespace")?{namespace:t.searchParams.get("namespace")}:{},...r.length>0?{statuses:r}:{}}}(r.url))),!0;if("POST"===r.method&&"/memories"===r.url){const e=await readJson(r);return sendJson(o,200,await t.memorize(e)),!0}if("POST"===r.method&&"/memories/recall"===r.url){const e=await readJson(r);return sendJson(o,200,await t.recallMemories(e)),!0}const a=function readMemoryArchiveId(e){const t=(e??"").match(/^\/memories\/([^/]+)\/archive$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);if("POST"===r.method&&a){const e=await readJson(r);return sendJson(o,200,await t.archiveMemory(a,"string"==typeof e.reason?e.reason:void 0)),!0}const d=function readMemoryUpdateId(e){const t=(e??"").match(/^\/memories\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);return!("PATCH"!==r.method||!d||(sendJson(o,200,await t.updateMemory({id:d,...await readJson(r)})),0))}({runtime:e,request:s,response:a}))return;const d=function readArtifactList(e){if(!e?.startsWith("/artifacts"))return;const t=new URL(e,"http://stable-harness.local");return"/artifacts"===t.pathname?{...t.searchParams.get("requestId")?{requestId:t.searchParams.get("requestId")}:{},...t.searchParams.get("sessionId")?{sessionId:t.searchParams.get("sessionId")}:{},...t.searchParams.get("agentId")?{agentId:t.searchParams.get("agentId")}:{}}:void 0}(s.url);if("GET"===s.method&&d)return void sendJson(a,200,e.listArtifacts(d));const i=function readArtifactContentId(e){const t=(e??"").match(/^\/artifacts\/([^/]+)\/content$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&i){const t=e.getArtifact(i),r=e.readArtifact(i);return void sendJson(a,t&&void 0!==r?200:404,t&&void 0!==r?{artifact:t,content:r}:{error:"artifact_content_not_found"})}const u=function readArtifactId(e){const t=(e??"").match(/^\/artifacts\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&u){const t=e.getArtifact(u);return void sendJson(a,t?200:404,t??{error:"artifact_not_found"})}const c=function readApprovalList(e){if(!e?.startsWith("/approvals"))return;const t=new URL(e,"http://stable-harness.local");if("/approvals"!==t.pathname)return;const r=t.searchParams.get("status");return{status:"pending"===r||"approved"===r||"rejected"===r?r:void 0}}(s.url);if("GET"===s.method&&c)return void sendJson(a,200,await e.listApprovals(c.status));const f=function readApprovalDecision(e){const t=(e??"").match(/^\/approvals\/([^/]+)\/(approve|reject)$/u);if(t?.[1]&&t[2])return{id:decodeURIComponent(t[1]),status:"approve"===t[2]?"approved":"rejected"}}(s.url);if("POST"===s.method&&f){const t=await e.resolveApproval(f.id,f.status);return void sendJson(a,t?200:404,t??{error:"approval_not_found"})}if("GET"===s.method&&"/workflows"===s.url)return void sendJson(a,200,e.inspect().workflows);const m=function readWorkflowMermaidId(e){const t=(e??"").match(/^\/workflows\/([^/]+)\/mermaid$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&m){const t=e.getWorkflow(m);return void sendJson(a,t?200:404,t?{mermaid:n(t)}:{error:"workflow_not_found"})}const l=function readWorkflowPlanId(e){const t=(e??"").match(/^\/workflows\/([^/]+)\/plan$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&l){const r=e.getWorkflow(l);return void sendJson(a,r?200:404,r?t(r):{error:"workflow_not_found"})}const p=function readRequestInspectionId(e){const t=(e??"").match(/^\/requests\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&p){const t=e.inspectRequest(p);return void sendJson(a,t?200:404,t??{error:"request_not_found"})}const h=function readTraceRequestId(e){const t=(e??"").match(/^\/runs\/([^/]+)\/trace$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&h){const t=e.getRun(h);return void sendJson(a,t?200:404,t?r(t):{error:"run_not_found"})}const v=function readSpanRequestId(e){const t=(e??"").match(/^\/runs\/([^/]+)\/spans$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&v){const t=e.getRun(v);return void sendJson(a,t?200:404,t?o(t):{error:"run_not_found"})}const I=function readReplayRequestId(e){const t=(e??"").match(/^\/requests\/([^/]+)\/replay$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&I){const t=e.exportReplayBundle(I);return void sendJson(a,t?200:404,t??{error:"run_not_found"})}if("POST"===s.method&&"/requests"===s.url){const t=await readJson(s);return void sendJson(a,200,await e.request(function readRuntimeRequest(e){const t=function readToolCall(e){if("object"!=typeof e||null===e)return;const t=e;return"string"==typeof t.toolId?{toolId:t.toolId,args:t.args}:void 0}(e.toolCall),r=function readWorkflow(e){const t=readRecord(e);if(t)return{..."string"==typeof t.workflowId?{workflowId:t.workflowId}:{},..."string"==typeof t.routeId?{routeId:t.routeId}:{},...void 0!==t.input?{input:t.input}:{},..."object"==typeof t.metadata&&t.metadata?{metadata:t.metadata}:{}}}(e.workflow),o=function readMemory(e){const t=readRecord(e);if(t)return{..."string"==typeof t.namespace?{namespace:t.namespace}:{},...!1===t.recall||readRecord(t.recall)?{recall:t.recall}:{},...Array.isArray(t.candidates)?{candidates:t.candidates}:{}}}(e.memory),n=readRecord(e.metadata);return{input:"string"==typeof e.input?e.input:"",..."string"==typeof e.agentId?{agentId:e.agentId}:{},..."string"==typeof e.sessionId?{sessionId:e.sessionId}:{},..."string"==typeof e.requestId?{requestId:e.requestId}:{},..."string"==typeof e.parentRunId?{parentRunId:e.parentRunId}:{},...t?{toolCall:t}:{},...r?{workflow:r}:{},...o?{memory:o}:{},...n?{metadata:n}:{}}}(t)))}sendJson(a,404,{error:"not_found"})}(e,s,a)}catch(e){sendJson(a,500,{error:e instanceof Error?e.message:String(e)})}}(s,e,a)})}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function sendJson(e,t,r){e.writeHead(t,{"content-type":"application/json"}),e.end(JSON.stringify(r))}async function readJson(e){const t=[];for await(const r of e)t.push(Buffer.isBuffer(r)?r:Buffer.from(r));return 0===t.length?{}:JSON.parse(Buffer.concat(t).toString("utf8"))}
@@ -1 +1 @@
1
- export function createInProcessClient(e){return{request:t=>e.request(t),subscribe:t=>e.subscribe(t),inspect:()=>e.inspect(),getRuntimePolicy:()=>e.getRuntimePolicy(),getWorkflow:t=>e.getWorkflow(t),getRun:t=>e.getRun(t),listArtifacts:t=>e.listArtifacts(t),getArtifact:t=>e.getArtifact(t),readArtifact:t=>e.readArtifact(t),exportReplayBundle:t=>e.exportReplayBundle(t),listRequests:t=>e.listRequests(t),listSessions:()=>e.listSessions(),inspectRequest:t=>e.inspectRequest(t),listApprovals:t=>e.listApprovals(t),getApproval:t=>e.getApproval(t),resolveApproval:(t,s)=>e.resolveApproval(t,s),cancel:(t,s)=>e.cancel(t,s),stop:()=>e.stop()}}
1
+ export function createInProcessClient(e){return{request:t=>e.request(t),subscribe:t=>e.subscribe(t),inspect:()=>e.inspect(),getRuntimePolicy:()=>e.getRuntimePolicy(),getWorkflow:t=>e.getWorkflow(t),getRun:t=>e.getRun(t),listArtifacts:t=>e.listArtifacts(t),getArtifact:t=>e.getArtifact(t),readArtifact:t=>e.readArtifact(t),exportReplayBundle:t=>e.exportReplayBundle(t),listRequests:t=>e.listRequests(t),listSessions:()=>e.listSessions(),inspectRequest:t=>e.inspectRequest(t),memorize:t=>e.memorize(t),recallMemories:t=>e.recallMemories(t),listMemories:t=>e.listMemories(t),updateMemory:t=>e.updateMemory(t),archiveMemory:(t,s)=>e.archiveMemory(t,s),listApprovals:t=>e.listApprovals(t),getApproval:t=>e.getApproval(t),resolveApproval:(t,s)=>e.resolveApproval(t,s),cancel:(t,s)=>e.cancel(t,s),deleteRequest:t=>e.deleteRequest(t),deleteSession:t=>e.deleteSession(t),stop:()=>e.stop()}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stable-harness",
3
- "version": "0.0.54",
3
+ "version": "0.0.55",
4
4
  "type": "module",
5
5
  "description": "Stable application runtime and operator control plane for agent workspaces.",
6
6
  "license": "Apache-2.0",
@@ -1 +1 @@
1
- import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as c}from"./memory.js";import{buildDeepAgentRequest as d}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){if(t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.handoff",modelRef:t.agent.modelRef,tools:t.agent.tools,skills:t.agent.skills,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=e.createDeepAgent?void 0:await async function loadDeepAgentsModule(){try{return await async function importOptionalPackage(e){return import(e)}("deepagents")}catch(e){throw new Error(`DeepAgents package is required for the default adapter path: ${function formatError(e){return e instanceof Error?e.message:String(e)}(e)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o=n(function buildDeepAgentParams(e,t,r){const n={...readDeepAgentsConfig(t),...readDeepAgentsConfig(e.agent.config.deepagents)},o=resolveDeepAgentsSkills(e,e.agent),a=n.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:n.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:n.backend??resolveDeepAgentsBackend(e,r,o),checkpointer:n.checkpointer,store:n.store,middleware:mergeMiddleware(e,e.agent,n.middleware,p),responseFormat:n.responseFormat,contextSchema:n.contextSchema,interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(0,e.agent,n),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=requestScopedRepeatState(e,t);return pruneUndefined({name:t,description:r?.description??readString(r?.config.description)??r?.id,systemPrompt:buildSystemPrompt(e,r),model:n.model??(r?resolveAgentModel(e,r):void 0),middleware:mergeMiddleware(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(0,0,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,e.config,r)),a=d(t),c=function buildDeepAgentInvokeConfig(e){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit)})}(t.agent);if(!0===t.request.metadata?.openaiStream&&o.streamEvents){const e=await o.streamEvents(a,{version:"v3",...c});return g(t,e,p)}const l=await o.invoke(a,c);return p(l)}}}function buildSystemPrompt(e,t){const n=t?.systemPrompt??readString(t?.config.systemPrompt);return r({workspace:e.workspace,request:e.request,agent:t},n)}function resolveDeepAgentsMemory(e,t){const r=readDeepAgentsStringArray(t?.config,"memory");if(r)return r;const n=[...readAgentMemorySources(e.workspace.root,t),...c(e.workspace).map(e=>`/memories/${e.id}.md`)],o=[...new Set(n)];return o.length>0?o:void 0}function readAgentMemorySources(e,t){return(t?.memory??[]).flatMap(t=>"string"==typeof t&&t.trim()?[backendMemorySourcePath(e,t.trim())]:isRecord(t)&&"string"==typeof t.path&&t.path.trim()?[backendMemorySourcePath(e,t.path.trim())]:[])}function backendMemorySourcePath(e,r){if(r.startsWith("/"))return r;if(t.isAbsolute(r)){const n=t.relative(e,r);return n&&!n.startsWith("..")?`/${n.split(t.sep).join("/")}`:canonicalPath(r)}const n=r.split(t.sep).join("/");return n.startsWith("/")?n:`/${n}`}function resolveDeepAgentsSkills(e,r){const n=readDeepAgentsStringArray(r?.config,"skills");if(n)return n;const o=[...new Set((r?.skills??[]).map(t=>e.workspace.skills.get(t)?.path).filter(e=>"string"==typeof e&&e.trim().length>0).map(r=>function backendSkillSourcePath(e,r){const n=t.dirname(t.dirname(r)),o=t.relative(e,n);return!o||o.startsWith("..")||t.isAbsolute(o)?""===o?"/":canonicalPath(n):`/${o.split(t.sep).join("/")}`}(e.workspace.root,r)))];return o.length>0?o:void 0}function resolveDeepAgentsBackend(e,t,r){if(t?.FilesystemBackend&&r&&0!==r.length)return()=>new t.FilesystemBackend({rootDir:e.workspace.root})}function mergeMiddleware(e,t,r,s=a(e.workspace.runtime.toolGateway)){const i=Array.isArray(r)?r:[],p=scopedInput(e,t),c=new Set,d=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:c,repeatState:s,repairModel:resolveAgentRepairModel(0,0,d)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}function requestScopedRepeatState(e,t){const r=`deepagents.repeat.${t}`,n=e.requestState?.get(r);if(n)return n;const o=a(e.workspace.runtime.toolGateway);return e.requestState&&o&&e.requestState.set(r,o),o}function scopedInput(e,t){return t?{...e,agent:t}:e}function resolveAgentModel(e,t){const r=t.modelRef?e.workspace.models.get(t.modelRef):void 0;return r?u(r):void 0}function resolveAgentRepairModel(e,t,r){const n=r.model;return function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}(n)?n:void 0}function readDeepAgentsConfig(e){return isRecord(e)?e:{}}function readDeepAgentsStringArray(e,t){const r=isRecord(e)?e:{},n=readDeepAgentsConfig(r.deepagents),o="memory"===t?["memory","memorySources"]:["skills","skillSources"];for(const e of o){const t=readStringArray(n[e]);if(t)return t}return readStringArray(r[t])}function pruneUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0}function canonicalPath(t){try{return e.native(t)}catch{return t}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
1
+ import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";import{cleanupDeepAgentsRuntimeSubstrate as f,resolveDeepAgentsRuntimeSubstrate as y}from"./internal/substrate/runtime.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){if(t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.handoff",modelRef:t.agent.modelRef,tools:t.agent.tools,skills:t.agent.skills,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=e.createDeepAgent?void 0:await async function loadDeepAgentsModule(){try{return await async function importOptionalPackage(e){return import(e)}("deepagents")}catch(e){throw new Error(`DeepAgents package is required for the default adapter path: ${function formatError(e){return e instanceof Error?e.message:String(e)}(e)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o={...readDeepAgentsConfig(e.config),...readDeepAgentsConfig(t.agent.config.deepagents)},a=y(t,o),d=n(function buildDeepAgentParams(e,t,r,n){const o=resolveDeepAgentsSkills(e,e.agent),a=t.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:t.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:t.backend??resolveDeepAgentsBackend(e,n,o),checkpointer:r.checkpointer,store:r.store,middleware:mergeMiddleware(e,e.agent,t.middleware,p),responseFormat:t.responseFormat,contextSchema:t.contextSchema,interruptOn:t.interruptOn,generalPurposeAgent:readBoolean(t.generalPurposeAgent),taskDescription:readString(t.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(0,e.agent,t),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=requestScopedRepeatState(e,t);return pruneUndefined({name:t,description:r?.description??readString(r?.config.description)??r?.id,systemPrompt:buildSystemPrompt(e,r),model:n.model??(r?resolveAgentModel(e,r):void 0),middleware:mergeMiddleware(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(0,0,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,o,a,r)),l=c(t),u=function buildDeepAgentInvokeConfig(e,t){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit),configurable:{thread_id:t}})}(t.agent,a.threadId);if(!0===t.request.metadata?.openaiStream&&d.streamEvents){const e=await d.streamEvents(l,{version:"v3",...u}),r=await g(t,e,p);return await f(a),r}const m=await d.invoke(l,u),A=p(m);return await f(a),A}}}function buildSystemPrompt(e,t){const n=t?.systemPrompt??readString(t?.config.systemPrompt);return r({workspace:e.workspace,request:e.request,agent:t},n)}function resolveDeepAgentsMemory(e,t){const r=readDeepAgentsStringArray(t?.config,"memory");if(r)return r;const n=[...readAgentMemorySources(e.workspace.root,t),...d(e.workspace).map(e=>`/memories/${e.id}.md`)],o=[...new Set(n)];return o.length>0?o:void 0}function readAgentMemorySources(e,t){return(t?.memory??[]).flatMap(t=>"string"==typeof t&&t.trim()?[backendMemorySourcePath(e,t.trim())]:isRecord(t)&&"string"==typeof t.path&&t.path.trim()?[backendMemorySourcePath(e,t.path.trim())]:[])}function backendMemorySourcePath(e,r){if(r.startsWith("/"))return r;if(t.isAbsolute(r)){const n=t.relative(e,r);return n&&!n.startsWith("..")?`/${n.split(t.sep).join("/")}`:canonicalPath(r)}const n=r.split(t.sep).join("/");return n.startsWith("/")?n:`/${n}`}function resolveDeepAgentsSkills(e,r){const n=readDeepAgentsStringArray(r?.config,"skills");if(n)return n;const o=[...new Set((r?.skills??[]).map(t=>e.workspace.skills.get(t)?.path).filter(e=>"string"==typeof e&&e.trim().length>0).map(r=>function backendSkillSourcePath(e,r){const n=t.dirname(t.dirname(r)),o=t.relative(e,n);return!o||o.startsWith("..")||t.isAbsolute(o)?""===o?"/":canonicalPath(n):`/${o.split(t.sep).join("/")}`}(e.workspace.root,r)))];return o.length>0?o:void 0}function resolveDeepAgentsBackend(e,t,r){if(t?.FilesystemBackend&&r&&0!==r.length)return()=>new t.FilesystemBackend({rootDir:e.workspace.root})}function mergeMiddleware(e,t,r,s=a(e.workspace.runtime.toolGateway)){const i=Array.isArray(r)?r:[],p=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(0,0,c)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}function requestScopedRepeatState(e,t){const r=`deepagents.repeat.${t}`,n=e.requestState?.get(r);if(n)return n;const o=a(e.workspace.runtime.toolGateway);return e.requestState&&o&&e.requestState.set(r,o),o}function scopedInput(e,t){return t?{...e,agent:t}:e}function resolveAgentModel(e,t){const r=t.modelRef?e.workspace.models.get(t.modelRef):void 0;return r?u(r):void 0}function resolveAgentRepairModel(e,t,r){const n=r.model;return function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}(n)?n:void 0}function readDeepAgentsConfig(e){return isRecord(e)?e:{}}function readDeepAgentsStringArray(e,t){const r=isRecord(e)?e:{},n=readDeepAgentsConfig(r.deepagents),o="memory"===t?["memory","memorySources"]:["skills","skillSources"];for(const e of o){const t=readStringArray(n[e]);if(t)return t}return readStringArray(r[t])}function pruneUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0}function canonicalPath(t){try{return e.native(t)}catch{return t}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -0,0 +1,10 @@
1
+ import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
2
+ export type DeepAgentsCheckpointProvider = "sqlite" | "file";
3
+ export type DeepAgentsCheckpointOptions = {
4
+ provider: DeepAgentsCheckpointProvider;
5
+ path: string;
6
+ busyTimeoutMs?: number;
7
+ wal?: boolean;
8
+ synchronous?: "off" | "normal" | "full";
9
+ };
10
+ export declare function createDeepAgentsCheckpointer(options: DeepAgentsCheckpointOptions): BaseCheckpointSaver;
@@ -0,0 +1 @@
1
+ import{existsSync as e,mkdirSync as t,readFileSync as i,writeFileSync as a}from"node:fs";import c from"node:path";import{DatabaseSync as n}from"node:sqlite";import{BaseCheckpointSaver as r,WRITES_IDX_MAP as s,copyCheckpoint as d,getCheckpointId as o}from"@langchain/langgraph-checkpoint";export function createDeepAgentsCheckpointer(e){return"file"===e.provider?new JsonFileCheckpointSaver(e.path):new SqliteCheckpointSaver(e)}class JsonFileCheckpointSaver extends r{filePath;constructor(e){super(),this.filePath=e}async getTuple(e){return tupleFromState(this.state(),e,this)}async*list(e,t){for(const i of listCheckpoints(this.state(),e,t))yield hydrateTuple(i,this.state().writes,this)}async put(e,t,i){const a=requiredThreadId(e,"put checkpoint"),c=checkpointNamespace(e),n=checkpointConfig(a,c,t.id),r=this.state(),s={threadId:a,namespace:c,checkpointId:t.id,checkpoint:await dump(this,d(t)),metadata:await dump(this,i),parentCheckpointId:o(e)||void 0};return r.checkpoints=r.checkpoints.filter(e=>!function sameCheckpoint(e,t){return e.threadId===t.threadId&&e.namespace===t.namespace&&e.checkpointId===t.checkpointId}(e,s)),r.checkpoints.push(s),this.write(r),n}async putWrites(e,t,i){const a=requiredThreadId(e,"put writes"),c=requiredCheckpointId(e),n=checkpointNamespace(e),r=this.state();for(let e=0;e<t.length;e+=1){const[d,o]=t[e],h=s[d]??e,p=r.writes.some(e=>sameWrite(e,{threadId:a,namespace:n,checkpointId:c,taskId:i,idx:h}));h>=0&&p||(r.writes=r.writes.filter(e=>!sameWrite(e,{threadId:a,namespace:n,checkpointId:c,taskId:i,idx:h})),r.writes.push({threadId:a,namespace:n,checkpointId:c,taskId:i,idx:h,channel:d,value:await dump(this,o)}))}this.write(r)}async deleteThread(e){const t=this.state();this.write({checkpoints:t.checkpoints.filter(t=>t.threadId!==e),writes:t.writes.filter(t=>t.threadId!==e)})}state(){if(!e(this.filePath))return{checkpoints:[],writes:[]};const t=JSON.parse(i(this.filePath,"utf8"));return{checkpoints:t.checkpoints??[],writes:t.writes??[]}}write(e){t(c.dirname(this.filePath),{recursive:!0}),a(this.filePath,`${JSON.stringify(e,null,2)}\n`)}}class SqliteCheckpointSaver extends r{db;constructor(e){super(),t(c.dirname(e.path),{recursive:!0}),this.db=new n(e.path),this.db.exec(`PRAGMA busy_timeout = ${e.busyTimeoutMs??5e3}`),!1!==e.wal&&this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec(`PRAGMA synchronous = ${e.synchronous?.toUpperCase()??"NORMAL"}`),this.db.exec(["CREATE TABLE IF NOT EXISTS checkpoints (thread_id TEXT NOT NULL, namespace TEXT NOT NULL, checkpoint_id TEXT NOT NULL, checkpoint TEXT NOT NULL, metadata TEXT NOT NULL, parent_checkpoint_id TEXT, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(thread_id, namespace, checkpoint_id))","CREATE TABLE IF NOT EXISTS writes (thread_id TEXT NOT NULL, namespace TEXT NOT NULL, checkpoint_id TEXT NOT NULL, task_id TEXT NOT NULL, idx INTEGER NOT NULL, channel TEXT NOT NULL, value TEXT NOT NULL, PRIMARY KEY(thread_id, namespace, checkpoint_id, task_id, idx))","CREATE INDEX IF NOT EXISTS idx_checkpoints_thread ON checkpoints(thread_id, namespace, checkpoint_id DESC)"].join(";"))}async getTuple(e){return tupleFromState(this.state(),e,this)}async*list(e,t){const i=this.state();for(const a of listCheckpoints(i,e,t))yield hydrateTuple(a,i.writes,this)}async put(e,t,i){const a=requiredThreadId(e,"put checkpoint"),c=checkpointNamespace(e);return this.db.prepare("INSERT OR REPLACE INTO checkpoints(thread_id, namespace, checkpoint_id, checkpoint, metadata, parent_checkpoint_id) VALUES (?, ?, ?, ?, ?, ?)").run(a,c,t.id,await dump(this,d(t)),await dump(this,i),o(e)||null),checkpointConfig(a,c,t.id)}async putWrites(e,t,i){const a=requiredThreadId(e,"put writes"),c=checkpointNamespace(e),n=requiredCheckpointId(e),r=this.db.prepare("INSERT OR REPLACE INTO writes(thread_id, namespace, checkpoint_id, task_id, idx, channel, value) VALUES (?, ?, ?, ?, ?, ?, ?)");for(let e=0;e<t.length;e+=1){const[d,o]=t[e],h=s[d]??e;r.run(a,c,n,i,h,d,await dump(this,o))}}async deleteThread(e){this.db.prepare("DELETE FROM writes WHERE thread_id = ?").run(e),this.db.prepare("DELETE FROM checkpoints WHERE thread_id = ?").run(e)}state(){return{checkpoints:this.db.prepare("SELECT thread_id AS threadId, namespace, checkpoint_id AS checkpointId, checkpoint, metadata, parent_checkpoint_id AS parentCheckpointId FROM checkpoints").all(),writes:this.db.prepare("SELECT thread_id AS threadId, namespace, checkpoint_id AS checkpointId, task_id AS taskId, idx, channel, value FROM writes").all()}}}async function tupleFromState(e,t,i){const a=t.configurable?.thread_id;if(!a)return;const c=checkpointNamespace(t),n=o(t),r=e.checkpoints.filter(e=>e.threadId===a&&e.namespace===c),s=n?r.find(e=>e.checkpointId===n):r.sort((e,t)=>t.checkpointId.localeCompare(e.checkpointId))[0];return s?hydrateTuple(s,e.writes,i):void 0}function listCheckpoints(e,t,i){const a=t.configurable?.thread_id,c=t.configurable?.checkpoint_ns,n=o(t);let r=e.checkpoints.filter(e=>!(a&&e.threadId!==a||void 0!==c&&e.namespace!==c));return r=r.filter(e=>!n||e.checkpointId===n),r=r.filter(e=>!i?.before?.configurable?.checkpoint_id||e.checkpointId<String(i.before.configurable.checkpoint_id)),r=r.sort((e,t)=>t.checkpointId.localeCompare(e.checkpointId)),i?.filter&&(r=r.filter(e=>function metadataMatches(e,t){const i=JSON.parse(Buffer.from(e,"base64").toString("utf8"));return Object.entries(t).every(([e,t])=>i[e]===t)}(e.metadata,i.filter??{}))),"number"==typeof i?.limit?r.slice(0,i.limit):r}async function hydrateTuple(e,t,i){const a=await Promise.all(t.filter(t=>t.threadId===e.threadId&&t.namespace===e.namespace&&t.checkpointId===e.checkpointId).sort((e,t)=>e.idx-t.idx).map(async e=>[e.taskId,e.channel,await load(i,e.value)]));return{config:checkpointConfig(e.threadId,e.namespace,e.checkpointId),checkpoint:await load(i,e.checkpoint),metadata:await load(i,e.metadata),pendingWrites:a,...e.parentCheckpointId?{parentConfig:checkpointConfig(e.threadId,e.namespace,e.parentCheckpointId)}:{}}}async function dump(e,t){const[,i]=await e.serde.dumpsTyped(t);return Buffer.from(i).toString("base64")}async function load(e,t){return e.serde.loadsTyped("json",Buffer.from(t,"base64"))}function requiredThreadId(e,t){const i=e.configurable?.thread_id;if("string"!=typeof i||!i)throw new Error(`Failed to ${t}: missing configurable.thread_id.`);return i}function requiredCheckpointId(e){const t=o(e);if(!t)throw new Error("Failed to put writes: missing configurable.checkpoint_id.");return t}function checkpointNamespace(e){return String(e.configurable?.checkpoint_ns??"")}function checkpointConfig(e,t,i){return{configurable:{thread_id:e,checkpoint_ns:t,checkpoint_id:i}}}function sameWrite(e,t){return e.threadId===t.threadId&&e.namespace===t.namespace&&e.checkpointId===t.checkpointId&&e.taskId===t.taskId&&e.idx===t.idx}
@@ -0,0 +1,11 @@
1
+ import type { BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
2
+ import type { RuntimeAdapterContext } from "@stable-harness/core";
3
+ export type DeepAgentsRuntimeSubstrate = {
4
+ checkpointer?: BaseCheckpointSaver;
5
+ store?: BaseStore;
6
+ threadId: string;
7
+ cleanupOnCompleted: boolean;
8
+ };
9
+ export declare function resolveDeepAgentsRuntimeSubstrate(input: RuntimeAdapterContext, deepagents: Record<string, unknown>): DeepAgentsRuntimeSubstrate;
10
+ declare function cleanupDeepAgentsRuntimeSubstrate(substrate: DeepAgentsRuntimeSubstrate): Promise<void>;
11
+ export { cleanupDeepAgentsRuntimeSubstrate };
@@ -0,0 +1 @@
1
+ import e from"node:path";import{createDeepAgentsCheckpointer as r}from"./checkpoint.js";import{createDeepAgentsStore as o}from"./store.js";export function resolveDeepAgentsRuntimeSubstrate(e,r){const o=function readSubstrateConfig(e){const r=readRecord(e.workspace.runtime.checkpoint)??{},o=readRecord(r.deepagents)??r;return{...o,performance:readRecord(o.performance),cleanup:readRecord(o.cleanup),checkpointer:readRecord(o.checkpointer),store:readRecord(o.store)}}(e),n=!1!==o.enabled,t=readProvider(o.provider)??"sqlite",i=o.performance??{},a=o.checkpointer??{},c=o.store??{};return{checkpointer:resolveCheckpointer({input:e,configured:r.checkpointer,enabled:n,provider:t,performance:i,config:o,checkpointerConfig:a}),store:resolveStore({input:e,configured:r.store,enabled:n,provider:t,performance:i,storeConfig:c}),threadId:`${workspaceId(e)}:${e.sessionId}:${e.requestId}`,cleanupOnCompleted:readCleanupOnCompleted(o)}}async function cleanupDeepAgentsRuntimeSubstrate(e){e.cleanupOnCompleted&&await(e.checkpointer?.deleteThread?.(e.threadId))}export{cleanupDeepAgentsRuntimeSubstrate};function resolveSubstratePath(r,o,n,t){const i="string"==typeof o&&o.trim()?o.trim():void 0;if(i)return e.isAbsolute(i)?i:e.resolve(r.workspace.root,i);const a="file"===n?"json":"sqlite";return e.resolve(r.workspace.root,function dataRoot(e){const r=e.workspace.runtime.dataRoot;return"string"==typeof r&&r.trim()?r.trim():".stable-harness"}(r),`${t}.${a}`)}function workspaceId(r){return(r.workspace.runtime.workspaceId??e.basename(r.workspace.root))||"workspace"}function resolveCheckpointer(e){return void 0!==e.configured?e.configured:e.enabled&&!1!==e.checkpointerConfig.enabled?r({provider:readProvider(e.checkpointerConfig.provider)??e.provider,path:resolveSubstratePath(e.input,e.checkpointerConfig.path??e.config.path,e.provider,"checkpoints/deepagents"),busyTimeoutMs:readNumber(e.performance.busyTimeoutMs)??readNumber(e.checkpointerConfig.busyTimeoutMs),wal:readBoolean(e.performance.wal)??readBoolean(e.checkpointerConfig.wal),synchronous:readSynchronous(e.performance.synchronous)??readSynchronous(e.checkpointerConfig.synchronous)}):void 0}function resolveStore(e){if(void 0!==e.configured)return e.configured;if(!e.enabled||!1===e.storeConfig.enabled)return;const r=function readStoreProvider(e){return readProvider(e)}(e.storeConfig.provider)??e.provider;return o({provider:r,path:resolveSubstratePath(e.input,e.storeConfig.path,r,"store/deepagents"),busyTimeoutMs:readNumber(e.performance.busyTimeoutMs)??readNumber(e.storeConfig.busyTimeoutMs),wal:readBoolean(e.performance.wal)??readBoolean(e.storeConfig.wal),synchronous:readSynchronous(e.performance.synchronous)??readSynchronous(e.storeConfig.synchronous)})}function readCleanupOnCompleted(e){const r=e.cleanup?.onCompleted;return!1!==r&&"keep"!==r}function readProvider(e){return"file"===e||"json"===e?"file":"sqlite"===e?"sqlite":void 0}function readSynchronous(e){return"off"===e||"normal"===e||"full"===e?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}
@@ -0,0 +1,10 @@
1
+ import { BaseStore } from "@langchain/langgraph-checkpoint";
2
+ export type DeepAgentsStoreProvider = "sqlite" | "file";
3
+ export type DeepAgentsStoreOptions = {
4
+ provider: DeepAgentsStoreProvider;
5
+ path: string;
6
+ busyTimeoutMs?: number;
7
+ wal?: boolean;
8
+ synchronous?: "off" | "normal" | "full";
9
+ };
10
+ export declare function createDeepAgentsStore(options: DeepAgentsStoreOptions): BaseStore;
@@ -0,0 +1 @@
1
+ import{existsSync as e,mkdirSync as t,readFileSync as a,writeFileSync as n}from"node:fs";import s from"node:path";import{DatabaseSync as i}from"node:sqlite";import{BaseStore as r}from"@langchain/langgraph-checkpoint";export function createDeepAgentsStore(e){return"file"===e.provider?new JsonFileStore(e.path):new SqliteStore(e)}class JsonFileStore extends r{filePath;constructor(e){super(),this.filePath=e}async batch(e){const t=this.state(),a=e.map(e=>applyOperation(t,e));return this.write(t),a}state(){return e(this.filePath)?{items:JSON.parse(a(this.filePath,"utf8")).items??[]}:{items:[]}}write(e){t(s.dirname(this.filePath),{recursive:!0}),n(this.filePath,`${JSON.stringify(e,null,2)}\n`)}}class SqliteStore extends r{db;constructor(e){super(),t(s.dirname(e.path),{recursive:!0}),this.db=new i(e.path),this.db.exec(`PRAGMA busy_timeout = ${e.busyTimeoutMs??5e3}`),!1!==e.wal&&this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec(`PRAGMA synchronous = ${e.synchronous?.toUpperCase()??"NORMAL"}`),this.db.exec(["CREATE TABLE IF NOT EXISTS items (namespace TEXT NOT NULL, key TEXT NOT NULL, value TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, PRIMARY KEY(namespace, key))","CREATE INDEX IF NOT EXISTS idx_items_namespace ON items(namespace)"].join(";"))}async batch(e){const t=this.state(),a=e.map(e=>applyOperation(t,e));return this.replace(t),a}state(){return{items:this.db.prepare("SELECT namespace, key, value, created_at AS createdAt, updated_at AS updatedAt FROM items").all().map(e=>({namespace:JSON.parse(e.namespace),key:e.key,value:JSON.parse(e.value),createdAt:e.createdAt,updatedAt:e.updatedAt}))}}replace(e){const t=this.db.prepare("DELETE FROM items"),a=this.db.prepare("INSERT INTO items(namespace, key, value, created_at, updated_at) VALUES (?, ?, ?, ?, ?)");this.db.exec("BEGIN");try{t.run();for(const t of e.items)a.run(JSON.stringify(t.namespace),t.key,JSON.stringify(t.value),t.createdAt,t.updatedAt);this.db.exec("COMMIT")}catch(e){throw this.db.exec("ROLLBACK"),e}}}function applyOperation(e,t){return"key"in t&&"namespace"in t&&!("value"in t)?function toItem(e){return e?toStoredItem(e):null}(e.items.find(e=>sameKey(e,t.namespace,t.key))??null):"value"in t?void function putItem(e,t,a,n){const s=e.items.find(e=>sameKey(e,t,a));if(null===n)return void(e.items=e.items.filter(e=>!sameKey(e,t,a)));const i=(new Date).toISOString();if(s)return s.value=n,void(s.updatedAt=i);e.items.push({namespace:t,key:a,value:n,createdAt:i,updatedAt:i})}(e,t.namespace,t.key,t.value):"namespacePrefix"in t?function searchItems(e,t,a,n,s){return e.items.filter(e=>function startsWithNamespace(e,t){return t.length<=e.length&&t.every((t,a)=>e[a]===t)}(e.namespace,t)).filter(e=>function matchesFilter(e,t){return!t||Object.entries(t).every(([t,a])=>e[t]===a)}(e.value,a)).sort((e,t)=>e.namespace.join("/").localeCompare(t.namespace.join("/"))||e.key.localeCompare(t.key)).slice(n,n+s).map(e=>({...toStoredItem(e),score:0}))}(e,t.namespacePrefix,t.filter,t.offset??0,t.limit??10):"matchConditions"in t?function listNamespaces(e,t){let a=[...new Map(e.items.map(e=>[e.namespace.join("\0"),e.namespace])).values()];const n=t.matchConditions??[];return a=a.filter(e=>n.every(t=>function namespaceMatches(e,t){const a=(Array.isArray(t.path)?t.path:[]).filter(e=>"string"==typeof e);return"suffix"===t.matchType?a.length<=e.length&&a.every((t,n)=>"*"===t||e[e.length-a.length+n]===t):a.length<=e.length&&a.every((t,a)=>"*"===t||e[a]===t)}(e,t))),void 0!==t.maxDepth&&(a=[...new Map(a.map(e=>{const a=e.slice(0,t.maxDepth);return[a.join("\0"),a]})).values()]),a.sort((e,t)=>e.join("/").localeCompare(t.join("/"))).slice(t.offset,t.offset+t.limit)}(e,t):void 0}function toStoredItem(e){return{value:e.value,key:e.key,namespace:e.namespace,createdAt:new Date(e.createdAt),updatedAt:new Date(e.updatedAt)}}function sameKey(e,t,a){return e.key===a&&e.namespace.length===t.length&&e.namespace.every((e,a)=>e===t[a])}
@@ -0,0 +1,9 @@
1
+ import type { RuntimeEvent } from "../events.js";
2
+ import type { RuntimeDeletionResult, RuntimeStore } from "../types.js";
3
+ export declare function createRuntimeAdministrationMethods(input: {
4
+ store: RuntimeStore;
5
+ emit: (event: RuntimeEvent) => void;
6
+ }): {
7
+ deleteRequest(requestId: string): RuntimeDeletionResult;
8
+ deleteSession(sessionId: string): RuntimeDeletionResult;
9
+ };
@@ -0,0 +1 @@
1
+ export function createRuntimeAdministrationMethods(e){return{deleteRequest(t){const s=e.store.getRun(t);return s?(e.emit({type:"runtime.request.deleted",requestId:t,sessionId:s.sessionId,agentId:s.agentId}),e.store.deleteRun(t),{deletedRequestIds:[t],deletedCount:1}):{deletedRequestIds:[],deletedCount:0}},deleteSession(t){const s=e.store.listRuns({sessionId:t});if(0===s.length)return{deletedRequestIds:[],deletedCount:0};const d=s.map(e=>e.requestId);return e.emit({type:"runtime.session.deleted",requestId:s[0]?.requestId??"",sessionId:t,agentId:s[0]?.agentId??"",deletedRequestIds:d}),e.store.deleteSession(t)}}}
@@ -0,0 +1,10 @@
1
+ import type { ListMemoriesInput, MemorizeInput, RecallInput, RuntimeMemoryStore, UpdateMemoryInput } from "@stable-harness/memory";
2
+ export declare function createRuntimeMemoryAdministration(input: {
3
+ memory?: RuntimeMemoryStore;
4
+ }): {
5
+ memorize(inputValue: MemorizeInput): Promise<import("@stable-harness/memory").MemoryRecord>;
6
+ recallMemories(inputValue: RecallInput): Promise<import("@stable-harness/memory").MemoryRecallResult>;
7
+ listMemories(inputValue: ListMemoriesInput): Promise<import("@stable-harness/memory").MemoryRecord[]>;
8
+ updateMemory(inputValue: UpdateMemoryInput): Promise<import("@stable-harness/memory").MemoryRecord | undefined>;
9
+ archiveMemory(id: string, reason?: string): Promise<import("@stable-harness/memory").MemoryRecord | undefined>;
10
+ };
@@ -0,0 +1 @@
1
+ export function createRuntimeMemoryAdministration(e){return{memorize:r=>requireMemory(e.memory).memorize(r),recallMemories:r=>requireMemory(e.memory).recall(r),listMemories:r=>requireMemory(e.memory).list(r),updateMemory:r=>requireMemory(e.memory).update(r),archiveMemory:(r,m)=>requireMemory(e.memory).archive(r,m)}}function requireMemory(e){if(!e)throw new Error("Runtime memory store is not configured");return e}
@@ -45,6 +45,17 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
45
45
  sessionId: string;
46
46
  agentId: string;
47
47
  reason?: string;
48
+ } | {
49
+ type: "runtime.request.deleted";
50
+ requestId: string;
51
+ sessionId: string;
52
+ agentId: string;
53
+ } | {
54
+ type: "runtime.session.deleted";
55
+ requestId: string;
56
+ sessionId: string;
57
+ agentId: string;
58
+ deletedRequestIds: string[];
48
59
  } | {
49
60
  type: "runtime.artifact.created";
50
61
  requestId: string;
@@ -1 +1 @@
1
- import{existsSync as e,mkdirSync as t,readFileSync as n,writeFileSync as r}from"node:fs";import u from"node:path";export function createInMemoryRuntimeStore(e=[]){const t=new Map(e.map(e=>[e.requestId,cloneRun(e)]));return{createRun(e){t.set(e.requestId,cloneRun(e))},updateRun(e,n){const r=t.get(e);if(r)return Object.assign(r,function clonePatch(e){return structuredClone(e)}(n)),cloneRun(r)},appendEvent(e){const n=t.get(e.requestId);if(!n)return;const r=function eventArtifact(e){return"artifact"in e&&e.artifact?e.artifact:void 0}(e);return r&&!n.artifacts.some(e=>e.id===r.id)&&n.artifacts.push(structuredClone(r)),n.events.push(function cloneEvent(e){return structuredClone(e)}(e)),cloneRun(n)},getRun:e=>function cloneOptionalRun(e){return e?cloneRun(e):void 0}(t.get(e)),listRuns:e=>[...t.values()].filter(t=>function matchesFilter(e,t){return!t||!(t.agentId&&t.agentId!==e.agentId||t.sessionId&&t.sessionId!==e.sessionId||t.state&&t.state!==e.state)}(t,e)).map(cloneRun)}}export function createJsonFileRuntimeStore(t){const r=u.resolve(t),i=createInMemoryRuntimeStore(function readStoreFile(t){if(!e(t))return[];const r=JSON.parse(n(t,"utf8"));if(!isRecord(r)||!Array.isArray(r.runs))throw new Error(`Invalid runtime store file: ${t}`);return r.runs.map(assertRunRecord)}(r));return{createRun(e){i.createRun(e),writeStoreFile(r,i.listRuns())},updateRun(e,t){const n=i.updateRun(e,t);return writeStoreFile(r,i.listRuns()),n},appendEvent(e){const t=i.appendEvent(e);return writeStoreFile(r,i.listRuns()),t},getRun:e=>i.getRun(e),listRuns:e=>i.listRuns(e)}}function writeStoreFile(e,n){t(u.dirname(e),{recursive:!0}),r(e,`${JSON.stringify({version:1,runs:n},null,2)}\n`)}function assertRunRecord(e){if(!isRecord(e)||"string"!=typeof e.requestId)throw new Error("Invalid runtime run record in store file");return cloneRun(e)}function cloneRun(e){return structuredClone(e)}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
1
+ import{existsSync as e,mkdirSync as t,readFileSync as n,writeFileSync as r}from"node:fs";import s from"node:path";export function createInMemoryRuntimeStore(e=[]){const t=new Map(e.map(e=>[e.requestId,cloneRun(e)]));return{createRun(e){t.set(e.requestId,cloneRun(e))},updateRun(e,n){const r=t.get(e);if(r)return Object.assign(r,function clonePatch(e){return structuredClone(e)}(n)),cloneRun(r)},appendEvent(e){const n=t.get(e.requestId);if(!n)return;const r=function eventArtifact(e){return"artifact"in e&&e.artifact?e.artifact:void 0}(e);return r&&!n.artifacts.some(e=>e.id===r.id)&&n.artifacts.push(structuredClone(r)),n.events.push(function cloneEvent(e){return structuredClone(e)}(e)),cloneRun(n)},getRun:e=>function cloneOptionalRun(e){return e?cloneRun(e):void 0}(t.get(e)),listRuns:e=>[...t.values()].filter(t=>function matchesFilter(e,t){return!t||!(t.agentId&&t.agentId!==e.agentId||t.sessionId&&t.sessionId!==e.sessionId||t.state&&t.state!==e.state)}(t,e)).map(cloneRun),deleteRun(e){const n=t.get(e);if(n)return t.delete(e),cloneRun(n)},deleteSession(e){const n=[...t.values()].filter(t=>t.sessionId===e).map(e=>e.requestId);for(const e of n)t.delete(e);return{deletedRequestIds:n,deletedCount:n.length}}}}export function createJsonFileRuntimeStore(t){const r=s.resolve(t),u=createInMemoryRuntimeStore(function readStoreFile(t){if(!e(t))return[];const r=JSON.parse(n(t,"utf8"));if(!isRecord(r)||!Array.isArray(r.runs))throw new Error(`Invalid runtime store file: ${t}`);return r.runs.map(assertRunRecord)}(r));return{createRun(e){u.createRun(e),writeStoreFile(r,u.listRuns())},updateRun(e,t){const n=u.updateRun(e,t);return writeStoreFile(r,u.listRuns()),n},appendEvent(e){const t=u.appendEvent(e);return writeStoreFile(r,u.listRuns()),t},getRun:e=>u.getRun(e),listRuns:e=>u.listRuns(e),deleteRun(e){const t=u.deleteRun(e);return writeStoreFile(r,u.listRuns()),t},deleteSession(e){const t=u.deleteSession(e);return writeStoreFile(r,u.listRuns()),t}}}function writeStoreFile(e,n){t(s.dirname(e),{recursive:!0}),r(e,`${JSON.stringify({version:1,runs:n},null,2)}\n`)}function assertRunRecord(e){if(!isRecord(e)||"string"!=typeof e.requestId)throw new Error("Invalid runtime run record in store file");return cloneRun(e)}function cloneRun(e){return structuredClone(e)}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -115,12 +115,18 @@ export type RuntimeRunFilter = {
115
115
  sessionId?: string;
116
116
  state?: RuntimeRecordState;
117
117
  };
118
+ export type RuntimeDeletionResult = {
119
+ deletedRequestIds: string[];
120
+ deletedCount: number;
121
+ };
118
122
  export type RuntimeStore = {
119
123
  createRun(record: RuntimeRunRecord): void;
120
124
  updateRun(requestId: string, patch: RuntimeStoreRunPatch): RuntimeRunRecord | undefined;
121
125
  appendEvent(event: RuntimeEvent): RuntimeRunRecord | undefined;
122
126
  getRun(requestId: string): RuntimeRunRecord | undefined;
123
127
  listRuns(filter?: RuntimeRunFilter): RuntimeRunRecord[];
128
+ deleteRun(requestId: string): RuntimeRunRecord | undefined;
129
+ deleteSession(sessionId: string): RuntimeDeletionResult;
124
130
  };
125
131
  export type RuntimeQueueRecord = {
126
132
  requestId: string;
@@ -1 +1 @@
1
- import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{buildAdapterErrorRecoveryPrompt as r,buildExecutionContractRecoveryRequest as a,isRecoverableAdapterError as s}from"./recovery/tool-call.js";import{recoverQualityReview as n,resolveQualityPolicy as o}from"./quality/index.js";import{recoverAdapterResultOutput as i}from"./runtime/recovery/adapter-result.js";import{completeRun as u,failRun as c}from"./runtime/completion.js";import{runDirectToolCall as p}from"./runtime/direct-tool-call.js";import{createApprovalGatedToolGateway as d}from"./runtime/governance/approval-gate.js";import{createSandboxedToolGateway as m}from"./runtime/governance/sandbox.js";import{createRuntimeInspectionMethods as l}from"./runtime/inspection/methods.js";import{createRuntimeCapabilityRegistry as w,normalizeAdapterResult as f}from"./runtime/capabilities.js";import{createMemoryRuntimeCapability as g}from"./runtime/memory.js";import{createInMemoryRuntimeStore as I}from"./runtime/persistence/stores.js";import{createProgressNarrationCapability as y}from"./runtime/progress-narration.js";import{repairRuntimeSelection as q}from"./runtime/selection-repair.js";import{createLangSmithTracingCapability as R}from"./runtime/tracing/langsmith.js";import{createToolFailureTracker as k}from"./runtime/tool-failure.js";import{runWorkflowRequest as v}from"./workflows/runtime.js";export function createStableHarnessRuntime(t){const f=new Set,b=t.store??I(),A=w([g(t),y({options:t.progressNarration,policy:t.workspace.runtime}),R({policy:t.workspace.runtime,store:b,options:t.langSmithTracing}),...t.capabilities??[]]),emitBase=t=>{const r=function enrichRuntimeEvent(t){return{...t,eventId:t.eventId??e(),emittedAt:t.emittedAt??(new Date).toISOString()}}(t);b.appendEvent(r);for(const e of f)e(r)},emit=e=>{emitBase(e),A.emitSideEffects(e,emitBase)},C=m({gateway:d({gateway:t.toolGateway,approvals:t.approvals,workspace:t.workspace,emit:emit}),workspace:t.workspace,sandbox:t.sandbox,emit:emit}),h={...t,toolGateway:C},x=k(function readToolFailurePolicy(e){if("object"!=typeof e||null===e||Array.isArray(e))return;const t=e.failurePolicy;return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}(t.workspace.runtime.toolGateway));return{request:async t=>async function runRuntimeRequest(t){const d=t.request.requestId??e(),m=t.request.sessionId??e(),l=[],{agent:w,adapter:f}=await async function resolveExecution(e,t,r){const a=t.agentId?await async function resolveRequestedAgentId(e,t,r){if(e.agents.has(t))return t;const a=await q({id:t,candidates:[...e.agents.values()].map(e=>({id:e.id,description:e.description})),trace:{...r,agentId:t,layer:"agent",owner:"stable_runtime_policy"}});return a.ok?a.id:t}(e.workspace,t.agentId,r):function resolveRoutedAgentId(e,t){for(const r of e.runtime.routes??[])if(routeMatches(r,t))return r.agentId;return e.runtime.defaultAgentId}(e.workspace,t.input),s=e.workspace.agents.get(a);if(!s)throw new Error(`Agent ${a} is not defined in the workspace`);if(t.toolCall||t.workflow)return{agent:s,adapter:void 0};const n=e.adapters.find(e=>e.canRun(s));if(!n)throw new Error(`No runtime adapter can run backend ${s.backend} for agent ${s.id}`);return{agent:s,adapter:n}}(t.input,t.request,{requestId:d,sessionId:m,emit:e=>l.push(e)});t.store.createRun(function createRunRecord(e,t,r,a){return{requestId:t,sessionId:r,agentId:a.id,input:e.input,state:"running",parentRunId:e.parentRunId,metadata:e.metadata,artifacts:[],startedAt:(new Date).toISOString(),events:[]}}(t.request,d,m,w)),l.forEach(t.emit),t.emit({type:"runtime.request.started",requestId:d,sessionId:m,agentId:w.id,input:t.request.input});try{if(t.request.workflow){const e=await v({workspace:t.input.workspace,adapters:t.input.workflowAdapters??[],toolGateway:t.input.toolGateway,request:{input:t.request.input,...t.request.workflow},requestId:d,sessionId:m,agentId:w.id,emit:t.emit});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}if(t.request.toolCall){const e=await p({gateway:t.input.toolGateway,workspace:t.input.workspace,emit:t.emit,request:t.request,requestId:d,sessionId:m,agent:w,toolFailureTracker:t.toolFailureTracker});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}return await async function runAdapterRequest(e){if(!e.adapter)throw new Error(`No runtime adapter can run backend ${e.agent.backend} for agent ${e.agent.id}`);const t=e.adapter,c=await e.capabilities.beforeAdapterRun(createCapabilityContext(e)),p=c.memory,d=c.pluginMemories??[],m=e.input.workspace.runtime,l=o(e.input.workspace.runtime,e.agent),w=new Map;let f;try{f=await runAdapterOnce(e,t,e.request,p,d,w)}catch(a){if(!s(a,m))throw a;e.emit(repairStarted(e,"adapter_error",1,errorMessage(a))),f=await runAdapterOnce(e,t,r(e.request,a,m),p,d,w),e.emit(repairCompleted(e,"adapter_error","retried",1,errorMessage(a)))}f=await i({...e,request:e.request,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),e.request,f,l),await e.capabilities.beforeAdapterResultContract({...createCapabilityContext(e),result:f});try{assertRequestExecutionContract(e)}catch(r){const s=a({request:e.request,events:e.store.getRun(e.requestId)?.events??[],policy:m});if(!s)throw r;e.emit(repairStarted(e,"execution_contract",1,errorMessage(r))),f=await runAdapterOnce(e,t,s,p,d,w),f=await i({...e,request:s,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),s,f,l),assertRequestExecutionContract(e),e.emit(repairCompleted(e,"execution_contract","retried",1,errorMessage(r)))}const g=u({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,result:f,artifacts:e.input.artifacts});return await e.capabilities.afterAdapterResponse({...createCapabilityContext(e),result:f,response:g}),g}({...t,adapter:f,requestId:d,sessionId:m,agent:w})}catch(e){return c({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,error:e})}}({input:h,capabilities:A,store:b,emit:emit,request:t,toolFailureTracker:x}),subscribe:e=>(f.add(e),()=>f.delete(e)),...l({workspace:t.workspace,store:b,artifacts:t.artifacts,approvals:t.approvals,emit:emit}),cancel(e,t){const r=b.getRun(e);r&&"running"===r.state&&(b.updateRun(e,{state:"cancelled",completedAt:(new Date).toISOString()}),emit({type:"runtime.request.cancelled",requestId:e,sessionId:r.sessionId,agentId:r.agentId,reason:t}))},async stop(){await A.stop(),f.clear()}}}function createCapabilityContext(e){return{workspace:e.input.workspace,store:e.store,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent}}function createQualityRuntimeInput(e,t,r,a){return{workspace:e.input.workspace,agent:e.agent,request:e.request,requestId:e.requestId,sessionId:e.sessionId,events:e.store.getRun(e.requestId)?.events??[],emit:e.emit,getEvents:()=>e.store.getRun(e.requestId)?.events??[],runAdapter:s=>runAdapterOnce(e,e.adapter,s,t,r,a),reviewModel:e.input.qualityReviewModel,memory:t,pluginMemories:r}}function assertRequestExecutionContract(e){t({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,metadata:e.request.metadata})}async function runAdapterOnce(e,t,r,a,s,n){return f(await t.run({workspace:e.input.workspace,agent:e.agent,request:r,requestId:e.requestId,sessionId:e.sessionId,memory:a,pluginMemories:s,toolGateway:e.input.toolGateway,toolFailureTracker:e.input.toolFailureTracker,requestState:n,getEvents:()=>e.store.getRun(e.requestId)?.events??[],emit:e.emit}))}function repairStarted(e,t,r,a){return{type:"runtime.repair.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,attempt:r,reason:a}}function repairCompleted(e,t,r,a,s){return{type:"runtime.repair.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,outcome:r,attempt:a,reason:s}}function errorMessage(e){return e instanceof Error?e.message:String(e)}function routeMatches(e,t){if(e.pattern)try{if(new RegExp(e.pattern,"iu").test(t))return!0}catch{return!1}const r=t.toLowerCase();return(e.keywords??[]).some(e=>r.includes(e.toLowerCase()))}
1
+ import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{buildAdapterErrorRecoveryPrompt as r,buildExecutionContractRecoveryRequest as a,isRecoverableAdapterError as s}from"./recovery/tool-call.js";import{recoverQualityReview as n,resolveQualityPolicy as o}from"./quality/index.js";import{recoverAdapterResultOutput as i}from"./runtime/recovery/adapter-result.js";import{completeRun as u,failRun as c}from"./runtime/completion.js";import{createRuntimeAdministrationMethods as p}from"./runtime/admin/administration.js";import{runDirectToolCall as d}from"./runtime/direct-tool-call.js";import{createApprovalGatedToolGateway as m}from"./runtime/governance/approval-gate.js";import{createSandboxedToolGateway as l}from"./runtime/governance/sandbox.js";import{createRuntimeInspectionMethods as w}from"./runtime/inspection/methods.js";import{createRuntimeCapabilityRegistry as f,normalizeAdapterResult as g}from"./runtime/capabilities.js";import{createMemoryRuntimeCapability as I}from"./runtime/memory.js";import{createRuntimeMemoryAdministration as y}from"./runtime/admin/memory.js";import{createInMemoryRuntimeStore as q}from"./runtime/persistence/stores.js";import{createProgressNarrationCapability as R}from"./runtime/progress-narration.js";import{repairRuntimeSelection as k}from"./runtime/selection-repair.js";import{createLangSmithTracingCapability as v}from"./runtime/tracing/langsmith.js";import{createToolFailureTracker as A}from"./runtime/tool-failure.js";import{runWorkflowRequest as b}from"./workflows/runtime.js";export function createStableHarnessRuntime(t){const g=new Set,C=t.store??q(),h=f([I(t),R({options:t.progressNarration,policy:t.workspace.runtime}),v({policy:t.workspace.runtime,store:C,options:t.langSmithTracing}),...t.capabilities??[]]),emitBase=t=>{const r=function enrichRuntimeEvent(t){return{...t,eventId:t.eventId??e(),emittedAt:t.emittedAt??(new Date).toISOString()}}(t);C.appendEvent(r);for(const e of g)e(r)},emit=e=>{emitBase(e),h.emitSideEffects(e,emitBase)},j=l({gateway:m({gateway:t.toolGateway,approvals:t.approvals,workspace:t.workspace,emit:emit}),workspace:t.workspace,sandbox:t.sandbox,emit:emit}),x={...t,toolGateway:j},E=A(function readToolFailurePolicy(e){if("object"!=typeof e||null===e||Array.isArray(e))return;const t=e.failurePolicy;return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}(t.workspace.runtime.toolGateway));return{request:async t=>async function runRuntimeRequest(t){const p=t.request.requestId??e(),m=t.request.sessionId??e(),l=[],{agent:w,adapter:f}=await async function resolveExecution(e,t,r){const a=t.agentId?await async function resolveRequestedAgentId(e,t,r){if(e.agents.has(t))return t;const a=await k({id:t,candidates:[...e.agents.values()].map(e=>({id:e.id,description:e.description})),trace:{...r,agentId:t,layer:"agent",owner:"stable_runtime_policy"}});return a.ok?a.id:t}(e.workspace,t.agentId,r):function resolveRoutedAgentId(e,t){for(const r of e.runtime.routes??[])if(routeMatches(r,t))return r.agentId;return e.runtime.defaultAgentId}(e.workspace,t.input),s=e.workspace.agents.get(a);if(!s)throw new Error(`Agent ${a} is not defined in the workspace`);if(t.toolCall||t.workflow)return{agent:s,adapter:void 0};const n=e.adapters.find(e=>e.canRun(s));if(!n)throw new Error(`No runtime adapter can run backend ${s.backend} for agent ${s.id}`);return{agent:s,adapter:n}}(t.input,t.request,{requestId:p,sessionId:m,emit:e=>l.push(e)});t.store.createRun(function createRunRecord(e,t,r,a){return{requestId:t,sessionId:r,agentId:a.id,input:e.input,state:"running",parentRunId:e.parentRunId,metadata:e.metadata,artifacts:[],startedAt:(new Date).toISOString(),events:[]}}(t.request,p,m,w)),l.forEach(t.emit),t.emit({type:"runtime.request.started",requestId:p,sessionId:m,agentId:w.id,input:t.request.input});try{if(t.request.workflow){const e=await b({workspace:t.input.workspace,adapters:t.input.workflowAdapters??[],toolGateway:t.input.toolGateway,request:{input:t.request.input,...t.request.workflow},requestId:p,sessionId:m,agentId:w.id,emit:t.emit});return u({store:t.store,emit:t.emit,requestId:p,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}if(t.request.toolCall){const e=await d({gateway:t.input.toolGateway,workspace:t.input.workspace,emit:t.emit,request:t.request,requestId:p,sessionId:m,agent:w,toolFailureTracker:t.toolFailureTracker});return u({store:t.store,emit:t.emit,requestId:p,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}return await async function runAdapterRequest(e){if(!e.adapter)throw new Error(`No runtime adapter can run backend ${e.agent.backend} for agent ${e.agent.id}`);const t=e.adapter,c=await e.capabilities.beforeAdapterRun(createCapabilityContext(e)),p=c.memory,d=c.pluginMemories??[],m=e.input.workspace.runtime,l=o(e.input.workspace.runtime,e.agent),w=new Map;let f;try{f=await runAdapterOnce(e,t,e.request,p,d,w)}catch(a){if(!s(a,m))throw a;e.emit(repairStarted(e,"adapter_error",1,errorMessage(a))),f=await runAdapterOnce(e,t,r(e.request,a,m),p,d,w),e.emit(repairCompleted(e,"adapter_error","retried",1,errorMessage(a)))}f=await i({...e,request:e.request,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),e.request,f,l),await e.capabilities.beforeAdapterResultContract({...createCapabilityContext(e),result:f});try{assertRequestExecutionContract(e)}catch(r){const s=a({request:e.request,events:e.store.getRun(e.requestId)?.events??[],policy:m});if(!s)throw r;e.emit(repairStarted(e,"execution_contract",1,errorMessage(r))),f=await runAdapterOnce(e,t,s,p,d,w),f=await i({...e,request:s,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),s,f,l),assertRequestExecutionContract(e),e.emit(repairCompleted(e,"execution_contract","retried",1,errorMessage(r)))}const g=u({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,result:f,artifacts:e.input.artifacts});return await e.capabilities.afterAdapterResponse({...createCapabilityContext(e),result:f,response:g}),g}({...t,adapter:f,requestId:p,sessionId:m,agent:w})}catch(e){return c({store:t.store,emit:t.emit,requestId:p,sessionId:m,agent:w,error:e})}}({input:x,capabilities:h,store:C,emit:emit,request:t,toolFailureTracker:E}),subscribe:e=>(g.add(e),()=>g.delete(e)),...w({workspace:t.workspace,store:C,artifacts:t.artifacts,approvals:t.approvals,emit:emit}),...p({store:C,emit:emit}),...y({memory:t.memory}),cancel(e,t){const r=C.getRun(e);r&&"running"===r.state&&(C.updateRun(e,{state:"cancelled",completedAt:(new Date).toISOString()}),emit({type:"runtime.request.cancelled",requestId:e,sessionId:r.sessionId,agentId:r.agentId,reason:t}))},async stop(){await h.stop(),g.clear()}}}function createCapabilityContext(e){return{workspace:e.input.workspace,store:e.store,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent}}function createQualityRuntimeInput(e,t,r,a){return{workspace:e.input.workspace,agent:e.agent,request:e.request,requestId:e.requestId,sessionId:e.sessionId,events:e.store.getRun(e.requestId)?.events??[],emit:e.emit,getEvents:()=>e.store.getRun(e.requestId)?.events??[],runAdapter:s=>runAdapterOnce(e,e.adapter,s,t,r,a),reviewModel:e.input.qualityReviewModel,memory:t,pluginMemories:r}}function assertRequestExecutionContract(e){t({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,metadata:e.request.metadata})}async function runAdapterOnce(e,t,r,a,s,n){return g(await t.run({workspace:e.input.workspace,agent:e.agent,request:r,requestId:e.requestId,sessionId:e.sessionId,memory:a,pluginMemories:s,toolGateway:e.input.toolGateway,toolFailureTracker:e.input.toolFailureTracker,requestState:n,getEvents:()=>e.store.getRun(e.requestId)?.events??[],emit:e.emit}))}function repairStarted(e,t,r,a){return{type:"runtime.repair.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,attempt:r,reason:a}}function repairCompleted(e,t,r,a,s){return{type:"runtime.repair.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,outcome:r,attempt:a,reason:s}}function errorMessage(e){return e instanceof Error?e.message:String(e)}function routeMatches(e,t){if(e.pattern)try{if(new RegExp(e.pattern,"iu").test(t))return!0}catch{return!1}const r=t.toLowerCase();return(e.keywords??[]).some(e=>r.includes(e.toLowerCase()))}
@@ -1,17 +1,17 @@
1
- import type { MemoryProvider, MemoryRecord, RuntimeMemoryStore } from "@stable-harness/memory";
1
+ import type { ListMemoriesInput, MemorizeInput, MemoryProvider, MemoryRecord, MemoryRecallResult, RecallInput, RuntimeMemoryStore, UpdateMemoryInput } from "@stable-harness/memory";
2
2
  import type { ApprovalQueue, ApprovalRequest, ApprovalRequestStatus } from "@stable-harness/governance";
3
3
  import type { RuntimeWorkflowAdapter, RuntimeWorkflowRequest, WorkspaceWorkflow } from "./workflows/index.js";
4
4
  import type { SpecDrivenWorkflowState } from "./spec-driven/index.js";
5
5
  import type { RuntimeEvent, RuntimeEventListener, RuntimeEmit } from "./runtime/events.js";
6
6
  import type { RuntimeToolFailureTracker } from "./runtime/tool-failure.js";
7
- import type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactRecord, RuntimeOutput, RuntimeRecordState, RuntimeRequest, RuntimeResponse, RuntimeReplayBundle, RuntimeRunFilter, RuntimeRunRecord } from "./runtime/types.js";
7
+ import type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactRecord, RuntimeOutput, RuntimeRecordState, RuntimeRequest, RuntimeResponse, RuntimeReplayBundle, RuntimeDeletionResult, RuntimeRunFilter, RuntimeRunRecord } from "./runtime/types.js";
8
8
  import type { RuntimeToolGateway } from "./runtime/tool-gateway.js";
9
9
  import type { CompiledWorkspace, WorkspaceAgent, WorkspaceRuntimePolicy } from "./workspace/types.js";
10
10
  export type { RuntimeEvent, RuntimeMemoryHook, RuntimeEventListener, RuntimeEmit } from "./runtime/events.js";
11
11
  export type { BoundaryScanFinding, BoundaryScanLayer, BoundaryScanLayerResult, BoundaryScanResource, BoundaryScanResult } from "./boundary-scan.js";
12
12
  export type { RuntimeCapabilityContext, RuntimeCapabilityModule, RuntimeCapabilityRegistry, RuntimeCapabilityState } from "./runtime/capabilities.js";
13
13
  export type { RuntimeProgressNarrationOptions, RuntimeProgressNarrationProvider } from "./runtime/progress-narration.js";
14
- export type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactInput, RuntimeArtifactRecord, RuntimeArtifactStore, RuntimeOutputArtifact, RuntimeCancelIntentInput, RuntimeHeartbeatInput, RuntimeMemoryCandidateInput, RuntimeOutput, RuntimeQueueClaimInput, RuntimeQueueRecord, RuntimeQueueStore, RuntimeRecoveryIntent, RuntimeRecordState, RuntimeRequest, RuntimeRequestControlRecord, RuntimeRequestMemory, RuntimeResponse, RuntimeReplayBundle, RuntimeReplayBundleIntegrity, RuntimeRunFilter, RuntimeRunRecord, RuntimeStore, RuntimeStoreRunPatch, RuntimeStuckRequestInput, } from "./runtime/types.js";
14
+ export type { RuntimeArtifact, RuntimeArtifactFilter, RuntimeArtifactInput, RuntimeArtifactRecord, RuntimeArtifactStore, RuntimeOutputArtifact, RuntimeCancelIntentInput, RuntimeHeartbeatInput, RuntimeMemoryCandidateInput, RuntimeOutput, RuntimeQueueClaimInput, RuntimeQueueRecord, RuntimeQueueStore, RuntimeRecoveryIntent, RuntimeRecordState, RuntimeRequest, RuntimeRequestControlRecord, RuntimeRequestMemory, RuntimeResponse, RuntimeDeletionResult, RuntimeReplayBundle, RuntimeReplayBundleIntegrity, RuntimeRunFilter, RuntimeRunRecord, RuntimeStore, RuntimeStoreRunPatch, RuntimeStuckRequestInput, } from "./runtime/types.js";
15
15
  export type { CompiledWorkspace, WorkspaceAdapterPolicy, WorkspaceAgent, WorkspaceBoundaryDiagnostic, WorkspaceBoundaryDiagnosticCode, WorkspaceBoundaryScanPolicy, WorkspaceMemory, WorkspaceModel, WorkspaceRetryPolicy, WorkspaceRetryReason, WorkspaceRetryTargetPolicy, WorkspaceRuntimePolicy, WorkspaceSkill, WorkspaceTool, WorkspaceToolRetryPolicy, WorkspaceValidationPolicy, } from "./workspace/types.js";
16
16
  export type { WorkspaceToolQualityDiagnostic, WorkspaceToolQualityDiagnosticCode, WorkspaceToolQualityPolicy, } from "./workspace/tool-quality.js";
17
17
  export type { WorkspaceEvaluation, WorkspaceEvaluationCase, } from "./evaluations/index.js";
@@ -140,6 +140,15 @@ export type RuntimeInspector = {
140
140
  };
141
141
  export type RuntimeLifecycle = {
142
142
  cancel(requestId: string, reason?: string): void;
143
+ deleteRequest(requestId: string): RuntimeDeletionResult;
144
+ deleteSession(sessionId: string): RuntimeDeletionResult;
143
145
  stop(): Promise<void>;
144
146
  };
145
- export type StableHarnessRuntime = RuntimeClient & RuntimeEventSource & RuntimeInspector & RuntimeLifecycle;
147
+ export type RuntimeMemoryAdministration = {
148
+ memorize(input: MemorizeInput): Promise<MemoryRecord>;
149
+ recallMemories(input: RecallInput): Promise<MemoryRecallResult>;
150
+ listMemories(input: ListMemoriesInput): Promise<MemoryRecord[]>;
151
+ updateMemory(input: UpdateMemoryInput): Promise<MemoryRecord | undefined>;
152
+ archiveMemory(id: string, reason?: string): Promise<MemoryRecord | undefined>;
153
+ };
154
+ export type StableHarnessRuntime = RuntimeClient & RuntimeEventSource & RuntimeInspector & RuntimeLifecycle & RuntimeMemoryAdministration;
@@ -5,5 +5,5 @@ export type { LangMemServiceProviderOptions, } from "./langmem-service.js";
5
5
  export type { MemoryProvider, MemoryProviderApprovalConfig, MemoryProviderConfig, MemoryProviderConsolidateInput, MemoryProviderDefaults, MemoryProviderMode, MemoryProviderProposeInput, MemoryProviderSearchInput, MemoryProviderTypeConfig, } from "./provider.js";
6
6
  export { cloneRecords, createInMemoryMemoryPersistenceAdapter, createMemorySnapshot, } from "./persistence.js";
7
7
  export { createDefaultMemoryPolicy } from "./policy.js";
8
- export { createInMemoryRuntimeMemoryStore } from "./store.js";
8
+ export { createInMemoryRuntimeMemoryStore, createJsonFileRuntimeMemoryStore } from "./store.js";
9
9
  export type { ListMemoriesInput, MemorizeInput, MemoryCandidate, MemoryDecision, MemoryDecisionAction, MemoryKind, MemoryMaintenanceAction, MemoryMaintenanceOperation, MemoryMaintenanceResult, MemoryPolicy, MemoryPersistenceAdapter, MemoryRecallResult, MemoryRecord, MemoryRecordStatus, MemoryScope, MemorySensitivity, MemoryStoreSnapshot, MemorySubmitResult, RecallInput, RuntimeMemoryStore, UpdateMemoryInput, } from "./types.js";
@@ -1 +1 @@
1
- export{applyMemoryMaintenance}from"./maintenance.js";export{createEmbeddedMemoryProvider}from"./provider.js";export{createLangMemServiceProvider}from"./langmem-service.js";export{cloneRecords,createInMemoryMemoryPersistenceAdapter,createMemorySnapshot}from"./persistence.js";export{createDefaultMemoryPolicy}from"./policy.js";export{createInMemoryRuntimeMemoryStore}from"./store.js";
1
+ export{applyMemoryMaintenance}from"./maintenance.js";export{createEmbeddedMemoryProvider}from"./provider.js";export{createLangMemServiceProvider}from"./langmem-service.js";export{cloneRecords,createInMemoryMemoryPersistenceAdapter,createMemorySnapshot}from"./persistence.js";export{createDefaultMemoryPolicy}from"./policy.js";export{createInMemoryRuntimeMemoryStore,createJsonFileRuntimeMemoryStore}from"./store.js";
@@ -1 +1 @@
1
- export async function createMemorySnapshot(e,t){return{namespace:t.namespace,records:await e.list(t),exportedAt:(new Date).toISOString()}}export function createInMemoryMemoryPersistenceAdapter(){const e=new Map;return{load:async t=>cloneRecords(e.get(t)??[]),async save(t){e.set(t.namespace,cloneRecords(t.records))}}}export function cloneRecords(e){return e.map(e=>({...e,sourceRefs:[...e.sourceRefs],tags:[...e.tags],metadata:{...e.metadata},provenance:{...e.provenance},supersedes:[...e.supersedes],conflictsWith:[...e.conflictsWith]}))}
1
+ export async function createMemorySnapshot(e,t){return{namespace:t.namespace??"",records:await e.list(t),exportedAt:(new Date).toISOString()}}export function createInMemoryMemoryPersistenceAdapter(){const e=new Map;return{load:async t=>cloneRecords(e.get(t)??[]),async save(t){e.set(t.namespace,cloneRecords(t.records))}}}export function cloneRecords(e){return e.map(e=>({...e,sourceRefs:[...e.sourceRefs],tags:[...e.tags],metadata:{...e.metadata},provenance:{...e.provenance},supersedes:[...e.supersedes],conflictsWith:[...e.conflictsWith]}))}
@@ -3,3 +3,6 @@ export declare function createInMemoryRuntimeMemoryStore(options?: {
3
3
  policy?: MemoryPolicy;
4
4
  records?: MemoryRecord[];
5
5
  }): RuntimeMemoryStore;
6
+ export declare function createJsonFileRuntimeMemoryStore(filePath: string, options?: {
7
+ policy?: MemoryPolicy;
8
+ }): RuntimeMemoryStore;
@@ -1 +1 @@
1
- import{randomUUID as e}from"node:crypto";import{createDefaultMemoryPolicy as t}from"./policy.js";import{cloneRecords as n}from"./persistence.js";export function createInMemoryRuntimeMemoryStore(e={}){const r=e.policy??t(),o=n(e.records??[]);return{async submitCandidate(e){const t=r.decide(e);if("store"!==t.action)return{candidate:e,decision:t};const n=createRecord({namespace:e.namespace,content:e.content,kind:t.kind,scope:t.scope,summary:e.summary,confidence:t.confidence,tags:e.tags,sensitivity:e.sensitivity,sourceType:e.sourceType,sourceRef:e.sourceRef,metadata:e.metadata,provenance:e.provenance,observedAt:e.observedAt,retrievalPriority:t.retrievalPriority});return o.push(n),{candidate:e,decision:{...t,recordId:n.id},record:cloneRecord(n)}},async memorize(e){const t=createRecord(e);return o.push(t),cloneRecord(t)},async recall(e){const t=e.query.toLowerCase(),n=filterRecords(o,e).filter(e=>function matchesQuery(e,t){return[e.canonicalKey,e.content,e.summary??"",...e.tags].join("\n").toLowerCase().includes(t)}(e,t)).sort(compareRecallPriority).slice(0,e.limit??10);return{records:n,context:buildMemoryContext(n)}},list:async e=>n(filterRecords(o,e)),async update(e){const t=o.find(t=>t.id===e.id);if(t)return function applyUpdate(e,t){e.content=t.content??e.content,e.summary=t.summary??e.summary,e.status=t.status??e.status,e.confidence=normalizeConfidence(t.confidence??e.confidence),e.tags=t.tags??e.tags,e.metadata=t.metadata?{...e.metadata,...t.metadata}:e.metadata,e.lastConfirmedAt=(new Date).toISOString(),e.revision+=1}(t,e),cloneRecord(t)},async archive(e,t){const n=o.find(t=>t.id===e);if(n)return n.status="archived",n.metadata={...n.metadata,archiveReason:t},n.revision+=1,cloneRecord(n)}}}function cloneRecord(e){return n([e])[0]}function createRecord(t){const n=(new Date).toISOString();return{id:e(),namespace:t.namespace,canonicalKey:(r=t.namespace,o=t.content,`${r}:${o.trim().toLowerCase().replace(/\s+/gu," ").slice(0,120)}`),kind:t.kind??"semantic",scope:t.scope??"workspace",status:"active",content:t.content,summary:t.summary,confidence:normalizeConfidence(t.confidence),sourceType:t.sourceType,sourceRefs:t.sourceRef?[t.sourceRef]:[],tags:t.tags??[],sensitivity:t.sensitivity??"internal",metadata:t.metadata??{},createdAt:n,observedAt:t.observedAt??n,lastConfirmedAt:n,provenance:t.provenance??{},revision:1,supersedes:[],conflictsWith:[],retrievalPriority:t.retrievalPriority??0};var r,o}function filterRecords(e,t){return e.filter(e=>e.namespace===t.namespace).filter(e=>!t.kinds||t.kinds.includes(e.kind)).filter(e=>!t.scopes||t.scopes.includes(e.scope)).filter(e=>(t.statuses??["active"]).includes(e.status))}function compareRecallPriority(e,t){return t.retrievalPriority-e.retrievalPriority||t.confidence-e.confidence||t.lastConfirmedAt.localeCompare(e.lastConfirmedAt)}function buildMemoryContext(e){return e.map(e=>`- [${e.kind}/${e.scope}] ${e.summary??e.content}`).join("\n")}function normalizeConfidence(e){return void 0===e||Number.isNaN(e)?.6:Math.min(1,Math.max(0,e))}
1
+ import{existsSync as e,mkdirSync as r,readFileSync as t,writeFileSync as n}from"node:fs";import{randomUUID as o}from"node:crypto";import i from"node:path";import{createDefaultMemoryPolicy as a}from"./policy.js";import{cloneRecords as c}from"./persistence.js";export function createInMemoryRuntimeMemoryStore(e={}){const r=e.policy??a(),t=c(e.records??[]);return{async submitCandidate(e){const n=r.decide(e);if("store"!==n.action)return{candidate:e,decision:n};const o=createRecord({namespace:e.namespace,content:e.content,kind:n.kind,scope:n.scope,summary:e.summary,confidence:n.confidence,tags:e.tags,sensitivity:e.sensitivity,sourceType:e.sourceType,sourceRef:e.sourceRef,metadata:e.metadata,provenance:e.provenance,observedAt:e.observedAt,retrievalPriority:n.retrievalPriority});return t.push(o),{candidate:e,decision:{...n,recordId:o.id},record:cloneRecord(o)}},async memorize(e){const r=createRecord(e);return t.push(r),cloneRecord(r)},async recall(e){const r=e.query.toLowerCase(),n=filterRecords(t,e).filter(e=>function matchesQuery(e,r){return[e.canonicalKey,e.content,e.summary??"",...e.tags].join("\n").toLowerCase().includes(r)}(e,r)).sort(compareRecallPriority).slice(0,e.limit??10);return{records:n,context:buildMemoryContext(n)}},list:async e=>c(filterRecords(t,e)),async update(e){const r=t.find(r=>r.id===e.id);if(r)return function applyUpdate(e,r){e.content=r.content??e.content,e.summary=r.summary??e.summary,e.status=r.status??e.status,e.confidence=normalizeConfidence(r.confidence??e.confidence),e.tags=r.tags??e.tags,e.metadata=r.metadata?{...e.metadata,...r.metadata}:e.metadata,e.lastConfirmedAt=(new Date).toISOString(),e.revision+=1}(r,e),cloneRecord(r)},async archive(e,r){const n=t.find(r=>r.id===e);if(n)return n.status="archived",n.metadata={...n.metadata,archiveReason:r},n.revision+=1,cloneRecord(n)}}}export function createJsonFileRuntimeMemoryStore(e,r={}){const t=i.resolve(e),n=createInMemoryRuntimeMemoryStore({policy:r.policy,records:readStoreFile(t)});return{async submitCandidate(e){const r=await n.submitCandidate(e);return await persistMemoryStore(t,n),r},async memorize(e){const r=await n.memorize(e);return await persistMemoryStore(t,n),r},recall:e=>n.recall(e),list:e=>n.list(e),async update(e){const r=await n.update(e);return await persistMemoryStore(t,n),r},async archive(e,r){const o=await n.archive(e,r);return await persistMemoryStore(t,n),o}}}function cloneRecord(e){return c([e])[0]}async function persistMemoryStore(e,t){!function writeStoreFile(e,t){r(i.dirname(e),{recursive:!0}),n(e,`${JSON.stringify({version:1,records:t},null,2)}\n`)}(e,await t.list({statuses:["active","stale","conflicted","archived","pending_review"]}))}function readStoreFile(r){if(!e(r))return[];const n=JSON.parse(t(r,"utf8"));if(!isRecord(n)||!Array.isArray(n.records))throw new Error(`Invalid runtime memory store file: ${r}`);return c(n.records.map(assertMemoryRecord))}function assertMemoryRecord(e){if(!isRecord(e)||"string"!=typeof e.id||"string"!=typeof e.namespace)throw new Error("Invalid memory record in store file");return e}function createRecord(e){const r=(new Date).toISOString();return{id:o(),namespace:e.namespace,canonicalKey:(t=e.namespace,n=e.content,`${t}:${n.trim().toLowerCase().replace(/\s+/gu," ").slice(0,120)}`),kind:e.kind??"semantic",scope:e.scope??"workspace",status:"active",content:e.content,summary:e.summary,confidence:normalizeConfidence(e.confidence),sourceType:e.sourceType,sourceRefs:e.sourceRef?[e.sourceRef]:[],tags:e.tags??[],sensitivity:e.sensitivity??"internal",metadata:e.metadata??{},createdAt:r,observedAt:e.observedAt??r,lastConfirmedAt:r,provenance:e.provenance??{},revision:1,supersedes:[],conflictsWith:[],retrievalPriority:e.retrievalPriority??0};var t,n}function filterRecords(e,r){return e.filter(e=>!r.namespace||e.namespace===r.namespace).filter(e=>!r.kinds||r.kinds.includes(e.kind)).filter(e=>!r.scopes||r.scopes.includes(e.scope)).filter(e=>(r.statuses??["active"]).includes(e.status))}function compareRecallPriority(e,r){return r.retrievalPriority-e.retrievalPriority||r.confidence-e.confidence||r.lastConfirmedAt.localeCompare(e.lastConfirmedAt)}function buildMemoryContext(e){return e.map(e=>`- [${e.kind}/${e.scope}] ${e.summary??e.content}`).join("\n")}function normalizeConfidence(e){return void 0===e||Number.isNaN(e)?.6:Math.min(1,Math.max(0,e))}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -111,7 +111,7 @@ export type MemoryMaintenanceResult = {
111
111
  reason: string;
112
112
  };
113
113
  export type ListMemoriesInput = {
114
- namespace: string;
114
+ namespace?: string;
115
115
  kinds?: MemoryKind[];
116
116
  scopes?: MemoryScope[];
117
117
  statuses?: MemoryRecordStatus[];
@@ -1 +1 @@
1
- import{createServer as t}from"node:http";import{compileWorkflowPlan as e,projectRuntimeTrace as r,projectRuntimeTraceSpans as o,renderWorkflowMermaid as n}from"@stable-harness/core";export function createHttpServer(s){return t(async(t,a)=>{try{if("GET"===t.method&&"/health"===t.url)return void sendJson(a,200,{ok:!0});if("GET"===t.method&&"/inspect"===t.url)return void sendJson(a,200,s.inspect());if("GET"===t.method&&"/requests"===t.url)return void sendJson(a,200,s.listRequests());if("GET"===t.method&&"/sessions"===t.url)return void sendJson(a,200,s.listSessions());const d=function readArtifactList(t){if(!t?.startsWith("/artifacts"))return;const e=new URL(t,"http://stable-harness.local");return"/artifacts"===e.pathname?{...e.searchParams.get("requestId")?{requestId:e.searchParams.get("requestId")}:{},...e.searchParams.get("sessionId")?{sessionId:e.searchParams.get("sessionId")}:{},...e.searchParams.get("agentId")?{agentId:e.searchParams.get("agentId")}:{}}:void 0}(t.url);if("GET"===t.method&&d)return void sendJson(a,200,s.listArtifacts(d));const i=function readArtifactContentId(t){const e=(t??"").match(/^\/artifacts\/([^/]+)\/content$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&i){const t=s.getArtifact(i),e=s.readArtifact(i);return void sendJson(a,t&&void 0!==e?200:404,t&&void 0!==e?{artifact:t,content:e}:{error:"artifact_content_not_found"})}const u=function readArtifactId(t){const e=(t??"").match(/^\/artifacts\/([^/]+)$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&u){const t=s.getArtifact(u);return void sendJson(a,t?200:404,t??{error:"artifact_not_found"})}const c=function readApprovalList(t){if(!t?.startsWith("/approvals"))return;const e=new URL(t,"http://stable-harness.local");if("/approvals"!==e.pathname)return;const r=e.searchParams.get("status");return{status:"pending"===r||"approved"===r||"rejected"===r?r:void 0}}(t.url);if("GET"===t.method&&c)return void sendJson(a,200,await s.listApprovals(c.status));const f=function readApprovalDecision(t){const e=(t??"").match(/^\/approvals\/([^/]+)\/(approve|reject)$/u);if(e?.[1]&&e[2])return{id:decodeURIComponent(e[1]),status:"approve"===e[2]?"approved":"rejected"}}(t.url);if("POST"===t.method&&f){const t=await s.resolveApproval(f.id,f.status);return void sendJson(a,t?200:404,t??{error:"approval_not_found"})}if("GET"===t.method&&"/workflows"===t.url)return void sendJson(a,200,s.inspect().workflows);const l=function readWorkflowMermaidId(t){const e=(t??"").match(/^\/workflows\/([^/]+)\/mermaid$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&l){const t=s.getWorkflow(l);return void sendJson(a,t?200:404,t?{mermaid:n(t)}:{error:"workflow_not_found"})}const p=function readWorkflowPlanId(t){const e=(t??"").match(/^\/workflows\/([^/]+)\/plan$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&p){const t=s.getWorkflow(p);return void sendJson(a,t?200:404,t?e(t):{error:"workflow_not_found"})}const m=function readRequestInspectionId(t){const e=(t??"").match(/^\/requests\/([^/]+)$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&m){const t=s.inspectRequest(m);return void sendJson(a,t?200:404,t??{error:"request_not_found"})}const h=function readTraceRequestId(t){const e=(t??"").match(/^\/runs\/([^/]+)\/trace$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&h){const t=s.getRun(h);return void sendJson(a,t?200:404,t?r(t):{error:"run_not_found"})}const I=function readSpanRequestId(t){const e=(t??"").match(/^\/runs\/([^/]+)\/spans$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&I){const t=s.getRun(I);return void sendJson(a,t?200:404,t?o(t):{error:"run_not_found"})}const v=function readReplayRequestId(t){const e=(t??"").match(/^\/requests\/([^/]+)\/replay$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&v){const t=s.exportReplayBundle(v);return void sendJson(a,t?200:404,t??{error:"run_not_found"})}if("POST"===t.method&&"/requests"===t.url){const e=await async function readJson(t){const e=[];for await(const r of t)e.push(Buffer.isBuffer(r)?r:Buffer.from(r));return 0===e.length?{}:JSON.parse(Buffer.concat(e).toString("utf8"))}(t);return void sendJson(a,200,await s.request(function readRuntimeRequest(t){const e=function readToolCall(t){if("object"!=typeof t||null===t)return;const e=t;return"string"==typeof e.toolId?{toolId:e.toolId,args:e.args}:void 0}(t.toolCall),r=function readWorkflow(t){const e=readRecord(t);if(e)return{..."string"==typeof e.workflowId?{workflowId:e.workflowId}:{},..."string"==typeof e.routeId?{routeId:e.routeId}:{},...void 0!==e.input?{input:e.input}:{},..."object"==typeof e.metadata&&e.metadata?{metadata:e.metadata}:{}}}(t.workflow),o=function readMemory(t){const e=readRecord(t);if(e)return{..."string"==typeof e.namespace?{namespace:e.namespace}:{},...!1===e.recall||readRecord(e.recall)?{recall:e.recall}:{},...Array.isArray(e.candidates)?{candidates:e.candidates}:{}}}(t.memory),n=readRecord(t.metadata);return{input:"string"==typeof t.input?t.input:"",..."string"==typeof t.agentId?{agentId:t.agentId}:{},..."string"==typeof t.sessionId?{sessionId:t.sessionId}:{},..."string"==typeof t.requestId?{requestId:t.requestId}:{},..."string"==typeof t.parentRunId?{parentRunId:t.parentRunId}:{},...e?{toolCall:e}:{},...r?{workflow:r}:{},...o?{memory:o}:{},...n?{metadata:n}:{}}}(e)))}sendJson(a,404,{error:"not_found"})}catch(t){sendJson(a,500,{error:t instanceof Error?t.message:String(t)})}})}function readRecord(t){return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}function sendJson(t,e,r){t.writeHead(e,{"content-type":"application/json"}),t.end(JSON.stringify(r))}
1
+ import{createServer as e}from"node:http";import{compileWorkflowPlan as t,projectRuntimeTrace as r,projectRuntimeTraceSpans as o,renderWorkflowMermaid as n}from"@stable-harness/core";export function createHttpServer(s){return e((e,a)=>{!async function handleHttpRequest(e,s,a){try{await async function routeHttpRequest(e,s,a){if("GET"===s.method&&"/health"===s.url)return void sendJson(a,200,{ok:!0});if("GET"===s.method&&"/inspect"===s.url)return void sendJson(a,200,e.inspect());if("GET"===s.method&&"/requests"===s.url)return void sendJson(a,200,e.listRequests());if(await async function handleAdministrationRoutes(e){const{runtime:t,request:r,response:o}=e;if("GET"===r.method&&"/sessions"===r.url)return sendJson(o,200,t.listSessions()),!0;const n=function readSessionDeleteId(e){const t=(e??"").match(/^\/sessions\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);if("DELETE"===r.method&&n)return sendJson(o,200,t.deleteSession(n)),!0;const s=function readRequestDeleteId(e){const t=(e??"").match(/^\/requests\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);if("DELETE"===r.method&&s)return sendJson(o,200,t.deleteRequest(s)),!0;if("GET"===r.method&&r.url?.startsWith("/memories"))return sendJson(o,200,await t.listMemories(function readMemoryList(e){const t=new URL(e??"/memories","http://stable-harness.local"),r=t.searchParams.getAll("status").filter(e=>"active"===e||"stale"===e||"conflicted"===e||"archived"===e||"pending_review"===e);return{...t.searchParams.get("namespace")?{namespace:t.searchParams.get("namespace")}:{},...r.length>0?{statuses:r}:{}}}(r.url))),!0;if("POST"===r.method&&"/memories"===r.url){const e=await readJson(r);return sendJson(o,200,await t.memorize(e)),!0}if("POST"===r.method&&"/memories/recall"===r.url){const e=await readJson(r);return sendJson(o,200,await t.recallMemories(e)),!0}const a=function readMemoryArchiveId(e){const t=(e??"").match(/^\/memories\/([^/]+)\/archive$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);if("POST"===r.method&&a){const e=await readJson(r);return sendJson(o,200,await t.archiveMemory(a,"string"==typeof e.reason?e.reason:void 0)),!0}const d=function readMemoryUpdateId(e){const t=(e??"").match(/^\/memories\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(r.url);return!("PATCH"!==r.method||!d||(sendJson(o,200,await t.updateMemory({id:d,...await readJson(r)})),0))}({runtime:e,request:s,response:a}))return;const d=function readArtifactList(e){if(!e?.startsWith("/artifacts"))return;const t=new URL(e,"http://stable-harness.local");return"/artifacts"===t.pathname?{...t.searchParams.get("requestId")?{requestId:t.searchParams.get("requestId")}:{},...t.searchParams.get("sessionId")?{sessionId:t.searchParams.get("sessionId")}:{},...t.searchParams.get("agentId")?{agentId:t.searchParams.get("agentId")}:{}}:void 0}(s.url);if("GET"===s.method&&d)return void sendJson(a,200,e.listArtifacts(d));const i=function readArtifactContentId(e){const t=(e??"").match(/^\/artifacts\/([^/]+)\/content$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&i){const t=e.getArtifact(i),r=e.readArtifact(i);return void sendJson(a,t&&void 0!==r?200:404,t&&void 0!==r?{artifact:t,content:r}:{error:"artifact_content_not_found"})}const u=function readArtifactId(e){const t=(e??"").match(/^\/artifacts\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&u){const t=e.getArtifact(u);return void sendJson(a,t?200:404,t??{error:"artifact_not_found"})}const c=function readApprovalList(e){if(!e?.startsWith("/approvals"))return;const t=new URL(e,"http://stable-harness.local");if("/approvals"!==t.pathname)return;const r=t.searchParams.get("status");return{status:"pending"===r||"approved"===r||"rejected"===r?r:void 0}}(s.url);if("GET"===s.method&&c)return void sendJson(a,200,await e.listApprovals(c.status));const f=function readApprovalDecision(e){const t=(e??"").match(/^\/approvals\/([^/]+)\/(approve|reject)$/u);if(t?.[1]&&t[2])return{id:decodeURIComponent(t[1]),status:"approve"===t[2]?"approved":"rejected"}}(s.url);if("POST"===s.method&&f){const t=await e.resolveApproval(f.id,f.status);return void sendJson(a,t?200:404,t??{error:"approval_not_found"})}if("GET"===s.method&&"/workflows"===s.url)return void sendJson(a,200,e.inspect().workflows);const m=function readWorkflowMermaidId(e){const t=(e??"").match(/^\/workflows\/([^/]+)\/mermaid$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&m){const t=e.getWorkflow(m);return void sendJson(a,t?200:404,t?{mermaid:n(t)}:{error:"workflow_not_found"})}const l=function readWorkflowPlanId(e){const t=(e??"").match(/^\/workflows\/([^/]+)\/plan$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&l){const r=e.getWorkflow(l);return void sendJson(a,r?200:404,r?t(r):{error:"workflow_not_found"})}const p=function readRequestInspectionId(e){const t=(e??"").match(/^\/requests\/([^/]+)$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&p){const t=e.inspectRequest(p);return void sendJson(a,t?200:404,t??{error:"request_not_found"})}const h=function readTraceRequestId(e){const t=(e??"").match(/^\/runs\/([^/]+)\/trace$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&h){const t=e.getRun(h);return void sendJson(a,t?200:404,t?r(t):{error:"run_not_found"})}const v=function readSpanRequestId(e){const t=(e??"").match(/^\/runs\/([^/]+)\/spans$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&v){const t=e.getRun(v);return void sendJson(a,t?200:404,t?o(t):{error:"run_not_found"})}const I=function readReplayRequestId(e){const t=(e??"").match(/^\/requests\/([^/]+)\/replay$/u);return t?.[1]?decodeURIComponent(t[1]):void 0}(s.url);if("GET"===s.method&&I){const t=e.exportReplayBundle(I);return void sendJson(a,t?200:404,t??{error:"run_not_found"})}if("POST"===s.method&&"/requests"===s.url){const t=await readJson(s);return void sendJson(a,200,await e.request(function readRuntimeRequest(e){const t=function readToolCall(e){if("object"!=typeof e||null===e)return;const t=e;return"string"==typeof t.toolId?{toolId:t.toolId,args:t.args}:void 0}(e.toolCall),r=function readWorkflow(e){const t=readRecord(e);if(t)return{..."string"==typeof t.workflowId?{workflowId:t.workflowId}:{},..."string"==typeof t.routeId?{routeId:t.routeId}:{},...void 0!==t.input?{input:t.input}:{},..."object"==typeof t.metadata&&t.metadata?{metadata:t.metadata}:{}}}(e.workflow),o=function readMemory(e){const t=readRecord(e);if(t)return{..."string"==typeof t.namespace?{namespace:t.namespace}:{},...!1===t.recall||readRecord(t.recall)?{recall:t.recall}:{},...Array.isArray(t.candidates)?{candidates:t.candidates}:{}}}(e.memory),n=readRecord(e.metadata);return{input:"string"==typeof e.input?e.input:"",..."string"==typeof e.agentId?{agentId:e.agentId}:{},..."string"==typeof e.sessionId?{sessionId:e.sessionId}:{},..."string"==typeof e.requestId?{requestId:e.requestId}:{},..."string"==typeof e.parentRunId?{parentRunId:e.parentRunId}:{},...t?{toolCall:t}:{},...r?{workflow:r}:{},...o?{memory:o}:{},...n?{metadata:n}:{}}}(t)))}sendJson(a,404,{error:"not_found"})}(e,s,a)}catch(e){sendJson(a,500,{error:e instanceof Error?e.message:String(e)})}}(s,e,a)})}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function sendJson(e,t,r){e.writeHead(t,{"content-type":"application/json"}),e.end(JSON.stringify(r))}async function readJson(e){const t=[];for await(const r of e)t.push(Buffer.isBuffer(r)?r:Buffer.from(r));return 0===t.length?{}:JSON.parse(Buffer.concat(t).toString("utf8"))}
@@ -1 +1 @@
1
- export function createInProcessClient(e){return{request:t=>e.request(t),subscribe:t=>e.subscribe(t),inspect:()=>e.inspect(),getRuntimePolicy:()=>e.getRuntimePolicy(),getWorkflow:t=>e.getWorkflow(t),getRun:t=>e.getRun(t),listArtifacts:t=>e.listArtifacts(t),getArtifact:t=>e.getArtifact(t),readArtifact:t=>e.readArtifact(t),exportReplayBundle:t=>e.exportReplayBundle(t),listRequests:t=>e.listRequests(t),listSessions:()=>e.listSessions(),inspectRequest:t=>e.inspectRequest(t),listApprovals:t=>e.listApprovals(t),getApproval:t=>e.getApproval(t),resolveApproval:(t,s)=>e.resolveApproval(t,s),cancel:(t,s)=>e.cancel(t,s),stop:()=>e.stop()}}
1
+ export function createInProcessClient(e){return{request:t=>e.request(t),subscribe:t=>e.subscribe(t),inspect:()=>e.inspect(),getRuntimePolicy:()=>e.getRuntimePolicy(),getWorkflow:t=>e.getWorkflow(t),getRun:t=>e.getRun(t),listArtifacts:t=>e.listArtifacts(t),getArtifact:t=>e.getArtifact(t),readArtifact:t=>e.readArtifact(t),exportReplayBundle:t=>e.exportReplayBundle(t),listRequests:t=>e.listRequests(t),listSessions:()=>e.listSessions(),inspectRequest:t=>e.inspectRequest(t),memorize:t=>e.memorize(t),recallMemories:t=>e.recallMemories(t),listMemories:t=>e.listMemories(t),updateMemory:t=>e.updateMemory(t),archiveMemory:(t,s)=>e.archiveMemory(t,s),listApprovals:t=>e.listApprovals(t),getApproval:t=>e.getApproval(t),resolveApproval:(t,s)=>e.resolveApproval(t,s),cancel:(t,s)=>e.cancel(t,s),deleteRequest:t=>e.deleteRequest(t),deleteSession:t=>e.deleteSession(t),stop:()=>e.stop()}}