stable-harness 0.0.21 → 0.0.23

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.
@@ -39,6 +39,11 @@ runtime:
39
39
  verdict.
40
40
  executionReview:
41
41
  requireToolEvidence: true
42
+ rejectUngroundedNumbers: true
43
+ synthesis:
44
+ enabled: true
45
+ mode: evidence_only
46
+ maxEvidenceItems: 5
42
47
  recovery:
43
48
  maxLoops: 2
44
49
  ```
@@ -75,6 +80,14 @@ declared inventory. If execution review fails, the runtime asks the agent to
75
80
  continue from the current state with ReAct: inspect the evidence gap, choose the
76
81
  next declared tool or subagent action, execute it, and synthesize from evidence.
77
82
 
83
+ When `synthesis.enabled` is true, the runtime may recover from a rejected final
84
+ answer by building an `evidence_only` report from successful observed tool or
85
+ delegated-task outputs. This is a control-plane synthesis path, not a domain
86
+ writer: it does not call more tools, does not add pretrained facts, and runs the
87
+ same execution review again before delivery. Control outputs such as invalid
88
+ input, approval blocks, or repeated-call limits are preserved as blockers or
89
+ evidence gaps rather than treated as factual evidence.
90
+
78
91
  BetterCall remains focused on individual tool-call reliability. Quality gates
79
92
  consume tool and repair diagnostics as evidence, but they live in Stable Harness
80
93
  because they govern the run lifecycle rather than a single tool call.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stable-harness",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "type": "module",
5
5
  "description": "Stable application runtime and operator control plane for agent workspaces.",
6
6
  "license": "Apache-2.0",
@@ -98,7 +98,7 @@
98
98
  "zod": "^4.1.13"
99
99
  },
100
100
  "devDependencies": {
101
- "@types/node": "^24.10.1",
101
+ "@types/node": "^25.6.2",
102
102
  "terser": "^5.47.1",
103
103
  "typescript": "^5.9.3"
104
104
  }
@@ -2,4 +2,10 @@ import type { RuntimeEvent } from "../types.js";
2
2
  export declare function hasPlanningEvidence(events: RuntimeEvent[]): boolean;
3
3
  export declare function successfulEvidenceToolIds(events: RuntimeEvent[]): string[];
4
4
  export declare function successfulEvidenceOutputs(events: RuntimeEvent[]): string[];
5
+ export type SuccessfulEvidenceItem = {
6
+ source: string;
7
+ output: string;
8
+ };
9
+ export declare function successfulEvidenceItems(events: RuntimeEvent[]): SuccessfulEvidenceItem[];
5
10
  export declare function controlBlockers(events: RuntimeEvent[]): string[];
11
+ export declare function controlGaps(events: RuntimeEvent[]): string[];
@@ -1 +1 @@
1
- export function hasPlanningEvidence(t){return t.some(t=>{const e=readAdapterEvent(t);return!!e&&("plan"===e.traceType||String(e.traceLabel??"").startsWith("plan.")||"write_todos"===e.toolId&&String(e.phase??"").startsWith("agent.tool."))})}export function successfulEvidenceToolIds(t){const e=t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return[t.toolId];const e=readAdapterEvent(t);return e&&"agent.tool.result"===e.phase&&"string"==typeof e.toolId&&isSuccessfulEvidenceEvent(e)?[e.toolId]:[]});return[...new Set(e)]}export function successfulEvidenceOutputs(t){return t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return stringifyEvidence(t.output);const e=readAdapterEvent(t);return e&&"agent.tool.result"===e.phase&&"string"==typeof e.toolId?!isSuccessfulEvidenceEvent(e)||function isPlanningTool(t){return/^(?:write_todos|read_todos)$/u.test(t)}(e.toolId)?[]:stringifyEvidence(e.output):[]})}export function controlBlockers(t){return t.flatMap(t=>{const e=readAdapterEvent(t),r=readString(e?.controlStatus)??readOutputStatus(e?.output);return r&&function isBlockerStatus(t){return/^(?:blocked|approval_required|schema_repair_failed|tool_argument_error|invalid_input)$/iu.test(t)}(r)?[`${readString(e?.toolId)??"tool"}:${r}`]:[]})}function stringifyEvidence(t){return"string"==typeof t?t.trim()?[t]:[]:null==t?[]:[JSON.stringify(t)]}function readAdapterEvent(t){return"runtime.adapter.event"===t.type&&isRecord(t.event)?t.event:void 0}function isSuccessfulEvidenceEvent(t){const e=readString(t.controlStatus)??readOutputStatus(t.output);return!e||/^(?:completed|success|ok|recorded)$/iu.test(e)}function readOutputStatus(t){if("string"!=typeof t)return;const e=function parseJsonRecord(t){try{const e=JSON.parse(t);return isRecord(e)?e:void 0}catch{return}}(t);return"string"==typeof e?.status?e.status:t.match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1]}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function readString(t){return"string"==typeof t&&t.trim()?t:void 0}
1
+ export function hasPlanningEvidence(t){return t.some(t=>{const e=readAdapterEvent(t);return!!e&&("plan"===e.traceType||String(e.traceLabel??"").startsWith("plan.")||"write_todos"===e.toolId&&String(e.phase??"").startsWith("agent.tool."))})}export function successfulEvidenceToolIds(t){const e=t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return[t.toolId];const e=readAdapterEvent(t);return e&&"agent.tool.result"===e.phase&&"string"==typeof e.toolId&&isSuccessfulEvidenceEvent(e)?[e.toolId]:[]});return[...new Set(e)]}export function successfulEvidenceOutputs(t){return successfulEvidenceItems(t).map(t=>t.output)}export function successfulEvidenceItems(t){return t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return stringifyEvidence(t.output).map(e=>({source:t.toolId,output:e}));const e=readAdapterEvent(t);return e&&"agent.tool.result"===e.phase&&"string"==typeof e.toolId?!isSuccessfulEvidenceEvent(e)||function isPlanningTool(t){return/^(?:write_todos|read_todos)$/u.test(t)}(e.toolId)?[]:stringifyEvidence(e.output).map(t=>({source:e.toolId,output:t})):[]})}export function controlBlockers(t){return t.flatMap(t=>{const e=readAdapterEvent(t),r=readString(e?.controlStatus)??readOutputStatus(e?.output);return r&&function isBlockerStatus(t){return/^(?:blocked|approval_required|schema_repair_failed|tool_argument_error|invalid_input)$/iu.test(t)}(r)?[`${readString(e?.toolId)??"tool"}:${r}`]:[]})}export function controlGaps(t){const e=new Set(successfulEvidenceItems(t).map(t=>t.source));return t.flatMap(t=>{const r=readAdapterEvent(t),n=readString(r?.controlStatus)??readOutputStatus(r?.output),o=readString(r?.toolId)??"tool";return n&&isGapStatus(n)?e.has(o)&&function isResolvedByLaterCompletion(t){return isGapStatus(t)}(n)?[]:[`${o}:${n}`]:[]})}function stringifyEvidence(t){return"string"==typeof t?t.trim()?[t]:[]:null==t?[]:[JSON.stringify(t)]}function readAdapterEvent(t){return"runtime.adapter.event"===t.type&&isRecord(t.event)?t.event:void 0}function isSuccessfulEvidenceEvent(t){const e=readString(t.controlStatus)??readOutputStatus(t.output);return!e||/^(?:completed|success|ok|recorded)$/iu.test(e)}function isGapStatus(t){return/^(?:dependency_required|plan_required|repeated_tool_call_limit|duplicate_tool_call)$/iu.test(t)}function readOutputStatus(t){if("string"!=typeof t)return;const e=function parseJsonRecord(t){try{const e=JSON.parse(t);return isRecord(e)?e:void 0}catch{return}}(t);return"string"==typeof e?.status?e.status:t.match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1]}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function readString(t){return"string"==typeof t&&t.trim()?t:void 0}
@@ -4,4 +4,5 @@ export * from "./planning-review.js";
4
4
  export * from "./execution-review.js";
5
5
  export * from "./llm-review.js";
6
6
  export * from "./recovery-policy.js";
7
+ export * from "./synthesis.js";
7
8
  export * from "./runtime.js";
@@ -1 +1 @@
1
- export*from"./types.js";export*from"./profile.js";export*from"./planning-review.js";export*from"./execution-review.js";export*from"./llm-review.js";export*from"./recovery-policy.js";export*from"./runtime.js";
1
+ export*from"./types.js";export*from"./profile.js";export*from"./planning-review.js";export*from"./execution-review.js";export*from"./llm-review.js";export*from"./recovery-policy.js";export*from"./synthesis.js";export*from"./runtime.js";
@@ -1 +1 @@
1
- export function resolveQualityPolicy(e,n){const r=n.config.quality??e.quality,o=function readProfile(e){const n="string"==typeof e?e:isRecord(e)?e.profile:void 0;return"fast"===n||"balanced"===n||"strict"===n?n:"off"}(r),i=function profileDefaults(e,n){const r=n.tools.length>0||n.subagents.length>0||(n.skills?.length??0)>0;return"off"===e?function disabledPolicy(e){return{enabled:!1,profile:e,reviewer:{mode:"deterministic"},planningReview:{enabled:!1,requirePlan:!1},executionReview:{enabled:!1,requireToolEvidence:!1,rejectEmptyFinal:!1,stopOnBlocker:!1,rejectUngroundedNumbers:!1},recovery:{enabled:!1,maxLoops:0}}}(e):{enabled:!0,profile:e,planningReview:{enabled:"fast"!==e,requirePlan:"fast"!==e&&r},executionReview:{enabled:!0,requireToolEvidence:"strict"===e&&r,rejectEmptyFinal:!0,stopOnBlocker:!0,rejectUngroundedNumbers:"strict"===e},recovery:{enabled:"fast"!==e,maxLoops:"strict"===e?3:2}}}(o,n),t=isRecord(r)?r:{},a=function readReviewer(e){const n=isRecord(e.reviewer)?e.reviewer:e,r="llm"===n.mode||"string"==typeof n.modelRef?"llm":"deterministic",o=isRecord(n.prompts)?n.prompts:{},i=readString(n.modelRef);return{mode:r,...i?{modelRef:i}:{},...readString(n.planningPrompt)??readString(o.planning)?{planningPrompt:readString(n.planningPrompt)??readString(o.planning)}:{},...readString(n.executionPrompt)??readString(o.execution)?{executionPrompt:readString(n.executionPrompt)??readString(o.execution)}:{}}}(t);return{enabled:i.enabled,profile:o,...a?{reviewer:a}:{},planningReview:{enabled:readBoolean(t.planningReview,"enabled")??i.planningReview.enabled,requirePlan:readBoolean(t.planningReview,"requirePlan")??i.planningReview.requirePlan},executionReview:{enabled:readBoolean(t.executionReview,"enabled")??i.executionReview.enabled,requireToolEvidence:readBoolean(t.executionReview,"requireToolEvidence")??i.executionReview.requireToolEvidence,rejectEmptyFinal:readBoolean(t.executionReview,"rejectEmptyFinal")??i.executionReview.rejectEmptyFinal,stopOnBlocker:readBoolean(t.executionReview,"stopOnBlocker")??i.executionReview.stopOnBlocker,rejectUngroundedNumbers:readBoolean(t.executionReview,"rejectUngroundedNumbers")??i.executionReview.rejectUngroundedNumbers},recovery:{enabled:readBoolean(t.recovery,"enabled")??i.recovery.enabled,maxLoops:readPositiveInteger(t.recovery,"maxLoops")??i.recovery.maxLoops}}}function readString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function readBoolean(e,n){const r=isRecord(e)?e:{};return"boolean"==typeof r[n]?r[n]:void 0}function readPositiveInteger(e,n){const r=(isRecord(e)?e:{})[n];return"number"==typeof r&&Number.isInteger(r)&&r>0?r:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
1
+ export function resolveQualityPolicy(e,n){const r=n.config.quality??e.quality,i=function readProfile(e){const n="string"==typeof e?e:isRecord(e)?e.profile:void 0;return"fast"===n||"balanced"===n||"strict"===n?n:"off"}(r),o=function profileDefaults(e,n){const r=n.tools.length>0||n.subagents.length>0||(n.skills?.length??0)>0;return"off"===e?function disabledPolicy(e){return{enabled:!1,profile:e,reviewer:{mode:"deterministic"},planningReview:{enabled:!1,requirePlan:!1},executionReview:{enabled:!1,requireToolEvidence:!1,rejectEmptyFinal:!1,stopOnBlocker:!1,rejectUngroundedNumbers:!1},synthesis:{enabled:!1,mode:"evidence_only",maxEvidenceItems:5},recovery:{enabled:!1,maxLoops:0}}}(e):{enabled:!0,profile:e,planningReview:{enabled:"fast"!==e,requirePlan:"fast"!==e&&r},executionReview:{enabled:!0,requireToolEvidence:"strict"===e&&r,rejectEmptyFinal:!0,stopOnBlocker:!0,rejectUngroundedNumbers:"strict"===e},synthesis:{enabled:!1,mode:"evidence_only",maxEvidenceItems:5},recovery:{enabled:"fast"!==e,maxLoops:"strict"===e?3:2}}}(i,n),t=isRecord(r)?r:{},a=function readReviewer(e){const n=isRecord(e.reviewer)?e.reviewer:e,r="llm"===n.mode||"string"==typeof n.modelRef?"llm":"deterministic",i=isRecord(n.prompts)?n.prompts:{},o=readString(n.modelRef);return{mode:r,...o?{modelRef:o}:{},...readString(n.planningPrompt)??readString(i.planning)?{planningPrompt:readString(n.planningPrompt)??readString(i.planning)}:{},...readString(n.executionPrompt)??readString(i.execution)?{executionPrompt:readString(n.executionPrompt)??readString(i.execution)}:{}}}(t);return{enabled:o.enabled,profile:i,...a?{reviewer:a}:{},planningReview:{enabled:readBoolean(t.planningReview,"enabled")??o.planningReview.enabled,requirePlan:readBoolean(t.planningReview,"requirePlan")??o.planningReview.requirePlan},executionReview:{enabled:readBoolean(t.executionReview,"enabled")??o.executionReview.enabled,requireToolEvidence:readBoolean(t.executionReview,"requireToolEvidence")??o.executionReview.requireToolEvidence,rejectEmptyFinal:readBoolean(t.executionReview,"rejectEmptyFinal")??o.executionReview.rejectEmptyFinal,stopOnBlocker:readBoolean(t.executionReview,"stopOnBlocker")??o.executionReview.stopOnBlocker,rejectUngroundedNumbers:readBoolean(t.executionReview,"rejectUngroundedNumbers")??o.executionReview.rejectUngroundedNumbers},synthesis:{enabled:readBoolean(t.synthesis,"enabled")??o.synthesis.enabled,mode:(d=t.synthesis,("evidence_only"===(isRecord(d)?d:{}).mode?"evidence_only":void 0)??o.synthesis.mode),maxEvidenceItems:readPositiveInteger(t.synthesis,"maxEvidenceItems")??o.synthesis.maxEvidenceItems},recovery:{enabled:readBoolean(t.recovery,"enabled")??o.recovery.enabled,maxLoops:readPositiveInteger(t.recovery,"maxLoops")??o.recovery.maxLoops}};var d}function readString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function readBoolean(e,n){const r=isRecord(e)?e:{};return"boolean"==typeof r[n]?r[n]:void 0}function readPositiveInteger(e,n){const r=(isRecord(e)?e:{})[n];return"number"==typeof r&&Number.isInteger(r)&&r>0?r:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
@@ -1 +1 @@
1
- import{successfulEvidenceOutputs as e}from"./event-evidence.js";import{buildQualityRecoveryRequest as i}from"./recovery-policy.js";import{reviewExecutionEvidence as t}from"./execution-review.js";import{reviewWithLlm as n}from"./llm-review.js";import{reviewPlanningEvidence as r}from"./planning-review.js";export async function recoverQualityReview(e,i,t,n){if(!n.enabled)return t;let r=i,s=t;for(let i=0;i<n.recovery.maxLoops+1;i+=1){const t=await emitPlanningReview(e,r,s,n);if("blocked"===t.verdict)return qualityFailureOutput("planning",t);const u=buildQualityRecovery(e,r,t,"planning",n,i);if(u){r=u,s=await e.runAdapter(r);continue}const a=await emitExecutionReview(e,r,s,n),o=buildQualityRecovery(e,r,a,"execution",n,i);if(!o)return"pass"===a.verdict?s:qualityFailureOutput("execution",a);r=o,s=await e.runAdapter(r)}return qualityFailureOutput("execution",{verdict:"blocked",issues:[{code:"quality_recovery_exhausted",message:`Quality recovery exceeded maxLoops=${n.recovery.maxLoops}.`,recoverable:!1}]})}function emitPlanningReview(e,i,t,n){return emitReview(e,"planning",r,i,t,n)}function emitExecutionReview(e,i,n,r){return emitReview(e,"execution",t,i,n,r)}async function emitReview(e,i,t,r,s,u){const a={...reviewInputFor(e,r),output:s},o="planning"===i?u.planningReview.enabled:u.executionReview.enabled;if(!o)return t(a,u);const c=t(a,u),l=await n({phase:i,review:a,policy:u,model:e.reviewModel}),d="pass"===c.verdict?l??c:c;return o&&function emitReviewEvent(e,i,t){"planning"!==i?e.emit({type:"runtime.quality.execution.reviewed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,verdict:t.verdict,issues:t.issues}):e.emit({type:"runtime.quality.planning.reviewed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,verdict:t.verdict,issues:t.issues})}(e,i,d),d}function buildQualityRecovery(t,n,r,s,u,a){if(a>=u.recovery.maxLoops)return;const o=i({request:n,result:r,phase:s,policy:u,availableToolIds:t.agent.tools,availableSubagentIds:t.agent.subagents,observedEvidence:"execution"===s?e(t.getEvents()):[]});return o&&t.emit({type:"runtime.quality.recovery.started",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,phase:s,attempt:a+1,verdict:r.verdict}),o}function reviewInputFor(e,i){return{workspace:e.workspace,agent:e.agent,request:i,events:e.getEvents()}}function qualityFailureOutput(e,i){return{text:[`Stable runtime quality review blocked final delivery during ${e}.`,"",...i.issues.length>0?i.issues.map(e=>`- ${e.code}: ${e.message}`):["- quality_review_failed: Quality review did not pass."]].join("\n")}}
1
+ import{successfulEvidenceOutputs as e}from"./event-evidence.js";import{buildQualityRecoveryRequest as t}from"./recovery-policy.js";import{reviewExecutionEvidence as i}from"./execution-review.js";import{reviewWithLlm as n}from"./llm-review.js";import{reviewPlanningEvidence as r}from"./planning-review.js";import{synthesizeEvidenceOnlyReport as s}from"./synthesis.js";export async function recoverQualityReview(e,t,i,n){if(!n.enabled)return i;let r=t,s=i;for(let t=0;t<n.recovery.maxLoops+1;t+=1){const i=await emitPlanningReview(e,r,s,n);if("blocked"===i.verdict)return qualityFailureOutput("planning",i);const u=buildQualityRecovery(e,r,i,"planning",n,t);if(u){r=u,s=await e.runAdapter(r);continue}const o=await emitExecutionReview(e,r,s,n),a=buildQualityRecovery(e,r,o,"execution",n,t);if(!a)return"pass"===o.verdict?s:await trySynthesizeExecution(e,r,o,n)??qualityFailureOutput("execution",o);r=a,s=await e.runAdapter(r)}return qualityFailureOutput("execution",{verdict:"blocked",issues:[{code:"quality_recovery_exhausted",message:`Quality recovery exceeded maxLoops=${n.recovery.maxLoops}.`,recoverable:!1}]})}async function trySynthesizeExecution(e,t,n,r){const u=s({...reviewInputFor(e,t),output:void 0},n,r);if(!u)return;e.emit({type:"runtime.quality.synthesis.created",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,mode:r.synthesis.mode});const o={text:u},a=i({...reviewInputFor(e,t),output:o},r);return emitReviewEvent(e,"execution",a),"pass"===a.verdict?o:void 0}function emitPlanningReview(e,t,i,n){return emitReview(e,"planning",r,t,i,n)}function emitExecutionReview(e,t,n,r){return emitReview(e,"execution",i,t,n,r)}async function emitReview(e,t,i,r,s,u){const o={...reviewInputFor(e,r),output:s},a="planning"===t?u.planningReview.enabled:u.executionReview.enabled;if(!a)return i(o,u);const c=i(o,u),d=await n({phase:t,review:o,policy:u,model:e.reviewModel}),v="pass"===c.verdict?d??c:c;return a&&emitReviewEvent(e,t,v),v}function emitReviewEvent(e,t,i){"planning"!==t?e.emit({type:"runtime.quality.execution.reviewed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,verdict:i.verdict,issues:i.issues}):e.emit({type:"runtime.quality.planning.reviewed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,verdict:i.verdict,issues:i.issues})}function buildQualityRecovery(i,n,r,s,u,o){if(o>=u.recovery.maxLoops)return;const a=t({request:n,result:r,phase:s,policy:u,availableToolIds:i.agent.tools,availableSubagentIds:i.agent.subagents,observedEvidence:"execution"===s?e(i.getEvents()):[]});return a&&i.emit({type:"runtime.quality.recovery.started",requestId:i.requestId,sessionId:i.sessionId,agentId:i.agent.id,phase:s,attempt:o+1,verdict:r.verdict}),a}function reviewInputFor(e,t){return{workspace:e.workspace,agent:e.agent,request:t,events:e.getEvents()}}function qualityFailureOutput(e,t){return{text:[`Stable runtime quality review blocked final delivery during ${e}.`,"",...t.issues.length>0?t.issues.map(e=>`- ${e.code}: ${e.message}`):["- quality_review_failed: Quality review did not pass."]].join("\n")}}
@@ -0,0 +1,2 @@
1
+ import type { QualityPolicy, QualityReviewInput, QualityReviewResult } from "./types.js";
2
+ export declare function synthesizeEvidenceOnlyReport(input: QualityReviewInput, review: QualityReviewResult, policy: QualityPolicy): string | undefined;
@@ -0,0 +1 @@
1
+ import{controlBlockers as e,controlGaps as n,successfulEvidenceItems as t}from"./event-evidence.js";export function synthesizeEvidenceOnlyReport(s,r,i){if(!i.enabled||!i.synthesis.enabled||"evidence_only"!==i.synthesis.mode)return;if("pass"===r.verdict||!function hasRecoverableSynthesisIssue(e){return e.issues.some(e=>"control_blocker"!==e.code)}(r))return;const o=t(s.events).slice(-i.synthesis.maxEvidenceItems),c=e(s.events),u=n(s.events);if(0===o.length&&0===c.length&&0===u.length)return;const a=function detectSynthesisLanguage(e){const n=e.workspace.runtime.responseLanguage;if(function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(n)){const e=readString(n.language)??readString(n.locale)??readString(n.target);if(e&&/^(?:zh|zh-|chinese|中文|汉语|漢語)/iu.test(e))return"zh";if(e&&/^(?:en|en-|english)$/iu.test(e))return"en"}return/\p{Script=Han}/u.test(e.request.input)?"zh":"en"}(s);return"zh"===a?function buildChineseReport(e,n,t){return["# 有依据的报告","","Stable Harness 已拒绝上一版最终回答,因为它未被已观察到的运行时证据完全支持。以下报告只根据已完成的工具或委托任务证据生成。","","## 已完成的证据来源",...sourceLines(e,"zh"),"","## 有证据支持的事实",...evidenceLines(e,"zh"),"","## 证据缺口与阻塞",...gapLines(n,t,"zh")].join("\n")}(o,c,u):function buildEnglishReport(e,n,t){return["# Grounded report","","Stable Harness rejected the previous final answer because it was not fully supported by observed runtime evidence. This report is synthesized only from completed tool or delegated-task evidence.","","## Completed evidence sources",...sourceLines(e,"en"),"","## Evidence-backed facts",...evidenceLines(e,"en"),"","## Evidence gaps and blockers",...gapLines(n,t,"en")].join("\n")}(o,c,u)}function sourceLines(e,n){return 0===e.length?["zh"===n?"- 未观察到成功的工具或委托任务证据。":"- No successful tool or delegated-task evidence was observed."]:[...e.reduce((e,n)=>e.set(n.source,(e.get(n.source)??0)+1),new Map)].map(([e,n])=>`- ${e}${n>1?` (${n})`:""}`)}function evidenceLines(e,n){return 0===e.length?["zh"===n?"- 证据缺口:没有可用于生成事实性结论的成功证据。":"- Evidence gap: no successful tool or delegated-task evidence was available."]:e.map(e=>`- ${e.source}: ${function formatEvidence(e){const n=e.replace(/\s+/gu," ").trim();return n.length>1200?`${n.slice(0,1197)}...`:n}(e.output)}`)}function gapLines(e,n,t){return 0===e.length&&0===n.length?["zh"===t?"- 未观察到未解决的运行时证据缺口或阻塞。":"- No unresolved runtime evidence gaps or blockers were observed."]:"zh"===t?[...e.map(e=>`- 阻塞:${e}`),...n.map(e=>`- 证据缺口:${e}`)]:[...e.map(e=>`- Blocked: ${e}`),...n.map(e=>`- Evidence gap: ${e}`)]}function readString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}
@@ -30,6 +30,11 @@ export type QualityPolicy = {
30
30
  stopOnBlocker: boolean;
31
31
  rejectUngroundedNumbers: boolean;
32
32
  };
33
+ synthesis: {
34
+ enabled: boolean;
35
+ mode: "evidence_only";
36
+ maxEvidenceItems: number;
37
+ };
33
38
  recovery: {
34
39
  enabled: boolean;
35
40
  maxLoops: number;
@@ -222,6 +222,12 @@ export type RuntimeEvent = {
222
222
  phase: "planning" | "execution";
223
223
  attempt: number;
224
224
  verdict: string;
225
+ } | {
226
+ type: "runtime.quality.synthesis.created";
227
+ requestId: string;
228
+ sessionId: string;
229
+ agentId: string;
230
+ mode: "evidence_only";
225
231
  } | {
226
232
  type: "runtime.adapter.event";
227
233
  requestId: string;
@@ -1,3 +1,3 @@
1
1
  import { type IncomingMessage, type ServerResponse } from "node:http";
2
2
  import { type StableHarnessRuntime } from "@stable-harness/core";
3
- export declare function createHttpServer(runtime: StableHarnessRuntime): import("http").Server<typeof IncomingMessage, typeof ServerResponse>;
3
+ export declare function createHttpServer(runtime: StableHarnessRuntime): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
@@ -6,4 +6,4 @@ export type OpenAiCompatibleServerOptions = {
6
6
  modelAgentMap?: Record<string, string>;
7
7
  defaultModel?: string;
8
8
  };
9
- export declare function createOpenAiCompatibleHttpServer(runtime: StableHarnessRuntime, options?: OpenAiCompatibleServerOptions): import("http").Server<typeof IncomingMessage, typeof ServerResponse>;
9
+ export declare function createOpenAiCompatibleHttpServer(runtime: StableHarnessRuntime, options?: OpenAiCompatibleServerOptions): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;