stable-harness 0.0.63 → 0.0.65

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.
@@ -7,6 +7,10 @@ export type RuntimeInventoryRepairLayer = "agent" | "workflow_route" | "workflow
7
7
  export type RuntimeInventoryRepairStatus = "repaired" | "blocked";
8
8
  export type RuntimeRepairLayer = "adapter_error" | "result_output" | "execution_contract" | "evidence_synthesis";
9
9
  export type RuntimeRepairOutcome = "retried" | "synthesized" | "blocked";
10
+ export type RuntimeRepairDiagnostics = {
11
+ outputPreview?: string;
12
+ toolCandidateIds?: string[];
13
+ };
10
14
  export type RuntimeInventoryRepairDiagnostic = {
11
15
  layer: RuntimeInventoryRepairLayer;
12
16
  owner: "stable_runtime_policy" | "protocol_adapter" | "upstream_backend" | "workspace_config";
@@ -77,6 +81,7 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
77
81
  layer: RuntimeRepairLayer;
78
82
  attempt?: number;
79
83
  reason?: string;
84
+ diagnostics?: RuntimeRepairDiagnostics;
80
85
  } | {
81
86
  type: "runtime.repair.completed";
82
87
  requestId: string;
@@ -86,6 +91,7 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
86
91
  outcome: RuntimeRepairOutcome;
87
92
  attempt?: number;
88
93
  reason?: string;
94
+ diagnostics?: RuntimeRepairDiagnostics;
89
95
  } | {
90
96
  type: "runtime.inventory.repair";
91
97
  requestId: string;
@@ -1 +1 @@
1
- import{assertNoRawToolCallOutput as e,assertNoToolExecutionErrorOutput as t,buildEvidenceSynthesisOutput as r,buildResultRecoveryRequest as o,containsRawToolCallOutput as l,rawToolCallFailureMessage as a,toolCallRecoveryEnabled as u}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(s){let i=s.result,n=s.request;const c=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,r="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,o="object"!=typeof r||null===r||Array.isArray(r)?void 0:r.maxResultRecoveryAttempts;return"number"==typeof o&&Number.isInteger(o)&&o>0?o:3}(s.recoveryPolicy);let y=0;for(let e=0;e<c;e+=1){const t=s.store.getRun(s.requestId)?.events??[],r=o({request:n,output:i.text,events:t.slice(y),availableToolIds:s.agent.tools,policy:s.recoveryPolicy});if(!r)break;n=r,y=s.store.getRun(s.requestId)?.events.length??0,emitRepair(s,"runtime.repair.started","result_output",e+1,"recoverable_result_output"),i=await s.runAdapter(r),emitRepair(s,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried")}return function finalizeRecoveredOutput(o,s){if(!u(o.recoveryPolicy))return s;let i=!1;l(s.text,o.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(o.request.metadata)&&(s={...s,text:a(),metadata:{...s.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(o,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked"));const n=r({request:o.request,output:s.text,events:o.store.getRun(o.requestId)?.events??[],policy:o.recoveryPolicy});return n&&(i=!0,s={...s,text:n,metadata:{...s.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(o,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),i||(e(s.text,o.recoveryPolicy),t(s.text,o.recoveryPolicy)),s}(s,i)}function emitRepair(e,t,r,o,l,a){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:r,attempt:o,reason:l};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:a??"retried"})}
1
+ import{assertNoRawToolCallOutput as e,assertNoToolExecutionErrorOutput as t,buildEvidenceSynthesisOutput as o,buildResultRecoveryRequest as r,containsRawToolCallOutput as a,rawToolCallFailureMessage as l,rawToolCallOutputPreview as s,toolCallRecoveryEnabled as i}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(s){let u=s.result,n=s.request;const c=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,o="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,r="object"!=typeof o||null===o||Array.isArray(o)?void 0:o.maxResultRecoveryAttempts;return"number"==typeof r&&Number.isInteger(r)&&r>0?r:3}(s.recoveryPolicy);let p=0;for(let e=0;e<c;e+=1){const t=s.store.getRun(s.requestId)?.events??[],o=r({request:n,output:u.text,events:t.slice(p),availableToolIds:s.agent.tools,policy:s.recoveryPolicy});if(!o)break;n=o,p=s.store.getRun(s.requestId)?.events.length??0,emitRepair(s,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(u.text,s.agent.tools)),u=await s.runAdapter(o),emitRepair(s,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(u.text,s.agent.tools))}return function finalizeRecoveredOutput(r,s){if(!i(r.recoveryPolicy))return s;let u=!1;if(a(s.text,r.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(r.request.metadata)){const e=s.text;s={...s,text:l(),metadata:{...s.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(r,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(e,r.agent.tools))}const n=o({request:r.request,output:s.text,events:r.store.getRun(r.requestId)?.events??[],policy:r.recoveryPolicy});return n&&(u=!0,s={...s,text:n,metadata:{...s.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(r,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),u||(a(s.text,r.recoveryPolicy)&&emitRepair(r,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(s.text,r.agent.tools)),e(s.text,r.recoveryPolicy),t(s.text,r.recoveryPolicy)),s}(s,u)}function emitRepair(e,t,o,r,a,l,s){const i={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...s?{diagnostics:s}:{}};e.emit("runtime.repair.started"===t?{type:t,...i}:{type:t,...i,outcome:l??"retried"})}function repairDiagnostics(e,t){return{outputPreview:s(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])new RegExp(`(?:^|[^A-Za-z0-9_-])${escapeRegexp(r)}(?:$|[^A-Za-z0-9_-])`,"u").test(e)&&o.add(r);return[...o]}function escapeRegexp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}
@@ -1 +1 @@
1
- export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):t.type.startsWith("runtime.repair.")?projectSingleSpan(e,t,r,"adapter",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.repair.started"===e.type||"runtime.repair.completed"===e.type?base(e,"adapter",e.type,{layer:e.layer,..."outcome"in e?{outcome:e.outcome}:{},..."attempt"in e?{attempt:e.attempt}:{},..."reason"in e?{reason:e.reason}:{}}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
1
+ export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):t.type.startsWith("runtime.repair.")?projectSingleSpan(e,t,r,"adapter",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.repair.started"===e.type||"runtime.repair.completed"===e.type?base(e,"adapter",e.type,{layer:e.layer,..."outcome"in e?{outcome:e.outcome}:{},..."attempt"in e?{attempt:e.attempt}:{},..."reason"in e?{reason:e.reason}:{},...e.diagnostics?{diagnostics:e.diagnostics}:{}}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
@@ -1,5 +1,5 @@
1
1
  import { type IncomingMessage, type ServerResponse } from "node:http";
2
- import type { StableHarnessRuntime } from "@stable-harness/core";
2
+ import { type StableHarnessRuntime } from "@stable-harness/core";
3
3
  export type OpenAiCompatibleServerOptions = {
4
4
  bearerToken?: string;
5
5
  corsOrigins?: string[];
@@ -1 +1 @@
1
- import{createServer as e}from"node:http";import{createCapabilitiesResponse as r,createModelsResponse as t,resolveAgentId as o,toChatCompletion as n,toRuntimeRequest as a}from"./openai-payload.js";import{createContentChunk as s,createRoleChunk as i,createStopChunk as d,missingFinalDelta as c,writeChatSse as l,writeRuntimeStreamEvent as u,writeSseHeaders as p}from"./openai-stream.js";export function createOpenAiCompatibleHttpServer(f,m={}){const h=function resolveServerOptions(e,r){const t=function readOpenAiProtocolConfig(e){const r=readRecord(e)??{};return readRecord(r.openaiCompatible)??readRecord(r["openai-compatible"])??readRecord(r.openai)??{}}(e.getRuntimePolicy().protocols);return{bearerToken:r.bearerToken??readConfigString(t.bearerToken),corsOrigins:r.corsOrigins??(o=t.corsOrigins,Array.isArray(o)?o.filter(e=>"string"==typeof e&&e.trim().length>0):void 0),modelAgentMap:r.modelAgentMap??readStringRecord(t.modelAgentMap),defaultModel:r.defaultModel??readConfigString(t.defaultModel)};var o}(f,m);return e(async(e,m)=>{try{if(function applyCorsHeaders(e,r,t){const o=function allowedCorsOrigin(e,r){if(e)return r.corsOrigins?.includes("*")?"*":r.corsOrigins?.includes(e)||function isLoopbackOrigin(e){try{const r=new URL(e);return"http:"===r.protocol&&["localhost","127.0.0.1","[::1]"].includes(r.hostname)}catch{return!1}}(e)?e:void 0}(e.headers.origin,t);o&&(r.setHeader("access-control-allow-origin",o),r.setHeader("vary","origin"))}(e,m,h),function handleCors(e,r){return"OPTIONS"===e.method&&(r.writeHead(204,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),r.end(),!0)}(e,m))return;if(!function isAuthorized(e,r){return!r.bearerToken||e.headers.authorization===`Bearer ${r.bearerToken}`}(e,h))return void sendJson(m,401,{error:{message:"unauthorized",type:"invalid_request_error"}});if("GET"===e.method&&"/v1/models"===e.url)return void sendJson(m,200,t(f,h));if("GET"===e.method&&"/v1/capabilities"===e.url)return void sendJson(m,200,r());const v=function readApprovalList(e){if(!e?.startsWith("/v1/approvals"))return;const r=new URL(e,"http://stable-harness.local");if("/v1/approvals"!==r.pathname)return;const t=r.searchParams.get("status");return{status:"pending"===t||"approved"===t||"rejected"===t?t:void 0}}(e.url);if("GET"===e.method&&v)return void sendJson(m,200,{data:await f.listApprovals(v.status)});const g=function readApprovalDecision(e){const r=(e??"").match(/^\/v1\/approvals\/([^/]+)\/(approve|reject)$/u);if(r?.[1]&&r[2])return{id:decodeURIComponent(r[1]),status:"approve"===r[2]?"approved":"rejected"}}(e.url);if("POST"===e.method&&g){const e=await f.resolveApproval(g.id,g.status);return void sendJson(m,e?200:404,e?{data:e}:{error:{message:"approval_not_found",type:"invalid_request_error"}})}if("POST"===e.method&&"/v1/chat/completions"===e.url)return void await async function handleChatCompletion(e,r,t,f){const m=await async function readJson(e){const r=[];for await(const t of e)r.push(Buffer.isBuffer(t)?t:Buffer.from(t));return 0===r.length?{}:JSON.parse(Buffer.concat(r).toString("utf8"))}(r);if(m.model&&!o(m.model,e,f))return void sendJson(t,404,{error:{message:`model_not_found: ${m.model}`,type:"invalid_request_error"}});const h=a(m,e,f,{sessionId:readHeaderString(r.headers["x-stable-harness-session-id"])});if(m.stream)return void await async function streamChatCompletion(e,r,t,o){p(r,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),l(r,i(o.requestId,t.model));let n="";const a=e.subscribe(e=>{e.requestId===o.requestId&&(n+=u(r,e,o.requestId,t.model)??"")});try{const a=await e.request(o),i=c(n,a.output);i&&l(r,s(o.requestId,t.model,i)),l(r,d(o.requestId,t.model)),r.write("data: [DONE]\n\n"),r.end()}finally{a()}}(e,t,m,h);const v=await e.request(h);sendJson(t,200,n(m,v))}(f,e,m,h);sendJson(m,404,{error:{message:"not_found",type:"invalid_request_error"}})}catch(e){sendJson(m,400,{error:{message:e instanceof Error?e.message:String(e),type:"invalid_request_error"}})}})}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function readStringRecord(e){const r=readRecord(e);if(r)return Object.fromEntries(Object.entries(r).filter(e=>"string"==typeof e[1]))}function readConfigString(e){if("string"!=typeof e||!e.trim())return;const r=e.match(/^\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-(.*))?\}$/u);return r?process.env[r[1]]??r[2]:e}function readHeaderString(e){const r=Array.isArray(e)?e[0]:e;return r&&r.trim()?r:void 0}function sendJson(e,r,t,o){e.writeHead(r,{"content-type":"application/json","access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),e.end(JSON.stringify(t))}
1
+ import{createServer as e}from"node:http";import{projectRuntimeTrace as r}from"@stable-harness/core";import{createCapabilitiesResponse as t,createModelsResponse as o,resolveAgentId as n,toChatCompletion as s,toRuntimeErrorResponse as a,toRuntimeRequest as i}from"./openai-payload.js";import{createContentChunk as d,createRoleChunk as c,createStopChunk as u,missingFinalDelta as l,writeChatSse as p,writeErrorSse as f,writeRuntimeStreamEvent as m,writeSseHeaders as h}from"./openai-stream.js";export function createOpenAiCompatibleHttpServer(v,g={}){const y=function resolveServerOptions(e,r){const t=function readOpenAiProtocolConfig(e){const r=readRecord(e)??{};return readRecord(r.openaiCompatible)??readRecord(r["openai-compatible"])??readRecord(r.openai)??{}}(e.getRuntimePolicy().protocols);return{bearerToken:r.bearerToken??readConfigString(t.bearerToken),corsOrigins:r.corsOrigins??(o=t.corsOrigins,Array.isArray(o)?o.filter(e=>"string"==typeof e&&e.trim().length>0):void 0),modelAgentMap:r.modelAgentMap??readStringRecord(t.modelAgentMap),defaultModel:r.defaultModel??readConfigString(t.defaultModel)};var o}(v,g);return e(async(e,g)=>{try{if(function applyCorsHeaders(e,r,t){const o=function allowedCorsOrigin(e,r){if(e)return r.corsOrigins?.includes("*")?"*":r.corsOrigins?.includes(e)||function isLoopbackOrigin(e){try{const r=new URL(e);return"http:"===r.protocol&&["localhost","127.0.0.1","[::1]"].includes(r.hostname)}catch{return!1}}(e)?e:void 0}(e.headers.origin,t);o&&(r.setHeader("access-control-allow-origin",o),r.setHeader("vary","origin"))}(e,g,y),function handleCors(e,r){return"OPTIONS"===e.method&&(r.writeHead(204,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),r.end(),!0)}(e,g))return;if(!function isAuthorized(e,r){return!r.bearerToken||e.headers.authorization===`Bearer ${r.bearerToken}`}(e,y))return void sendJson(g,401,{error:{message:"unauthorized",type:"invalid_request_error"}});if("GET"===e.method&&"/v1/models"===e.url)return void sendJson(g,200,o(v,y));if("GET"===e.method&&"/v1/capabilities"===e.url)return void sendJson(g,200,t());const O=function readTraceRequestId(e){const r=(e??"").match(/^\/v1\/stable-harness\/runs\/([^/]+)\/trace$/u);return r?.[1]?decodeURIComponent(r[1]):void 0}(e.url);if("GET"===e.method&&O){const e=v.getRun(O);return void sendJson(g,e?200:404,e?r(e):{error:{message:"run_not_found",type:"invalid_request_error"}})}const S=function readApprovalList(e){if(!e?.startsWith("/v1/approvals"))return;const r=new URL(e,"http://stable-harness.local");if("/v1/approvals"!==r.pathname)return;const t=r.searchParams.get("status");return{status:"pending"===t||"approved"===t||"rejected"===t?t:void 0}}(e.url);if("GET"===e.method&&S)return void sendJson(g,200,{data:await v.listApprovals(S.status)});const R=function readApprovalDecision(e){const r=(e??"").match(/^\/v1\/approvals\/([^/]+)\/(approve|reject)$/u);if(r?.[1]&&r[2])return{id:decodeURIComponent(r[1]),status:"approve"===r[2]?"approved":"rejected"}}(e.url);if("POST"===e.method&&R){const e=await v.resolveApproval(R.id,R.status);return void sendJson(g,e?200:404,e?{data:e}:{error:{message:"approval_not_found",type:"invalid_request_error"}})}if("POST"===e.method&&"/v1/chat/completions"===e.url)return void await async function handleChatCompletion(e,r,t,o){const v=await async function readJson(e){const r=[];for await(const t of e)r.push(Buffer.isBuffer(t)?t:Buffer.from(t));return 0===r.length?{}:JSON.parse(Buffer.concat(r).toString("utf8"))}(r);if(v.model&&!n(v.model,e,o))return void sendJson(t,404,{error:{message:`model_not_found: ${v.model}`,type:"invalid_request_error"}});const g=i(v,e,o,{sessionId:readHeaderString(r.headers["x-stable-harness-session-id"])});if(v.stream)return void await async function streamChatCompletion(e,r,t,o){h(r,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),p(r,c(o.requestId,t.model));let n="";const s=e.subscribe(e=>{e.requestId===o.requestId&&(n+=m(r,e,o.requestId,t.model)??"")});try{const s=await e.request(o);if(isRuntimeError(s))return f(r,a(s)),r.write("data: [DONE]\n\n"),void r.end();const i=l(n,s.output);i&&p(r,d(o.requestId,t.model,i)),p(r,u(o.requestId,t.model)),r.write("data: [DONE]\n\n"),r.end()}finally{s()}}(e,t,v,g);const y=await e.request(g);isRuntimeError(y)?sendJson(t,function runtimeErrorStatus(e){return"cancelled"===e.state?409:500}(y),a(y)):sendJson(t,200,s(v,y))}(v,e,g,y);sendJson(g,404,{error:{message:"not_found",type:"invalid_request_error"}})}catch(e){sendJson(g,400,{error:{message:e instanceof Error?e.message:String(e),type:"invalid_request_error"}})}})}function isRuntimeError(e){return"failed"===e.state||"cancelled"===e.state}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function readStringRecord(e){const r=readRecord(e);if(r)return Object.fromEntries(Object.entries(r).filter(e=>"string"==typeof e[1]))}function readConfigString(e){if("string"!=typeof e||!e.trim())return;const r=e.match(/^\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-(.*))?\}$/u);return r?process.env[r[1]]??r[2]:e}function readHeaderString(e){const r=Array.isArray(e)?e[0]:e;return r&&r.trim()?r:void 0}function sendJson(e,r,t,o){e.writeHead(r,{"content-type":"application/json","access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),e.end(JSON.stringify(t))}
@@ -47,6 +47,7 @@ export declare function createCapabilitiesResponse(): {
47
47
  endpoints: string[];
48
48
  streaming: boolean;
49
49
  toolProgressEvents: boolean;
50
+ runtimeTrace: boolean;
50
51
  };
51
52
  export declare function toChatCompletion(body: ChatCompletionRequest, result: RuntimeResponse): {
52
53
  id: string;
@@ -72,3 +73,17 @@ export declare function toChatCompletion(body: ChatCompletionRequest, result: Ru
72
73
  state: import("@stable-harness/core").RuntimeRecordState;
73
74
  };
74
75
  };
76
+ export declare function toRuntimeErrorResponse(result: RuntimeResponse): {
77
+ error: {
78
+ message: string;
79
+ type: string;
80
+ code: string;
81
+ param: null;
82
+ };
83
+ metadata: {
84
+ requestId: string;
85
+ sessionId: string;
86
+ agentId: string;
87
+ state: import("@stable-harness/core").RuntimeRecordState;
88
+ };
89
+ };
@@ -1 +1 @@
1
- import{randomUUID as e}from"node:crypto";export function toRuntimeRequest(t,n,s,o={}){const r=function messagesToInput(e){if(!Array.isArray(e)||0===e.length)throw new Error("messages must be a non-empty array");return e.map(e=>`${e.role??"user"}: ${contentToText(e.content)}`).join("\n\n")}(t.messages),a=`chatcmpl-${e()}`,i=o.sessionId??function readSessionId(e){const t=e?.sessionId??e?.session_id??e?.conversationId??e?.conversation_id;return"string"==typeof t&&t.trim()?t:void 0}(t.metadata),c=normalizeOpenAiMessages(t.messages),u=i?function prependSessionMessages(e,t,n){if(function hasClientHistory(e){return e.some(e=>"assistant"===e.role)||e.filter(e=>"user"===e.role).length>1}(n))return n;const s=e.listRequests({sessionId:t,state:"completed"}).flatMap(t=>function inspectSessionTurn(e,t){const n=e.inspectRequest(t),s=n?.output?.trim(),o=function lastUserMessage(e){return normalizeOpenAiMessages(Array.isArray(e)?e:void 0).filter(e=>"user"===e.role&&e.content.trim()).at(-1)}(n?.metadata?.openaiMessages)?.content;return o&&s?[{role:"user",content:o},{role:"assistant",content:s}]:[]}(e,t.requestId)).slice(-12);return s.length>0?[...s,...n]:n}(n,i,c):c;return{input:r,requestId:a,agentId:resolveAgentId(t.model,n,s),...i?{sessionId:i}:{},metadata:{protocol:"openai-compatible",openaiStream:!0===t.stream,openaiMessages:u,openaiSessionHistory:u.length>c.length,model:t.model,user:t.user,clientMetadata:t.metadata}}}export function resolveAgentId(e,t,n){if(!e)return;const s=n.modelAgentMap?.[e];return s||(t.inspect().agents.includes(e)?e:void 0)}export function createModelsResponse(e,t){const n=Object.keys(t.modelAgentMap??{});return{object:"list",data:[...new Set([...e.inspect().agents,...n])].sort().map(e=>({id:e,object:"model",created:0,owned_by:"stable-harness"}))}}export function createCapabilitiesResponse(){return{object:"stable_harness.capabilities",endpoints:["/v1/models","/v1/chat/completions","/v1/capabilities"],streaming:!0,toolProgressEvents:!0}}export function toChatCompletion(e,t){return{id:t.requestId,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:e.model??t.agentId,choices:[{index:0,message:{role:"assistant",content:t.output},finish_reason:"stop"}],usage:estimateUsage(e.messages,t.output),metadata:{sessionId:t.sessionId,agentId:t.agentId,state:t.state}}}function normalizeOpenAiMessages(e){return Array.isArray(e)?e.map(e=>({role:e.role??"user",content:contentToText(e.content)})):[]}function contentToText(e){if("string"==typeof e)return e;if(!Array.isArray(e))throw new Error("message content must be a string or content part array");return e.map(contentPartToText).join("\n")}function contentPartToText(e){if("object"!=typeof e||null===e)throw new Error("message content parts must be objects");const t=e;if("text"===t.type&&"string"==typeof t.text)return t.text;const n=t.image_url;if("image_url"===t.type&&"string"==typeof n?.url)return`[image:${n.url}]`;throw new Error("unsupported_content_type")}function estimateUsage(e,t){const n=estimateTokens(Array.isArray(e)?e.map(e=>contentToText(e.content)).join("\n"):""),s=estimateTokens(t);return{prompt_tokens:n,completion_tokens:s,total_tokens:n+s}}function estimateTokens(e){return e.trim()?Math.ceil(1.3*e.trim().split(/\s+/u).length):0}
1
+ import{randomUUID as e}from"node:crypto";export function toRuntimeRequest(t,n,s,o={}){const r=function messagesToInput(e){if(!Array.isArray(e)||0===e.length)throw new Error("messages must be a non-empty array");return e.map(e=>`${e.role??"user"}: ${contentToText(e.content)}`).join("\n\n")}(t.messages),a=`chatcmpl-${e()}`,i=o.sessionId??function readSessionId(e){const t=e?.sessionId??e?.session_id??e?.conversationId??e?.conversation_id;return"string"==typeof t&&t.trim()?t:void 0}(t.metadata),c=normalizeOpenAiMessages(t.messages),u=i?function prependSessionMessages(e,t,n){if(function hasClientHistory(e){return e.some(e=>"assistant"===e.role)||e.filter(e=>"user"===e.role).length>1}(n))return n;const s=e.listRequests({sessionId:t,state:"completed"}).flatMap(t=>function inspectSessionTurn(e,t){const n=e.inspectRequest(t),s=n?.output?.trim(),o=function lastUserMessage(e){return normalizeOpenAiMessages(Array.isArray(e)?e:void 0).filter(e=>"user"===e.role&&e.content.trim()).at(-1)}(n?.metadata?.openaiMessages)?.content;return o&&s?[{role:"user",content:o},{role:"assistant",content:s}]:[]}(e,t.requestId)).slice(-12);return s.length>0?[...s,...n]:n}(n,i,c):c;return{input:r,requestId:a,agentId:resolveAgentId(t.model,n,s),...i?{sessionId:i}:{},metadata:{protocol:"openai-compatible",openaiStream:!0===t.stream,openaiMessages:u,openaiSessionHistory:u.length>c.length,model:t.model,user:t.user,clientMetadata:t.metadata}}}export function resolveAgentId(e,t,n){if(!e)return;const s=n.modelAgentMap?.[e];return s||(t.inspect().agents.includes(e)?e:void 0)}export function createModelsResponse(e,t){const n=Object.keys(t.modelAgentMap??{});return{object:"list",data:[...new Set([...e.inspect().agents,...n])].sort().map(e=>({id:e,object:"model",created:0,owned_by:"stable-harness"}))}}export function createCapabilitiesResponse(){return{object:"stable_harness.capabilities",endpoints:["/v1/models","/v1/chat/completions","/v1/capabilities","/v1/stable-harness/runs/{request_id}/trace"],streaming:!0,toolProgressEvents:!0,runtimeTrace:!0}}export function toChatCompletion(e,t){return{id:t.requestId,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:e.model??t.agentId,choices:[{index:0,message:{role:"assistant",content:t.output},finish_reason:"stop"}],usage:estimateUsage(e.messages,t.output),metadata:{sessionId:t.sessionId,agentId:t.agentId,state:t.state}}}export function toRuntimeErrorResponse(e){const t="cancelled"===e.state;return{error:{message:e.output||(t?"Runtime request was cancelled.":"Runtime request failed."),type:t?"request_cancelled":"server_error",code:t?"runtime_cancelled":"runtime_failed",param:null},metadata:{requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,state:e.state}}}function normalizeOpenAiMessages(e){return Array.isArray(e)?e.map(e=>({role:e.role??"user",content:contentToText(e.content)})):[]}function contentToText(e){if("string"==typeof e)return e;if(!Array.isArray(e))throw new Error("message content must be a string or content part array");return e.map(contentPartToText).join("\n")}function contentPartToText(e){if("object"!=typeof e||null===e)throw new Error("message content parts must be objects");const t=e;if("text"===t.type&&"string"==typeof t.text)return t.text;const n=t.image_url;if("image_url"===t.type&&"string"==typeof n?.url)return`[image:${n.url}]`;throw new Error("unsupported_content_type")}function estimateUsage(e,t){const n=estimateTokens(Array.isArray(e)?e.map(e=>contentToText(e.content)).join("\n"):""),s=estimateTokens(t);return{prompt_tokens:n,completion_tokens:s,total_tokens:n+s}}function estimateTokens(e){return e.trim()?Math.ceil(1.3*e.trim().split(/\s+/u).length):0}
@@ -37,3 +37,4 @@ export declare function createStopChunk(id: string, model: string | undefined):
37
37
  export declare function writeRuntimeStreamEvent(response: ServerResponse, event: RuntimeEvent, id: string, model: string | undefined): string | undefined;
38
38
  export declare function writeSseHeaders(response: ServerResponse, headers: Record<string, string>): void;
39
39
  export declare function writeChatSse(response: ServerResponse, body: unknown): void;
40
+ export declare function writeErrorSse(response: ServerResponse, body: unknown): void;
@@ -1 +1 @@
1
- export function missingFinalDelta(e,t){return e?!t||e.includes(t)?"":t.startsWith(e)?t.slice(e.length):t:t}export function createRoleChunk(e,t){return createChunk(e,t,{role:"assistant"},null)}export function createContentChunk(e,t,n){return createChunk(e,t,{content:n},null)}export function createStopChunk(e,t){return createChunk(e,t,{},"stop")}export function writeRuntimeStreamEvent(e,t,n,r){const o=function readAdapterDelta(e){if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event;return"deepagents.message.coordinator_delta"!==t.eventType&&"agent.output.delta"!==t.phase||"string"!=typeof t.text?void 0:t.text}(t);if(o)return writeChatSse(e,createContentChunk(n,r,o)),o;!function writeProgressEvent(e,t){const n=function readToolProgress(e){if("runtime.tool.direct.started"===e.type||"runtime.tool.direct.completed"===e.type)return{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:e.type,tool_id:e.toolId};if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event,n=function readToolProgressType(e){return"deepagents.tool_execution.start"===e.eventType?"deepagents.tool_execution.start":"deepagents.tool_execution.result"===e.eventType?"deepagents.tool_execution.result":"agent.tool.start"===e.phase||"agent.tool.result"===e.phase?e.phase:void 0}(t),r="string"==typeof t.toolId?t.toolId:void 0;return n&&r?{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:n,tool_id:r,adapter:t.adapter}:void 0}(t);n&&writeSse(e,"stable_harness.tool.progress",n)}(e,t),function writeNarrationEvent(e,t){"runtime.progress.narration"===t.type&&writeSse(e,"stable_harness.progress.narration",{request_id:t.requestId,session_id:t.sessionId,agent_id:t.agentId,type:t.type,message:t.message,provider:t.provider,source_event_types:t.sourceEventTypes,source_event_ids:t.sourceEventIds,model:t.model,style:t.style})}(e,t)}export function writeSseHeaders(e,t){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive",...t})}export function writeChatSse(e,t){e.write(`data: ${JSON.stringify(t)}\n\n`)}function createChunk(e,t,n,r){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:t??"stable-harness",choices:[{index:0,delta:n,finish_reason:r}]}}function writeSse(e,t,n){e.write(`event: ${t}\n`),e.write(`data: ${JSON.stringify(n)}\n\n`)}
1
+ export function missingFinalDelta(e,t){return e?!t||e.includes(t)?"":t.startsWith(e)?t.slice(e.length):t:t}export function createRoleChunk(e,t){return createChunk(e,t,{role:"assistant"},null)}export function createContentChunk(e,t,n){return createChunk(e,t,{content:n},null)}export function createStopChunk(e,t){return createChunk(e,t,{},"stop")}export function writeRuntimeStreamEvent(e,t,n,r){const o=function readAdapterDelta(e){if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event;return"deepagents.message.coordinator_delta"!==t.eventType&&"agent.output.delta"!==t.phase||"string"!=typeof t.text?void 0:t.text}(t);if(o)return writeChatSse(e,createContentChunk(n,r,o)),o;!function writeProgressEvent(e,t){const n=function readToolProgress(e){if("runtime.tool.direct.started"===e.type||"runtime.tool.direct.completed"===e.type)return{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:e.type,tool_id:e.toolId};if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event,n=function readToolProgressType(e){return"deepagents.tool_execution.start"===e.eventType?"deepagents.tool_execution.start":"deepagents.tool_execution.result"===e.eventType?"deepagents.tool_execution.result":"agent.tool.start"===e.phase||"agent.tool.result"===e.phase?e.phase:void 0}(t),r="string"==typeof t.toolId?t.toolId:void 0;return n&&r?{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:n,tool_id:r,adapter:t.adapter}:void 0}(t);n&&writeSse(e,"stable_harness.tool.progress",n)}(e,t),function writeNarrationEvent(e,t){"runtime.progress.narration"===t.type&&writeSse(e,"stable_harness.progress.narration",{request_id:t.requestId,session_id:t.sessionId,agent_id:t.agentId,type:t.type,message:t.message,provider:t.provider,source_event_types:t.sourceEventTypes,source_event_ids:t.sourceEventIds,model:t.model,style:t.style})}(e,t)}export function writeSseHeaders(e,t){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive",...t})}export function writeChatSse(e,t){e.write(`data: ${JSON.stringify(t)}\n\n`)}export function writeErrorSse(e,t){writeSse(e,"error",t)}function createChunk(e,t,n,r){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:t??"stable-harness",choices:[{index:0,delta:n,finish_reason:r}]}}function writeSse(e,t,n){e.write(`event: ${t}\n`),e.write(`data: ${JSON.stringify(n)}\n\n`)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stable-harness",
3
- "version": "0.0.63",
3
+ "version": "0.0.65",
4
4
  "type": "module",
5
5
  "description": "Stable application runtime and operator control plane for agent workspaces.",
6
6
  "license": "Apache-2.0",
@@ -7,6 +7,10 @@ export type RuntimeInventoryRepairLayer = "agent" | "workflow_route" | "workflow
7
7
  export type RuntimeInventoryRepairStatus = "repaired" | "blocked";
8
8
  export type RuntimeRepairLayer = "adapter_error" | "result_output" | "execution_contract" | "evidence_synthesis";
9
9
  export type RuntimeRepairOutcome = "retried" | "synthesized" | "blocked";
10
+ export type RuntimeRepairDiagnostics = {
11
+ outputPreview?: string;
12
+ toolCandidateIds?: string[];
13
+ };
10
14
  export type RuntimeInventoryRepairDiagnostic = {
11
15
  layer: RuntimeInventoryRepairLayer;
12
16
  owner: "stable_runtime_policy" | "protocol_adapter" | "upstream_backend" | "workspace_config";
@@ -77,6 +81,7 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
77
81
  layer: RuntimeRepairLayer;
78
82
  attempt?: number;
79
83
  reason?: string;
84
+ diagnostics?: RuntimeRepairDiagnostics;
80
85
  } | {
81
86
  type: "runtime.repair.completed";
82
87
  requestId: string;
@@ -86,6 +91,7 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
86
91
  outcome: RuntimeRepairOutcome;
87
92
  attempt?: number;
88
93
  reason?: string;
94
+ diagnostics?: RuntimeRepairDiagnostics;
89
95
  } | {
90
96
  type: "runtime.inventory.repair";
91
97
  requestId: string;
@@ -1 +1 @@
1
- import{assertNoRawToolCallOutput as e,assertNoToolExecutionErrorOutput as t,buildEvidenceSynthesisOutput as r,buildResultRecoveryRequest as o,containsRawToolCallOutput as l,rawToolCallFailureMessage as a,toolCallRecoveryEnabled as u}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(s){let i=s.result,n=s.request;const c=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,r="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,o="object"!=typeof r||null===r||Array.isArray(r)?void 0:r.maxResultRecoveryAttempts;return"number"==typeof o&&Number.isInteger(o)&&o>0?o:3}(s.recoveryPolicy);let y=0;for(let e=0;e<c;e+=1){const t=s.store.getRun(s.requestId)?.events??[],r=o({request:n,output:i.text,events:t.slice(y),availableToolIds:s.agent.tools,policy:s.recoveryPolicy});if(!r)break;n=r,y=s.store.getRun(s.requestId)?.events.length??0,emitRepair(s,"runtime.repair.started","result_output",e+1,"recoverable_result_output"),i=await s.runAdapter(r),emitRepair(s,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried")}return function finalizeRecoveredOutput(o,s){if(!u(o.recoveryPolicy))return s;let i=!1;l(s.text,o.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(o.request.metadata)&&(s={...s,text:a(),metadata:{...s.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(o,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked"));const n=r({request:o.request,output:s.text,events:o.store.getRun(o.requestId)?.events??[],policy:o.recoveryPolicy});return n&&(i=!0,s={...s,text:n,metadata:{...s.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(o,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),i||(e(s.text,o.recoveryPolicy),t(s.text,o.recoveryPolicy)),s}(s,i)}function emitRepair(e,t,r,o,l,a){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:r,attempt:o,reason:l};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:a??"retried"})}
1
+ import{assertNoRawToolCallOutput as e,assertNoToolExecutionErrorOutput as t,buildEvidenceSynthesisOutput as o,buildResultRecoveryRequest as r,containsRawToolCallOutput as a,rawToolCallFailureMessage as l,rawToolCallOutputPreview as s,toolCallRecoveryEnabled as i}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(s){let u=s.result,n=s.request;const c=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,o="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,r="object"!=typeof o||null===o||Array.isArray(o)?void 0:o.maxResultRecoveryAttempts;return"number"==typeof r&&Number.isInteger(r)&&r>0?r:3}(s.recoveryPolicy);let p=0;for(let e=0;e<c;e+=1){const t=s.store.getRun(s.requestId)?.events??[],o=r({request:n,output:u.text,events:t.slice(p),availableToolIds:s.agent.tools,policy:s.recoveryPolicy});if(!o)break;n=o,p=s.store.getRun(s.requestId)?.events.length??0,emitRepair(s,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(u.text,s.agent.tools)),u=await s.runAdapter(o),emitRepair(s,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(u.text,s.agent.tools))}return function finalizeRecoveredOutput(r,s){if(!i(r.recoveryPolicy))return s;let u=!1;if(a(s.text,r.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(r.request.metadata)){const e=s.text;s={...s,text:l(),metadata:{...s.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(r,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(e,r.agent.tools))}const n=o({request:r.request,output:s.text,events:r.store.getRun(r.requestId)?.events??[],policy:r.recoveryPolicy});return n&&(u=!0,s={...s,text:n,metadata:{...s.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(r,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),u||(a(s.text,r.recoveryPolicy)&&emitRepair(r,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(s.text,r.agent.tools)),e(s.text,r.recoveryPolicy),t(s.text,r.recoveryPolicy)),s}(s,u)}function emitRepair(e,t,o,r,a,l,s){const i={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...s?{diagnostics:s}:{}};e.emit("runtime.repair.started"===t?{type:t,...i}:{type:t,...i,outcome:l??"retried"})}function repairDiagnostics(e,t){return{outputPreview:s(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])new RegExp(`(?:^|[^A-Za-z0-9_-])${escapeRegexp(r)}(?:$|[^A-Za-z0-9_-])`,"u").test(e)&&o.add(r);return[...o]}function escapeRegexp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}
@@ -1 +1 @@
1
- export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):t.type.startsWith("runtime.repair.")?projectSingleSpan(e,t,r,"adapter",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.repair.started"===e.type||"runtime.repair.completed"===e.type?base(e,"adapter",e.type,{layer:e.layer,..."outcome"in e?{outcome:e.outcome}:{},..."attempt"in e?{attempt:e.attempt}:{},..."reason"in e?{reason:e.reason}:{}}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
1
+ export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):t.type.startsWith("runtime.repair.")?projectSingleSpan(e,t,r,"adapter",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.repair.started"===e.type||"runtime.repair.completed"===e.type?base(e,"adapter",e.type,{layer:e.layer,..."outcome"in e?{outcome:e.outcome}:{},..."attempt"in e?{attempt:e.attempt}:{},..."reason"in e?{reason:e.reason}:{},...e.diagnostics?{diagnostics:e.diagnostics}:{}}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
@@ -1,5 +1,5 @@
1
1
  import { type IncomingMessage, type ServerResponse } from "node:http";
2
- import type { StableHarnessRuntime } from "@stable-harness/core";
2
+ import { type StableHarnessRuntime } from "@stable-harness/core";
3
3
  export type OpenAiCompatibleServerOptions = {
4
4
  bearerToken?: string;
5
5
  corsOrigins?: string[];
@@ -1 +1 @@
1
- import{createServer as e}from"node:http";import{createCapabilitiesResponse as r,createModelsResponse as t,resolveAgentId as o,toChatCompletion as n,toRuntimeRequest as a}from"./openai-payload.js";import{createContentChunk as s,createRoleChunk as i,createStopChunk as d,missingFinalDelta as c,writeChatSse as l,writeRuntimeStreamEvent as u,writeSseHeaders as p}from"./openai-stream.js";export function createOpenAiCompatibleHttpServer(f,m={}){const h=function resolveServerOptions(e,r){const t=function readOpenAiProtocolConfig(e){const r=readRecord(e)??{};return readRecord(r.openaiCompatible)??readRecord(r["openai-compatible"])??readRecord(r.openai)??{}}(e.getRuntimePolicy().protocols);return{bearerToken:r.bearerToken??readConfigString(t.bearerToken),corsOrigins:r.corsOrigins??(o=t.corsOrigins,Array.isArray(o)?o.filter(e=>"string"==typeof e&&e.trim().length>0):void 0),modelAgentMap:r.modelAgentMap??readStringRecord(t.modelAgentMap),defaultModel:r.defaultModel??readConfigString(t.defaultModel)};var o}(f,m);return e(async(e,m)=>{try{if(function applyCorsHeaders(e,r,t){const o=function allowedCorsOrigin(e,r){if(e)return r.corsOrigins?.includes("*")?"*":r.corsOrigins?.includes(e)||function isLoopbackOrigin(e){try{const r=new URL(e);return"http:"===r.protocol&&["localhost","127.0.0.1","[::1]"].includes(r.hostname)}catch{return!1}}(e)?e:void 0}(e.headers.origin,t);o&&(r.setHeader("access-control-allow-origin",o),r.setHeader("vary","origin"))}(e,m,h),function handleCors(e,r){return"OPTIONS"===e.method&&(r.writeHead(204,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),r.end(),!0)}(e,m))return;if(!function isAuthorized(e,r){return!r.bearerToken||e.headers.authorization===`Bearer ${r.bearerToken}`}(e,h))return void sendJson(m,401,{error:{message:"unauthorized",type:"invalid_request_error"}});if("GET"===e.method&&"/v1/models"===e.url)return void sendJson(m,200,t(f,h));if("GET"===e.method&&"/v1/capabilities"===e.url)return void sendJson(m,200,r());const v=function readApprovalList(e){if(!e?.startsWith("/v1/approvals"))return;const r=new URL(e,"http://stable-harness.local");if("/v1/approvals"!==r.pathname)return;const t=r.searchParams.get("status");return{status:"pending"===t||"approved"===t||"rejected"===t?t:void 0}}(e.url);if("GET"===e.method&&v)return void sendJson(m,200,{data:await f.listApprovals(v.status)});const g=function readApprovalDecision(e){const r=(e??"").match(/^\/v1\/approvals\/([^/]+)\/(approve|reject)$/u);if(r?.[1]&&r[2])return{id:decodeURIComponent(r[1]),status:"approve"===r[2]?"approved":"rejected"}}(e.url);if("POST"===e.method&&g){const e=await f.resolveApproval(g.id,g.status);return void sendJson(m,e?200:404,e?{data:e}:{error:{message:"approval_not_found",type:"invalid_request_error"}})}if("POST"===e.method&&"/v1/chat/completions"===e.url)return void await async function handleChatCompletion(e,r,t,f){const m=await async function readJson(e){const r=[];for await(const t of e)r.push(Buffer.isBuffer(t)?t:Buffer.from(t));return 0===r.length?{}:JSON.parse(Buffer.concat(r).toString("utf8"))}(r);if(m.model&&!o(m.model,e,f))return void sendJson(t,404,{error:{message:`model_not_found: ${m.model}`,type:"invalid_request_error"}});const h=a(m,e,f,{sessionId:readHeaderString(r.headers["x-stable-harness-session-id"])});if(m.stream)return void await async function streamChatCompletion(e,r,t,o){p(r,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),l(r,i(o.requestId,t.model));let n="";const a=e.subscribe(e=>{e.requestId===o.requestId&&(n+=u(r,e,o.requestId,t.model)??"")});try{const a=await e.request(o),i=c(n,a.output);i&&l(r,s(o.requestId,t.model,i)),l(r,d(o.requestId,t.model)),r.write("data: [DONE]\n\n"),r.end()}finally{a()}}(e,t,m,h);const v=await e.request(h);sendJson(t,200,n(m,v))}(f,e,m,h);sendJson(m,404,{error:{message:"not_found",type:"invalid_request_error"}})}catch(e){sendJson(m,400,{error:{message:e instanceof Error?e.message:String(e),type:"invalid_request_error"}})}})}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function readStringRecord(e){const r=readRecord(e);if(r)return Object.fromEntries(Object.entries(r).filter(e=>"string"==typeof e[1]))}function readConfigString(e){if("string"!=typeof e||!e.trim())return;const r=e.match(/^\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-(.*))?\}$/u);return r?process.env[r[1]]??r[2]:e}function readHeaderString(e){const r=Array.isArray(e)?e[0]:e;return r&&r.trim()?r:void 0}function sendJson(e,r,t,o){e.writeHead(r,{"content-type":"application/json","access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),e.end(JSON.stringify(t))}
1
+ import{createServer as e}from"node:http";import{projectRuntimeTrace as r}from"@stable-harness/core";import{createCapabilitiesResponse as t,createModelsResponse as o,resolveAgentId as n,toChatCompletion as s,toRuntimeErrorResponse as a,toRuntimeRequest as i}from"./openai-payload.js";import{createContentChunk as d,createRoleChunk as c,createStopChunk as u,missingFinalDelta as l,writeChatSse as p,writeErrorSse as f,writeRuntimeStreamEvent as m,writeSseHeaders as h}from"./openai-stream.js";export function createOpenAiCompatibleHttpServer(v,g={}){const y=function resolveServerOptions(e,r){const t=function readOpenAiProtocolConfig(e){const r=readRecord(e)??{};return readRecord(r.openaiCompatible)??readRecord(r["openai-compatible"])??readRecord(r.openai)??{}}(e.getRuntimePolicy().protocols);return{bearerToken:r.bearerToken??readConfigString(t.bearerToken),corsOrigins:r.corsOrigins??(o=t.corsOrigins,Array.isArray(o)?o.filter(e=>"string"==typeof e&&e.trim().length>0):void 0),modelAgentMap:r.modelAgentMap??readStringRecord(t.modelAgentMap),defaultModel:r.defaultModel??readConfigString(t.defaultModel)};var o}(v,g);return e(async(e,g)=>{try{if(function applyCorsHeaders(e,r,t){const o=function allowedCorsOrigin(e,r){if(e)return r.corsOrigins?.includes("*")?"*":r.corsOrigins?.includes(e)||function isLoopbackOrigin(e){try{const r=new URL(e);return"http:"===r.protocol&&["localhost","127.0.0.1","[::1]"].includes(r.hostname)}catch{return!1}}(e)?e:void 0}(e.headers.origin,t);o&&(r.setHeader("access-control-allow-origin",o),r.setHeader("vary","origin"))}(e,g,y),function handleCors(e,r){return"OPTIONS"===e.method&&(r.writeHead(204,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),r.end(),!0)}(e,g))return;if(!function isAuthorized(e,r){return!r.bearerToken||e.headers.authorization===`Bearer ${r.bearerToken}`}(e,y))return void sendJson(g,401,{error:{message:"unauthorized",type:"invalid_request_error"}});if("GET"===e.method&&"/v1/models"===e.url)return void sendJson(g,200,o(v,y));if("GET"===e.method&&"/v1/capabilities"===e.url)return void sendJson(g,200,t());const O=function readTraceRequestId(e){const r=(e??"").match(/^\/v1\/stable-harness\/runs\/([^/]+)\/trace$/u);return r?.[1]?decodeURIComponent(r[1]):void 0}(e.url);if("GET"===e.method&&O){const e=v.getRun(O);return void sendJson(g,e?200:404,e?r(e):{error:{message:"run_not_found",type:"invalid_request_error"}})}const S=function readApprovalList(e){if(!e?.startsWith("/v1/approvals"))return;const r=new URL(e,"http://stable-harness.local");if("/v1/approvals"!==r.pathname)return;const t=r.searchParams.get("status");return{status:"pending"===t||"approved"===t||"rejected"===t?t:void 0}}(e.url);if("GET"===e.method&&S)return void sendJson(g,200,{data:await v.listApprovals(S.status)});const R=function readApprovalDecision(e){const r=(e??"").match(/^\/v1\/approvals\/([^/]+)\/(approve|reject)$/u);if(r?.[1]&&r[2])return{id:decodeURIComponent(r[1]),status:"approve"===r[2]?"approved":"rejected"}}(e.url);if("POST"===e.method&&R){const e=await v.resolveApproval(R.id,R.status);return void sendJson(g,e?200:404,e?{data:e}:{error:{message:"approval_not_found",type:"invalid_request_error"}})}if("POST"===e.method&&"/v1/chat/completions"===e.url)return void await async function handleChatCompletion(e,r,t,o){const v=await async function readJson(e){const r=[];for await(const t of e)r.push(Buffer.isBuffer(t)?t:Buffer.from(t));return 0===r.length?{}:JSON.parse(Buffer.concat(r).toString("utf8"))}(r);if(v.model&&!n(v.model,e,o))return void sendJson(t,404,{error:{message:`model_not_found: ${v.model}`,type:"invalid_request_error"}});const g=i(v,e,o,{sessionId:readHeaderString(r.headers["x-stable-harness-session-id"])});if(v.stream)return void await async function streamChatCompletion(e,r,t,o){h(r,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),p(r,c(o.requestId,t.model));let n="";const s=e.subscribe(e=>{e.requestId===o.requestId&&(n+=m(r,e,o.requestId,t.model)??"")});try{const s=await e.request(o);if(isRuntimeError(s))return f(r,a(s)),r.write("data: [DONE]\n\n"),void r.end();const i=l(n,s.output);i&&p(r,d(o.requestId,t.model,i)),p(r,u(o.requestId,t.model)),r.write("data: [DONE]\n\n"),r.end()}finally{s()}}(e,t,v,g);const y=await e.request(g);isRuntimeError(y)?sendJson(t,function runtimeErrorStatus(e){return"cancelled"===e.state?409:500}(y),a(y)):sendJson(t,200,s(v,y))}(v,e,g,y);sendJson(g,404,{error:{message:"not_found",type:"invalid_request_error"}})}catch(e){sendJson(g,400,{error:{message:e instanceof Error?e.message:String(e),type:"invalid_request_error"}})}})}function isRuntimeError(e){return"failed"===e.state||"cancelled"===e.state}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function readStringRecord(e){const r=readRecord(e);if(r)return Object.fromEntries(Object.entries(r).filter(e=>"string"==typeof e[1]))}function readConfigString(e){if("string"!=typeof e||!e.trim())return;const r=e.match(/^\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-(.*))?\}$/u);return r?process.env[r[1]]??r[2]:e}function readHeaderString(e){const r=Array.isArray(e)?e[0]:e;return r&&r.trim()?r:void 0}function sendJson(e,r,t,o){e.writeHead(r,{"content-type":"application/json","access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),e.end(JSON.stringify(t))}
@@ -47,6 +47,7 @@ export declare function createCapabilitiesResponse(): {
47
47
  endpoints: string[];
48
48
  streaming: boolean;
49
49
  toolProgressEvents: boolean;
50
+ runtimeTrace: boolean;
50
51
  };
51
52
  export declare function toChatCompletion(body: ChatCompletionRequest, result: RuntimeResponse): {
52
53
  id: string;
@@ -72,3 +73,17 @@ export declare function toChatCompletion(body: ChatCompletionRequest, result: Ru
72
73
  state: import("@stable-harness/core").RuntimeRecordState;
73
74
  };
74
75
  };
76
+ export declare function toRuntimeErrorResponse(result: RuntimeResponse): {
77
+ error: {
78
+ message: string;
79
+ type: string;
80
+ code: string;
81
+ param: null;
82
+ };
83
+ metadata: {
84
+ requestId: string;
85
+ sessionId: string;
86
+ agentId: string;
87
+ state: import("@stable-harness/core").RuntimeRecordState;
88
+ };
89
+ };
@@ -1 +1 @@
1
- import{randomUUID as e}from"node:crypto";export function toRuntimeRequest(t,n,s,o={}){const r=function messagesToInput(e){if(!Array.isArray(e)||0===e.length)throw new Error("messages must be a non-empty array");return e.map(e=>`${e.role??"user"}: ${contentToText(e.content)}`).join("\n\n")}(t.messages),a=`chatcmpl-${e()}`,i=o.sessionId??function readSessionId(e){const t=e?.sessionId??e?.session_id??e?.conversationId??e?.conversation_id;return"string"==typeof t&&t.trim()?t:void 0}(t.metadata),c=normalizeOpenAiMessages(t.messages),u=i?function prependSessionMessages(e,t,n){if(function hasClientHistory(e){return e.some(e=>"assistant"===e.role)||e.filter(e=>"user"===e.role).length>1}(n))return n;const s=e.listRequests({sessionId:t,state:"completed"}).flatMap(t=>function inspectSessionTurn(e,t){const n=e.inspectRequest(t),s=n?.output?.trim(),o=function lastUserMessage(e){return normalizeOpenAiMessages(Array.isArray(e)?e:void 0).filter(e=>"user"===e.role&&e.content.trim()).at(-1)}(n?.metadata?.openaiMessages)?.content;return o&&s?[{role:"user",content:o},{role:"assistant",content:s}]:[]}(e,t.requestId)).slice(-12);return s.length>0?[...s,...n]:n}(n,i,c):c;return{input:r,requestId:a,agentId:resolveAgentId(t.model,n,s),...i?{sessionId:i}:{},metadata:{protocol:"openai-compatible",openaiStream:!0===t.stream,openaiMessages:u,openaiSessionHistory:u.length>c.length,model:t.model,user:t.user,clientMetadata:t.metadata}}}export function resolveAgentId(e,t,n){if(!e)return;const s=n.modelAgentMap?.[e];return s||(t.inspect().agents.includes(e)?e:void 0)}export function createModelsResponse(e,t){const n=Object.keys(t.modelAgentMap??{});return{object:"list",data:[...new Set([...e.inspect().agents,...n])].sort().map(e=>({id:e,object:"model",created:0,owned_by:"stable-harness"}))}}export function createCapabilitiesResponse(){return{object:"stable_harness.capabilities",endpoints:["/v1/models","/v1/chat/completions","/v1/capabilities"],streaming:!0,toolProgressEvents:!0}}export function toChatCompletion(e,t){return{id:t.requestId,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:e.model??t.agentId,choices:[{index:0,message:{role:"assistant",content:t.output},finish_reason:"stop"}],usage:estimateUsage(e.messages,t.output),metadata:{sessionId:t.sessionId,agentId:t.agentId,state:t.state}}}function normalizeOpenAiMessages(e){return Array.isArray(e)?e.map(e=>({role:e.role??"user",content:contentToText(e.content)})):[]}function contentToText(e){if("string"==typeof e)return e;if(!Array.isArray(e))throw new Error("message content must be a string or content part array");return e.map(contentPartToText).join("\n")}function contentPartToText(e){if("object"!=typeof e||null===e)throw new Error("message content parts must be objects");const t=e;if("text"===t.type&&"string"==typeof t.text)return t.text;const n=t.image_url;if("image_url"===t.type&&"string"==typeof n?.url)return`[image:${n.url}]`;throw new Error("unsupported_content_type")}function estimateUsage(e,t){const n=estimateTokens(Array.isArray(e)?e.map(e=>contentToText(e.content)).join("\n"):""),s=estimateTokens(t);return{prompt_tokens:n,completion_tokens:s,total_tokens:n+s}}function estimateTokens(e){return e.trim()?Math.ceil(1.3*e.trim().split(/\s+/u).length):0}
1
+ import{randomUUID as e}from"node:crypto";export function toRuntimeRequest(t,n,s,o={}){const r=function messagesToInput(e){if(!Array.isArray(e)||0===e.length)throw new Error("messages must be a non-empty array");return e.map(e=>`${e.role??"user"}: ${contentToText(e.content)}`).join("\n\n")}(t.messages),a=`chatcmpl-${e()}`,i=o.sessionId??function readSessionId(e){const t=e?.sessionId??e?.session_id??e?.conversationId??e?.conversation_id;return"string"==typeof t&&t.trim()?t:void 0}(t.metadata),c=normalizeOpenAiMessages(t.messages),u=i?function prependSessionMessages(e,t,n){if(function hasClientHistory(e){return e.some(e=>"assistant"===e.role)||e.filter(e=>"user"===e.role).length>1}(n))return n;const s=e.listRequests({sessionId:t,state:"completed"}).flatMap(t=>function inspectSessionTurn(e,t){const n=e.inspectRequest(t),s=n?.output?.trim(),o=function lastUserMessage(e){return normalizeOpenAiMessages(Array.isArray(e)?e:void 0).filter(e=>"user"===e.role&&e.content.trim()).at(-1)}(n?.metadata?.openaiMessages)?.content;return o&&s?[{role:"user",content:o},{role:"assistant",content:s}]:[]}(e,t.requestId)).slice(-12);return s.length>0?[...s,...n]:n}(n,i,c):c;return{input:r,requestId:a,agentId:resolveAgentId(t.model,n,s),...i?{sessionId:i}:{},metadata:{protocol:"openai-compatible",openaiStream:!0===t.stream,openaiMessages:u,openaiSessionHistory:u.length>c.length,model:t.model,user:t.user,clientMetadata:t.metadata}}}export function resolveAgentId(e,t,n){if(!e)return;const s=n.modelAgentMap?.[e];return s||(t.inspect().agents.includes(e)?e:void 0)}export function createModelsResponse(e,t){const n=Object.keys(t.modelAgentMap??{});return{object:"list",data:[...new Set([...e.inspect().agents,...n])].sort().map(e=>({id:e,object:"model",created:0,owned_by:"stable-harness"}))}}export function createCapabilitiesResponse(){return{object:"stable_harness.capabilities",endpoints:["/v1/models","/v1/chat/completions","/v1/capabilities","/v1/stable-harness/runs/{request_id}/trace"],streaming:!0,toolProgressEvents:!0,runtimeTrace:!0}}export function toChatCompletion(e,t){return{id:t.requestId,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:e.model??t.agentId,choices:[{index:0,message:{role:"assistant",content:t.output},finish_reason:"stop"}],usage:estimateUsage(e.messages,t.output),metadata:{sessionId:t.sessionId,agentId:t.agentId,state:t.state}}}export function toRuntimeErrorResponse(e){const t="cancelled"===e.state;return{error:{message:e.output||(t?"Runtime request was cancelled.":"Runtime request failed."),type:t?"request_cancelled":"server_error",code:t?"runtime_cancelled":"runtime_failed",param:null},metadata:{requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,state:e.state}}}function normalizeOpenAiMessages(e){return Array.isArray(e)?e.map(e=>({role:e.role??"user",content:contentToText(e.content)})):[]}function contentToText(e){if("string"==typeof e)return e;if(!Array.isArray(e))throw new Error("message content must be a string or content part array");return e.map(contentPartToText).join("\n")}function contentPartToText(e){if("object"!=typeof e||null===e)throw new Error("message content parts must be objects");const t=e;if("text"===t.type&&"string"==typeof t.text)return t.text;const n=t.image_url;if("image_url"===t.type&&"string"==typeof n?.url)return`[image:${n.url}]`;throw new Error("unsupported_content_type")}function estimateUsage(e,t){const n=estimateTokens(Array.isArray(e)?e.map(e=>contentToText(e.content)).join("\n"):""),s=estimateTokens(t);return{prompt_tokens:n,completion_tokens:s,total_tokens:n+s}}function estimateTokens(e){return e.trim()?Math.ceil(1.3*e.trim().split(/\s+/u).length):0}
@@ -37,3 +37,4 @@ export declare function createStopChunk(id: string, model: string | undefined):
37
37
  export declare function writeRuntimeStreamEvent(response: ServerResponse, event: RuntimeEvent, id: string, model: string | undefined): string | undefined;
38
38
  export declare function writeSseHeaders(response: ServerResponse, headers: Record<string, string>): void;
39
39
  export declare function writeChatSse(response: ServerResponse, body: unknown): void;
40
+ export declare function writeErrorSse(response: ServerResponse, body: unknown): void;
@@ -1 +1 @@
1
- export function missingFinalDelta(e,t){return e?!t||e.includes(t)?"":t.startsWith(e)?t.slice(e.length):t:t}export function createRoleChunk(e,t){return createChunk(e,t,{role:"assistant"},null)}export function createContentChunk(e,t,n){return createChunk(e,t,{content:n},null)}export function createStopChunk(e,t){return createChunk(e,t,{},"stop")}export function writeRuntimeStreamEvent(e,t,n,r){const o=function readAdapterDelta(e){if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event;return"deepagents.message.coordinator_delta"!==t.eventType&&"agent.output.delta"!==t.phase||"string"!=typeof t.text?void 0:t.text}(t);if(o)return writeChatSse(e,createContentChunk(n,r,o)),o;!function writeProgressEvent(e,t){const n=function readToolProgress(e){if("runtime.tool.direct.started"===e.type||"runtime.tool.direct.completed"===e.type)return{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:e.type,tool_id:e.toolId};if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event,n=function readToolProgressType(e){return"deepagents.tool_execution.start"===e.eventType?"deepagents.tool_execution.start":"deepagents.tool_execution.result"===e.eventType?"deepagents.tool_execution.result":"agent.tool.start"===e.phase||"agent.tool.result"===e.phase?e.phase:void 0}(t),r="string"==typeof t.toolId?t.toolId:void 0;return n&&r?{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:n,tool_id:r,adapter:t.adapter}:void 0}(t);n&&writeSse(e,"stable_harness.tool.progress",n)}(e,t),function writeNarrationEvent(e,t){"runtime.progress.narration"===t.type&&writeSse(e,"stable_harness.progress.narration",{request_id:t.requestId,session_id:t.sessionId,agent_id:t.agentId,type:t.type,message:t.message,provider:t.provider,source_event_types:t.sourceEventTypes,source_event_ids:t.sourceEventIds,model:t.model,style:t.style})}(e,t)}export function writeSseHeaders(e,t){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive",...t})}export function writeChatSse(e,t){e.write(`data: ${JSON.stringify(t)}\n\n`)}function createChunk(e,t,n,r){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:t??"stable-harness",choices:[{index:0,delta:n,finish_reason:r}]}}function writeSse(e,t,n){e.write(`event: ${t}\n`),e.write(`data: ${JSON.stringify(n)}\n\n`)}
1
+ export function missingFinalDelta(e,t){return e?!t||e.includes(t)?"":t.startsWith(e)?t.slice(e.length):t:t}export function createRoleChunk(e,t){return createChunk(e,t,{role:"assistant"},null)}export function createContentChunk(e,t,n){return createChunk(e,t,{content:n},null)}export function createStopChunk(e,t){return createChunk(e,t,{},"stop")}export function writeRuntimeStreamEvent(e,t,n,r){const o=function readAdapterDelta(e){if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event;return"deepagents.message.coordinator_delta"!==t.eventType&&"agent.output.delta"!==t.phase||"string"!=typeof t.text?void 0:t.text}(t);if(o)return writeChatSse(e,createContentChunk(n,r,o)),o;!function writeProgressEvent(e,t){const n=function readToolProgress(e){if("runtime.tool.direct.started"===e.type||"runtime.tool.direct.completed"===e.type)return{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:e.type,tool_id:e.toolId};if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event,n=function readToolProgressType(e){return"deepagents.tool_execution.start"===e.eventType?"deepagents.tool_execution.start":"deepagents.tool_execution.result"===e.eventType?"deepagents.tool_execution.result":"agent.tool.start"===e.phase||"agent.tool.result"===e.phase?e.phase:void 0}(t),r="string"==typeof t.toolId?t.toolId:void 0;return n&&r?{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:n,tool_id:r,adapter:t.adapter}:void 0}(t);n&&writeSse(e,"stable_harness.tool.progress",n)}(e,t),function writeNarrationEvent(e,t){"runtime.progress.narration"===t.type&&writeSse(e,"stable_harness.progress.narration",{request_id:t.requestId,session_id:t.sessionId,agent_id:t.agentId,type:t.type,message:t.message,provider:t.provider,source_event_types:t.sourceEventTypes,source_event_ids:t.sourceEventIds,model:t.model,style:t.style})}(e,t)}export function writeSseHeaders(e,t){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive",...t})}export function writeChatSse(e,t){e.write(`data: ${JSON.stringify(t)}\n\n`)}export function writeErrorSse(e,t){writeSse(e,"error",t)}function createChunk(e,t,n,r){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:t??"stable-harness",choices:[{index:0,delta:n,finish_reason:r}]}}function writeSse(e,t,n){e.write(`event: ${t}\n`),e.write(`data: ${JSON.stringify(n)}\n\n`)}