@tea-agent/loop-agent 0.38.1 → 0.38.3
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 +126 -12
- package/README.md +2 -0
- package/bin/loop-agent.js +7 -3
- package/dist/application/dag/generate-task-dag.js +9 -0
- package/dist/application/task-lifecycle/advance.js +4 -0
- package/dist/build-stamp.json +3 -3
- package/dist/commands/init.js +2 -14
- package/dist/commands/task-advance.js +31 -0
- package/dist/executors/dag-pi-executor.js +99 -5
- package/dist/executors/pi-event-serializer.js +42 -1
- package/dist/executors/pi-executor.js +51 -0
- package/dist/executors/pi-extension-resolver.js +233 -0
- package/dist/executors/pi-sdk-executor.js +187 -59
- package/dist/executors/shell-executor.js +324 -16
- package/dist/executors/shell-write-guard.js +7 -0
- package/dist/governance/manifest-types.js +0 -2
- package/dist/shared/operator/capabilities.js +87 -22
- package/dist/task/config-types.js +22 -0
- package/dist/task/contract/constants.js +1 -0
- package/dist/task/contract/diff.js +26 -0
- package/dist/task/contract/project.js +5 -0
- package/dist/task/contract/schema.js +6 -1
- package/dist/task/source-prepare/build-draft.js +15 -0
- package/dist/worker/console/chat/deferred-turn.js +91 -0
- package/dist/worker/console/chat/pi-runtime.js +10 -5
- package/dist/worker/console/chat/routes.js +458 -47
- package/dist/worker/console/chat/semantic-activity.js +13 -13
- package/dist/worker/console/chat/session-store.js +146 -2
- package/dist/worker/console/harness-pi-model-matrix.js +2 -11
- package/dist/worker/console/operator-actions.js +5 -4
- package/dist/worker/console/pi-readiness.js +5 -4
- package/dist/worker/console/recovery-cta.js +4 -4
- package/dist/worker/console/recovery-error-copy.js +4 -4
- package/dist/worker/console/server.js +6 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-Hfsot6rP.js → abnfDiagram-N423BO3Z-C4kVYweA.js} +1 -1
- package/dist/worker/console/static/assets/{arc-YGwEASin.js → arc-Bj2M8iO5.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CmOM0F92.js → architectureDiagram-T3A2C74G-CLlXe4-6.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-DDLuaHC5.js → blockDiagram-VBNYF7ZC-psEp5xH0.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-B0Um43W4.js → c4Diagram-5PPSVZJV-DeKcOCGJ.js} +1 -1
- package/dist/worker/console/static/assets/channel-CPF4N7pf.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DvBN4JZc.js → chunk-2GRJ4B5K-K0C744p1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-B1UVgW4E.js → chunk-2Q5K7J3B-xbNw4J9-.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-Cf0GgXzX.js → chunk-5RXB4S5H-DjLaSDUO.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DbNA24sj.js → chunk-5VM5RSS4-CtiPlKel.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Bi_0Be06.js → chunk-6Q2QTUOP-DZtolir7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C8pPGvRd.js → chunk-GF5L2VYU-CPcdNeew.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BitQY8Z-.js → chunk-JWPE2WC7-NgHc6V37.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-U67GCiEo.js → chunk-KBJHAD2P-DQ_T-hg8.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-IoJwXPBA.js → chunk-RYQCIY6F-DgLsxcVP.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-YDZ_UHgE.js → chunk-XXDRQBXY-UrVoM9z1.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C2DwA_Y1.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C2DwA_Y1.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CUZgsiRC.js → cose-bilkent-JH36ORCC-CLkYvTb3.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-COmCh4pT.js → cynefin-VYW2F7L2-BwT_xKrE.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Ta6FSm68.js → cynefinDiagram-MW4NZA55-Bi9tuzif.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-UdcR-VW9.js → dagre-VZM6K2ZE-BCIqkWBV.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-DybcO3Et.js → diagram-7IWD3JNH-Dip6l9_Z.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-wErDFWLw.js → diagram-B4RE2ZJO-B-xkh_wK.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DkVHZWqz.js → diagram-LBJQPF4R-DZO0kTt_.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DdqWs7QN.js → diagram-Q27KOJAE-D6ZplNbZ.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-C9dMVmDo.js → diagram-UB23O5K3-BPekbhoS.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-B2T2WcBK.js → ebnfDiagram-BXEA7PRR-BtmaJpK5.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Bt9rjDFq.js → erDiagram-JOGREHBK-6DS0Xc44.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-U8ic_tvi.js → flowDiagram-UKHOOZJN-CihnROSm.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-BfQJdQoO.js → ganttDiagram-PKOTCBZU-CZC4zOE2.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-CpMftH4O.js → gitGraphDiagram-DS77QQ5N-Dq1fhzGN.js} +1 -1
- package/dist/worker/console/static/assets/index-DTZOKgAn.js +404 -0
- package/dist/worker/console/static/assets/index-Ya5FE7cD.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DzqWXNO_.js → infoDiagram-6WML65LV-DlSl4BGx.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-CJmGQ5Yp.js → ishikawaDiagram-WSZJBQD7-snnzFl_U.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-ChPtKFLz.js → journeyDiagram-NVQOT4AX-BDE7qpMx.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-PRe7wB5u.js → kanban-definition-27J2QSJJ-CD2Ci04G.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DpKX6QNp.js → linear-DdnapKIH.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-Dnl76b7Y.js → mermaid.core-BVjAT9b8.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-S9PCXc3J.js → mindmap-definition-FAOFIHXS-D0yJk-zA.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-Du8e-FSX.js → pegDiagram-VL7TDLO6-BVo9tFP-.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CY6OmHTc.js → pieDiagram-7S7Q4E2Y-DnOV-mZ_.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-C65GPhpj.js → quadrantDiagram-CIZ2JOQS-CzUJo58i.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-U6IUiTCL.js → railroadDiagram-AXF67PYL-Bvikrolh.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D-I_9Qhi.js → requirementDiagram-LRYGKXZP-DtaSVCap.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-B57Fhed0.js → sankeyDiagram-W5VNT64P-C2c9A0wW.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CJOtiw21.js → sequenceDiagram-SI44F4Z6-DmXJcU7r.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-FyX8zxSh.js → sizeCapture-X5ZJPWSS-B4GUFW92.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-eF-pbs9t.js → stateDiagram-OKZ733FA-Dsad2MXf.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-B8FB_cNk.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CcfkA-Dq.js → swimlanes-SLNWSIFB-DGq48Fbi.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CrZYaWfx.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-DH8FjnOK.js → timeline-definition-Z64GVDOM-CSSi6OFf.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-beoTagJg.js → vennDiagram-T6HMQDX7-BqyzPrWv.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CQSfw4cK.js → wardleyDiagram-T6FBY63Y-DlznVb6S.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CQgzQ6jn.js → xychartDiagram-ELKLHX3M-CfBcgJ_K.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/console-types.js +0 -12
- package/dist/worker/console/static-src/app/useOperatorActions.js +1 -1
- package/dist/worker/console/static-src/app/useRecoveryActions.js +2 -2
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +38 -1
- package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +328 -0
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +8 -1
- package/dist/worker/console/static-src/operator-chat/turn-submission.js +42 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +3 -0
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +204 -11
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +23 -1
- package/dist/worker/observe/node-input.js +72 -3
- package/dist/worker/observe/static/dag-history-labels.js +4 -0
- package/dist/worker/observe/static/state.js +2 -2
- package/dist/worker/observe/static/views/dag-inspector.js +51 -0
- package/dist/worker/observe/static/views/session-timeline.js +18 -5
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +809 -53
- package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
- package/dist/workflows/dag/backend-test-execution-contract.js +18 -9
- package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
- package/dist/workflows/dag/backend-test-intake-context.js +32 -0
- package/dist/workflows/dag/backend-test-layout.js +133 -0
- package/dist/workflows/dag/backend-test-markdown-workflow.js +167 -32
- package/dist/workflows/dag/backend-test-module-stem.js +5 -0
- package/dist/workflows/dag/backend-test-pytest-collection.js +368 -33
- package/dist/workflows/dag/backend-test-result-contract.js +1 -1
- package/dist/workflows/dag/backend-test-scenario-param.js +884 -140
- package/dist/workflows/dag/backend-test-scenario-partitions.js +321 -0
- package/dist/workflows/dag/backend-test-writer-completeness.js +100 -56
- package/dist/workflows/dag/contract-output-registry.js +15 -0
- package/dist/workflows/dag/contract-validator-registrations.js +2 -1
- package/dist/workflows/dag/convergence/controller.js +141 -0
- package/dist/workflows/dag/dynamic-runtime/map.js +24 -8
- package/dist/workflows/dag/dynamic-runtime/shared.js +1 -1
- package/dist/workflows/dag/failure-category.js +4 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +355 -26
- package/dist/workflows/dag/frontend-prewrite-gate.js +96 -84
- package/dist/workflows/dag/frontend-test-case-quality.js +5 -13
- package/dist/workflows/dag/frontend-test-environment-probe.js +227 -0
- package/dist/workflows/dag/frontend-test-markdown.js +61 -0
- package/dist/workflows/dag/frontend-test-result-contract.js +10 -18
- package/dist/workflows/dag/frontend-test-standard-scenarios.js +68 -0
- package/dist/workflows/dag/init-hybrid.js +720 -177
- package/dist/workflows/dag/node-execution.js +164 -26
- package/dist/workflows/dag/prompt.js +60 -1
- package/dist/workflows/dag/rerun-feedback.js +212 -0
- package/dist/workflows/dag/rerun-plan.js +112 -27
- package/dist/workflows/dag/rerun-run.js +3 -0
- package/dist/workflows/dag/rerun-task.js +61 -2
- package/dist/workflows/dag/retry-policy.js +18 -0
- package/dist/workflows/dag/structured-output-repair.js +712 -0
- package/dist/workflows/dag/types.js +121 -0
- package/dist/workflows/dag/validate.js +41 -1
- package/docs/operations/local-development-environment.md +1 -5
- package/docs/skills/vetted-skill-registry.md +14 -0
- package/docs/templates/README.md +1 -1
- package/docs/templates/agent-dag.schema.json +44 -0
- package/docs/templates/backend-test-dag.json +60 -35
- package/docs/templates/frontend-test-dag.json +8 -10
- package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +1 -1
- package/docs/templates/harness.schema.json +0 -8
- package/harness.json +1 -8
- package/package.json +8 -4
- package/skills/analyze-product-requirements/SKILL.md +8 -5
- package/skills/analyze-product-requirements/references/acceptance-criteria.md +1 -1
- package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +10 -6
- package/skills/analyze-product-requirements/references/example.md +50 -0
- package/skills/analyze-product-requirements/references/forward-test-cases.md +11 -7
- package/skills/analyze-product-requirements/references/kb-integration.md +5 -5
- package/skills/analyze-product-requirements/references/product-analysis-schema.md +8 -4
- package/skills/analyze-product-requirements/references/product-requirement-schema.md +2 -2
- package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +1 -1
- package/skills/analyze-product-requirements/scripts/test-validators.mjs +11 -1
- package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +20 -1
- package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +9 -0
- package/skills/codebase-scout/SKILL.md +1 -1
- package/skills/frontend-implementation/references/node-contracts.md +2 -2
- package/skills/improve-codebase-architecture/SKILL.md +81 -0
- package/skills/improve-codebase-architecture/deepening.md +37 -0
- package/skills/improve-codebase-architecture/html-report.md +123 -0
- package/skills/improve-codebase-architecture/interface-design.md +44 -0
- package/skills/improve-codebase-architecture/language.md +53 -0
- package/dist/worker/console/static/assets/channel-Dp_2Aqf1.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL--CODy37j.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE--CODy37j.js +0 -1
- package/dist/worker/console/static/assets/index-BA5-N5ER.css +0 -1
- package/dist/worker/console/static/assets/index-DKPXBrdc.js +0 -325
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-B-mvnLEc.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-JtpBmIv4.js +0 -8
|
@@ -17,6 +17,7 @@ import { dispatchOperatorAction } from "../operator-actions.js";
|
|
|
17
17
|
import { authorizeOperatorChatTool } from "./tools.js";
|
|
18
18
|
import { projectOperationForChat } from "./chat-event-store.js";
|
|
19
19
|
import { scrubSecrets } from "./explore-tools.js";
|
|
20
|
+
import { hashDeferredTurnPayload, parseDeferredTurn, } from "./deferred-turn.js";
|
|
20
21
|
const CHAT_TITLE_MAX_CHARS = 80;
|
|
21
22
|
/** Safe, one-line bounded title used for placeholders and model output. */
|
|
22
23
|
export function cleanChatTitle(value) {
|
|
@@ -53,6 +54,7 @@ export class ChatSessionStore {
|
|
|
53
54
|
const raw = await readJsonIfExists(recordPath(this.appData, sessionId));
|
|
54
55
|
if (!raw || raw.sessionId !== sessionId)
|
|
55
56
|
return undefined;
|
|
57
|
+
const deferredTurn = parseDeferredTurn(raw.deferredTurn);
|
|
56
58
|
return {
|
|
57
59
|
schemaVersion: 2,
|
|
58
60
|
sessionId,
|
|
@@ -67,6 +69,7 @@ export class ChatSessionStore {
|
|
|
67
69
|
...(typeof raw.modelProvider === "string" ? { modelProvider: raw.modelProvider } : {}),
|
|
68
70
|
...(typeof raw.modelId === "string" ? { modelId: raw.modelId } : {}),
|
|
69
71
|
...(typeof raw.thinkingLevel === "string" ? { thinkingLevel: raw.thinkingLevel } : {}),
|
|
72
|
+
...(deferredTurn ? { deferredTurn } : {}),
|
|
70
73
|
messages: Array.isArray(raw.messages) ? raw.messages : [],
|
|
71
74
|
toolInvocations: Array.isArray(raw.toolInvocations) ? raw.toolInvocations : [],
|
|
72
75
|
};
|
|
@@ -147,6 +150,7 @@ export class ChatSessionStore {
|
|
|
147
150
|
...(input.targetSessionFile ? { sessionFile: input.targetSessionFile } : { sessionFile: undefined }),
|
|
148
151
|
createdAt: now,
|
|
149
152
|
updatedAt: now,
|
|
153
|
+
deferredTurn: undefined,
|
|
150
154
|
messages: structuredClone(source.messages),
|
|
151
155
|
toolInvocations: structuredClone(source.toolInvocations),
|
|
152
156
|
};
|
|
@@ -216,6 +220,146 @@ export class ChatSessionStore {
|
|
|
216
220
|
return true;
|
|
217
221
|
});
|
|
218
222
|
}
|
|
223
|
+
async putDeferredTurn(sessionId, input) {
|
|
224
|
+
return this.serialize(sessionId, async () => {
|
|
225
|
+
const record = await this.get(sessionId);
|
|
226
|
+
if (!record)
|
|
227
|
+
return { ok: false, code: "NOT_FOUND" };
|
|
228
|
+
const clientRequestId = input.clientRequestId.trim();
|
|
229
|
+
const blockedByTurnId = input.blockedByTurnId.trim();
|
|
230
|
+
const text = input.text.trim() || (input.images.length > 0 ? "请查看附件图片。" : "");
|
|
231
|
+
if (!clientRequestId || !blockedByTurnId || !text) {
|
|
232
|
+
return { ok: false, code: "INVALID_INPUT" };
|
|
233
|
+
}
|
|
234
|
+
const payloadHash = hashDeferredTurnPayload({ text, images: input.images });
|
|
235
|
+
const existing = record.deferredTurn;
|
|
236
|
+
if (existing) {
|
|
237
|
+
if (existing.clientRequestId === clientRequestId) {
|
|
238
|
+
if (existing.payloadHash !== payloadHash) {
|
|
239
|
+
return {
|
|
240
|
+
ok: false,
|
|
241
|
+
code: "REQUEST_ID_REUSE_CONFLICT",
|
|
242
|
+
deferredTurn: existing,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return { ok: true, deferredTurn: existing, idempotent: true };
|
|
246
|
+
}
|
|
247
|
+
if (existing.state !== "queued") {
|
|
248
|
+
return {
|
|
249
|
+
ok: false,
|
|
250
|
+
code: "NOT_REPLACEABLE",
|
|
251
|
+
deferredTurn: existing,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
if (input.expectedRevision !== existing.revision) {
|
|
255
|
+
return {
|
|
256
|
+
ok: false,
|
|
257
|
+
code: "REVISION_CONFLICT",
|
|
258
|
+
deferredTurn: existing,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (input.expectedRevision !== undefined &&
|
|
263
|
+
input.expectedRevision !== 0) {
|
|
264
|
+
return { ok: false, code: "REVISION_CONFLICT" };
|
|
265
|
+
}
|
|
266
|
+
const now = new Date().toISOString();
|
|
267
|
+
const deferredTurn = {
|
|
268
|
+
schemaVersion: 1,
|
|
269
|
+
revision: (existing?.revision ?? 0) + 1,
|
|
270
|
+
clientRequestId,
|
|
271
|
+
payloadHash,
|
|
272
|
+
blockedByTurnId,
|
|
273
|
+
text,
|
|
274
|
+
images: structuredClone(input.images),
|
|
275
|
+
state: "queued",
|
|
276
|
+
createdAt: existing?.createdAt ?? now,
|
|
277
|
+
updatedAt: now,
|
|
278
|
+
};
|
|
279
|
+
record.deferredTurn = deferredTurn;
|
|
280
|
+
record.updatedAt = now;
|
|
281
|
+
await writeSecureJson(recordPath(this.appData, sessionId), record);
|
|
282
|
+
return { ok: true, deferredTurn, idempotent: false };
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
async claimDeferredTurn(sessionId, expectedRevision) {
|
|
286
|
+
return this.serialize(sessionId, async () => {
|
|
287
|
+
const record = await this.get(sessionId);
|
|
288
|
+
const existing = record?.deferredTurn;
|
|
289
|
+
if (!record || !existing)
|
|
290
|
+
return { ok: false, code: "NOT_FOUND" };
|
|
291
|
+
if (existing.revision !== expectedRevision) {
|
|
292
|
+
return { ok: false, code: "REVISION_CONFLICT", deferredTurn: existing };
|
|
293
|
+
}
|
|
294
|
+
if (existing.state !== "queued") {
|
|
295
|
+
return { ok: false, code: "NOT_CLAIMABLE", deferredTurn: existing };
|
|
296
|
+
}
|
|
297
|
+
const next = {
|
|
298
|
+
...existing,
|
|
299
|
+
revision: existing.revision + 1,
|
|
300
|
+
state: "dispatching",
|
|
301
|
+
updatedAt: new Date().toISOString(),
|
|
302
|
+
};
|
|
303
|
+
record.deferredTurn = next;
|
|
304
|
+
record.updatedAt = next.updatedAt;
|
|
305
|
+
await writeSecureJson(recordPath(this.appData, sessionId), record);
|
|
306
|
+
return { ok: true, deferredTurn: next };
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
async transitionDeferredTurn(sessionId, input) {
|
|
310
|
+
return this.serialize(sessionId, async () => {
|
|
311
|
+
const record = await this.get(sessionId);
|
|
312
|
+
const existing = record?.deferredTurn;
|
|
313
|
+
if (!record || !existing || existing.revision !== input.expectedRevision)
|
|
314
|
+
return undefined;
|
|
315
|
+
const next = {
|
|
316
|
+
...existing,
|
|
317
|
+
revision: existing.revision + 1,
|
|
318
|
+
state: input.state,
|
|
319
|
+
updatedAt: new Date().toISOString(),
|
|
320
|
+
...(input.acceptedTurnId ? { acceptedTurnId: input.acceptedTurnId } : {}),
|
|
321
|
+
...(input.lastError ? { lastError: input.lastError } : {}),
|
|
322
|
+
};
|
|
323
|
+
if (!input.lastError)
|
|
324
|
+
delete next.lastError;
|
|
325
|
+
record.deferredTurn = next;
|
|
326
|
+
record.updatedAt = next.updatedAt;
|
|
327
|
+
await writeSecureJson(recordPath(this.appData, sessionId), record);
|
|
328
|
+
return next;
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
async deleteDeferredTurn(sessionId, input) {
|
|
332
|
+
return this.serialize(sessionId, async () => {
|
|
333
|
+
const record = await this.get(sessionId);
|
|
334
|
+
const existing = record?.deferredTurn;
|
|
335
|
+
if (!record || !existing || existing.clientRequestId !== input.clientRequestId) {
|
|
336
|
+
return { ok: false, code: "NOT_FOUND" };
|
|
337
|
+
}
|
|
338
|
+
if (existing.state !== "queued" && existing.state !== "failed") {
|
|
339
|
+
return { ok: false, code: "NOT_CANCELLABLE", deferredTurn: existing };
|
|
340
|
+
}
|
|
341
|
+
if (existing.revision !== input.expectedRevision) {
|
|
342
|
+
return { ok: false, code: "REVISION_CONFLICT", deferredTurn: existing };
|
|
343
|
+
}
|
|
344
|
+
delete record.deferredTurn;
|
|
345
|
+
record.updatedAt = new Date().toISOString();
|
|
346
|
+
await writeSecureJson(recordPath(this.appData, sessionId), record);
|
|
347
|
+
return { ok: true, deferredTurn: existing };
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
async clearDeferredTurnForRequest(sessionId, clientRequestId) {
|
|
351
|
+
return this.serialize(sessionId, async () => {
|
|
352
|
+
const record = await this.get(sessionId);
|
|
353
|
+
const existing = record?.deferredTurn;
|
|
354
|
+
if (!record || !existing || existing.clientRequestId !== clientRequestId) {
|
|
355
|
+
return undefined;
|
|
356
|
+
}
|
|
357
|
+
delete record.deferredTurn;
|
|
358
|
+
record.updatedAt = new Date().toISOString();
|
|
359
|
+
await writeSecureJson(recordPath(this.appData, sessionId), record);
|
|
360
|
+
return { deferredTurn: existing, clearedRevision: existing.revision + 1 };
|
|
361
|
+
});
|
|
362
|
+
}
|
|
219
363
|
async appendMessage(sessionId, message) {
|
|
220
364
|
return this.serialize(sessionId, async () => {
|
|
221
365
|
const record = await this.get(sessionId);
|
|
@@ -340,10 +484,10 @@ export async function runChatTurn(options) {
|
|
|
340
484
|
},
|
|
341
485
|
};
|
|
342
486
|
}
|
|
343
|
-
await store.appendMessage(sessionId, { role: "user", text });
|
|
487
|
+
const userMessage = await store.appendMessage(sessionId, { role: "user", text });
|
|
344
488
|
const afterUserMessage = await store.get(sessionId);
|
|
345
489
|
if (afterUserMessage)
|
|
346
|
-
await options.onUserMessagePersisted?.(afterUserMessage);
|
|
490
|
+
await options.onUserMessagePersisted?.(afterUserMessage, userMessage);
|
|
347
491
|
let turnError;
|
|
348
492
|
// Collect persistence promises so runChatTurn does not resolve before the
|
|
349
493
|
// chat history / audit trail is durably written (also makes the outcome
|
|
@@ -82,16 +82,8 @@ export async function readPiModelMatrixProjection(repoRoot) {
|
|
|
82
82
|
const manifest = await readHarnessJson(repoRoot);
|
|
83
83
|
const pi = manifest?.executors?.pi;
|
|
84
84
|
const projection = {};
|
|
85
|
-
const options = new Set();
|
|
86
85
|
if (!pi || typeof pi !== "object")
|
|
87
|
-
return
|
|
88
|
-
const configuredOptions = Array.isArray(pi.modelOptions)
|
|
89
|
-
? pi.modelOptions.filter((item) => typeof item === "string" &&
|
|
90
|
-
item.trim().length > 0 &&
|
|
91
|
-
item.trim() === item)
|
|
92
|
-
: [];
|
|
93
|
-
for (const option of configuredOptions)
|
|
94
|
-
options.add(option);
|
|
86
|
+
return projection;
|
|
95
87
|
for (const tier of PI_MODEL_TIERS) {
|
|
96
88
|
const selection = normalizeExecutorTierValue(pi[tier]);
|
|
97
89
|
if (!selection)
|
|
@@ -103,9 +95,8 @@ export async function readPiModelMatrixProjection(repoRoot) {
|
|
|
103
95
|
? `${selection.provider}/${selection.model}`
|
|
104
96
|
: selection.model,
|
|
105
97
|
};
|
|
106
|
-
options.add(projection[tier].value);
|
|
107
98
|
}
|
|
108
|
-
return
|
|
99
|
+
return projection;
|
|
109
100
|
}
|
|
110
101
|
/**
|
|
111
102
|
* 原子更新 harness.json executors.pi.LOW/MED/HIGH:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { access, readFile } from "node:fs/promises";
|
|
2
|
-
import { buildOperatorCapabilitiesDocument } from "../../shared/operator/capabilities.js";
|
|
2
|
+
import { buildOperatorCapabilitiesDocument, OFFICIAL_TAIL_ACTION_IDS, } from "../../shared/operator/capabilities.js";
|
|
3
3
|
import { buildOperatorResult, operatorFailed, operatorSucceeded, } from "../../shared/operator/envelope.js";
|
|
4
4
|
import { CANONICAL_TASK_ID_PATTERN, formatLocalBusinessDate, getTaskPaths, loadTaskConfig, } from "../../task/runtime.js";
|
|
5
5
|
import { diffTaskContract, validateDraftForTask, } from "../../task/contract/index.js";
|
|
@@ -1060,7 +1060,7 @@ export async function dispatchOperatorAction(ctx, req) {
|
|
|
1060
1060
|
}
|
|
1061
1061
|
if (operatorAction) {
|
|
1062
1062
|
const target = buildOperatorCapabilitiesDocument().actions.find((entry) => entry.action === operatorAction &&
|
|
1063
|
-
entry.
|
|
1063
|
+
OFFICIAL_TAIL_ACTION_IDS.has(entry.action) &&
|
|
1064
1064
|
entry.humanConfirmation === "required");
|
|
1065
1065
|
if (!target)
|
|
1066
1066
|
return invalid(action, "operatorAction must name a required official action");
|
|
@@ -2610,8 +2610,9 @@ export async function dispatchOperatorAction(ctx, req) {
|
|
|
2610
2610
|
// M5 official-command coverage uses one generic tail for newly registered
|
|
2611
2611
|
// CLI actions. It remains inside dispatchOperatorAction (the sole dispatch
|
|
2612
2612
|
// surface) and only accepts argv arrays declared by the capability schema.
|
|
2613
|
-
|
|
2614
|
-
|
|
2613
|
+
// 2026-08-18: high-frequency entries got real descriptions; membership is
|
|
2614
|
+
// now derived from OFFICIAL_TAIL_ACTION_IDS, not description prefixes.
|
|
2615
|
+
const capability = buildOperatorCapabilitiesDocument().actions.find((entry) => entry.action === action && OFFICIAL_TAIL_ACTION_IDS.has(entry.action));
|
|
2615
2616
|
if (capability) {
|
|
2616
2617
|
const rawArgs = p.args;
|
|
2617
2618
|
if (rawArgs !== undefined &&
|
|
@@ -85,7 +85,7 @@ function hasProviderConfig(snapshot) {
|
|
|
85
85
|
/**
|
|
86
86
|
* Discover live Pi SDK / auth / model readiness via ModelRuntime.
|
|
87
87
|
* Kept inside worker/console (dynamic import) so Worker does not depend on
|
|
88
|
-
* executors; contract matches pi-sdk-executor 0.
|
|
88
|
+
* executors; contract matches pi-sdk-executor 0.83.0.
|
|
89
89
|
*/
|
|
90
90
|
export async function discoverPiReadinessProbe(options) {
|
|
91
91
|
const repoRoot = options?.repoRoot ?? process.cwd();
|
|
@@ -118,7 +118,7 @@ export async function discoverPiReadinessProbe(options) {
|
|
|
118
118
|
modelsAvailable: false,
|
|
119
119
|
interviewSessionOk: false,
|
|
120
120
|
details: {
|
|
121
|
-
sdkMessage: "Pi SDK incompatible: requires createAgentSession, getAgentDir, and ModelRuntime.create (0.
|
|
121
|
+
sdkMessage: "Pi SDK incompatible: requires createAgentSession, getAgentDir, and ModelRuntime.create (0.83.0)",
|
|
122
122
|
authMessage: "skipped (sdk incompatible)",
|
|
123
123
|
modelsMessage: "skipped (sdk incompatible)",
|
|
124
124
|
sessionMessage: "skipped (sdk incompatible)",
|
|
@@ -159,7 +159,7 @@ export async function discoverPiReadinessProbe(options) {
|
|
|
159
159
|
modelsAvailable: false,
|
|
160
160
|
interviewSessionOk: false,
|
|
161
161
|
details: {
|
|
162
|
-
sdkMessage: "Pi SDK 0.
|
|
162
|
+
sdkMessage: "Pi SDK 0.83.0 contract available",
|
|
163
163
|
authMessage: `ModelRuntime.create failed: ${message}`,
|
|
164
164
|
modelsMessage: "skipped (runtime init failed)",
|
|
165
165
|
sessionMessage: "skipped (runtime init failed)",
|
|
@@ -222,8 +222,9 @@ export async function discoverPiReadinessProbe(options) {
|
|
|
222
222
|
authReady,
|
|
223
223
|
modelsAvailable,
|
|
224
224
|
interviewSessionOk,
|
|
225
|
+
piAvailableModels: availableModels,
|
|
225
226
|
details: {
|
|
226
|
-
sdkMessage: `Pi SDK 0.
|
|
227
|
+
sdkMessage: `Pi SDK 0.83.0 contract available (agentDir=${agentDir})`,
|
|
227
228
|
authMessage: authReady
|
|
228
229
|
? `credentials/providers ready (available=${availableCount}, providerConfig=${providerConfigured})`
|
|
229
230
|
: "no available models and no stored/configured provider credentials (set Pi auth or provider API keys)",
|
|
@@ -59,20 +59,20 @@ const CTA = {
|
|
|
59
59
|
},
|
|
60
60
|
dagRerun: {
|
|
61
61
|
id: "dagRerun",
|
|
62
|
-
label: "
|
|
62
|
+
label: "从失败节点恢复",
|
|
63
63
|
requiresReason: true,
|
|
64
64
|
action: "dagRerun",
|
|
65
65
|
lane: "dag",
|
|
66
|
-
guide: "
|
|
66
|
+
guide: "Provider、网络、限流或超时等非代码问题的首选:先评估安全子图,合格后创建 continuation run 从有效节点恢复(无需 Human Gate)。Worker 持有的 run、workspace/controller 漂移或含 unsafe shell 时不要强跑子图",
|
|
67
67
|
commandHint: "loop-agent dag rerun --run-id <run-id> --from-node <node-id> --plan",
|
|
68
68
|
},
|
|
69
69
|
standaloneTaskRerun: {
|
|
70
70
|
id: "standaloneTaskRerun",
|
|
71
|
-
label: "
|
|
71
|
+
label: "带反馈重新执行任务",
|
|
72
72
|
requiresReason: true,
|
|
73
73
|
action: "standaloneTaskRerun",
|
|
74
74
|
lane: "dag",
|
|
75
|
-
guide: "独立 DAG run
|
|
75
|
+
guide: "独立 DAG run 无法安全从节点恢复时,重新生成完整 DAG,并带入上一轮仍未解决的 verify/review 反馈;没有可继承反馈时会明确说明(无需 Human Gate)。Worker 持有的 run 请用下方「重新排队 Worker Task」",
|
|
76
76
|
commandHint: "loop-agent dag rerun-task --run-id <run-id> --reason <text> --json",
|
|
77
77
|
},
|
|
78
78
|
workerTaskRetry: {
|
|
@@ -107,7 +107,7 @@ export function nextActionForIneligibleRerun(reasons) {
|
|
|
107
107
|
"worker-managed-rerun-unsupported")) {
|
|
108
108
|
return "下一步:请点下方「重新排队 Worker Task」,从头完整执行。";
|
|
109
109
|
}
|
|
110
|
-
return "
|
|
110
|
+
return "下一步:请改用「带反馈重新执行任务」,重新生成完整 DAG。";
|
|
111
111
|
}
|
|
112
112
|
export function formatIneligibleRerunMessage(input) {
|
|
113
113
|
const fallback = input.fallbackMessage?.trim();
|
|
@@ -141,16 +141,16 @@ export function rewriteRecoveryOperatorError(raw) {
|
|
|
141
141
|
return formatIneligibleRerunMessage({ fallbackMessage: text });
|
|
142
142
|
}
|
|
143
143
|
if (/action must be a mutation-gate target/i.test(text)) {
|
|
144
|
-
return "这个操作不能再走确认门。Worker 启动的任务请直接点「重新排队 Worker Task
|
|
144
|
+
return "这个操作不能再走确认门。Worker 启动的任务请直接点「重新排队 Worker Task」;独立运行请点「带反馈重新执行任务」。";
|
|
145
145
|
}
|
|
146
146
|
if (/cannot read dagReport run facts/i.test(text)) {
|
|
147
147
|
return "读不到这次运行的失败报告,不能完整重跑。请先点「查看报告」或「Doctor 诊断」。";
|
|
148
148
|
}
|
|
149
149
|
if (/dagRerunPlan run facts unavailable/i.test(text)) {
|
|
150
|
-
return "
|
|
150
|
+
return "读不到节点恢复资格,不能直接改走完整重跑。请先点「从失败节点恢复」查看资格,或先「查看报告」。";
|
|
151
151
|
}
|
|
152
152
|
if (/node rerun plan is eligible/i.test(text)) {
|
|
153
|
-
return "
|
|
153
|
+
return "节点恢复是安全的,请改用「从失败节点恢复」,不必重新执行完整任务。";
|
|
154
154
|
}
|
|
155
155
|
if (/does not support autonomous standaloneTaskRerun/i.test(text)) {
|
|
156
156
|
return "当前失败不适合自动完整重跑。请先点「查看报告」,按建议操作。";
|
|
@@ -16,7 +16,7 @@ import { ChatSessionStore } from "./chat/session-store.js";
|
|
|
16
16
|
import { createChatEventStore, createChatOperationLinker, } from "./chat/chat-event-store.js";
|
|
17
17
|
import { createChatTurnExecutionRegistry } from "./chat/turn-execution-registry.js";
|
|
18
18
|
import { ConsolePiRuntime } from "./chat/pi-runtime.js";
|
|
19
|
-
import { handleChatRequest } from "./chat/routes.js";
|
|
19
|
+
import { handleChatRequest, recoverDeferredTurns, } from "./chat/routes.js";
|
|
20
20
|
import { createOperationEventStore, } from "./operation-sse.js";
|
|
21
21
|
import { OperationStore } from "./operation-store.js";
|
|
22
22
|
import { probePiReadiness, } from "./pi-readiness.js";
|
|
@@ -175,6 +175,11 @@ export async function createConsoleServer(options) {
|
|
|
175
175
|
getConsoleOrigin,
|
|
176
176
|
allowNonLoopbackAccess: !loopbackBind,
|
|
177
177
|
};
|
|
178
|
+
// Durable single-slot follow-ups are server-owned. Recover them at boot even
|
|
179
|
+
// when no browser currently has the Session open.
|
|
180
|
+
void recoverDeferredTurns(chatRouteDeps).catch((error) => {
|
|
181
|
+
console.error(`[console] deferred Turn recovery failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
182
|
+
});
|
|
178
183
|
const nightAuxTicker = new NightAuxTicker({
|
|
179
184
|
repoRoot,
|
|
180
185
|
client,
|
|
@@ -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-DZtolir7.js";import{p as f}from"./chunk-JWPE2WC7-NgHc6V37.js";import{_ as n,l as o}from"./mermaid.core-BVjAT9b8.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-BwT_xKrE.js";import"./index-DTZOKgAn.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-BVjAT9b8.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};
|