@tea-agent/loop-agent 0.43.0-next.11 → 0.43.0-next.13
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/CHANGELOG.md +3 -0
- package/dist/build-stamp.json +3 -3
- package/dist/commands/client-recovery.js +20 -55
- package/dist/executors/shell-write-guard.js +27 -32
- package/dist/shared/pi-context-pressure/extension.js +26 -16
- package/dist/shared/pi-provider-recovery.js +182 -0
- package/dist/shared/pi-retry-settings.js +40 -0
- package/dist/worker/console/chat/pi-runtime.js +7 -5
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-CTSK0xbU.js → abnfDiagram-N423BO3Z-BEg5712w.js} +1 -1
- package/dist/worker/console/static/assets/{arc-_2MfctFP.js → arc-CkQvaBGZ.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-DsDe2wTg.js → architectureDiagram-T3A2C74G-BrdwFNJ7.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Dtz_779U.js → blockDiagram-VBNYF7ZC-M_LjP2kx.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-LaULi-gw.js → c4Diagram-5PPSVZJV-Bwr5Dtjc.js} +1 -1
- package/dist/worker/console/static/assets/channel-CKmyKgY-.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DuHBqqX8.js → chunk-2GRJ4B5K-CDc44stW.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-BZgZs1dn.js → chunk-2Q5K7J3B-DZELwsTt.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-tzwmlIO_.js → chunk-5RXB4S5H-D7YI6SWX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-CeYrLkSn.js → chunk-5VM5RSS4-Bc46bEyj.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-C92cgilm.js → chunk-6Q2QTUOP-Bj4vc-Dp.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-XOXpGC0F.js → chunk-GF5L2VYU-DRi-0nDX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CGHbJyCH.js → chunk-JWPE2WC7-Dr-wFY60.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-Bs2-LTzf.js → chunk-KBJHAD2P-CqIHE_D7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-rN7up7E4.js → chunk-RYQCIY6F-C-Dl8wzk.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-B_fWjKpR.js → chunk-XXDRQBXY-CV4Mydz3.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-D8Wc3jJP.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-D8Wc3jJP.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-DE3SdJvB.js → cose-bilkent-JH36ORCC-C3MamSMJ.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-B-4yuRAX.js → cynefin-VYW2F7L2-zo_Jy2sf.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-TiCPFuO8.js → cynefinDiagram-MW4NZA55-BB2PN1AG.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-7crzLMzA.js → dagre-VZM6K2ZE-BimYueoi.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-Cvr-x6Fd.js → diagram-7IWD3JNH-Di1ObJRS.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BzcRHUjH.js → diagram-B4RE2ZJO-C83l-IJx.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-BjkAXilh.js → diagram-LBJQPF4R-B3S3fOpm.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BkzyATK7.js → diagram-Q27KOJAE-urW_Zhe7.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-rZuTarYP.js → diagram-UB23O5K3-nvIbCwF6.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-CAYENaN1.js → ebnfDiagram-BXEA7PRR-DG6O3KpP.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DCEam0Uq.js → erDiagram-JOGREHBK-DpXdtdsj.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-e_dH4wVO.js → flowDiagram-UKHOOZJN-DvXWHrND.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CvZa2zOK.js → ganttDiagram-PKOTCBZU-6F7SbvUS.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-CbT5TuKp.js → gitGraphDiagram-DS77QQ5N-D1tZnFec.js} +1 -1
- package/dist/worker/console/static/assets/{index-CUPeoE8W.js → index-CWarwRqc.js} +94 -94
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BWzHQa_Z.js → infoDiagram-6WML65LV-HN4qwJ2M.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BTjlovtU.js → ishikawaDiagram-WSZJBQD7-OJ4qwDRo.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DkvQoCc1.js → journeyDiagram-NVQOT4AX-CJZ6giQk.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-CHSzGi3W.js → kanban-definition-27J2QSJJ-co60m19S.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DZMkTCWH.js → linear-D1KeFqZY.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BIMhty7A.js → mermaid.core-i7dDGqov.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-Dx-tyMl3.js → mindmap-definition-FAOFIHXS-1SkQxBh1.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-C6G34rbY.js → pegDiagram-VL7TDLO6-B10dhI-Y.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CHK9XOfm.js → pieDiagram-7S7Q4E2Y-CiUKUo6j.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-CDARkI0w.js → quadrantDiagram-CIZ2JOQS-C5vH4LXZ.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-DiuUe0ZQ.js → railroadDiagram-AXF67PYL-5nlWOCEj.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-RE61UR56.js → requirementDiagram-LRYGKXZP-CILd6QS3.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-KDNLHMEG.js → sankeyDiagram-W5VNT64P-Dfp18ZO2.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CeVgXnD9.js → sequenceDiagram-SI44F4Z6-B9pkswBi.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-CXwGyjjG.js → sizeCapture-X5ZJPWSS-C1-eSgx4.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BjTfozab.js → stateDiagram-OKZ733FA-COJsOoAF.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Bpfb0q5s.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BaXOB8GT.js → swimlanes-SLNWSIFB-Dv5NXJUM.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BEwGGabW.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-C3r2hqUU.js → timeline-definition-Z64GVDOM-DRdrZ7eR.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-MWKgl1S9.js → vennDiagram-T6HMQDX7-0-2TlwCj.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-C9iFcZPk.js → wardleyDiagram-T6FBY63Y-3-o3q92P.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-DqnM24Jp.js → xychartDiagram-ELKLHX3M-DSgOgdUi.js} +1 -1
- package/dist/worker/console/static/index.html +1 -1
- package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +192 -0
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +9 -1
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +78 -35
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +145 -70
- package/dist/worker/console/static-src/operator-chat/useComposer.js +182 -69
- package/dist/workflows/dag/frontend-repair.js +55 -76
- package/docs/architecture/runtime-boundaries.md +3 -3
- package/package.json +4 -1
- package/dist/worker/console/static/assets/channel-CqS4yBWT.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DVOxNOq0.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DVOxNOq0.js +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BXoYsyr2.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DfKliS4e.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
### 改进
|
|
12
12
|
|
|
13
|
+
- Operator Chat 内置内部 provider 瞬态异常恢复:即使目标仓库未执行 `loop-agent init`,也能识别完整或被裁剪的 `UnknownError` / `TypeValidationError` / `LLMRequestError` / 502 / 中文「网络波动、模型处理超时」响应,将其规范化后交给 Pi 原生有界重试;Console 缺省使用 loop-agent 推荐重试参数,项目显式字段优先于用户全局字段,用户配置优先于推荐默认值。共享纯分类器同时生成 OpenCode 插件谓词,overflow、认证、权限、配额、取消和业务错误继续 fail-fast。
|
|
14
|
+
|
|
13
15
|
- Operator Chat 浏览器面板默认以完整权限运行(去掉 iframe 沙箱与「临时解锁」状态条),并放开本机回环地址限制——`localhost` / `127.0.0.1` / `::1` 等本地开发服务器可直接在面板内浏览;地址栏仍仅放行 http/https,`javascript:` / `data:` / `file:` 等危险协议继续拦截,拒绝嵌入站点(X-Frame-Options / frame-ancestors)的解释面板与出口保持不变。
|
|
14
16
|
|
|
15
17
|
- 前端 Plan 普通分片按本批完整需求材料打包,固定提示词、用户消息和工具定义不再挤占 24 KB 分片目标,也不再触发发送前的机械二分,减少小需求逐 AC 会话;实际模型容量检查与超限恢复继续生效。
|
|
@@ -20,6 +22,7 @@
|
|
|
20
22
|
|
|
21
23
|
### 修复
|
|
22
24
|
|
|
25
|
+
- 修复 Operator Chat 的跨会话输入污染与快速重复提交:切换会话时立即撤销旧会话发送权,草稿、附件和 ↑ 输入历史按会话独立保存;发送、排队、撤回、编辑、插话、文件建议和图片读取的迟到结果只回写原会话。提交改用带快照的有界 attempt,相同内容的快速双 Enter/双击只产生一次请求,失败恢复或排队响应不再覆盖后来输入;流式更新和会话切换保持同一个 composer DOM,中文 IME 更稳定。同步修复 durable 用户消息确认后时间重排导致闪烁光标跑到用户消息上方的问题。
|
|
23
26
|
|
|
24
27
|
- 前端设计审查的写入门禁只统计已提交的审批终态,避免审查范围、发现记录导致合法审批被误判为缺失或歧义;要求修改时保留具体审查意见,缺失、重复及冲突终态仍阻断写入。
|
|
25
28
|
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.43.0-next.
|
|
4
|
-
"gitSha": "
|
|
5
|
-
"builtAt": "2026-09-
|
|
3
|
+
"version": "0.43.0-next.13",
|
|
4
|
+
"gitSha": "4e92f5b2b1c43bc8971d9c9e6c21f76fa557189d",
|
|
5
|
+
"builtAt": "2026-09-11T00:55:37.486Z"
|
|
6
6
|
}
|
|
@@ -18,6 +18,7 @@ export const BACKOFF_MS = [2000, 4000, 8000, 16000, 30000];
|
|
|
18
18
|
export const MAX_SESSION_RETRIES = 5;
|
|
19
19
|
/** Hard cap for OpenCode overflow compact+resume recoveries (≤ 2). */
|
|
20
20
|
export const MAX_OVERFLOW_RECOVERIES = 1;
|
|
21
|
+
import { buildGeneratedTransientProviderClassifierSource, classifyTransientProviderError, } from "../shared/pi-provider-recovery.js";
|
|
21
22
|
import { PI_RECOMMENDED_COMPACTION, PI_RECOMMENDED_RETRY, } from "../shared/pi-retry-settings.js";
|
|
22
23
|
import { CONTEXT_OVERFLOW_PHRASES, buildGeneratedOverflowClassifierSource, isContextOverflow as classifySharedOverflow, } from "../shared/pi-context-pressure/overflow.js";
|
|
23
24
|
export { PI_RECOMMENDED_COMPACTION, PI_RECOMMENDED_RETRY };
|
|
@@ -51,17 +52,6 @@ const PERMANENT_MESSAGE_PATTERNS = [
|
|
|
51
52
|
pattern: /\b(business validation|invalid task|schema validation)\b/i,
|
|
52
53
|
},
|
|
53
54
|
];
|
|
54
|
-
const TRANSIENT_MESSAGE_PATTERNS = [
|
|
55
|
-
/\bcode[:\s]*502\b/i,
|
|
56
|
-
/\b502\b/,
|
|
57
|
-
/\bLLMRequestError\b/i,
|
|
58
|
-
/\bnetwork fluctuation\b/i,
|
|
59
|
-
/\btimeout\b/i,
|
|
60
|
-
/\btransient provider failure\b/i,
|
|
61
|
-
/\bnon-standard (payload|response)\b/i,
|
|
62
|
-
/\bupstream returned\b/i,
|
|
63
|
-
/\bmodel processing timeout\b/i,
|
|
64
|
-
];
|
|
65
55
|
export function isClientRecoveryMode(value) {
|
|
66
56
|
return (typeof value === "string" &&
|
|
67
57
|
CLIENT_RECOVERY_MODES.includes(value));
|
|
@@ -172,30 +162,16 @@ export function isContextOverflow(error) {
|
|
|
172
162
|
return classifySharedOverflow(error);
|
|
173
163
|
}
|
|
174
164
|
function looksTransient(error) {
|
|
175
|
-
|
|
176
|
-
if (TRANSIENT_MESSAGE_PATTERNS.some((pattern) => pattern.test(text)))
|
|
177
|
-
return true;
|
|
178
|
-
if (error && typeof error === "object") {
|
|
179
|
-
const record = error;
|
|
180
|
-
if (record.code === 502 || record.status === 502)
|
|
181
|
-
return true;
|
|
182
|
-
if (record.data && typeof record.data === "object") {
|
|
183
|
-
const data = record.data;
|
|
184
|
-
if (data.code === 502 || data.status === 502)
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return false;
|
|
165
|
+
return classifyTransientProviderError(error).retryable;
|
|
189
166
|
}
|
|
190
167
|
/**
|
|
191
168
|
* Decide whether an OpenCode error should be resumed by the project plugin.
|
|
192
|
-
*
|
|
169
|
+
* Compensates wrapped UnknownError / TypeValidation failures and known stripped
|
|
170
|
+
* internal-provider fluctuation messages that built-in APIError retry misses.
|
|
193
171
|
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* signal (502 / LLMRequestError / timeout / etc.). A pure schema mismatch
|
|
198
|
-
* without a transient signal is still rejected (resumable: false).
|
|
172
|
+
* The historical success reason remains `transient-unknown-error` for report
|
|
173
|
+
* compatibility. A pure schema mismatch without a transient signal is still
|
|
174
|
+
* rejected (resumable: false).
|
|
199
175
|
*/
|
|
200
176
|
export function classifyTransientUnknownError(error) {
|
|
201
177
|
const permanent = permanentReason(error);
|
|
@@ -208,6 +184,9 @@ export function classifyTransientUnknownError(error) {
|
|
|
208
184
|
}
|
|
209
185
|
const isUnknownShape = hasUnknownErrorShape(error);
|
|
210
186
|
const isTypeValidationShape = hasTypeValidationShape(error);
|
|
187
|
+
if (looksTransient(error)) {
|
|
188
|
+
return { resumable: true, reason: "transient-unknown-error" };
|
|
189
|
+
}
|
|
211
190
|
if (!isUnknownShape && !isTypeValidationShape) {
|
|
212
191
|
return {
|
|
213
192
|
resumable: false,
|
|
@@ -215,14 +194,11 @@ export function classifyTransientUnknownError(error) {
|
|
|
215
194
|
interaction: PERMANENT_ERROR_INTERACTION,
|
|
216
195
|
};
|
|
217
196
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
return { resumable: true, reason: "transient-unknown-error" };
|
|
197
|
+
return {
|
|
198
|
+
resumable: false,
|
|
199
|
+
reason: "unknown-non-transient",
|
|
200
|
+
interaction: PERMANENT_ERROR_INTERACTION,
|
|
201
|
+
};
|
|
226
202
|
}
|
|
227
203
|
export function nextBackoffMs(attempt) {
|
|
228
204
|
if (!Number.isInteger(attempt) ||
|
|
@@ -478,8 +454,9 @@ export function buildOpenCodeTransientRetryPluginSource() {
|
|
|
478
454
|
* loop-agent OpenCode transient recovery plugin
|
|
479
455
|
* Path: ${OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH}
|
|
480
456
|
*
|
|
481
|
-
* Compensates
|
|
482
|
-
*
|
|
457
|
+
* Compensates wrapped UnknownError / TypeValidation failures and known
|
|
458
|
+
* stripped internal-provider fluctuation messages that OpenCode built-in
|
|
459
|
+
* APIError retry does not cover. Never runs concurrently with session.status === "retry".
|
|
483
460
|
* Permanent failures use interaction "${PERMANENT_ERROR_INTERACTION}".
|
|
484
461
|
* User aborts (MessageAbortedError / cancel words) are silently cleared.
|
|
485
462
|
* Best-effort file log: ${OPENCODE_TRANSIENT_RETRY_LOG_PATH}.
|
|
@@ -502,7 +479,7 @@ const LOG_PATH = (() => {
|
|
|
502
479
|
const PERMANENT_INTERACTION = ${JSON.stringify(PERMANENT_ERROR_INTERACTION)};
|
|
503
480
|
const BACKOFF_MS = ${JSON.stringify([...BACKOFF_MS])};
|
|
504
481
|
const MAX_RETRIES = ${MAX_SESSION_RETRIES};
|
|
505
|
-
${
|
|
482
|
+
${buildGeneratedTransientProviderClassifierSource()}
|
|
506
483
|
void logToFile("load ok");
|
|
507
484
|
|
|
508
485
|
const sessionState = new Map();
|
|
@@ -563,19 +540,7 @@ function isPermanent(error) {
|
|
|
563
540
|
|
|
564
541
|
function isTransientUnknown(error) {
|
|
565
542
|
if (isPermanent(error)) return false;
|
|
566
|
-
|
|
567
|
-
const hasUnknown = /UnknownError/i.test(text) || (error && /UnknownError/i.test(String(error.name || "")));
|
|
568
|
-
const hasTypeValidation =
|
|
569
|
-
/\\bTypeValidationError\\b/i.test(text) ||
|
|
570
|
-
/Type validation failed/i.test(text) ||
|
|
571
|
-
(error && /TypeValidationError/i.test(String(error.name || "")));
|
|
572
|
-
if (!hasUnknown && !hasTypeValidation) return false;
|
|
573
|
-
return (
|
|
574
|
-
/\\b(code[:\\s]*502|502|LLMRequestError|network fluctuation|timeout|transient provider failure|non-standard)\\b/i.test(
|
|
575
|
-
text,
|
|
576
|
-
) ||
|
|
577
|
-
(error && (error.code === 502 || error.status === 502))
|
|
578
|
-
);
|
|
543
|
+
return isKnownTransientProviderError(error);
|
|
579
544
|
}
|
|
580
545
|
|
|
581
546
|
function buildResumePrompt(sessionId, error, attempt) {
|
|
@@ -94,48 +94,43 @@ const DAG_RUNS_PREFIX = ".harness/dag-runs/";
|
|
|
94
94
|
* They are not product evidence and must not fail exclusive write guards.
|
|
95
95
|
* Intentional report/product writes remain governed by writePolicy/writeSet.
|
|
96
96
|
*/
|
|
97
|
-
|
|
98
|
-
const normalized = normalizePath(filePath);
|
|
99
|
-
if (!normalized)
|
|
100
|
-
return false;
|
|
97
|
+
const EPHEMERAL_CACHE_DIRS = [
|
|
101
98
|
// CodeGraph extension sync side effect (plan 2026-08-21 D7): a loaded
|
|
102
99
|
// pi-codegraph extension keeps an existing .codegraph/ index fresh at
|
|
103
100
|
// session start; those index files are extension-owned run state, not
|
|
104
101
|
// writer output, so they never count as write-guard violations.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
normalized.startsWith(".pytest_cache/")) {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
if (normalized === ".mypy_cache" || normalized.startsWith(".mypy_cache/")) {
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
if (normalized === ".ruff_cache" || normalized.startsWith(".ruff_cache/")) {
|
|
116
|
-
return true;
|
|
117
|
-
}
|
|
102
|
+
".codegraph",
|
|
103
|
+
".pytest_cache",
|
|
104
|
+
".mypy_cache",
|
|
105
|
+
".ruff_cache",
|
|
118
106
|
// playwright-cli default session dumps (console/page/network) under repo cwd.
|
|
119
107
|
// Real browser case evidence must still be written under testcase/** explicitly.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
if (normalized === ".coverage" || normalized.startsWith(".coverage.")) {
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
108
|
+
".playwright-cli",
|
|
109
|
+
];
|
|
110
|
+
const EPHEMERAL_CACHE_DIR_PREFIXES = [
|
|
127
111
|
// vite/vitest runtime caches live under node_modules/.vite (e.g.
|
|
128
112
|
// node_modules/.vite/vitest/results.json). node_modules is the gitignored
|
|
129
113
|
// dependency tree — tool cache writes there are never a writer's product
|
|
130
114
|
// change and must not trip the write guard.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
115
|
+
"node_modules/.vite",
|
|
116
|
+
];
|
|
117
|
+
const EPHEMERAL_CACHE_FILES = new Set([".coverage"]);
|
|
118
|
+
const EPHEMERAL_CACHE_PATH_PATTERNS = [
|
|
119
|
+
/(?:^|\/)__pycache__(?:\/|$)/,
|
|
120
|
+
/\.(?:pyc|pyo)$/,
|
|
121
|
+
];
|
|
122
|
+
function isExactOrChildPath(value, names) {
|
|
123
|
+
return names.some((name) => value === name || value.startsWith(`${name}/`));
|
|
124
|
+
}
|
|
125
|
+
export function isEphemeralToolCachePath(filePath) {
|
|
126
|
+
const normalized = normalizePath(filePath);
|
|
127
|
+
if (!normalized)
|
|
128
|
+
return false;
|
|
129
|
+
return (isExactOrChildPath(normalized, EPHEMERAL_CACHE_DIRS) ||
|
|
130
|
+
EPHEMERAL_CACHE_DIR_PREFIXES.some((prefix) => normalized.startsWith(`${prefix}/`)) ||
|
|
131
|
+
EPHEMERAL_CACHE_FILES.has(normalized) ||
|
|
132
|
+
normalized.startsWith(".coverage.") ||
|
|
133
|
+
EPHEMERAL_CACHE_PATH_PATTERNS.some((pattern) => pattern.test(normalized)));
|
|
139
134
|
}
|
|
140
135
|
/** MVP post-run guard: only paths that changed during the shell node are checked. */
|
|
141
136
|
export function validateShellWriteGuard(input) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { shouldRewriteAssistantTransientProviderError } from "../pi-provider-recovery.js";
|
|
1
2
|
import { buildOverflowCheckpoint } from "./checkpoint.js";
|
|
2
3
|
import { shouldRewriteAssistantOverflow } from "./overflow.js";
|
|
3
4
|
import { clearRetrieveBypass, compressProviderPayload, createSiftRetrieveToolDefinition, SIFT_RETRIEVE_TOOL_NAME, } from "./sift-bridge.js";
|
|
@@ -11,35 +12,44 @@ export function createCompactionController() {
|
|
|
11
12
|
export function createContextPressureExtension(options) {
|
|
12
13
|
const l2 = options.policy.mode !== "off";
|
|
13
14
|
const l1 = Boolean(options.sift);
|
|
14
|
-
|
|
15
|
+
const transientRecovery = options.normalizeTransientProviderErrors === true;
|
|
16
|
+
if (!l2 && !l1 && !transientRecovery)
|
|
15
17
|
return undefined;
|
|
16
18
|
return {
|
|
17
19
|
name: options.name ?? "operator-chat-context-pressure",
|
|
18
20
|
hidden: true,
|
|
19
21
|
factory: (api) => {
|
|
20
|
-
if (l2) {
|
|
22
|
+
if (l2 || transientRecovery) {
|
|
21
23
|
api.on("message_end", (event) => {
|
|
22
24
|
const message = event.message;
|
|
23
25
|
if (!message || typeof message !== "object")
|
|
24
26
|
return undefined;
|
|
25
27
|
const rec = message;
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
+
if (l2) {
|
|
29
|
+
if (typeof rec.errorMessage === "string") {
|
|
30
|
+
options.controller.lastError = rec.errorMessage;
|
|
31
|
+
}
|
|
32
|
+
if (rec.role === "assistant") {
|
|
33
|
+
clearRetrieveBypassIfPresent(options.sift);
|
|
34
|
+
}
|
|
35
|
+
const rewritten = shouldRewriteAssistantOverflow(message);
|
|
36
|
+
if (rewritten) {
|
|
37
|
+
incrementCounter(options.controller.counters, "overflow");
|
|
38
|
+
return {
|
|
39
|
+
message: {
|
|
40
|
+
...rec,
|
|
41
|
+
errorMessage: rewritten,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
28
45
|
}
|
|
29
|
-
if (
|
|
30
|
-
|
|
46
|
+
if (transientRecovery) {
|
|
47
|
+
return shouldRewriteAssistantTransientProviderError(message);
|
|
31
48
|
}
|
|
32
|
-
|
|
33
|
-
if (!rewritten)
|
|
34
|
-
return undefined;
|
|
35
|
-
incrementCounter(options.controller.counters, "overflow");
|
|
36
|
-
return {
|
|
37
|
-
message: {
|
|
38
|
-
...rec,
|
|
39
|
-
errorMessage: rewritten,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
49
|
+
return undefined;
|
|
42
50
|
});
|
|
51
|
+
}
|
|
52
|
+
if (l2) {
|
|
43
53
|
api.on("session_before_compact", (event) => {
|
|
44
54
|
const reason = event.reason;
|
|
45
55
|
if (reason === "overflow") {
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { buildGeneratedOverflowClassifierSource, isContextOverflow, } from "./pi-context-pressure/overflow.js";
|
|
2
|
+
export const NORMALIZED_TRANSIENT_PROVIDER_PREFIX = "provider returned error:";
|
|
3
|
+
const ERROR_TEXT_LIMIT = 1_500;
|
|
4
|
+
const PERMANENT_ERROR_PATTERNS = [
|
|
5
|
+
/\b(?:401|403|429)\b|unauthori[sz]ed|forbidden|authentication|invalid api[-_ ]?key|认证错误|鉴权失败/i,
|
|
6
|
+
/\b(?:quota|billing|insufficient.?credit|out of budget)\b|余额不足|配额(?:不足|耗尽)/i,
|
|
7
|
+
/rate.?limit|too many requests|请求.{0,8}(?:频繁|过多)|频率.{0,8}限制|限流/i,
|
|
8
|
+
/aborted by user|user cancel|cancelled|canceled|用户取消/i,
|
|
9
|
+
/business validation|invalid task|schema validation|业务校验/i,
|
|
10
|
+
];
|
|
11
|
+
export const BUILT_IN_TRANSIENT_PROVIDER_RULES = Object.freeze([
|
|
12
|
+
Object.freeze({
|
|
13
|
+
id: "wrapped-transient-provider-error",
|
|
14
|
+
all: Object.freeze([
|
|
15
|
+
/\b(?:UnknownError|TypeValidationError)\b|Type validation failed/i,
|
|
16
|
+
]),
|
|
17
|
+
any: Object.freeze([
|
|
18
|
+
/\b502\b|\bcode[:\s]*502\b/i,
|
|
19
|
+
/\bLLMRequestError\b/i,
|
|
20
|
+
/network fluctuation|timeout|model processing timeout/i,
|
|
21
|
+
/网络波动|模型处理超时|当前请求超时/i,
|
|
22
|
+
/transient provider failure|non-standard (?:payload|response)|upstream returned/i,
|
|
23
|
+
]),
|
|
24
|
+
}),
|
|
25
|
+
Object.freeze({
|
|
26
|
+
id: "internal-llm-request-error",
|
|
27
|
+
all: Object.freeze([/\bLLMRequestError\b/i]),
|
|
28
|
+
any: Object.freeze([
|
|
29
|
+
/\b502\b|\bcode[:\s]*502\b/i,
|
|
30
|
+
/network fluctuation|timeout|model processing timeout/i,
|
|
31
|
+
/网络波动|模型处理超时|当前请求超时/i,
|
|
32
|
+
/non-standard (?:payload|response)|upstream returned/i,
|
|
33
|
+
]),
|
|
34
|
+
}),
|
|
35
|
+
Object.freeze({
|
|
36
|
+
id: "internal-provider-fluctuation",
|
|
37
|
+
any: Object.freeze([/网络波动|模型处理超时|当前请求超时/i]),
|
|
38
|
+
}),
|
|
39
|
+
]);
|
|
40
|
+
function stringifyErrorPart(value) {
|
|
41
|
+
if (typeof value === "string")
|
|
42
|
+
return value;
|
|
43
|
+
if (value == null)
|
|
44
|
+
return "";
|
|
45
|
+
try {
|
|
46
|
+
return JSON.stringify(value);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return String(value);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function errorText(error) {
|
|
53
|
+
if (typeof error === "string")
|
|
54
|
+
return error;
|
|
55
|
+
if (error == null)
|
|
56
|
+
return "";
|
|
57
|
+
if (typeof error !== "object")
|
|
58
|
+
return String(error);
|
|
59
|
+
const record = error;
|
|
60
|
+
return [
|
|
61
|
+
stringifyErrorPart(record.name),
|
|
62
|
+
stringifyErrorPart(record.message),
|
|
63
|
+
stringifyErrorPart(record.status),
|
|
64
|
+
stringifyErrorPart(record.code),
|
|
65
|
+
stringifyErrorPart(record.data),
|
|
66
|
+
stringifyErrorPart(error),
|
|
67
|
+
]
|
|
68
|
+
.filter(Boolean)
|
|
69
|
+
.join(" ");
|
|
70
|
+
}
|
|
71
|
+
function patternMatches(pattern, text) {
|
|
72
|
+
pattern.lastIndex = 0;
|
|
73
|
+
const matched = pattern.test(text);
|
|
74
|
+
pattern.lastIndex = 0;
|
|
75
|
+
return matched;
|
|
76
|
+
}
|
|
77
|
+
function ruleMatches(rule, text) {
|
|
78
|
+
const all = rule.all ?? [];
|
|
79
|
+
const any = rule.any ?? [];
|
|
80
|
+
if (all.length === 0 && any.length === 0)
|
|
81
|
+
return false;
|
|
82
|
+
if (!all.every((pattern) => patternMatches(pattern, text)))
|
|
83
|
+
return false;
|
|
84
|
+
return any.length === 0 || any.some((pattern) => patternMatches(pattern, text));
|
|
85
|
+
}
|
|
86
|
+
function isPermanentProviderError(error, text) {
|
|
87
|
+
if (isContextOverflow(error))
|
|
88
|
+
return true;
|
|
89
|
+
return PERMANENT_ERROR_PATTERNS.some((pattern) => patternMatches(pattern, text));
|
|
90
|
+
}
|
|
91
|
+
export function classifyTransientProviderError(error, options = {}) {
|
|
92
|
+
const text = errorText(error);
|
|
93
|
+
if (!text || isPermanentProviderError(error, text)) {
|
|
94
|
+
return { retryable: false, reason: "permanent" };
|
|
95
|
+
}
|
|
96
|
+
const rules = [
|
|
97
|
+
...BUILT_IN_TRANSIENT_PROVIDER_RULES,
|
|
98
|
+
...(options.additionalRules ?? []),
|
|
99
|
+
];
|
|
100
|
+
const matched = rules.find((rule) => ruleMatches(rule, text));
|
|
101
|
+
return matched
|
|
102
|
+
? { retryable: true, ruleId: matched.id }
|
|
103
|
+
: { retryable: false, reason: "no-match" };
|
|
104
|
+
}
|
|
105
|
+
export function normalizeTransientProviderErrorMessage(current, options = {}) {
|
|
106
|
+
if (!current || current.startsWith(NORMALIZED_TRANSIENT_PROVIDER_PREFIX)) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
if (!classifyTransientProviderError(current, options).retryable)
|
|
110
|
+
return undefined;
|
|
111
|
+
const bounded = current.length <= ERROR_TEXT_LIMIT
|
|
112
|
+
? current
|
|
113
|
+
: `${current.slice(0, ERROR_TEXT_LIMIT - 1)}…`;
|
|
114
|
+
return `${NORMALIZED_TRANSIENT_PROVIDER_PREFIX} ${bounded}`;
|
|
115
|
+
}
|
|
116
|
+
export function shouldRewriteAssistantTransientProviderError(message, options = {}) {
|
|
117
|
+
if (!message || typeof message !== "object")
|
|
118
|
+
return undefined;
|
|
119
|
+
const record = message;
|
|
120
|
+
if (record.role !== "assistant")
|
|
121
|
+
return undefined;
|
|
122
|
+
if (record.stopReason !== undefined && record.stopReason !== "error") {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
const current = typeof record.errorMessage === "string" ? record.errorMessage : "";
|
|
126
|
+
const rewritten = normalizeTransientProviderErrorMessage(current, options);
|
|
127
|
+
return rewritten
|
|
128
|
+
? { message: { ...record, errorMessage: rewritten } }
|
|
129
|
+
: undefined;
|
|
130
|
+
}
|
|
131
|
+
function serializePatterns(patterns) {
|
|
132
|
+
return JSON.stringify(patterns.map((pattern) => ({ source: pattern.source, flags: pattern.flags })));
|
|
133
|
+
}
|
|
134
|
+
/** Generate the pure predicate embedded in the project-level OpenCode plugin. */
|
|
135
|
+
export function buildGeneratedTransientProviderClassifierSource() {
|
|
136
|
+
const rules = BUILT_IN_TRANSIENT_PROVIDER_RULES.map((rule) => ({
|
|
137
|
+
id: rule.id,
|
|
138
|
+
all: (rule.all ?? []).map((pattern) => ({
|
|
139
|
+
source: pattern.source,
|
|
140
|
+
flags: pattern.flags,
|
|
141
|
+
})),
|
|
142
|
+
any: (rule.any ?? []).map((pattern) => ({
|
|
143
|
+
source: pattern.source,
|
|
144
|
+
flags: pattern.flags,
|
|
145
|
+
})),
|
|
146
|
+
}));
|
|
147
|
+
return `${buildGeneratedOverflowClassifierSource()}
|
|
148
|
+
const TRANSIENT_PROVIDER_PERMANENT_PATTERNS = ${serializePatterns(PERMANENT_ERROR_PATTERNS)};
|
|
149
|
+
const TRANSIENT_PROVIDER_RULES = ${JSON.stringify(rules)};
|
|
150
|
+
function transientProviderStringify(value) {
|
|
151
|
+
if (typeof value === "string") return value;
|
|
152
|
+
if (value == null) return "";
|
|
153
|
+
try { return JSON.stringify(value); } catch { return String(value); }
|
|
154
|
+
}
|
|
155
|
+
function transientProviderText(error) {
|
|
156
|
+
if (typeof error === "string") return error;
|
|
157
|
+
if (error == null) return "";
|
|
158
|
+
if (typeof error !== "object") return String(error);
|
|
159
|
+
return [
|
|
160
|
+
transientProviderStringify(error.name),
|
|
161
|
+
transientProviderStringify(error.message),
|
|
162
|
+
transientProviderStringify(error.status),
|
|
163
|
+
transientProviderStringify(error.code),
|
|
164
|
+
transientProviderStringify(error.data),
|
|
165
|
+
transientProviderStringify(error),
|
|
166
|
+
].filter(Boolean).join(" ");
|
|
167
|
+
}
|
|
168
|
+
function transientProviderPatternMatches(pattern, text) {
|
|
169
|
+
return new RegExp(pattern.source, pattern.flags).test(text);
|
|
170
|
+
}
|
|
171
|
+
function transientProviderRuleMatches(rule, text) {
|
|
172
|
+
if (rule.all.length === 0 && rule.any.length === 0) return false;
|
|
173
|
+
if (!rule.all.every((pattern) => transientProviderPatternMatches(pattern, text))) return false;
|
|
174
|
+
return rule.any.length === 0 || rule.any.some((pattern) => transientProviderPatternMatches(pattern, text));
|
|
175
|
+
}
|
|
176
|
+
function isKnownTransientProviderError(error) {
|
|
177
|
+
const text = transientProviderText(error);
|
|
178
|
+
if (!text || isOverflowMessage(text)) return false;
|
|
179
|
+
if (TRANSIENT_PROVIDER_PERMANENT_PATTERNS.some((pattern) => transientProviderPatternMatches(pattern, text))) return false;
|
|
180
|
+
return TRANSIENT_PROVIDER_RULES.some((rule) => transientProviderRuleMatches(rule, text));
|
|
181
|
+
}`;
|
|
182
|
+
}
|
|
@@ -21,3 +21,43 @@ export const PI_RECOMMENDED_RETRY = {
|
|
|
21
21
|
},
|
|
22
22
|
};
|
|
23
23
|
export const PI_RECOMMENDED_COMPACTION = { enabled: true };
|
|
24
|
+
function validBoolean(value) {
|
|
25
|
+
return typeof value === "boolean";
|
|
26
|
+
}
|
|
27
|
+
function validNonNegativeNumber(value) {
|
|
28
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
29
|
+
}
|
|
30
|
+
function preferredOptionalNonNegativeNumber(...values) {
|
|
31
|
+
return values.find(validNonNegativeNumber);
|
|
32
|
+
}
|
|
33
|
+
function preferredValue(projectValue, globalValue, fallback, isValid) {
|
|
34
|
+
if (isValid(projectValue))
|
|
35
|
+
return projectValue;
|
|
36
|
+
if (isValid(globalValue))
|
|
37
|
+
return globalValue;
|
|
38
|
+
return fallback;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Apply Console-owned retry defaults without writing settings files.
|
|
42
|
+
* Explicit project fields win over global fields, which win over defaults.
|
|
43
|
+
*/
|
|
44
|
+
export function applyProcessRetryOverride(manager) {
|
|
45
|
+
if (!manager?.applyOverrides)
|
|
46
|
+
return { applied: false };
|
|
47
|
+
const project = manager.getProjectSettings?.()?.retry;
|
|
48
|
+
const global = manager.getGlobalSettings?.()?.retry;
|
|
49
|
+
const currentProvider = manager.getProviderRetrySettings?.();
|
|
50
|
+
const timeoutMs = preferredOptionalNonNegativeNumber(project?.provider?.timeoutMs, global?.provider?.timeoutMs, currentProvider?.timeoutMs);
|
|
51
|
+
const retry = {
|
|
52
|
+
enabled: preferredValue(project?.enabled, global?.enabled, PI_RECOMMENDED_RETRY.enabled, validBoolean),
|
|
53
|
+
maxRetries: preferredValue(project?.maxRetries, global?.maxRetries, PI_RECOMMENDED_RETRY.maxRetries, validNonNegativeNumber),
|
|
54
|
+
baseDelayMs: preferredValue(project?.baseDelayMs, global?.baseDelayMs, PI_RECOMMENDED_RETRY.baseDelayMs, validNonNegativeNumber),
|
|
55
|
+
provider: {
|
|
56
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
57
|
+
maxRetries: preferredValue(project?.provider?.maxRetries, global?.provider?.maxRetries, PI_RECOMMENDED_RETRY.provider.maxRetries, validNonNegativeNumber),
|
|
58
|
+
maxRetryDelayMs: preferredValue(project?.provider?.maxRetryDelayMs, global?.provider?.maxRetryDelayMs, PI_RECOMMENDED_RETRY.provider.maxRetryDelayMs, validNonNegativeNumber),
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
manager.applyOverrides({ retry });
|
|
62
|
+
return { applied: true, retry };
|
|
63
|
+
}
|
|
@@ -37,6 +37,7 @@ import { authorizeChatSessionTool, DEFAULT_CONSOLE_CHAT_SESSION_MODE, chatActive
|
|
|
37
37
|
import { buildAgentCustomTool, ExploreOrchestrator, } from "./subagents/index.js";
|
|
38
38
|
import { createOperatorChatResourceLoader, } from "./resource-loader.js";
|
|
39
39
|
import { applySkillAutoInvocationPreferences, loadResourcePreferences, } from "./resource-preferences-store.js";
|
|
40
|
+
import { applyProcessRetryOverride, } from "../../../shared/pi-retry-settings.js";
|
|
40
41
|
import { applyProcessCompactionOverride, createCompactionController, createContextPressureExtension, createSiftBridgeState, housekeepSiftStash, isConsoleSiftEnabled, parseCompactionPolicy, parseSiftBridgeConfig, projectPromptPressure, deriveEffectiveWindow, projectSafeTelemetry, emptyContextPressureCounters, } from "../../../shared/pi-context-pressure/index.js";
|
|
41
42
|
import { incrementCounter as incrementPressureCounter } from "../../../shared/pi-context-pressure/telemetry.js";
|
|
42
43
|
import { resolveDefaultChatModel, resolveLowChatModel, } from "./model-resolver.js";
|
|
@@ -482,7 +483,6 @@ export class ConsolePiRuntime {
|
|
|
482
483
|
const inheritedFactories = Array.isArray(base.extensionFactories)
|
|
483
484
|
? base.extensionFactories
|
|
484
485
|
: [];
|
|
485
|
-
const sessionMode = this.sessionModeOf(sessionId);
|
|
486
486
|
const todoContextExtension = sessionId && this.options.todoRegistry
|
|
487
487
|
? createTodoCompactionContextExtension({
|
|
488
488
|
sessionId,
|
|
@@ -578,9 +578,11 @@ export class ConsolePiRuntime {
|
|
|
578
578
|
policy,
|
|
579
579
|
controller: this.getCompactionController(sessionId),
|
|
580
580
|
sift,
|
|
581
|
+
normalizeTransientProviderErrors: true,
|
|
581
582
|
});
|
|
582
583
|
}
|
|
583
|
-
|
|
584
|
+
applySessionRecoveryOverrides(sessionId, services, session) {
|
|
585
|
+
applyProcessRetryOverride(services?.settingsManager);
|
|
584
586
|
const manager = services?.settingsManager;
|
|
585
587
|
const window = session?.getSessionStats?.()?.contextUsage?.contextWindow;
|
|
586
588
|
applyProcessCompactionOverride(manager, {
|
|
@@ -598,7 +600,7 @@ export class ConsolePiRuntime {
|
|
|
598
600
|
const window = stats?.contextUsage?.contextWindow;
|
|
599
601
|
const tokens = stats?.contextUsage?.tokens;
|
|
600
602
|
if (typeof window === "number" && window > 0) {
|
|
601
|
-
this.
|
|
603
|
+
this.applySessionRecoveryOverrides(sessionId, this.serviceScopes.get(sessionId) ?? {}, session);
|
|
602
604
|
}
|
|
603
605
|
const projection = projectPromptPressure({
|
|
604
606
|
currentContextTokens: tokens,
|
|
@@ -903,7 +905,7 @@ export class ConsolePiRuntime {
|
|
|
903
905
|
}
|
|
904
906
|
await bindSessionExtensions(session);
|
|
905
907
|
pinOperatorChatTools(session, init.sessionMode);
|
|
906
|
-
this.
|
|
908
|
+
this.applySessionRecoveryOverrides(init.sessionId, services, session);
|
|
907
909
|
return {
|
|
908
910
|
session,
|
|
909
911
|
modelRuntime,
|
|
@@ -1378,7 +1380,7 @@ export class ConsolePiRuntime {
|
|
|
1378
1380
|
await session.reload();
|
|
1379
1381
|
const services = this.serviceScopes.get(sessionId);
|
|
1380
1382
|
if (services)
|
|
1381
|
-
this.
|
|
1383
|
+
this.applySessionRecoveryOverrides(sessionId, services, session);
|
|
1382
1384
|
await this.refreshModelConfiguration(sessionId, "force");
|
|
1383
1385
|
pinOperatorChatTools(session, this.sessionModeOf(sessionId));
|
|
1384
1386
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-Bj4vc-Dp.js";import{p as f}from"./chunk-JWPE2WC7-Dr-wFY60.js";import{_ as n,l as o}from"./mermaid.core-i7dDGqov.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-zo_Jy2sf.js";import"./index-CWarwRqc.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-i7dDGqov.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|