@x-otto/session-contract 0.0.1-alpha.4 → 0.1.0-alpha.9
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.
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,10 @@ type SessionEvent = (Base & {
|
|
|
61
61
|
cacheHitRatio?: number; /** RFC-235:本回合实际 effort 档(供回合摘要行显示 ·Effort)。 */
|
|
62
62
|
effort?: string; /** 回合结束原因(缺省 = 'completed',向后兼容旧事件)。 */
|
|
63
63
|
stopReason?: 'completed' | 'interrupted' | 'error';
|
|
64
|
+
/** RFC-442:错误终止时的错误消息(stopReason='error' 时携带)。
|
|
65
|
+
* 供 TUI 回合摘要行渲染错误详情——用户不再只看到"✗ 失败",还能看到失败原因。
|
|
66
|
+
* 透传自 interchange 层 AgentSessionEvent.prompt.end.errorMessage。 */
|
|
67
|
+
errorMessage?: string;
|
|
64
68
|
})
|
|
65
69
|
/**
|
|
66
70
|
* RFC-209 §2.5:满意度脉冲调查展示指令(web-ui 消费)。**不是 `projectSessionEvent`
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/project.ts","../src/requests.ts","../src/frontend-port.ts","../src/constants.ts","../src/pulse-survey-trigger.ts"],"mappings":";;;UA2BiB,QAAA;EACf,EAAA;EACA,KAAA;EACA,MAAA,GAAS,YAAA;;EAET,IAAA;AAAA;AAAA,UAEe,aAAA;EACf,EAAA;EACA,IAAA;EACA,MAAA;EACA,MAAA;AAAA;;AAoBF;;;;;UAXiB,UAAA;EACf,KAAA;EACA,SAAA;EAYkB;EAVlB,OAAA;EACA,SAAA;EAgBwB;EAdxB,KAAA;EACA,YAAA;AAAA;AAAA,UAGe,cAAA;EACf,EAAA;EACA,IAAA;EACA,SAAA,GAAY,MAAA;AAAA;AAWd;;;;;AAAA,KAJY,cAAA,GAAiB,aAAA;AAAA,KAExB,IAAA;EAAS,SAAA;AAAA;;KAEF,WAAA,GAAc,QAAA;AAAA,KACd,YAAA,GAAe,aAAA;AAAA,KAEf,YAAA,IACP,IAAA;EAAS,IAAA;EAAsB,IAAA;AAAA,MAC/B,IAAA;EACC,IAAA;EACA,KAAA;EACA,MAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/project.ts","../src/requests.ts","../src/frontend-port.ts","../src/constants.ts","../src/pulse-survey-trigger.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{resolveTodoSyncTargets as e}from"@x-otto/orchestration-contracts";function t(){return{delegated:new Map,todoList:[],currentTurn:0}}const n=new Set([`task_delegate`,`team_run`,`fork_call`]);function r(e){return new Set(e.filter(e=>e.metadata?.category===`orchestration`).map(e=>e.name))}function i(t,n){if(n.tracked===!1||(typeof n.mode==`string`?n.mode:`sync`)!==`sync`)return!1;let r=Array.isArray(n.taskIds)?n.taskIds.filter(e=>typeof e==`string`):void 0,i=e(t.todoList,r);return i.length===0?!1:(t.todoList=t.todoList.map(e=>e.id!=null&&i.includes(e.id)?{...e,status:`done`}:e),!0)}function a(e,t,r={}){let a=e.sessionId,s=r.isDelegationTool??(e=>n.has(e));switch(e.type){case`prompt.start`:return t.currentTurn++,[{sessionId:a,kind:`prompt.start`,text:e.text}];case`prompt.end`:{t.delegated.clear();let n=r.cacheHitRatio?.();return[{sessionId:a,kind:`delegate.update`,tasks:[]},{sessionId:a,kind:`prompt.end`,model:e.model??r.currentModel?.()??``,tokens:r.turnTokens?.(),cacheHitRatio:n??void 0,effort:e.thinkingLevel,stopReason:e.stopReason}]}case`turn.start`:return[{sessionId:a,kind:`turn.budget`,toolTurnCount:e.toolTurnCount,maxToolTurns:e.maxToolTurns,outputTokens:e.promptOutputTokens,outputTokenBudget:e.promptOutputTokenBudget}];case`stream.event`:{let t=e.event;switch(t.type){case`text_delta`:return[{sessionId:a,kind:`stream.text.delta`,delta:t.delta??``}];case`thinking_delta`:return[{sessionId:a,kind:`stream.thinking.delta`,delta:t.delta??``}];case`text_start`:return[{sessionId:a,kind:`stream.text.start`}];case`text_end`:return[{sessionId:a,kind:`stream.text.end`}];case`thinking_start`:return[{sessionId:a,kind:`stream.thinking.start`}];case`thinking_end`:return[{sessionId:a,kind:`stream.thinking.end`}];case`error`:return[{sessionId:a,kind:`error`,message:o(t.error),code:`STREAM_ERROR`}];case`start`:case`tool_call_start`:case`tool_call_delta`:case`tool_call_end`:case`done`:return[];default:return[]}}case`tool.call.start`:{let n=e.toolCall,r=[{sessionId:a,kind:`tool.start`,call:n}];if(s(n.name)){let e=n.arguments??{},i=e.subagent??e.agent??e.category??e.team,o=typeof e.prompt==`string`?e.prompt.replace(/\n/g,` `).slice(0,48):void 0;t.delegated.set(n.id,{id:n.id,name:typeof i==`string`?i:n.name,detail:o,status:`running`}),r.push({sessionId:a,kind:`delegate.update`,tasks:[...t.delegated.values()]})}return r}case`tool.call.end`:{let{toolCall:n,isError:o}=e,s=n.arguments??{},c=t=>({sessionId:a,kind:`tool.end`,call:n,isError:o,resultText:e.resultText??r.toolResultText?.(n),resultTokensEstimate:e.resultTokensEstimate,suppressMessage:t});if(n.name===`write_todos`&&Array.isArray(s.todos)){let e=s.todos;if(s.action===`update`)for(let n of e){let e=t.todoList.findIndex(e=>e.id===n.id);e>=0?t.todoList[e]={...t.todoList[e],...n,turn:t.currentTurn}:t.todoList.push({...n,turn:t.currentTurn})}else t.todoList=e.map(e=>({...e,turn:t.currentTurn}));return[c(!0),{sessionId:a,kind:`tasks.update`,tasks:[...t.todoList],title:s.title}]}if(t.delegated.has(n.id)){let e=t.delegated.get(n.id);t.delegated.set(n.id,{...e,status:o?`error`:`done`});let r=[{sessionId:a,kind:`delegate.update`,tasks:[...t.delegated.values()]},c()];return n.name===`task_delegate`&&!o&&i(t,s)&&r.push({sessionId:a,kind:`tasks.update`,tasks:[...t.todoList]}),r}return[c()]}case`session.start`:return[{sessionId:a,kind:`session.activity`,action:`created`}];case`session.end`:return[{sessionId:a,kind:`session.activity`,action:`ended`}];case`streaming.start`:return[{sessionId:a,kind:`session.status`,status:`streaming`,model:e.model}];case`streaming.end`:{let t=e;return[{sessionId:a,kind:`session.status`,status:`idle`,model:t.model,stopReason:t.stopReason}]}case`compaction.start`:return[{sessionId:a,kind:`session.status`,status:`compacting`,messageCount:e.messageCount}];case`compaction.end`:return[{sessionId:a,kind:`session.status`,status:`idle`,retainedCount:e.retainedCount}];case`approval.required`:{let t=e;return[{sessionId:a,kind:`approval.required`,id:t.id,toolName:t.toolName,arguments:t.arguments,description:t.description,risk:t.risk}]}case`approval.resolved`:{let t=e;return[{sessionId:a,kind:`approval.resolved`,id:t.id,approved:t.approved}]}case`ask.user.required`:{let t=e;return[{sessionId:a,kind:`ask.required`,requestId:t.requestId,question:t.question}]}case`ask.user.resolved`:return[{sessionId:a,kind:`ask.resolved`,requestId:e.requestId}];case`plan.approval.required`:{let t=e;return[{sessionId:a,kind:`plan.approval.required`,requestId:t.requestId,planContent:t.planContent}]}case`plan.approval.resolved`:{let t=e;return[{sessionId:a,kind:`plan.approval.resolved`,requestId:t.requestId,action:t.action}]}case`error`:return[{sessionId:a,kind:`error`,message:o(e.error),code:`SESSION_ERROR`}];case`prompt.continued`:case`messages.persist`:case`agent.status`:case`budget.notice`:case`prompt.budget.notice`:case`progress.stall.notice`:case`tool.call.mismatch.notice`:case`session.cost-budget-exceeded`:case`turn.end`:case`memory.pruned`:case`session.cleared`:case`run.paused`:case`run.resumed`:case`run.pause_requested`:case`run.pause_cancelled`:case`session.history-capped`:case`session.write-lease-denied`:case`session.write-lease-restored`:case`session.crash-gap-detected`:case`image.vision-delegate`:case`a2ui.action`:case`compaction.reactive.notice`:case`image.degradation.notice`:case`steer.consumed`:return[];default:return[]}}function o(e){return e instanceof Error?e.message:typeof e==`string`?e:`unknown error`}function s(e){return{answer:e.recommendation,acceptedRecommendation:!0,resolvedBy:`auto_recommendation`}}function c(e,t,n){if(t.length===0&&!n)return s(e);let r=(e.options??[]).filter(e=>e.recommended).map(e=>e.label),i=r.length>0&&t.length===r.length&&t.every(e=>r.includes(e)),a=t.length>0?t.join(`, `):``;return{answer:n?a?`${a}\n\n补充信息:${n}`:n:a,selectedOptionLabels:t.length>0?t:void 0,acceptedRecommendation:i,resolvedBy:`human`,freeformText:n}}function l(e,t){let n=t?.trim();return n?{answer:n,acceptedRecommendation:n===e.recommendation,resolvedBy:`human`}:s(e)}function u(e,t,n){return typeof e!=`string`||!e.includes(n)?null:(typeof t?.command==`string`?t.command:``)||null}function d(e,t){if(e===void 0)return t;let n=parseInt(e,10);return isNaN(n)||n<=0?t:n}const f=5e4,p=64*1024*1024,m=5e3,h=3e4,g=1024*1024*1024,_=16*1024*1024,v=1024*1024*1024;function y(e){return{totalBytes:e?.totalBytes??d(process.env.OTTO_SESSION_TOTAL_RESIDENCY_BUDGET,1073741824),minPerSessionBytes:e?.minPerSessionBytes??d(process.env.OTTO_SESSION_MIN_PER_SESSION_BYTES,16777216),maxPerSessionBytes:e?.maxPerSessionBytes??d(process.env.OTTO_SESSION_MAX_PER_SESSION_BYTES,1073741824),maxContentBytes:e?.maxContentBytes??d(process.env.OTTO_SESSION_MAX_CONTENT_BYTES,67108864),maxHistoryMessages:e?.maxHistoryMessages??d(process.env.OTTO_SESSION_MAX_HISTORY_MESSAGES,5e4),resumeWindowMessages:e?.resumeWindowMessages??d(process.env.OTTO_SESSION_RESUME_WINDOW_MESSAGES,5e3),compactionTimeoutMs:e?.compactionTimeoutMs??d(process.env.OTTO_SESSION_COMPACTION_TIMEOUT_MS,3e4)}}function b(e,t,n,r=Math.random){return!t.enabled||t.forcedUpgradeActive||n.lastShownTurn!==void 0&&e-n.lastShownTurn<t.minTurnGap?!1:r()<t.probability}export{n as DEFAULT_DELEGATION_TOOLS,h as SESSION_COMPACTION_TIMEOUT_MS,p as SESSION_MAX_CONTENT_BYTES,f as SESSION_MAX_HISTORY_MESSAGES,v as SESSION_MAX_PER_SESSION_BYTES,_ as SESSION_MIN_PER_SESSION_BYTES,m as SESSION_RESUME_WINDOW_MESSAGES,g as SESSION_TOTAL_RESIDENCY_BUDGET,s as autoAdoptAnswer,t as createProjectorState,r as deriveDelegationToolNames,a as projectSessionEvent,c as resolveChoiceAnswer,y as resolveResidencyBudget,l as resolveTextAnswer,u as sandboxBypassCommand,b as shouldShowPulseSurvey};
|
|
1
|
+
import{resolveTodoSyncTargets as e}from"@x-otto/orchestration-contracts";function t(){return{delegated:new Map,todoList:[],currentTurn:0}}const n=new Set([`task_delegate`,`team_run`,`fork_call`]);function r(e){return new Set(e.filter(e=>e.metadata?.category===`orchestration`).map(e=>e.name))}function i(t,n){if(n.tracked===!1||(typeof n.mode==`string`?n.mode:`sync`)!==`sync`)return!1;let r=Array.isArray(n.taskIds)?n.taskIds.filter(e=>typeof e==`string`):void 0,i=e(t.todoList,r);return i.length===0?!1:(t.todoList=t.todoList.map(e=>e.id!=null&&i.includes(e.id)?{...e,status:`done`}:e),!0)}function a(e,t,r={}){let a=e.sessionId,s=r.isDelegationTool??(e=>n.has(e));switch(e.type){case`prompt.start`:return t.currentTurn++,[{sessionId:a,kind:`prompt.start`,text:e.text}];case`prompt.end`:{t.delegated.clear();let n=r.cacheHitRatio?.();return[{sessionId:a,kind:`delegate.update`,tasks:[]},{sessionId:a,kind:`prompt.end`,model:e.model??r.currentModel?.()??``,tokens:r.turnTokens?.(),cacheHitRatio:n??void 0,effort:e.thinkingLevel,stopReason:e.stopReason,errorMessage:e.errorMessage}]}case`turn.start`:return[{sessionId:a,kind:`turn.budget`,toolTurnCount:e.toolTurnCount,maxToolTurns:e.maxToolTurns,outputTokens:e.promptOutputTokens,outputTokenBudget:e.promptOutputTokenBudget}];case`stream.event`:{let t=e.event;switch(t.type){case`text_delta`:return[{sessionId:a,kind:`stream.text.delta`,delta:t.delta??``}];case`thinking_delta`:return[{sessionId:a,kind:`stream.thinking.delta`,delta:t.delta??``}];case`text_start`:return[{sessionId:a,kind:`stream.text.start`}];case`text_end`:return[{sessionId:a,kind:`stream.text.end`}];case`thinking_start`:return[{sessionId:a,kind:`stream.thinking.start`}];case`thinking_end`:return[{sessionId:a,kind:`stream.thinking.end`}];case`error`:return[{sessionId:a,kind:`error`,message:o(t.error),code:`STREAM_ERROR`}];case`start`:case`tool_call_start`:case`tool_call_delta`:case`tool_call_end`:case`done`:return[];default:return[]}}case`tool.call.start`:{let n=e.toolCall,r=[{sessionId:a,kind:`tool.start`,call:n}];if(s(n.name)){let e=n.arguments??{},i=e.subagent??e.agent??e.category??e.team,o=typeof e.prompt==`string`?e.prompt.replace(/\n/g,` `).slice(0,48):void 0;t.delegated.set(n.id,{id:n.id,name:typeof i==`string`?i:n.name,detail:o,status:`running`}),r.push({sessionId:a,kind:`delegate.update`,tasks:[...t.delegated.values()]})}return r}case`tool.call.end`:{let{toolCall:n,isError:o}=e,s=n.arguments??{},c=t=>({sessionId:a,kind:`tool.end`,call:n,isError:o,resultText:e.resultText??r.toolResultText?.(n),resultTokensEstimate:e.resultTokensEstimate,suppressMessage:t});if(n.name===`write_todos`&&Array.isArray(s.todos)){let e=s.todos;if(s.action===`update`)for(let n of e){let e=t.todoList.findIndex(e=>e.id===n.id);e>=0?t.todoList[e]={...t.todoList[e],...n,turn:t.currentTurn}:t.todoList.push({...n,turn:t.currentTurn})}else t.todoList=e.map(e=>({...e,turn:t.currentTurn}));return[c(!0),{sessionId:a,kind:`tasks.update`,tasks:[...t.todoList],title:s.title}]}if(t.delegated.has(n.id)){let e=t.delegated.get(n.id);t.delegated.set(n.id,{...e,status:o?`error`:`done`});let r=[{sessionId:a,kind:`delegate.update`,tasks:[...t.delegated.values()]},c()];return n.name===`task_delegate`&&!o&&i(t,s)&&r.push({sessionId:a,kind:`tasks.update`,tasks:[...t.todoList]}),r}return[c()]}case`session.start`:return[{sessionId:a,kind:`session.activity`,action:`created`}];case`session.end`:return[{sessionId:a,kind:`session.activity`,action:`ended`}];case`streaming.start`:return[{sessionId:a,kind:`session.status`,status:`streaming`,model:e.model}];case`streaming.end`:{let t=e;return[{sessionId:a,kind:`session.status`,status:`idle`,model:t.model,stopReason:t.stopReason}]}case`compaction.start`:return[{sessionId:a,kind:`session.status`,status:`compacting`,messageCount:e.messageCount}];case`compaction.end`:return[{sessionId:a,kind:`session.status`,status:`idle`,retainedCount:e.retainedCount}];case`approval.required`:{let t=e;return[{sessionId:a,kind:`approval.required`,id:t.id,toolName:t.toolName,arguments:t.arguments,description:t.description,risk:t.risk}]}case`approval.resolved`:{let t=e;return[{sessionId:a,kind:`approval.resolved`,id:t.id,approved:t.approved}]}case`ask.user.required`:{let t=e;return[{sessionId:a,kind:`ask.required`,requestId:t.requestId,question:t.question}]}case`ask.user.resolved`:return[{sessionId:a,kind:`ask.resolved`,requestId:e.requestId}];case`plan.approval.required`:{let t=e;return[{sessionId:a,kind:`plan.approval.required`,requestId:t.requestId,planContent:t.planContent}]}case`plan.approval.resolved`:{let t=e;return[{sessionId:a,kind:`plan.approval.resolved`,requestId:t.requestId,action:t.action}]}case`error`:return[{sessionId:a,kind:`error`,message:o(e.error),code:`SESSION_ERROR`}];case`prompt.continued`:case`messages.persist`:case`agent.status`:case`budget.notice`:case`prompt.budget.notice`:case`progress.stall.notice`:case`tool.call.mismatch.notice`:case`turn.idle.notice`:case`session.cost-budget-exceeded`:case`turn.end`:case`memory.pruned`:case`session.cleared`:case`run.paused`:case`run.resumed`:case`run.pause_requested`:case`run.pause_cancelled`:case`session.history-capped`:case`session.write-lease-denied`:case`session.write-lease-restored`:case`session.crash-gap-detected`:case`image.vision-delegate`:case`a2ui.action`:case`compaction.reactive.notice`:case`image.degradation.notice`:case`steer.consumed`:return[];default:return[]}}function o(e){return e instanceof Error?e.message:typeof e==`string`?e:`unknown error`}function s(e){return{answer:e.recommendation,acceptedRecommendation:!0,resolvedBy:`auto_recommendation`}}function c(e,t,n){if(t.length===0&&!n)return s(e);let r=(e.options??[]).filter(e=>e.recommended).map(e=>e.label),i=r.length>0&&t.length===r.length&&t.every(e=>r.includes(e)),a=t.length>0?t.join(`, `):``;return{answer:n?a?`${a}\n\n补充信息:${n}`:n:a,selectedOptionLabels:t.length>0?t:void 0,acceptedRecommendation:i,resolvedBy:`human`,freeformText:n}}function l(e,t){let n=t?.trim();return n?{answer:n,acceptedRecommendation:n===e.recommendation,resolvedBy:`human`}:s(e)}function u(e,t,n){return typeof e!=`string`||!e.includes(n)?null:(typeof t?.command==`string`?t.command:``)||null}function d(e,t){if(e===void 0)return t;let n=parseInt(e,10);return isNaN(n)||n<=0?t:n}const f=5e4,p=64*1024*1024,m=5e3,h=3e4,g=1024*1024*1024,_=16*1024*1024,v=1024*1024*1024;function y(e){return{totalBytes:e?.totalBytes??d(process.env.OTTO_SESSION_TOTAL_RESIDENCY_BUDGET,1073741824),minPerSessionBytes:e?.minPerSessionBytes??d(process.env.OTTO_SESSION_MIN_PER_SESSION_BYTES,16777216),maxPerSessionBytes:e?.maxPerSessionBytes??d(process.env.OTTO_SESSION_MAX_PER_SESSION_BYTES,1073741824),maxContentBytes:e?.maxContentBytes??d(process.env.OTTO_SESSION_MAX_CONTENT_BYTES,67108864),maxHistoryMessages:e?.maxHistoryMessages??d(process.env.OTTO_SESSION_MAX_HISTORY_MESSAGES,5e4),resumeWindowMessages:e?.resumeWindowMessages??d(process.env.OTTO_SESSION_RESUME_WINDOW_MESSAGES,5e3),compactionTimeoutMs:e?.compactionTimeoutMs??d(process.env.OTTO_SESSION_COMPACTION_TIMEOUT_MS,3e4)}}function b(e,t,n,r=Math.random){return!t.enabled||t.forcedUpgradeActive||n.lastShownTurn!==void 0&&e-n.lastShownTurn<t.minTurnGap?!1:r()<t.probability}export{n as DEFAULT_DELEGATION_TOOLS,h as SESSION_COMPACTION_TIMEOUT_MS,p as SESSION_MAX_CONTENT_BYTES,f as SESSION_MAX_HISTORY_MESSAGES,v as SESSION_MAX_PER_SESSION_BYTES,_ as SESSION_MIN_PER_SESSION_BYTES,m as SESSION_RESUME_WINDOW_MESSAGES,g as SESSION_TOTAL_RESIDENCY_BUDGET,s as autoAdoptAnswer,t as createProjectorState,r as deriveDelegationToolNames,a as projectSessionEvent,c as resolveChoiceAnswer,y as resolveResidencyBudget,l as resolveTextAnswer,u as sandboxBypassCommand,b as shouldShowPulseSurvey};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/project.ts","../src/requests.ts","../src/constants.ts","../src/pulse-survey-trigger.ts"],"sourcesContent":["/**\n * project.ts — 投影器:AgentSessionEvent/StreamEvent 子集 → SessionEvent[](前端无关事实)。\n *\n * 忠实复刻 cli.ts `session.subscribe` 同步部分。**投影器持有集合累加器**(delegated Map /\n * todoList),发 snapshot —— 合并逻辑只此一份,不让消费端各抄一遍。流式累加归 reducer(消费端)。\n */\nimport type { AgentSessionEvent } from '@x-otto/interchange'\nimport { resolveTodoSyncTargets } from '@x-otto/orchestration-contracts'\n\nimport type {\n SessionEvent,\n ProjectCtx,\n TaskItem,\n DelegatedTask,\n DelegatedArg,\n} from './types'\n\n// 直接用 ./types 的 canonical TaskItem/DelegatedTask 作累加器元素类型,\n// 取代本地结构同形的重声明(Todo/DelegatedEntry)——后者逼出 `as unknown as DelegatedArg/TaskItemArg`\n// 桥接「同形异名」。统一后 `[...values()]` 直接是 DelegatedArg/TaskItemArg,casts 全消。\nexport interface ProjectorState {\n delegated: Map<string, DelegatedTask>\n todoList: TaskItem[]\n /** 当前回合编号(1-based)。prompt.start 时自增。 */\n currentTurn: number\n}\nexport function createProjectorState(): ProjectorState {\n return { delegated: new Map(), todoList: [], currentTurn: 0 }\n}\n\n/**\n * 委托工具名的**回退集**(仅当宿主未注入 `ProjectCtx.isDelegationTool` 时使用)。\n *\n * 宿主装配时应从 ToolRegistry 按 `metadata.category === 'orchestration'` 派生实际集合\n * 注入投影器,使插件注册的新委托类工具能被投影器识别。本集合只是硬编码兜底,\n * 不应被消费方直接当真源使用(tui message-lines 的 SUBAGENT_TOOLS 是渲染层本地\n * 分类,从此处派生 + 本地补充 'Task' 是合理的本地需求)。\n */\nexport const DEFAULT_DELEGATION_TOOLS = new Set(['task_delegate', 'team_run', 'fork_call'])\n\n/**\n * 从工具列表派生委托工具名集——宿主装配时调用,结果注入 `ProjectCtx.isDelegationTool`。\n *\n * 按 `metadata.category === 'orchestration'` 过滤(与 tool-nodes.ts 的分类一致)。\n * 返回的 Set 直接用作 isDelegationTool 的谓词。\n */\nexport function deriveDelegationToolNames(\n tools: { name: string; metadata?: { category?: string } }[],\n): Set<string> {\n return new Set(\n tools\n .filter((t) => t.metadata?.category === 'orchestration')\n .map((t) => t.name),\n )\n}\n\n/**\n * 子代理完成后的 todo 自动同步——投影器侧调用方(规则逻辑归口 resolveTodoSyncTargets,\n * 单源在 @x-otto/orchestration-contracts/src/delegation.ts)。\n * 前置过滤(tracked/mode)留在此处,只管\"该不该同步\"的判定;\n * \"标哪些项 done\"的规则逻辑调 resolveTodoSyncTargets。\n * 返回是否发生了变更(据此决定是否发 tasks.update)。\n */\nfunction applyDelegateTodoSync(state: ProjectorState, args: Record<string, unknown>): boolean {\n // RFC-302 D8:untracked(tracked:false)走 callAgent 旁路,宿主侧不经\n // syncTodosOnSubagentComplete——镜像必须同门,否则 TUI/session metadata 误标 done。\n if (args.tracked === false) return false\n const mode = typeof args.mode === 'string' ? args.mode : 'sync'\n if (mode !== 'sync') return false\n\n const taskIds = Array.isArray(args.taskIds)\n ? (args.taskIds as unknown[]).filter((x): x is string => typeof x === 'string')\n : undefined\n\n const targetIds = resolveTodoSyncTargets(state.todoList, taskIds)\n if (targetIds.length === 0) return false\n\n state.todoList = state.todoList.map((t) =>\n t.id != null && targetIds.includes(t.id) ? { ...t, status: 'done' as const } : t,\n )\n return true\n}\n\nexport function projectSessionEvent(\n event: AgentSessionEvent,\n state: ProjectorState,\n ctx: ProjectCtx = {},\n): SessionEvent[] {\n const sessionId = event.sessionId\n const isDelegation = ctx.isDelegationTool ?? ((n: string) => DEFAULT_DELEGATION_TOOLS.has(n))\n\n switch (event.type) {\n case 'prompt.start':\n state.currentTurn++\n return [\n {\n sessionId,\n kind: 'prompt.start',\n text: event.text,\n },\n ]\n\n case 'prompt.end': {\n state.delegated.clear()\n const ratio = ctx.cacheHitRatio?.()\n return [\n { sessionId, kind: 'delegate.update', tasks: [] satisfies DelegatedArg },\n {\n sessionId,\n kind: 'prompt.end',\n // 优先用事件自带的模型快照(AgentSession 在 prompt() 入口捕获的\"这一轮实际执行模型\");\n // 缺省(旧事件/未来其它来源)时兜底走 ctx.currentModel() 惰性读取活跃 session.model。\n model: event.model ?? ctx.currentModel?.() ?? '',\n tokens: ctx.turnTokens?.(),\n cacheHitRatio: ratio == null ? undefined : ratio,\n effort: event.thinkingLevel,\n stopReason: event.stopReason,\n },\n ]\n }\n\n case 'turn.start':\n return [\n {\n sessionId,\n kind: 'turn.budget',\n toolTurnCount: event.toolTurnCount,\n maxToolTurns: event.maxToolTurns,\n outputTokens: event.promptOutputTokens,\n outputTokenBudget: event.promptOutputTokenBudget,\n },\n ]\n\n case 'stream.event': {\n const e = event.event\n switch (e.type) {\n case 'text_delta':\n return [{ sessionId, kind: 'stream.text.delta', delta: e.delta ?? '' }]\n case 'thinking_delta':\n return [{ sessionId, kind: 'stream.thinking.delta', delta: e.delta ?? '' }]\n case 'text_start':\n return [{ sessionId, kind: 'stream.text.start' }]\n case 'text_end':\n return [{ sessionId, kind: 'stream.text.end' }]\n case 'thinking_start':\n return [{ sessionId, kind: 'stream.thinking.start' }]\n case 'thinking_end':\n return [{ sessionId, kind: 'stream.thinking.end' }]\n case 'error':\n return [{ sessionId, kind: 'error', message: errMessage(e.error), code: 'STREAM_ERROR' }]\n // 08-12 review W5:以下成员**有意不投影**(与 AgentSessionEvent 投影的「显式空\n // case + 穷举 default」纪律对齐)——此前它们静默落入 `default: return []`,\n // 新增 StreamEvent 成员时编译器不会提示投影器漏处理(静默丢弃盲区)。\n // - start/tool_call_start/tool_call_delta/tool_call_end:工具调用细节经独立的\n // tool.call.start/end AgentSessionEvent 投影,不经 stream.event 透传;\n // - done:回合完成经 prompt.end/turn.budget AgentSessionEvent 投影(含\n // usage/stopReason/model),不经 stream.event 透传。\n case 'start':\n case 'tool_call_start':\n case 'tool_call_delta':\n case 'tool_call_end':\n case 'done':\n return []\n default: {\n // 编译期穷举守卫:e 在所有显式 case 之后应为 never。新增 StreamEvent 成员\n // 漏写 case 时这行赋值报 TS2322,指向本文件强制处理(与外层 switch 同纪律)。\n const _exhaustive: never = e\n void _exhaustive\n return []\n }\n }\n }\n\n case 'tool.call.start': {\n const call = event.toolCall\n const out: SessionEvent[] = [{ sessionId, kind: 'tool.start', call }]\n if (isDelegation(call.name)) {\n const a = call.arguments ?? {}\n const label = a.subagent ?? a.agent ?? a.category ?? a.team\n const detail =\n typeof a.prompt === 'string' ? a.prompt.replace(/\\n/g, ' ').slice(0, 48) : undefined\n state.delegated.set(call.id, {\n id: call.id,\n name: typeof label === 'string' ? label : call.name,\n detail,\n status: 'running',\n })\n out.push({\n sessionId,\n kind: 'delegate.update',\n tasks: [...state.delegated.values()],\n })\n }\n return out\n }\n\n case 'tool.call.end': {\n const { toolCall: call, isError } = event\n const args = call.arguments ?? {}\n const mkToolEnd = (suppressMessage?: boolean): SessionEvent => ({\n sessionId,\n kind: 'tool.end',\n call,\n isError,\n // 残影修复(2026-07):优先用事件自带的 resultText(按本次 toolCall 精确对应,\n // AgentSession.onToolCallEnd 在产生处构造)。ctx.toolResultText 仅作旧数据兼容\n // 回退(如 replay 老 trace 无该字段的场景)——它从 session.messages() 倒查\"最后\n // 一条 tool_result\",在并行/异步工具场景下会与当前 call 错配(残影根因),新代码\n // 路径不应再依赖它。\n resultText: event.resultText ?? ctx.toolResultText?.(call),\n resultTokensEstimate: event.resultTokensEstimate,\n suppressMessage,\n })\n\n if (call.name === 'write_todos' && Array.isArray(args.todos)) {\n // 边界:write_todos 工具实参是未定型 wire 数据;此处单点定型为 TaskItem[]。\n const incoming = args.todos as TaskItem[]\n if (args.action === 'update') {\n for (const t of incoming) {\n const i = state.todoList.findIndex((x) => x.id === t.id)\n if (i >= 0) state.todoList[i] = { ...state.todoList[i], ...t, turn: state.currentTurn }\n else state.todoList.push({ ...t, turn: state.currentTurn })\n }\n } else {\n state.todoList = incoming.map((t) => ({ ...t, turn: state.currentTurn }))\n }\n return [\n mkToolEnd(true),\n {\n sessionId,\n kind: 'tasks.update',\n tasks: [...state.todoList],\n title: args.title as string | undefined,\n },\n ]\n }\n\n if (state.delegated.has(call.id)) {\n const task = state.delegated.get(call.id)!\n state.delegated.set(call.id, { ...task, status: isError ? 'error' : 'done' })\n const out: SessionEvent[] = [\n {\n sessionId,\n kind: 'delegate.update',\n tasks: [...state.delegated.values()],\n },\n mkToolEnd(),\n ]\n // 镜像宿主的子代理 todo 自动同步(tools/orchestration/dispatched-task.ts\n // syncTodosOnSubagentComplete):该同步直调 orchestrator.writeTodos、不产生\n // write_todos 工具事件,若不在此镜像,TUI 面板与 session metadata 永远收不到\n // (泄漏根因)。规则两处必须一致:仅 sync 模式 + 非错误;taskIds 显式 → 标这些项\n // done;未指定且恰好一个 in_progress → 标它 done;其余不动。\n if (call.name === 'task_delegate' && !isError) {\n const synced = applyDelegateTodoSync(state, args)\n if (synced) {\n out.push({ sessionId, kind: 'tasks.update', tasks: [...state.todoList] })\n }\n }\n return out\n }\n\n return [mkToolEnd()]\n }\n\n // —— 会话生命周期 / 状态 ——\n case 'session.start':\n return [{ sessionId, kind: 'session.activity', action: 'created' }]\n case 'session.end':\n return [{ sessionId, kind: 'session.activity', action: 'ended' }]\n case 'streaming.start': {\n const e = event\n return [{ sessionId, kind: 'session.status', status: 'streaming', model: e.model }]\n }\n case 'streaming.end': {\n const e = event\n return [\n { sessionId, kind: 'session.status', status: 'idle', model: e.model, stopReason: e.stopReason },\n ]\n }\n case 'compaction.start': {\n const e = event\n return [{ sessionId, kind: 'session.status', status: 'compacting', messageCount: e.messageCount }]\n }\n case 'compaction.end': {\n const e = event\n return [{ sessionId, kind: 'session.status', status: 'idle', retainedCount: e.retainedCount }]\n }\n\n // —— HITL(审批 / 问询 / 计划批准)——\n case 'approval.required': {\n const e = event\n return [\n {\n sessionId,\n kind: 'approval.required',\n id: e.id,\n toolName: e.toolName,\n arguments: e.arguments,\n description: e.description,\n risk: e.risk,\n },\n ]\n }\n case 'approval.resolved': {\n const e = event\n return [{ sessionId, kind: 'approval.resolved', id: e.id, approved: e.approved }]\n }\n case 'ask.user.required': {\n const e = event\n return [{ sessionId, kind: 'ask.required', requestId: e.requestId, question: e.question }]\n }\n case 'ask.user.resolved': {\n const e = event\n return [{ sessionId, kind: 'ask.resolved', requestId: e.requestId }]\n }\n case 'plan.approval.required': {\n const e = event\n return [\n { sessionId, kind: 'plan.approval.required', requestId: e.requestId, planContent: e.planContent },\n ]\n }\n case 'plan.approval.resolved': {\n const e = event\n return [{ sessionId, kind: 'plan.approval.resolved', requestId: e.requestId, action: e.action }]\n }\n\n // —— 错误 ——\n case 'error': {\n const e = event\n return [{ sessionId, kind: 'error', message: errMessage(e.error), code: 'SESSION_ERROR' }]\n }\n\n // —— 有意不投影的事件(终局审查 2026-07-18 S1:显式列出 + never 穷举守卫)——\n // 此前这些类型静默落入 `default: return []`——问题是新增 AgentSessionEvent 成员时\n // 编译器不会提示投影器漏了处理(静默丢弃,前端永远看不到)。显式空 case + default\n // never 断言后:interchange 新增事件类型 → 此 switch 编译失败 → 强制显式决策\n // (投影 or 声明不投影),\"漏投影\"从运行时静默 bug 变为编译期错误。\n case 'prompt.continued': // TUI 经 AgentSessionEvent 直接消费(todo 闸门续跑提示),无 SessionEvent 投影\n case 'messages.persist': // 持久化内部信号,非用户可见事实\n case 'agent.status': // 引擎状态机内部迁移,前端消费 streaming.start/end 粒度即可\n case 'budget.notice': // TUI 经原始事件直接消费(预算提示条)\n case 'prompt.budget.notice': // 同上\n case 'progress.stall.notice': // RFC-203:早期停滞检出提示,TUI 经原始事件直接消费(同 budget.notice 纹理)\n case 'tool.call.mismatch.notice': // RFC-232:工具调用协议违约提示,TUI 经原始事件直接消费(同上纹理)\n case 'session.cost-budget-exceeded': // RFC-204:会话成本预算提醒,TUI 经原始事件直接消费(同上纹理)\n case 'turn.end': // turn.start 已携带回合边界信息,end 无增量事实\n case 'memory.pruned': // 裁剪可观测性走 trace,非会话转录事实\n case 'session.cleared': // clear 由发起端(命令层)自行反馈,投影层无需重复\n case 'run.paused': // 暂停/恢复由 TUI 经原始事件消费(RFC-180)\n case 'run.resumed':\n case 'run.pause_requested': // 暂停请求/取消同上(RFC-186 D2/D4 事件拆分;feae2243 加事件时漏补本穷举)\n case 'run.pause_cancelled':\n case 'session.history-capped': // 驻留裁剪可观测性由 TUI/trace 经原始事件消费(RFC-178)\n case 'session.write-lease-denied': // 写租约状态由 TUI 经原始事件 toast(RFC-159 D3)\n case 'session.write-lease-restored':\n case 'session.crash-gap-detected': // 崩溃丢失对账告警由 TUI 经原始事件 toast(RFC-305 D3)\n case 'image.vision-delegate': // 视觉委托统计由 TUI 经原始事件消费(RFC-181)\n case 'a2ui.action': // A2UI 组件动作由面板宿主经原始事件消费(RFC-105 D6)\n case 'compaction.reactive.notice': // 反应式压缩由 TUI 经原始事件消费(终局 review 2026-07-21,复用 compact_boundary/compactionLog)\n case 'image.degradation.notice': // 图片降级兜底由 TUI 经原始事件消费 toast(终局 review 2026-07-21)\n case 'steer.consumed': // RFC-337 D3:steer 待定回显转正信号,TUI 经原始事件直接消费(commitPendingSteer);web/service 前端无 pendingSteer UI 概念,无投影\n return []\n\n default: {\n // 编译期穷举守卫:event 在所有显式 case 之后应为 never。新增事件类型漏写 case 时\n // 这行赋值报 TS2322,指向本文件强制处理。\n const _exhaustive: never = event\n void _exhaustive\n return []\n }\n }\n}\n\nfunction errMessage(err: unknown): string {\n if (err instanceof Error) return err.message\n if (typeof err === 'string') return err\n return 'unknown error'\n}\n","/**\n * requests.ts — 请求子通道的**纯决策逻辑**(ask_user 自动采纳 / approval 沙箱升级)。\n *\n * cli 的异步处理器(session.subscribe 的 ask.user.required / approval.required)仍持控制流\n * (await UI + session.resolve*),但把「该解析成什么答案」「要不要 bypass」这两段易错的安全关键\n * 决策下沉到这些纯函数 —— 可单测、对齐「取消/留空绝不悬挂工具,自动采纳推荐」纪律。\n */\n\nexport interface AskQuestionLike {\n recommendation: string\n options?: { label: string; recommended?: boolean }[]\n}\n\nexport interface AskAnswer {\n answer: string\n selectedOptionLabels?: string[]\n acceptedRecommendation: boolean\n resolvedBy: 'human' | 'auto_recommendation'\n /** grill_me allowFreeform:用户在选项之外输入的补充文字。 */\n freeformText?: string\n}\n\n/** 取消/留空 → 自动采纳推荐(resolvedBy=auto_recommendation;绝不悬挂工具)。 */\nexport function autoAdoptAnswer(q: AskQuestionLike): AskAnswer {\n return { answer: q.recommendation, acceptedRecommendation: true, resolvedBy: 'auto_recommendation' }\n}\n\n/** 单/多选题+可选自由文本:据用户已选 label(调用方须先去 ★ 装饰)解析。空选 → 自动采纳。\n * acceptedRecommendation:当且仅当选中集恰等于推荐集(非空)。 */\nexport function resolveChoiceAnswer(q: AskQuestionLike, selected: string[], freeformText?: string): AskAnswer {\n if (selected.length === 0 && !freeformText) return autoAdoptAnswer(q)\n const recommended = (q.options ?? []).filter((o) => o.recommended).map((o) => o.label)\n const accepted =\n recommended.length > 0 &&\n selected.length === recommended.length &&\n selected.every((l) => recommended.includes(l))\n const answer = selected.length > 0 ? selected.join(', ') : ''\n const fullAnswer = freeformText ? (answer ? `${answer}\\n\\n补充信息:${freeformText}` : freeformText) : answer\n return { answer: fullAnswer, selectedOptionLabels: selected.length > 0 ? selected : undefined, acceptedRecommendation: accepted, resolvedBy: 'human', freeformText }\n}\n\n/** 自由文本题:空/取消 → 自动采纳;否则人答(文本等于推荐才算采纳)。 */\nexport function resolveTextAnswer(q: AskQuestionLike, text: string | null | undefined): AskAnswer {\n const t = text?.trim()\n if (!t) return autoAdoptAnswer(q)\n return { answer: t, acceptedRecommendation: t === q.recommendation, resolvedBy: 'human' }\n}\n\n/** 沙箱升级 approval:描述带 marker 且参数含 command → 返回需 bypass 的命令,否则 null。\n * 调用方仅在「已批准」时据返回值放行(早于 resolveApproval,approval=escalated 语义)。 */\nexport function sandboxBypassCommand(\n description: unknown,\n args: Record<string, unknown> | undefined,\n marker: string,\n): string | null {\n if (typeof description !== 'string' || !description.includes(marker)) return null\n const cmd = typeof args?.command === 'string' ? args.command : ''\n return cmd || null\n}\n","/**\n * 08-13 终局 review B9:契约包依赖纯净性——本包不再依赖 `@x-otto/env`。\n *\n * env 的 `normalizeEnv` 核心是\"parseInt 正整数校验 + 回退默认 + 诊断\"。契约包此前\n * 为这一语义 import 整个运行时环境包(path 常量/端口配置等无关面一并进入依赖图)。\n * 本包内联最小等价实现(8 行)。\n *\n * **RFC-422 D5(2026-08-14):env 读取从模块加载期移入 resolveResidencyBudget 函数内部**。\n * 此前常量在模块顶层 `parsePositiveIntEnv(process.env[...], 默认)` 读 env → 值被烘焙进\n * 常量 → `resolveResidencyBudget` 通过 `?? 常量` 间接获得 env 值。这造成\"双通道配置\"缺陷:\n * 模块加载期 env 快照 + 运行时 settings 注入,合并优先级靠调用方约定(app.ts 的 pick()\n * 读 process.env 判断 env 是否设置),类型系统无法强制。\n *\n * 变更后:常量退化为纯默认值(不读 env),`parsePositiveIntEnv` 移入\n * `resolveResidencyBudget` 函数内部——运行时被调用时对每个字段执行\n * `settings值 ?? parsePositiveIntEnv(env, 默认值)`。env 与 settings 的优先级\n * 由 resolveResidencyBudget 内部统一处理(settings 优先于 env,调用方不再需要\n * 判断 env 是否设置)。\n *\n * **诊断策略(08-13 终局复核修订)**:非法值**静默回退默认**,不做任何 stderr/警告\n * 副作用。理由:①契约包是\"纯层\",不应拥有输出副作用;②这些常量是治理闸、默认值即\n * 正确基线(fail-open),诊断是边际价值。误配置的可观测性由 env 包的\n * OTTO_*_STRICT 校验与设置面板承担,不在本包职责。\n *\n * 正确性保证不变:非法/缺失值一律回退默认(fail-open,默认值即治理闸的正确基线)。\n */\nfunction parsePositiveIntEnv(value: string | undefined, defaultValue: number): number {\n if (value === undefined) return defaultValue\n const parsed = parseInt(value, 10)\n if (isNaN(parsed) || parsed <= 0) {\n return defaultValue\n }\n return parsed\n}\n\n/**\n * 会话历史存储**条数**上限——**结构兜底闸**(RFC-321 D7 闸位重排,2026-08-07)。\n *\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。env 覆盖由 resolveResidencyBudget\n * 在运行时处理。\n *\n * **不是内存治理主闸**。主闸是 `SESSION_MAX_CONTENT_BYTES`(字节维度,见下);本常量\n * 只防\"条目数爆炸\"这一字节维度管不到的 CPU 问题。\n *\n * **与模型上下文无关**(RFC-053 规则 1,不可削弱):上下文该看多少历史只由 token 那套\n * 决定。本上限只影响**内存视图**;DB 侧 append-forever(RFC-159 D1)。\n */\nexport const SESSION_MAX_HISTORY_MESSAGES = 50_000\n\n/**\n * 会话消息内容字节估算预算——**回退默认值**(RFC-323 后非主闸)。\n *\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n *\n * 语义变更见 RFC-323 的 ResidencyAllocator 已成为实际主闸。本常量为分配器缺席时\n * 的回退默认值。\n */\nexport const SESSION_MAX_CONTENT_BYTES = 64 * 1024 * 1024\n\n/**\n * 会话 resume 时的**尾窗口装载条数**(RFC-321 D7 新增,与条数 cap 解耦)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_RESUME_WINDOW_MESSAGES = 5_000\n\n/**\n * RFC-324 D1/R5:turn-gated 压缩的超时兜底(毫秒,默认 30s,G1 已 grill 确认)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_COMPACTION_TIMEOUT_MS = 30_000\n\n/**\n * RFC-323:进程级驻留总预算(估算口径)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_TOTAL_RESIDENCY_BUDGET = 1024 * 1024 * 1024\n\n/**\n * RFC-323:单会话字节预算下界(N 极大时不被摊薄到无法工作)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_MIN_PER_SESSION_BYTES = 16 * 1024 * 1024\n\n/**\n * RFC-323:单会话字节预算上界(N=1 时的封顶)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_MAX_PER_SESSION_BYTES = 1024 * 1024 * 1024\n\n/**\n * RFC-323 M4:驻留预算的运行时配置对象。\n *\n * 存在理由(D6b):上方常量在模块加载时立即求值为 number(env 快照),无法反映\n * app 启动后才 load 的 settings.json。故运行时读值点改从本对象读——由 app 层合并\n * `env(上方常量)> settings > 默认` 后注入。所有字段可选,缺省回退对应常量。\n */\nexport interface ResidencyBudgetConfig {\n totalBytes?: number\n minPerSessionBytes?: number\n maxPerSessionBytes?: number\n maxContentBytes?: number\n maxHistoryMessages?: number\n resumeWindowMessages?: number\n /**\n * RFC-324 D1/R5:turn-gated 压缩的超时兜底(毫秒)。逃生阀压缩超过此值仍未完成时,\n * 降级为 fire-and-forget——**不允许压缩未完成就永久阻塞 turn**。\n */\n compactionTimeoutMs?: number\n}\n\n/**\n * RFC-323 M4:合并 settings 覆盖到 env/默认常量之上,产出完整的 ResidencyBudgetConfig。\n *\n * RFC-422 D5:env 读取从模块加载期移入本函数内部。\n * 优先级:**settings > env > 默认常量**(settings 显式传入的值优先;否则读 env;\n * env 也未设置则回退到纯默认常量)。此前优先级是 env > settings > 默认(靠调用方\n * pick() 判断 env 是否设置)——现在 settings 优先于 env 是更直观的语义(用户在\n * .otto/config.json 里显式写的值应该覆盖环境变量),且消除了调用方约定。\n *\n * 注意:常量本身已是纯默认值(不再读 env),env 读取在本函数内运行时求值。\n */\nexport function resolveResidencyBudget(\n settings?: ResidencyBudgetConfig,\n): Required<ResidencyBudgetConfig> {\n return {\n totalBytes: settings?.totalBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_TOTAL_RESIDENCY_BUDGET'], SESSION_TOTAL_RESIDENCY_BUDGET),\n minPerSessionBytes: settings?.minPerSessionBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MIN_PER_SESSION_BYTES'], SESSION_MIN_PER_SESSION_BYTES),\n maxPerSessionBytes: settings?.maxPerSessionBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MAX_PER_SESSION_BYTES'], SESSION_MAX_PER_SESSION_BYTES),\n maxContentBytes: settings?.maxContentBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MAX_CONTENT_BYTES'], SESSION_MAX_CONTENT_BYTES),\n maxHistoryMessages: settings?.maxHistoryMessages ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MAX_HISTORY_MESSAGES'], SESSION_MAX_HISTORY_MESSAGES),\n resumeWindowMessages: settings?.resumeWindowMessages ?? parsePositiveIntEnv(process.env['OTTO_SESSION_RESUME_WINDOW_MESSAGES'], SESSION_RESUME_WINDOW_MESSAGES),\n compactionTimeoutMs: settings?.compactionTimeoutMs ?? parsePositiveIntEnv(process.env['OTTO_SESSION_COMPACTION_TIMEOUT_MS'], SESSION_COMPACTION_TIMEOUT_MS),\n }\n}\n","/**\n * pulse-survey-trigger.ts — RFC-208 §2.1/§3.1:满意度脉冲调查触发判定纯函数。\n * RFC-209 M3:从 packages/cli 下沉至此(cli 与 service 均已依赖 @x-otto/session-contract,\n * 而 service 不应依赖 cli——EventBridge 需要复用本函数做 web-ui 侧 `pulse-survey.show`\n * 触发判定,见 RFC-209 milestone 执行阶段 grill 确认)。\n *\n * 纯逻辑类,不依赖 @x-otto/tui/@x-otto/coding 类型——判定「本次 prompt.end 是否应展示脉冲调查」,\n * 实际展示(tui.setPulseSurvey / web-ui pulse-survey.show)与数据写入(FeedbackRegistry)\n * 留在调用方(cli 侧 interactive-events.ts / service 侧 event-bridge.ts)。\n *\n * 触发锚点是 prompt.end(对话轮次真正结束的权威时点),按可配置概率随机抽样而非固定周期——\n * 固定周期容易被用户学习产生\"来了、又是这个\"的疲劳感;抽样配合最小回合间隔更接近\"偶尔冒出,\n * 不成为负担\"的调性。判定逻辑必须是纯函数、接受注入的 `random` 参数(RFC-208 重要事项规则 5)\n * ——不得在函数内部直接硬编码调用 `Math.random()`,保证可测试性(CLI 交互层直接用 Math.random\n * 有先例,见 draft-entries.ts,但触发判定这类需要精确验证边界值的逻辑必须可注入固定值测试)。\n *\n * `lastShownTurn` 是进程内存态,不持久化跨会话——重启 otto 后重新从零计间隔,符合\"轻量抽样,\n * 不需要跨会话精确统计\"的调性,避免为此引入额外的持久化状态文件。\n */\n\nexport interface PulseSurveyTriggerState {\n lastShownTurn?: number\n}\n\nexport interface PulseSurveyTriggerConfig {\n enabled: boolean\n probability: number\n minTurnGap: number\n /**\n * 当前是否有 Band A hard modal(如 forcedUpgrade)在场——为真时恒不触发(RFC-208 §5\n * 风险段\"forced-upgrade 并发\"缓解措施之一)。调用方传入 `modals.forcedUpgrade` 等值。\n */\n forcedUpgradeActive: boolean\n}\n\n/**\n * 判定本次 `prompt.end` 是否应展示满意度脉冲调查。\n *\n * @param currentTurn 当前对话轮次(`projState.currentTurn`)\n * @param config 触发配置(来自 `.otto/config.json` 的 `pulse_survey` 块 + 当前 Band A 状态)\n * @param state 触发状态(`lastShownTurn` 进程内存态,调用方持有并在命中时更新)\n * @param random 随机数源,默认 `Math.random`;测试注入固定值验证确定性\n */\nexport function shouldShowPulseSurvey(\n currentTurn: number,\n config: PulseSurveyTriggerConfig,\n state: PulseSurveyTriggerState,\n random: () => number = Math.random,\n): boolean {\n if (!config.enabled) return false\n if (config.forcedUpgradeActive) return false\n if (state.lastShownTurn !== undefined && currentTurn - state.lastShownTurn < config.minTurnGap) return false\n return random() < config.probability\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/project.ts","../src/requests.ts","../src/constants.ts","../src/pulse-survey-trigger.ts"],"sourcesContent":["/**\n * project.ts — 投影器:AgentSessionEvent/StreamEvent 子集 → SessionEvent[](前端无关事实)。\n *\n * 忠实复刻 cli.ts `session.subscribe` 同步部分。**投影器持有集合累加器**(delegated Map /\n * todoList),发 snapshot —— 合并逻辑只此一份,不让消费端各抄一遍。流式累加归 reducer(消费端)。\n */\nimport type { AgentSessionEvent } from '@x-otto/interchange'\nimport { resolveTodoSyncTargets } from '@x-otto/orchestration-contracts'\n\nimport type {\n SessionEvent,\n ProjectCtx,\n TaskItem,\n DelegatedTask,\n DelegatedArg,\n} from './types'\n\n// 直接用 ./types 的 canonical TaskItem/DelegatedTask 作累加器元素类型,\n// 取代本地结构同形的重声明(Todo/DelegatedEntry)——后者逼出 `as unknown as DelegatedArg/TaskItemArg`\n// 桥接「同形异名」。统一后 `[...values()]` 直接是 DelegatedArg/TaskItemArg,casts 全消。\nexport interface ProjectorState {\n delegated: Map<string, DelegatedTask>\n todoList: TaskItem[]\n /** 当前回合编号(1-based)。prompt.start 时自增。 */\n currentTurn: number\n}\nexport function createProjectorState(): ProjectorState {\n return { delegated: new Map(), todoList: [], currentTurn: 0 }\n}\n\n/**\n * 委托工具名的**回退集**(仅当宿主未注入 `ProjectCtx.isDelegationTool` 时使用)。\n *\n * 宿主装配时应从 ToolRegistry 按 `metadata.category === 'orchestration'` 派生实际集合\n * 注入投影器,使插件注册的新委托类工具能被投影器识别。本集合只是硬编码兜底,\n * 不应被消费方直接当真源使用(tui message-lines 的 SUBAGENT_TOOLS 是渲染层本地\n * 分类,从此处派生 + 本地补充 'Task' 是合理的本地需求)。\n */\nexport const DEFAULT_DELEGATION_TOOLS = new Set(['task_delegate', 'team_run', 'fork_call'])\n\n/**\n * 从工具列表派生委托工具名集——宿主装配时调用,结果注入 `ProjectCtx.isDelegationTool`。\n *\n * 按 `metadata.category === 'orchestration'` 过滤(与 tool-nodes.ts 的分类一致)。\n * 返回的 Set 直接用作 isDelegationTool 的谓词。\n */\nexport function deriveDelegationToolNames(\n tools: { name: string; metadata?: { category?: string } }[],\n): Set<string> {\n return new Set(\n tools\n .filter((t) => t.metadata?.category === 'orchestration')\n .map((t) => t.name),\n )\n}\n\n/**\n * 子代理完成后的 todo 自动同步——投影器侧调用方(规则逻辑归口 resolveTodoSyncTargets,\n * 单源在 @x-otto/orchestration-contracts/src/delegation.ts)。\n * 前置过滤(tracked/mode)留在此处,只管\"该不该同步\"的判定;\n * \"标哪些项 done\"的规则逻辑调 resolveTodoSyncTargets。\n * 返回是否发生了变更(据此决定是否发 tasks.update)。\n */\nfunction applyDelegateTodoSync(state: ProjectorState, args: Record<string, unknown>): boolean {\n // RFC-302 D8:untracked(tracked:false)走 callAgent 旁路,宿主侧不经\n // syncTodosOnSubagentComplete——镜像必须同门,否则 TUI/session metadata 误标 done。\n if (args.tracked === false) return false\n const mode = typeof args.mode === 'string' ? args.mode : 'sync'\n if (mode !== 'sync') return false\n\n const taskIds = Array.isArray(args.taskIds)\n ? (args.taskIds as unknown[]).filter((x): x is string => typeof x === 'string')\n : undefined\n\n const targetIds = resolveTodoSyncTargets(state.todoList, taskIds)\n if (targetIds.length === 0) return false\n\n state.todoList = state.todoList.map((t) =>\n t.id != null && targetIds.includes(t.id) ? { ...t, status: 'done' as const } : t,\n )\n return true\n}\n\nexport function projectSessionEvent(\n event: AgentSessionEvent,\n state: ProjectorState,\n ctx: ProjectCtx = {},\n): SessionEvent[] {\n const sessionId = event.sessionId\n const isDelegation = ctx.isDelegationTool ?? ((n: string) => DEFAULT_DELEGATION_TOOLS.has(n))\n\n switch (event.type) {\n case 'prompt.start':\n state.currentTurn++\n return [\n {\n sessionId,\n kind: 'prompt.start',\n text: event.text,\n },\n ]\n\n case 'prompt.end': {\n state.delegated.clear()\n const ratio = ctx.cacheHitRatio?.()\n return [\n { sessionId, kind: 'delegate.update', tasks: [] satisfies DelegatedArg },\n {\n sessionId,\n kind: 'prompt.end',\n // 优先用事件自带的模型快照(AgentSession 在 prompt() 入口捕获的\"这一轮实际执行模型\");\n // 缺省(旧事件/未来其它来源)时兜底走 ctx.currentModel() 惰性读取活跃 session.model。\n model: event.model ?? ctx.currentModel?.() ?? '',\n tokens: ctx.turnTokens?.(),\n cacheHitRatio: ratio == null ? undefined : ratio,\n effort: event.thinkingLevel,\n stopReason: event.stopReason,\n errorMessage: event.errorMessage,\n },\n ]\n }\n\n case 'turn.start':\n return [\n {\n sessionId,\n kind: 'turn.budget',\n toolTurnCount: event.toolTurnCount,\n maxToolTurns: event.maxToolTurns,\n outputTokens: event.promptOutputTokens,\n outputTokenBudget: event.promptOutputTokenBudget,\n },\n ]\n\n case 'stream.event': {\n const e = event.event\n switch (e.type) {\n case 'text_delta':\n return [{ sessionId, kind: 'stream.text.delta', delta: e.delta ?? '' }]\n case 'thinking_delta':\n return [{ sessionId, kind: 'stream.thinking.delta', delta: e.delta ?? '' }]\n case 'text_start':\n return [{ sessionId, kind: 'stream.text.start' }]\n case 'text_end':\n return [{ sessionId, kind: 'stream.text.end' }]\n case 'thinking_start':\n return [{ sessionId, kind: 'stream.thinking.start' }]\n case 'thinking_end':\n return [{ sessionId, kind: 'stream.thinking.end' }]\n case 'error':\n return [{ sessionId, kind: 'error', message: errMessage(e.error), code: 'STREAM_ERROR' }]\n // 08-12 review W5:以下成员**有意不投影**(与 AgentSessionEvent 投影的「显式空\n // case + 穷举 default」纪律对齐)——此前它们静默落入 `default: return []`,\n // 新增 StreamEvent 成员时编译器不会提示投影器漏处理(静默丢弃盲区)。\n // - start/tool_call_start/tool_call_delta/tool_call_end:工具调用细节经独立的\n // tool.call.start/end AgentSessionEvent 投影,不经 stream.event 透传;\n // - done:回合完成经 prompt.end/turn.budget AgentSessionEvent 投影(含\n // usage/stopReason/model),不经 stream.event 透传。\n case 'start':\n case 'tool_call_start':\n case 'tool_call_delta':\n case 'tool_call_end':\n case 'done':\n return []\n default: {\n // 编译期穷举守卫:e 在所有显式 case 之后应为 never。新增 StreamEvent 成员\n // 漏写 case 时这行赋值报 TS2322,指向本文件强制处理(与外层 switch 同纪律)。\n const _exhaustive: never = e\n void _exhaustive\n return []\n }\n }\n }\n\n case 'tool.call.start': {\n const call = event.toolCall\n const out: SessionEvent[] = [{ sessionId, kind: 'tool.start', call }]\n if (isDelegation(call.name)) {\n const a = call.arguments ?? {}\n const label = a.subagent ?? a.agent ?? a.category ?? a.team\n const detail =\n typeof a.prompt === 'string' ? a.prompt.replace(/\\n/g, ' ').slice(0, 48) : undefined\n state.delegated.set(call.id, {\n id: call.id,\n name: typeof label === 'string' ? label : call.name,\n detail,\n status: 'running',\n })\n out.push({\n sessionId,\n kind: 'delegate.update',\n tasks: [...state.delegated.values()],\n })\n }\n return out\n }\n\n case 'tool.call.end': {\n const { toolCall: call, isError } = event\n const args = call.arguments ?? {}\n const mkToolEnd = (suppressMessage?: boolean): SessionEvent => ({\n sessionId,\n kind: 'tool.end',\n call,\n isError,\n // 残影修复(2026-07):优先用事件自带的 resultText(按本次 toolCall 精确对应,\n // AgentSession.onToolCallEnd 在产生处构造)。ctx.toolResultText 仅作旧数据兼容\n // 回退(如 replay 老 trace 无该字段的场景)——它从 session.messages() 倒查\"最后\n // 一条 tool_result\",在并行/异步工具场景下会与当前 call 错配(残影根因),新代码\n // 路径不应再依赖它。\n resultText: event.resultText ?? ctx.toolResultText?.(call),\n resultTokensEstimate: event.resultTokensEstimate,\n suppressMessage,\n })\n\n if (call.name === 'write_todos' && Array.isArray(args.todos)) {\n // 边界:write_todos 工具实参是未定型 wire 数据;此处单点定型为 TaskItem[]。\n const incoming = args.todos as TaskItem[]\n if (args.action === 'update') {\n for (const t of incoming) {\n const i = state.todoList.findIndex((x) => x.id === t.id)\n if (i >= 0) state.todoList[i] = { ...state.todoList[i], ...t, turn: state.currentTurn }\n else state.todoList.push({ ...t, turn: state.currentTurn })\n }\n } else {\n state.todoList = incoming.map((t) => ({ ...t, turn: state.currentTurn }))\n }\n return [\n mkToolEnd(true),\n {\n sessionId,\n kind: 'tasks.update',\n tasks: [...state.todoList],\n title: args.title as string | undefined,\n },\n ]\n }\n\n if (state.delegated.has(call.id)) {\n const task = state.delegated.get(call.id)!\n state.delegated.set(call.id, { ...task, status: isError ? 'error' : 'done' })\n const out: SessionEvent[] = [\n {\n sessionId,\n kind: 'delegate.update',\n tasks: [...state.delegated.values()],\n },\n mkToolEnd(),\n ]\n // 镜像宿主的子代理 todo 自动同步(tools/orchestration/dispatched-task.ts\n // syncTodosOnSubagentComplete):该同步直调 orchestrator.writeTodos、不产生\n // write_todos 工具事件,若不在此镜像,TUI 面板与 session metadata 永远收不到\n // (泄漏根因)。规则两处必须一致:仅 sync 模式 + 非错误;taskIds 显式 → 标这些项\n // done;未指定且恰好一个 in_progress → 标它 done;其余不动。\n if (call.name === 'task_delegate' && !isError) {\n const synced = applyDelegateTodoSync(state, args)\n if (synced) {\n out.push({ sessionId, kind: 'tasks.update', tasks: [...state.todoList] })\n }\n }\n return out\n }\n\n return [mkToolEnd()]\n }\n\n // —— 会话生命周期 / 状态 ——\n case 'session.start':\n return [{ sessionId, kind: 'session.activity', action: 'created' }]\n case 'session.end':\n return [{ sessionId, kind: 'session.activity', action: 'ended' }]\n case 'streaming.start': {\n const e = event\n return [{ sessionId, kind: 'session.status', status: 'streaming', model: e.model }]\n }\n case 'streaming.end': {\n const e = event\n return [\n { sessionId, kind: 'session.status', status: 'idle', model: e.model, stopReason: e.stopReason },\n ]\n }\n case 'compaction.start': {\n const e = event\n return [{ sessionId, kind: 'session.status', status: 'compacting', messageCount: e.messageCount }]\n }\n case 'compaction.end': {\n const e = event\n return [{ sessionId, kind: 'session.status', status: 'idle', retainedCount: e.retainedCount }]\n }\n\n // —— HITL(审批 / 问询 / 计划批准)——\n case 'approval.required': {\n const e = event\n return [\n {\n sessionId,\n kind: 'approval.required',\n id: e.id,\n toolName: e.toolName,\n arguments: e.arguments,\n description: e.description,\n risk: e.risk,\n },\n ]\n }\n case 'approval.resolved': {\n const e = event\n return [{ sessionId, kind: 'approval.resolved', id: e.id, approved: e.approved }]\n }\n case 'ask.user.required': {\n const e = event\n return [{ sessionId, kind: 'ask.required', requestId: e.requestId, question: e.question }]\n }\n case 'ask.user.resolved': {\n const e = event\n return [{ sessionId, kind: 'ask.resolved', requestId: e.requestId }]\n }\n case 'plan.approval.required': {\n const e = event\n return [\n { sessionId, kind: 'plan.approval.required', requestId: e.requestId, planContent: e.planContent },\n ]\n }\n case 'plan.approval.resolved': {\n const e = event\n return [{ sessionId, kind: 'plan.approval.resolved', requestId: e.requestId, action: e.action }]\n }\n\n // —— 错误 ——\n case 'error': {\n const e = event\n return [{ sessionId, kind: 'error', message: errMessage(e.error), code: 'SESSION_ERROR' }]\n }\n\n // —— 有意不投影的事件(终局审查 2026-07-18 S1:显式列出 + never 穷举守卫)——\n // 此前这些类型静默落入 `default: return []`——问题是新增 AgentSessionEvent 成员时\n // 编译器不会提示投影器漏了处理(静默丢弃,前端永远看不到)。显式空 case + default\n // never 断言后:interchange 新增事件类型 → 此 switch 编译失败 → 强制显式决策\n // (投影 or 声明不投影),\"漏投影\"从运行时静默 bug 变为编译期错误。\n case 'prompt.continued': // TUI 经 AgentSessionEvent 直接消费(todo 闸门续跑提示),无 SessionEvent 投影\n case 'messages.persist': // 持久化内部信号,非用户可见事实\n case 'agent.status': // 引擎状态机内部迁移,前端消费 streaming.start/end 粒度即可\n case 'budget.notice': // TUI 经原始事件直接消费(预算提示条)\n case 'prompt.budget.notice': // 同上\n case 'progress.stall.notice': // RFC-203:早期停滞检出提示,TUI 经原始事件直接消费(同 budget.notice 纹理)\n case 'tool.call.mismatch.notice': // RFC-232:工具调用协议违约提示,TUI 经原始事件直接消费(同上纹理)\n case 'turn.idle.notice': // RFC-385:首轮空转检出提示,TUI 经原始事件直接消费(同上纹理)\n case 'session.cost-budget-exceeded': // RFC-204:会话成本预算提醒,TUI 经原始事件直接消费(同上纹理)\n case 'turn.end': // turn.start 已携带回合边界信息,end 无增量事实\n case 'memory.pruned': // 裁剪可观测性走 trace,非会话转录事实\n case 'session.cleared': // clear 由发起端(命令层)自行反馈,投影层无需重复\n case 'run.paused': // 暂停/恢复由 TUI 经原始事件消费(RFC-180)\n case 'run.resumed':\n case 'run.pause_requested': // 暂停请求/取消同上(RFC-186 D2/D4 事件拆分;feae2243 加事件时漏补本穷举)\n case 'run.pause_cancelled':\n case 'session.history-capped': // 驻留裁剪可观测性由 TUI/trace 经原始事件消费(RFC-178)\n case 'session.write-lease-denied': // 写租约状态由 TUI 经原始事件 toast(RFC-159 D3)\n case 'session.write-lease-restored':\n case 'session.crash-gap-detected': // 崩溃丢失对账告警由 TUI 经原始事件 toast(RFC-305 D3)\n case 'image.vision-delegate': // 视觉委托统计由 TUI 经原始事件消费(RFC-181)\n case 'a2ui.action': // A2UI 组件动作由面板宿主经原始事件消费(RFC-105 D6)\n case 'compaction.reactive.notice': // 反应式压缩由 TUI 经原始事件消费(终局 review 2026-07-21,复用 compact_boundary/compactionLog)\n case 'image.degradation.notice': // 图片降级兜底由 TUI 经原始事件消费 toast(终局 review 2026-07-21)\n case 'steer.consumed': // RFC-337 D3:steer 待定回显转正信号,TUI 经原始事件直接消费(commitPendingSteer);web/service 前端无 pendingSteer UI 概念,无投影\n return []\n\n default: {\n // 编译期穷举守卫:event 在所有显式 case 之后应为 never。新增事件类型漏写 case 时\n // 这行赋值报 TS2322,指向本文件强制处理。\n const _exhaustive: never = event\n void _exhaustive\n return []\n }\n }\n}\n\nfunction errMessage(err: unknown): string {\n if (err instanceof Error) return err.message\n if (typeof err === 'string') return err\n return 'unknown error'\n}\n","/**\n * requests.ts — 请求子通道的**纯决策逻辑**(ask_user 自动采纳 / approval 沙箱升级)。\n *\n * cli 的异步处理器(session.subscribe 的 ask.user.required / approval.required)仍持控制流\n * (await UI + session.resolve*),但把「该解析成什么答案」「要不要 bypass」这两段易错的安全关键\n * 决策下沉到这些纯函数 —— 可单测、对齐「取消/留空绝不悬挂工具,自动采纳推荐」纪律。\n */\n\nexport interface AskQuestionLike {\n recommendation: string\n options?: { label: string; recommended?: boolean }[]\n}\n\nexport interface AskAnswer {\n answer: string\n selectedOptionLabels?: string[]\n acceptedRecommendation: boolean\n resolvedBy: 'human' | 'auto_recommendation'\n /** grill_me allowFreeform:用户在选项之外输入的补充文字。 */\n freeformText?: string\n}\n\n/** 取消/留空 → 自动采纳推荐(resolvedBy=auto_recommendation;绝不悬挂工具)。 */\nexport function autoAdoptAnswer(q: AskQuestionLike): AskAnswer {\n return { answer: q.recommendation, acceptedRecommendation: true, resolvedBy: 'auto_recommendation' }\n}\n\n/** 单/多选题+可选自由文本:据用户已选 label(调用方须先去 ★ 装饰)解析。空选 → 自动采纳。\n * acceptedRecommendation:当且仅当选中集恰等于推荐集(非空)。 */\nexport function resolveChoiceAnswer(q: AskQuestionLike, selected: string[], freeformText?: string): AskAnswer {\n if (selected.length === 0 && !freeformText) return autoAdoptAnswer(q)\n const recommended = (q.options ?? []).filter((o) => o.recommended).map((o) => o.label)\n const accepted =\n recommended.length > 0 &&\n selected.length === recommended.length &&\n selected.every((l) => recommended.includes(l))\n const answer = selected.length > 0 ? selected.join(', ') : ''\n const fullAnswer = freeformText ? (answer ? `${answer}\\n\\n补充信息:${freeformText}` : freeformText) : answer\n return { answer: fullAnswer, selectedOptionLabels: selected.length > 0 ? selected : undefined, acceptedRecommendation: accepted, resolvedBy: 'human', freeformText }\n}\n\n/** 自由文本题:空/取消 → 自动采纳;否则人答(文本等于推荐才算采纳)。 */\nexport function resolveTextAnswer(q: AskQuestionLike, text: string | null | undefined): AskAnswer {\n const t = text?.trim()\n if (!t) return autoAdoptAnswer(q)\n return { answer: t, acceptedRecommendation: t === q.recommendation, resolvedBy: 'human' }\n}\n\n/** 沙箱升级 approval:描述带 marker 且参数含 command → 返回需 bypass 的命令,否则 null。\n * 调用方仅在「已批准」时据返回值放行(早于 resolveApproval,approval=escalated 语义)。 */\nexport function sandboxBypassCommand(\n description: unknown,\n args: Record<string, unknown> | undefined,\n marker: string,\n): string | null {\n if (typeof description !== 'string' || !description.includes(marker)) return null\n const cmd = typeof args?.command === 'string' ? args.command : ''\n return cmd || null\n}\n","/**\n * 08-13 终局 review B9:契约包依赖纯净性——本包不再依赖 `@x-otto/env`。\n *\n * env 的 `normalizeEnv` 核心是\"parseInt 正整数校验 + 回退默认 + 诊断\"。契约包此前\n * 为这一语义 import 整个运行时环境包(path 常量/端口配置等无关面一并进入依赖图)。\n * 本包内联最小等价实现(8 行)。\n *\n * **RFC-422 D5(2026-08-14):env 读取从模块加载期移入 resolveResidencyBudget 函数内部**。\n * 此前常量在模块顶层 `parsePositiveIntEnv(process.env[...], 默认)` 读 env → 值被烘焙进\n * 常量 → `resolveResidencyBudget` 通过 `?? 常量` 间接获得 env 值。这造成\"双通道配置\"缺陷:\n * 模块加载期 env 快照 + 运行时 settings 注入,合并优先级靠调用方约定(app.ts 的 pick()\n * 读 process.env 判断 env 是否设置),类型系统无法强制。\n *\n * 变更后:常量退化为纯默认值(不读 env),`parsePositiveIntEnv` 移入\n * `resolveResidencyBudget` 函数内部——运行时被调用时对每个字段执行\n * `settings值 ?? parsePositiveIntEnv(env, 默认值)`。env 与 settings 的优先级\n * 由 resolveResidencyBudget 内部统一处理(settings 优先于 env,调用方不再需要\n * 判断 env 是否设置)。\n *\n * **诊断策略(08-13 终局复核修订)**:非法值**静默回退默认**,不做任何 stderr/警告\n * 副作用。理由:①契约包是\"纯层\",不应拥有输出副作用;②这些常量是治理闸、默认值即\n * 正确基线(fail-open),诊断是边际价值。误配置的可观测性由 env 包的\n * OTTO_*_STRICT 校验与设置面板承担,不在本包职责。\n *\n * 正确性保证不变:非法/缺失值一律回退默认(fail-open,默认值即治理闸的正确基线)。\n */\nfunction parsePositiveIntEnv(value: string | undefined, defaultValue: number): number {\n if (value === undefined) return defaultValue\n const parsed = parseInt(value, 10)\n if (isNaN(parsed) || parsed <= 0) {\n return defaultValue\n }\n return parsed\n}\n\n/**\n * 会话历史存储**条数**上限——**结构兜底闸**(RFC-321 D7 闸位重排,2026-08-07)。\n *\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。env 覆盖由 resolveResidencyBudget\n * 在运行时处理。\n *\n * **不是内存治理主闸**。主闸是 `SESSION_MAX_CONTENT_BYTES`(字节维度,见下);本常量\n * 只防\"条目数爆炸\"这一字节维度管不到的 CPU 问题。\n *\n * **与模型上下文无关**(RFC-053 规则 1,不可削弱):上下文该看多少历史只由 token 那套\n * 决定。本上限只影响**内存视图**;DB 侧 append-forever(RFC-159 D1)。\n */\nexport const SESSION_MAX_HISTORY_MESSAGES = 50_000\n\n/**\n * 会话消息内容字节估算预算——**回退默认值**(RFC-323 后非主闸)。\n *\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n *\n * 语义变更见 RFC-323 的 ResidencyAllocator 已成为实际主闸。本常量为分配器缺席时\n * 的回退默认值。\n */\nexport const SESSION_MAX_CONTENT_BYTES = 64 * 1024 * 1024\n\n/**\n * 会话 resume 时的**尾窗口装载条数**(RFC-321 D7 新增,与条数 cap 解耦)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_RESUME_WINDOW_MESSAGES = 5_000\n\n/**\n * RFC-324 D1/R5:turn-gated 压缩的超时兜底(毫秒,默认 30s,G1 已 grill 确认)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_COMPACTION_TIMEOUT_MS = 30_000\n\n/**\n * RFC-323:进程级驻留总预算(估算口径)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_TOTAL_RESIDENCY_BUDGET = 1024 * 1024 * 1024\n\n/**\n * RFC-323:单会话字节预算下界(N 极大时不被摊薄到无法工作)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_MIN_PER_SESSION_BYTES = 16 * 1024 * 1024\n\n/**\n * RFC-323:单会话字节预算上界(N=1 时的封顶)。\n * RFC-422 D5:本常量现为纯默认值(不再读 env)。\n */\nexport const SESSION_MAX_PER_SESSION_BYTES = 1024 * 1024 * 1024\n\n/**\n * RFC-323 M4:驻留预算的运行时配置对象。\n *\n * 存在理由(D6b):上方常量在模块加载时立即求值为 number(env 快照),无法反映\n * app 启动后才 load 的 settings.json。故运行时读值点改从本对象读——由 app 层合并\n * `env(上方常量)> settings > 默认` 后注入。所有字段可选,缺省回退对应常量。\n */\nexport interface ResidencyBudgetConfig {\n totalBytes?: number\n minPerSessionBytes?: number\n maxPerSessionBytes?: number\n maxContentBytes?: number\n maxHistoryMessages?: number\n resumeWindowMessages?: number\n /**\n * RFC-324 D1/R5:turn-gated 压缩的超时兜底(毫秒)。逃生阀压缩超过此值仍未完成时,\n * 降级为 fire-and-forget——**不允许压缩未完成就永久阻塞 turn**。\n */\n compactionTimeoutMs?: number\n}\n\n/**\n * RFC-323 M4:合并 settings 覆盖到 env/默认常量之上,产出完整的 ResidencyBudgetConfig。\n *\n * RFC-422 D5:env 读取从模块加载期移入本函数内部。\n * 优先级:**settings > env > 默认常量**(settings 显式传入的值优先;否则读 env;\n * env 也未设置则回退到纯默认常量)。此前优先级是 env > settings > 默认(靠调用方\n * pick() 判断 env 是否设置)——现在 settings 优先于 env 是更直观的语义(用户在\n * .otto/config.json 里显式写的值应该覆盖环境变量),且消除了调用方约定。\n *\n * 注意:常量本身已是纯默认值(不再读 env),env 读取在本函数内运行时求值。\n */\nexport function resolveResidencyBudget(\n settings?: ResidencyBudgetConfig,\n): Required<ResidencyBudgetConfig> {\n return {\n totalBytes: settings?.totalBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_TOTAL_RESIDENCY_BUDGET'], SESSION_TOTAL_RESIDENCY_BUDGET),\n minPerSessionBytes: settings?.minPerSessionBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MIN_PER_SESSION_BYTES'], SESSION_MIN_PER_SESSION_BYTES),\n maxPerSessionBytes: settings?.maxPerSessionBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MAX_PER_SESSION_BYTES'], SESSION_MAX_PER_SESSION_BYTES),\n maxContentBytes: settings?.maxContentBytes ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MAX_CONTENT_BYTES'], SESSION_MAX_CONTENT_BYTES),\n maxHistoryMessages: settings?.maxHistoryMessages ?? parsePositiveIntEnv(process.env['OTTO_SESSION_MAX_HISTORY_MESSAGES'], SESSION_MAX_HISTORY_MESSAGES),\n resumeWindowMessages: settings?.resumeWindowMessages ?? parsePositiveIntEnv(process.env['OTTO_SESSION_RESUME_WINDOW_MESSAGES'], SESSION_RESUME_WINDOW_MESSAGES),\n compactionTimeoutMs: settings?.compactionTimeoutMs ?? parsePositiveIntEnv(process.env['OTTO_SESSION_COMPACTION_TIMEOUT_MS'], SESSION_COMPACTION_TIMEOUT_MS),\n }\n}\n","/**\n * pulse-survey-trigger.ts — RFC-208 §2.1/§3.1:满意度脉冲调查触发判定纯函数。\n * RFC-209 M3:从 packages/cli 下沉至此(cli 与 service 均已依赖 @x-otto/session-contract,\n * 而 service 不应依赖 cli——EventBridge 需要复用本函数做 web-ui 侧 `pulse-survey.show`\n * 触发判定,见 RFC-209 milestone 执行阶段 grill 确认)。\n *\n * 纯逻辑类,不依赖 @x-otto/tui/@x-otto/coding 类型——判定「本次 prompt.end 是否应展示脉冲调查」,\n * 实际展示(tui.setPulseSurvey / web-ui pulse-survey.show)与数据写入(FeedbackRegistry)\n * 留在调用方(cli 侧 interactive-events.ts / service 侧 event-bridge.ts)。\n *\n * 触发锚点是 prompt.end(对话轮次真正结束的权威时点),按可配置概率随机抽样而非固定周期——\n * 固定周期容易被用户学习产生\"来了、又是这个\"的疲劳感;抽样配合最小回合间隔更接近\"偶尔冒出,\n * 不成为负担\"的调性。判定逻辑必须是纯函数、接受注入的 `random` 参数(RFC-208 重要事项规则 5)\n * ——不得在函数内部直接硬编码调用 `Math.random()`,保证可测试性(CLI 交互层直接用 Math.random\n * 有先例,见 draft-entries.ts,但触发判定这类需要精确验证边界值的逻辑必须可注入固定值测试)。\n *\n * `lastShownTurn` 是进程内存态,不持久化跨会话——重启 otto 后重新从零计间隔,符合\"轻量抽样,\n * 不需要跨会话精确统计\"的调性,避免为此引入额外的持久化状态文件。\n */\n\nexport interface PulseSurveyTriggerState {\n lastShownTurn?: number\n}\n\nexport interface PulseSurveyTriggerConfig {\n enabled: boolean\n probability: number\n minTurnGap: number\n /**\n * 当前是否有 Band A hard modal(如 forcedUpgrade)在场——为真时恒不触发(RFC-208 §5\n * 风险段\"forced-upgrade 并发\"缓解措施之一)。调用方传入 `modals.forcedUpgrade` 等值。\n */\n forcedUpgradeActive: boolean\n}\n\n/**\n * 判定本次 `prompt.end` 是否应展示满意度脉冲调查。\n *\n * @param currentTurn 当前对话轮次(`projState.currentTurn`)\n * @param config 触发配置(来自 `.otto/config.json` 的 `pulse_survey` 块 + 当前 Band A 状态)\n * @param state 触发状态(`lastShownTurn` 进程内存态,调用方持有并在命中时更新)\n * @param random 随机数源,默认 `Math.random`;测试注入固定值验证确定性\n */\nexport function shouldShowPulseSurvey(\n currentTurn: number,\n config: PulseSurveyTriggerConfig,\n state: PulseSurveyTriggerState,\n random: () => number = Math.random,\n): boolean {\n if (!config.enabled) return false\n if (config.forcedUpgradeActive) return false\n if (state.lastShownTurn !== undefined && currentTurn - state.lastShownTurn < config.minTurnGap) return false\n return random() < config.probability\n}\n"],"mappings":"yEA0BA,SAAgB,GAAuC,CACrD,MAAO,CAAE,UAAW,IAAI,IAAO,SAAU,EAAE,CAAE,YAAa,EAAG,CAW/D,MAAa,EAA2B,IAAI,IAAI,CAAC,gBAAiB,WAAY,YAAY,CAAC,CAQ3F,SAAgB,EACd,EACa,CACb,OAAO,IAAI,IACT,EACG,OAAQ,GAAM,EAAE,UAAU,WAAa,gBAAgB,CACvD,IAAK,GAAM,EAAE,KAAK,CACtB,CAUH,SAAS,EAAsB,EAAuB,EAAwC,CAK5F,GAFI,EAAK,UAAY,KACR,OAAO,EAAK,MAAS,SAAW,EAAK,KAAO,UAC5C,OAAQ,MAAO,GAE5B,IAAM,EAAU,MAAM,QAAQ,EAAK,QAAQ,CACtC,EAAK,QAAsB,OAAQ,GAAmB,OAAO,GAAM,SAAS,CAC7E,IAAA,GAEE,EAAY,EAAuB,EAAM,SAAU,EAAQ,CAMjE,OALI,EAAU,SAAW,EAAU,IAEnC,EAAM,SAAW,EAAM,SAAS,IAAK,GACnC,EAAE,IAAM,MAAQ,EAAU,SAAS,EAAE,GAAG,CAAG,CAAE,GAAG,EAAG,OAAQ,OAAiB,CAAG,EAChF,CACM,IAGT,SAAgB,EACd,EACA,EACA,EAAkB,EAAE,CACJ,CAChB,IAAM,EAAY,EAAM,UAClB,EAAe,EAAI,mBAAsB,GAAc,EAAyB,IAAI,EAAE,EAE5F,OAAQ,EAAM,KAAd,CACE,IAAK,eAEH,MADA,GAAM,cACC,CACL,CACE,YACA,KAAM,eACN,KAAM,EAAM,KACb,CACF,CAEH,IAAK,aAAc,CACjB,EAAM,UAAU,OAAO,CACvB,IAAM,EAAQ,EAAI,iBAAiB,CACnC,MAAO,CACL,CAAE,YAAW,KAAM,kBAAmB,MAAO,EAAE,CAAyB,CACxE,CACE,YACA,KAAM,aAGN,MAAO,EAAM,OAAS,EAAI,gBAAgB,EAAI,GAC9C,OAAQ,EAAI,cAAc,CAC1B,cAAe,GAAgB,IAAA,GAC/B,OAAQ,EAAM,cACd,WAAY,EAAM,WAClB,aAAc,EAAM,aACrB,CACF,CAGH,IAAK,aACH,MAAO,CACL,CACE,YACA,KAAM,cACN,cAAe,EAAM,cACrB,aAAc,EAAM,aACpB,aAAc,EAAM,mBACpB,kBAAmB,EAAM,wBAC1B,CACF,CAEH,IAAK,eAAgB,CACnB,IAAM,EAAI,EAAM,MAChB,OAAQ,EAAE,KAAV,CACE,IAAK,aACH,MAAO,CAAC,CAAE,YAAW,KAAM,oBAAqB,MAAO,EAAE,OAAS,GAAI,CAAC,CACzE,IAAK,iBACH,MAAO,CAAC,CAAE,YAAW,KAAM,wBAAyB,MAAO,EAAE,OAAS,GAAI,CAAC,CAC7E,IAAK,aACH,MAAO,CAAC,CAAE,YAAW,KAAM,oBAAqB,CAAC,CACnD,IAAK,WACH,MAAO,CAAC,CAAE,YAAW,KAAM,kBAAmB,CAAC,CACjD,IAAK,iBACH,MAAO,CAAC,CAAE,YAAW,KAAM,wBAAyB,CAAC,CACvD,IAAK,eACH,MAAO,CAAC,CAAE,YAAW,KAAM,sBAAuB,CAAC,CACrD,IAAK,QACH,MAAO,CAAC,CAAE,YAAW,KAAM,QAAS,QAAS,EAAW,EAAE,MAAM,CAAE,KAAM,eAAgB,CAAC,CAQ3F,IAAK,QACL,IAAK,kBACL,IAAK,kBACL,IAAK,gBACL,IAAK,OACH,MAAO,EAAE,CACX,QAKE,MAAO,EAAE,EAKf,IAAK,kBAAmB,CACtB,IAAM,EAAO,EAAM,SACb,EAAsB,CAAC,CAAE,YAAW,KAAM,aAAc,OAAM,CAAC,CACrE,GAAI,EAAa,EAAK,KAAK,CAAE,CAC3B,IAAM,EAAI,EAAK,WAAa,EAAE,CACxB,EAAQ,EAAE,UAAY,EAAE,OAAS,EAAE,UAAY,EAAE,KACjD,EACJ,OAAO,EAAE,QAAW,SAAW,EAAE,OAAO,QAAQ,MAAO,IAAI,CAAC,MAAM,EAAG,GAAG,CAAG,IAAA,GAC7E,EAAM,UAAU,IAAI,EAAK,GAAI,CAC3B,GAAI,EAAK,GACT,KAAM,OAAO,GAAU,SAAW,EAAQ,EAAK,KAC/C,SACA,OAAQ,UACT,CAAC,CACF,EAAI,KAAK,CACP,YACA,KAAM,kBACN,MAAO,CAAC,GAAG,EAAM,UAAU,QAAQ,CAAC,CACrC,CAAC,CAEJ,OAAO,EAGT,IAAK,gBAAiB,CACpB,GAAM,CAAE,SAAU,EAAM,WAAY,EAC9B,EAAO,EAAK,WAAa,EAAE,CAC3B,EAAa,IAA6C,CAC9D,YACA,KAAM,WACN,OACA,UAMA,WAAY,EAAM,YAAc,EAAI,iBAAiB,EAAK,CAC1D,qBAAsB,EAAM,qBAC5B,kBACD,EAED,GAAI,EAAK,OAAS,eAAiB,MAAM,QAAQ,EAAK,MAAM,CAAE,CAE5D,IAAM,EAAW,EAAK,MACtB,GAAI,EAAK,SAAW,SAClB,IAAK,IAAM,KAAK,EAAU,CACxB,IAAM,EAAI,EAAM,SAAS,UAAW,GAAM,EAAE,KAAO,EAAE,GAAG,CACpD,GAAK,EAAG,EAAM,SAAS,GAAK,CAAE,GAAG,EAAM,SAAS,GAAI,GAAG,EAAG,KAAM,EAAM,YAAa,CAClF,EAAM,SAAS,KAAK,CAAE,GAAG,EAAG,KAAM,EAAM,YAAa,CAAC,MAG7D,EAAM,SAAW,EAAS,IAAK,IAAO,CAAE,GAAG,EAAG,KAAM,EAAM,YAAa,EAAE,CAE3E,MAAO,CACL,EAAU,GAAK,CACf,CACE,YACA,KAAM,eACN,MAAO,CAAC,GAAG,EAAM,SAAS,CAC1B,MAAO,EAAK,MACb,CACF,CAGH,GAAI,EAAM,UAAU,IAAI,EAAK,GAAG,CAAE,CAChC,IAAM,EAAO,EAAM,UAAU,IAAI,EAAK,GAAG,CACzC,EAAM,UAAU,IAAI,EAAK,GAAI,CAAE,GAAG,EAAM,OAAQ,EAAU,QAAU,OAAQ,CAAC,CAC7E,IAAM,EAAsB,CAC1B,CACE,YACA,KAAM,kBACN,MAAO,CAAC,GAAG,EAAM,UAAU,QAAQ,CAAC,CACrC,CACD,GAAW,CACZ,CAYD,OANI,EAAK,OAAS,iBAAmB,CAAC,GACrB,EAAsB,EAAO,EAAK,EAE/C,EAAI,KAAK,CAAE,YAAW,KAAM,eAAgB,MAAO,CAAC,GAAG,EAAM,SAAS,CAAE,CAAC,CAGtE,EAGT,MAAO,CAAC,GAAW,CAAC,CAItB,IAAK,gBACH,MAAO,CAAC,CAAE,YAAW,KAAM,mBAAoB,OAAQ,UAAW,CAAC,CACrE,IAAK,cACH,MAAO,CAAC,CAAE,YAAW,KAAM,mBAAoB,OAAQ,QAAS,CAAC,CACnE,IAAK,kBAEH,MAAO,CAAC,CAAE,YAAW,KAAM,iBAAkB,OAAQ,YAAa,MADxD,EACiE,MAAO,CAAC,CAErF,IAAK,gBAAiB,CACpB,IAAM,EAAI,EACV,MAAO,CACL,CAAE,YAAW,KAAM,iBAAkB,OAAQ,OAAQ,MAAO,EAAE,MAAO,WAAY,EAAE,WAAY,CAChG,CAEH,IAAK,mBAEH,MAAO,CAAC,CAAE,YAAW,KAAM,iBAAkB,OAAQ,aAAc,aADzD,EACyE,aAAc,CAAC,CAEpG,IAAK,iBAEH,MAAO,CAAC,CAAE,YAAW,KAAM,iBAAkB,OAAQ,OAAQ,cADnD,EACoE,cAAe,CAAC,CAIhG,IAAK,oBAAqB,CACxB,IAAM,EAAI,EACV,MAAO,CACL,CACE,YACA,KAAM,oBACN,GAAI,EAAE,GACN,SAAU,EAAE,SACZ,UAAW,EAAE,UACb,YAAa,EAAE,YACf,KAAM,EAAE,KACT,CACF,CAEH,IAAK,oBAAqB,CACxB,IAAM,EAAI,EACV,MAAO,CAAC,CAAE,YAAW,KAAM,oBAAqB,GAAI,EAAE,GAAI,SAAU,EAAE,SAAU,CAAC,CAEnF,IAAK,oBAAqB,CACxB,IAAM,EAAI,EACV,MAAO,CAAC,CAAE,YAAW,KAAM,eAAgB,UAAW,EAAE,UAAW,SAAU,EAAE,SAAU,CAAC,CAE5F,IAAK,oBAEH,MAAO,CAAC,CAAE,YAAW,KAAM,eAAgB,UADjC,EAC8C,UAAW,CAAC,CAEtE,IAAK,yBAA0B,CAC7B,IAAM,EAAI,EACV,MAAO,CACL,CAAE,YAAW,KAAM,yBAA0B,UAAW,EAAE,UAAW,YAAa,EAAE,YAAa,CAClG,CAEH,IAAK,yBAA0B,CAC7B,IAAM,EAAI,EACV,MAAO,CAAC,CAAE,YAAW,KAAM,yBAA0B,UAAW,EAAE,UAAW,OAAQ,EAAE,OAAQ,CAAC,CAIlG,IAAK,QAEH,MAAO,CAAC,CAAE,YAAW,KAAM,QAAS,QAAS,EADnC,EACgD,MAAM,CAAE,KAAM,gBAAiB,CAAC,CAQ5F,IAAK,mBACL,IAAK,mBACL,IAAK,eACL,IAAK,gBACL,IAAK,uBACL,IAAK,wBACL,IAAK,4BACL,IAAK,mBACL,IAAK,+BACL,IAAK,WACL,IAAK,gBACL,IAAK,kBACL,IAAK,aACL,IAAK,cACL,IAAK,sBACL,IAAK,sBACL,IAAK,yBACL,IAAK,6BACL,IAAK,+BACL,IAAK,6BACL,IAAK,wBACL,IAAK,cACL,IAAK,6BACL,IAAK,2BACL,IAAK,iBACH,MAAO,EAAE,CAEX,QAKE,MAAO,EAAE,EAKf,SAAS,EAAW,EAAsB,CAGxC,OAFI,aAAe,MAAc,EAAI,QACjC,OAAO,GAAQ,SAAiB,EAC7B,gBCpWT,SAAgB,EAAgB,EAA+B,CAC7D,MAAO,CAAE,OAAQ,EAAE,eAAgB,uBAAwB,GAAM,WAAY,sBAAuB,CAKtG,SAAgB,EAAoB,EAAoB,EAAoB,EAAkC,CAC5G,GAAI,EAAS,SAAW,GAAK,CAAC,EAAc,OAAO,EAAgB,EAAE,CACrE,IAAM,GAAe,EAAE,SAAW,EAAE,EAAE,OAAQ,GAAM,EAAE,YAAY,CAAC,IAAK,GAAM,EAAE,MAAM,CAChF,EACJ,EAAY,OAAS,GACrB,EAAS,SAAW,EAAY,QAChC,EAAS,MAAO,GAAM,EAAY,SAAS,EAAE,CAAC,CAC1C,EAAS,EAAS,OAAS,EAAI,EAAS,KAAK,KAAK,CAAG,GAE3D,MAAO,CAAE,OADU,EAAgB,EAAS,GAAG,EAAO,WAAW,IAAiB,EAAgB,EACrE,qBAAsB,EAAS,OAAS,EAAI,EAAW,IAAA,GAAW,uBAAwB,EAAU,WAAY,QAAS,eAAc,CAItK,SAAgB,EAAkB,EAAoB,EAA4C,CAChG,IAAM,EAAI,GAAM,MAAM,CAEtB,OADK,EACE,CAAE,OAAQ,EAAG,uBAAwB,IAAM,EAAE,eAAgB,WAAY,QAAS,CAD1E,EAAgB,EAAE,CAMnC,SAAgB,EACd,EACA,EACA,EACe,CAGf,OAFI,OAAO,GAAgB,UAAY,CAAC,EAAY,SAAS,EAAO,CAAS,MACjE,OAAO,GAAM,SAAY,SAAW,EAAK,QAAU,KACjD,KC/BhB,SAAS,EAAoB,EAA2B,EAA8B,CACpF,GAAI,IAAU,IAAA,GAAW,OAAO,EAChC,IAAM,EAAS,SAAS,EAAO,GAAG,CAIlC,OAHI,MAAM,EAAO,EAAI,GAAU,EACtB,EAEF,EAeT,MAAa,EAA+B,IAU/B,EAA4B,GAAK,KAAO,KAMxC,EAAiC,IAMjC,EAAgC,IAMhC,EAAiC,KAAO,KAAO,KAM/C,EAAgC,GAAK,KAAO,KAM5C,EAAgC,KAAO,KAAO,KAkC3D,SAAgB,EACd,EACiC,CACjC,MAAO,CACL,WAAY,GAAU,YAAc,EAAoB,QAAQ,IAAI,oCAAA,WAAuE,CAC3I,mBAAoB,GAAU,oBAAsB,EAAoB,QAAQ,IAAI,mCAAA,SAAqE,CACzJ,mBAAoB,GAAU,oBAAsB,EAAoB,QAAQ,IAAI,mCAAA,WAAqE,CACzJ,gBAAiB,GAAU,iBAAmB,EAAoB,QAAQ,IAAI,+BAAA,SAA6D,CAC3I,mBAAoB,GAAU,oBAAsB,EAAoB,QAAQ,IAAI,kCAAA,IAAmE,CACvJ,qBAAsB,GAAU,sBAAwB,EAAoB,QAAQ,IAAI,oCAAA,IAAuE,CAC/J,oBAAqB,GAAU,qBAAuB,EAAoB,QAAQ,IAAI,mCAAA,IAAqE,CAC5J,CCzFH,SAAgB,EACd,EACA,EACA,EACA,EAAuB,KAAK,OACnB,CAIT,MAHI,CAAC,EAAO,SACR,EAAO,qBACP,EAAM,gBAAkB,IAAA,IAAa,EAAc,EAAM,cAAgB,EAAO,WAAmB,GAChG,GAAQ,CAAG,EAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x-otto/session-contract",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0-alpha.9",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist"
|
|
6
6
|
],
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"tag": "alpha"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@x-otto/interchange": "0.1.0-alpha.
|
|
23
|
-
"@x-otto/orchestration-contracts": "0.0
|
|
22
|
+
"@x-otto/interchange": "0.1.0-alpha.9",
|
|
23
|
+
"@x-otto/orchestration-contracts": "0.1.0-alpha.9"
|
|
24
24
|
},
|
|
25
25
|
"private": false,
|
|
26
26
|
"scripts": {
|