nolo-cli 0.38.0-alpha.3 → 0.47.0-alpha.2
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/{_executeModel-SWONBJ7Z.js → _executeModel-5PG6CUWD.js} +41 -42
- package/{action-KMBZ3LCZ.js → action-FLLC2SIX.js} +7 -7
- package/{addContentAction-KQ44UT2U.js → addContentAction-SVSPUUK4.js} +6 -6
- package/{addDialogAgentAction-ILSDCMYL.js → addDialogAgentAction-W3JGU4F7.js} +5 -5
- package/{agentDeleteCommand-SMUJYI6N.js → agentDeleteCommand-SHSPQZHI.js} +25 -26
- package/{agentEmailCommands-YWCGZ4RO.js → agentEmailCommands-LQKO5GRW.js} +54 -55
- package/{agentListCommands-ULFV2XJQ.js → agentListCommands-5QTNEYMQ.js} +31 -29
- package/{agentMachineCommands-7YZ2TIYZ.js → agentMachineCommands-P5K454CN.js} +24 -25
- package/{agentPullCommand-TSWAJPS2.js → agentPullCommand-M552CYSI.js} +2 -2
- package/{agentRecordCommands-EVOSSHJR.js → agentRecordCommands-Z4QYCNP4.js} +50 -51
- package/{agentRunCommand-PO55WUIY.js → agentRunCommand-HV3Y34B5.js} +52 -53
- package/{agentRunControl-7MUPSYDQ.js → agentRunControl-LHXOP4IU.js} +43 -1
- package/{agentRuntimeLocal-Q6D3G6G7.js → agentRuntimeLocal-ZKXYFLXI.js} +20 -21
- package/{agentSlice-6TRUUOSX.js → agentSlice-NKFLP3RI.js} +6 -6
- package/{agentSuperviseCommands-MKWW3ICX.js → agentSuperviseCommands-IMRZ56RC.js} +2 -2
- package/{appDeleteCommands-JDBSRLTX.js → appDeleteCommands-XYGAZIJX.js} +24 -25
- package/{appDeployCommands-Q5H2NBKQ.js → appDeployCommands-7T5CABRB.js} +24 -25
- package/{appDeployStatusCommands-PSYBUIZT.js → appDeployStatusCommands-KTFQMRPZ.js} +24 -25
- package/{appGetCommands-IX64IUW6.js → appGetCommands-HOX2ULSV.js} +24 -25
- package/{appListCommands-BJZFX65H.js → appListCommands-3SLCEHND.js} +24 -25
- package/{authCommand-B2XRHNJH.js → authCommand-OY2E2VQK.js} +12 -12
- package/{authCommands-GWABTFMR.js → authCommands-SBQVTD6V.js} +5 -5
- package/{chatQueueReduxAdapter-N7Z5MUPU.js → chatQueueReduxAdapter-WMMBQK3Y.js} +20 -20
- package/chunk-25J3BB35.js +6041 -0
- package/{chunk-U6QQLXWI.js → chunk-2X5S4IBZ.js} +1 -1
- package/{chunk-MJWX4JQO.js → chunk-3EEK7T3D.js} +1 -1
- package/{chunk-UNHKVD2N.js → chunk-43CXXVJD.js} +1 -1
- package/{chunk-WRP5TTM6.js → chunk-4MXGXSYN.js} +83 -3
- package/{chunk-7N7XKGEQ.js → chunk-4ZNDBDWG.js} +6 -6
- package/{chunk-XVVNNJAA.js → chunk-5BPZLBFB.js} +20 -51
- package/{chunk-MWGCZ4CS.js → chunk-5PPFYHU2.js} +3 -3
- package/{chunk-W445DPVT.js → chunk-5QRCPERU.js} +1 -1
- package/{chunk-GKHV4UH5.js → chunk-5UOBIU5G.js} +31 -3
- package/{chunk-BMB563Y6.js → chunk-6BYAXNH5.js} +3 -3
- package/{chunk-SMPAUSX5.js → chunk-6FGXGFAH.js} +2 -2
- package/{chunk-46VPXYIV.js → chunk-6LYUN76O.js} +5 -5
- package/{chunk-FTM4KUOZ.js → chunk-7XTC3KRG.js} +1 -1
- package/{chunk-IMHO5LC6.js → chunk-7XZ5GXSN.js} +1 -1
- package/{chunk-E2OQ5N2F.js → chunk-AEXP2UZT.js} +341 -16
- package/{chunk-MZZZYUZS.js → chunk-AV2CELZZ.js} +37 -12
- package/{chunk-JI2TIPLP.js → chunk-AYXSUBVC.js} +1 -1
- package/{chunk-J6WH4PYZ.js → chunk-CIF4X6ZM.js} +1 -1
- package/{chunk-GZRMWK5R.js → chunk-DQLYEGP7.js} +2 -2
- package/{chunk-GUYMR3JL.js → chunk-E2QH2AYX.js} +69 -3
- package/{chunk-B6H5XCT2.js → chunk-EMEUU5IY.js} +3 -3
- package/{chunk-X6EN3KJX.js → chunk-ENYDQKOB.js} +319 -71
- package/{chunk-RCFIB45Q.js → chunk-EVBFYPDC.js} +2 -2
- package/{chunk-PV734VZX.js → chunk-EXLOROHG.js} +1 -1
- package/{chunk-WRN7L5CS.js → chunk-FA4SY4F5.js} +1 -1
- package/{chunk-4WVNHL3V.js → chunk-FAWK6DBF.js} +157 -51
- package/{chunk-IFS5CUEH.js → chunk-FJHLA6SX.js} +1 -1
- package/{chunk-T2BZICLK.js → chunk-G46DB6KG.js} +49 -6
- package/{chunk-FGLKRJDI.js → chunk-GK74OOFT.js} +2 -2
- package/{chunk-LM6IYQ3F.js → chunk-GLKOYSRU.js} +8 -1
- package/{chunk-JIADXJYU.js → chunk-H2G6JXTR.js} +1 -1
- package/{chunk-IKGHZMK2.js → chunk-H2JQB6B6.js} +12 -12
- package/{chunk-MGIHZ5CJ.js → chunk-HAPCUPEO.js} +2 -2
- package/{chunk-LD6Y6RJY.js → chunk-HGDOIDQ4.js} +2 -2
- package/{chunk-NZLQ7B5P.js → chunk-HOM6NILS.js} +3 -3
- package/{chunk-IZNJDUJ4.js → chunk-I4JISVWK.js} +1 -1
- package/{chunk-N4XRDM26.js → chunk-IA3A5373.js} +2 -2
- package/{chunk-Y5MMUI3L.js → chunk-IWUPQUWA.js} +2 -2
- package/{chunk-L7SMDIL6.js → chunk-JEGPB5H2.js} +3 -3
- package/{chunk-GEPHJJW4.js → chunk-L7NG2M6H.js} +1 -1
- package/{chunk-XQES6LXQ.js → chunk-LFLWZX76.js} +2 -2
- package/{chunk-IIOHYLIG.js → chunk-LGUQHYAL.js} +1 -1
- package/{chunk-4AWH4LQA.js → chunk-LYGNQHUW.js} +3 -1
- package/{db-3H3JECGY.js → chunk-M5PVFLD4.js} +11 -158
- package/{chunk-WN5AJG5I.js → chunk-MKZRKDQM.js} +1 -1
- package/{chunk-VOXNBPLB.js → chunk-MUIJYGYW.js} +649 -41
- package/{chunk-CYAC5WXX.js → chunk-MWT2BBCH.js} +213 -45
- package/{chunk-V5GA74HI.js → chunk-MZXZJVVD.js} +20 -39
- package/{chunk-ZBB3MZR3.js → chunk-OLNC7AWK.js} +7 -4
- package/{chunk-J5NMOM35.js → chunk-OYNDYVSE.js} +1 -1
- package/{chunk-C6ELZQ7H.js → chunk-OZVGA4SY.js} +1 -1
- package/{chunk-K4KIFRIN.js → chunk-Q24S4NDF.js} +1 -1
- package/{chunk-NRROOY22.js → chunk-Q6DMA2OM.js} +271 -130
- package/{chunk-2WKUUY2E.js → chunk-SVEUG45B.js} +5 -3
- package/{chunk-IZCHPD7T.js → chunk-TNPCQNGQ.js} +11 -6
- package/{chunk-4DMPISV6.js → chunk-URBGEE42.js} +2 -2
- package/{chunk-2KO5QQFV.js → chunk-V2IPBG5U.js} +1 -1
- package/{chunk-B6YYACBT.js → chunk-WPFNAEIW.js} +1 -1
- package/{chunk-23KKIMD5.js → chunk-WVGEBWA6.js} +4 -4
- package/{chunk-KU6CDTZ5.js → chunk-XMI3APSU.js} +61 -49
- package/{chunk-64KIQZA2.js → chunk-XO3G35OV.js} +1 -1
- package/{chunk-UWGWUOVN.js → chunk-YNOGNUBC.js} +108 -47
- package/{chunk-XT73C4VH.js → chunk-Z5NW3O7V.js} +1 -1
- package/{codingSkills-H6N5EKSX.js → codingSkills-BYQI6EPT.js} +2 -2
- package/{createAgentAutomationAction-U57ZMPMS.js → createAgentAutomationAction-ENDNA3Q4.js} +21 -21
- package/{createDialogAction-MAJLBNK4.js → createDialogAction-2KNX6S2D.js} +23 -23
- package/{createPageAction-4EX7HU6G.js → createPageAction-SNBCYPK6.js} +21 -21
- package/db-VQSAOWAO.js +162 -0
- package/{dbSlice-PIQGICNM.js → dbSlice-XWUM4QOF.js} +5 -5
- package/deleteFile-NPZ64DFN.js +1 -1
- package/{dialogCommands-4MHZXEIS.js → dialogCommands-6E5P35DG.js} +28 -26
- package/{dialogSlice-AL3UJLOJ.js → dialogSlice-RTPOD6EW.js} +20 -20
- package/{docCreateCommands-GDYFEK67.js → docCreateCommands-JWY25UFB.js} +23 -24
- package/{docDeleteCommands-WIE5CXED.js → docDeleteCommands-BPJOCSX4.js} +24 -25
- package/{docReadCommands-LTOOPJVC.js → docReadCommands-BSEZCYTQ.js} +23 -24
- package/{docStore-35B5VAFF.js → docStore-TYHVLU7G.js} +22 -22
- package/{docUpdateCommands-TZGAGXSG.js → docUpdateCommands-S2IE2VV4.js} +23 -24
- package/{fetchMessages-CUEFN4GQ.js → fetchMessages-KZQVBXKY.js} +3 -3
- package/{getPricing-P3E2WRIH.js → getPricing-X3HXP6VQ.js} +3 -3
- package/{handleSendMessageAction-PXX2R5JS.js → handleSendMessageAction-QYXDQXGH.js} +21 -21
- package/index.js +69 -69
- package/levelLazyShim-GZBKODGI.js +7 -0
- package/{localDialogRead-P7CHFMIC.js → localDialogRead-NQ33HBSI.js} +2 -2
- package/{localRuntimeAuthority-S77B5QVB.js → localRuntimeAuthority-KQDAE64E.js} +4 -4
- package/{localRuntimeDb-N3H3HQ7G.js → localRuntimeDb-PF7CFKDL.js} +2 -2
- package/{machineCommands-VCPPY23X.js → machineCommands-QCE4KLGR.js} +48 -49
- package/{machineWsRunDispatch-A4C727GL.js → machineWsRunDispatch-FBRMGU5D.js} +48 -49
- package/{models-L7S2EKPM.js → models-7LWATQFH.js} +2 -2
- package/package.json +1 -1
- package/{read-6C2XD3YZ.js → read-DQQ75VI3.js} +2 -2
- package/{readDocTool-Y7AB365O.js → readDocTool-HCQQFAZD.js} +1 -1
- package/{readlineWorkspace-BIBIM6DG.js → readlineWorkspace-2TACWKMN.js} +164 -78
- package/{removeDialogAgentAction-KG5WMJRZ.js → removeDialogAgentAction-DNONRKST.js} +7 -7
- package/{runAgentClientLoop-RKDXMIZW.js → runAgentClientLoop-GBLDVBT5.js} +39 -39
- package/{runtimeDoctorCommands-HT4O2PXL.js → runtimeDoctorCommands-JKTTN723.js} +4 -4
- package/serverStoreFactory-YMXDF4NI.js +20 -0
- package/{setDialogExtraReferencesAction-O2NLXMSM.js → setDialogExtraReferencesAction-ERHUPT3F.js} +6 -6
- package/{setPrimaryDialogAgentAction-FYYUY7PB.js → setPrimaryDialogAgentAction-6C2HYNEC.js} +7 -7
- package/{settingSlice-GPLI6E3M.js → settingSlice-YVRJFKQX.js} +6 -6
- package/{spaceCommands-4FMO3SNP.js → spaceCommands-XOLPJMRK.js} +23 -24
- package/{spaceSlice-2W4GJ2OE.js → spaceSlice-OQPAGQDP.js} +21 -21
- package/{streamAgentChatTurn-FS52LDQP.js → streamAgentChatTurn-SN5XJJ7U.js} +91 -49
- package/{switchDialogAgentAction-GH5P6Q3Z.js → switchDialogAgentAction-HP57XYFP.js} +5 -5
- package/{tools-3J5CKEE7.js → tools-Y65Y3CI4.js} +32 -32
- package/{tuiSummaryLlmCaller-SHRB4RWM.js → tuiSummaryLlmCaller-NBTWT57U.js} +25 -14
- package/{updateDialogTitleAction-5MGPA3OO.js → updateDialogTitleAction-OAOP7CCE.js} +24 -23
- package/chunk-4APLX2RT.js +0 -1514
- package/chunk-P66M7LSQ.js +0 -58
- package/{chunk-6WD3OOJS.js → chunk-UV6VISQJ.js} +0 -0
- package/{tableCommands-PQUJ55AS.js → tableCommands-P2TXJ3CF.js} +1 -1
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
providerHttpFailure,
|
|
8
8
|
readSseFrames,
|
|
9
9
|
throwIfChatCompletionStreamFailed
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-AV2CELZZ.js";
|
|
11
11
|
import {
|
|
12
12
|
FRESH_TOOL_OUTPUT_MAX_CHARS,
|
|
13
13
|
MAX_HISTORICAL_TOOL_CONTENT_CHARS,
|
|
@@ -17,17 +17,10 @@ import {
|
|
|
17
17
|
resolveHistoricalToolContentCap,
|
|
18
18
|
resolveToolOutputProfile,
|
|
19
19
|
stripImagePartsFromMessages
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-XO3G35OV.js";
|
|
21
21
|
import {
|
|
22
22
|
sanitizeForOutbound
|
|
23
23
|
} from "./chunk-T27IEBNQ.js";
|
|
24
|
-
import {
|
|
25
|
-
EMPTY_ASSISTANT_REPAIR_PROMPT,
|
|
26
|
-
formatLengthTruncatedReasoningTail,
|
|
27
|
-
hasAssistantVisibleOutput,
|
|
28
|
-
resolveEmptyAssistantFallbackMessage,
|
|
29
|
-
resolveEmptyAssistantOutcome
|
|
30
|
-
} from "./chunk-P66M7LSQ.js";
|
|
31
24
|
import {
|
|
32
25
|
createThinkParserState,
|
|
33
26
|
createToolCallAccumulator,
|
|
@@ -39,10 +32,11 @@ import {
|
|
|
39
32
|
buildCurrentTimeBlock,
|
|
40
33
|
buildIdentityBlock,
|
|
41
34
|
buildRuntimeGuidanceBlocks,
|
|
35
|
+
normalizeChatCompletionsBodyForProvider,
|
|
42
36
|
requiresBareImageUrl,
|
|
43
37
|
resolveToolGuidedSections,
|
|
44
38
|
toBareImageUrlMessages
|
|
45
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-G46DB6KG.js";
|
|
46
40
|
import {
|
|
47
41
|
convertMessagesToResponsesInput,
|
|
48
42
|
extractReasoningFromResponseOutput,
|
|
@@ -52,11 +46,11 @@ import {
|
|
|
52
46
|
shouldStripReasoningContentForOutbound,
|
|
53
47
|
toOpenAiCompatibleMessages,
|
|
54
48
|
toResponsesTools
|
|
55
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-6BYAXNH5.js";
|
|
56
50
|
import {
|
|
57
51
|
buildProviderAuthHeaders,
|
|
58
52
|
buildProviderExecutionPlan
|
|
59
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-5UOBIU5G.js";
|
|
60
54
|
import {
|
|
61
55
|
NOLO_WORKSPACE_TOOL_NAMES,
|
|
62
56
|
buildNoloWorkspaceCommandArgs,
|
|
@@ -64,13 +58,18 @@ import {
|
|
|
64
58
|
noloStringArg,
|
|
65
59
|
parseNoloWorkspaceToolArguments,
|
|
66
60
|
resolveNoloDialogInput
|
|
67
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-TNPCQNGQ.js";
|
|
68
62
|
import {
|
|
69
63
|
buildDialogFallbackTitleFromUserInput
|
|
70
64
|
} from "./chunk-2MBTWINN.js";
|
|
71
65
|
import {
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
EMPTY_ASSISTANT_REPAIR_PROMPT,
|
|
67
|
+
getModelContextWindow,
|
|
68
|
+
hasAssistantVisibleOutput,
|
|
69
|
+
resolveEmptyAssistantFallbackMessage,
|
|
70
|
+
resolveEmptyAssistantOutcome,
|
|
71
|
+
resolveTruncatedReasoningTailLog
|
|
72
|
+
} from "./chunk-4MXGXSYN.js";
|
|
74
73
|
import {
|
|
75
74
|
COMPACTION_SUMMARY_SCHEMA_VERSION,
|
|
76
75
|
COMPACTION_SUMMARY_SYSTEM_PROMPT,
|
|
@@ -84,7 +83,7 @@ import {
|
|
|
84
83
|
formatMessagesForSummaryWithTruncation,
|
|
85
84
|
planCompression,
|
|
86
85
|
planContextUsage
|
|
87
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-GK74OOFT.js";
|
|
88
87
|
import {
|
|
89
88
|
resolveNoloStateDir
|
|
90
89
|
} from "./chunk-FD36SCCD.js";
|
|
@@ -107,13 +106,13 @@ import {
|
|
|
107
106
|
import {
|
|
108
107
|
dialogMessageKey,
|
|
109
108
|
dialogMessageRange
|
|
110
|
-
} from "./chunk-
|
|
111
|
-
import {
|
|
112
|
-
asTrimmedNonEmptyStringArray
|
|
113
|
-
} from "./chunk-I42VC5KR.js";
|
|
109
|
+
} from "./chunk-SVEUG45B.js";
|
|
114
110
|
import {
|
|
115
111
|
asOptionalFiniteNumber
|
|
116
112
|
} from "./chunk-WWC7I6TA.js";
|
|
113
|
+
import {
|
|
114
|
+
asTrimmedNonEmptyStringArray
|
|
115
|
+
} from "./chunk-I42VC5KR.js";
|
|
117
116
|
import {
|
|
118
117
|
asTrimmedLowercaseString
|
|
119
118
|
} from "./chunk-QSJ3HFEF.js";
|
|
@@ -447,6 +446,15 @@ function spillToolOutput(options) {
|
|
|
447
446
|
hash
|
|
448
447
|
};
|
|
449
448
|
}
|
|
449
|
+
function formatToolOverflowMarker(args) {
|
|
450
|
+
const { spillRef, totalChars, totalLines, omittedChars } = args;
|
|
451
|
+
const omittedNote = omittedChars !== void 0 && omittedChars > 0 ? ` omitted: ${omittedChars} chars;` : "";
|
|
452
|
+
return `
|
|
453
|
+
|
|
454
|
+
[TOOL-OVERFLOW: full output spilled to ${spillRef} (total: ${totalChars} chars, ${totalLines} lines;${omittedNote} inspect via readFile or grep)]
|
|
455
|
+
|
|
456
|
+
`;
|
|
457
|
+
}
|
|
450
458
|
|
|
451
459
|
// packages/agent-runtime/localAutoCompaction.ts
|
|
452
460
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -1770,22 +1778,32 @@ async function runLocalAgentTurn(input) {
|
|
|
1770
1778
|
if (!!result.reasoning_content) reasoningEmptyRepairCount += 1;
|
|
1771
1779
|
continue;
|
|
1772
1780
|
}
|
|
1781
|
+
if (outcome.kind === "ok_with_warning") {
|
|
1782
|
+
result = {
|
|
1783
|
+
...result,
|
|
1784
|
+
errorMessage: resolveEmptyAssistantFallbackMessage(outcome.reason),
|
|
1785
|
+
emptyAssistantFallbackReason: outcome.reason,
|
|
1786
|
+
emptyAssistantRepairUsed
|
|
1787
|
+
};
|
|
1788
|
+
break;
|
|
1789
|
+
}
|
|
1773
1790
|
if (outcome.kind === "fallback") {
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
console.warn(`
|
|
1791
|
+
const reasoningTailLog = resolveTruncatedReasoningTailLog(outcome.reason, result.reasoning_content);
|
|
1792
|
+
if (reasoningTailLog) {
|
|
1793
|
+
console.warn(`
|
|
1778
1794
|
${reasoningTailLog}
|
|
1779
1795
|
`);
|
|
1780
|
-
}
|
|
1781
1796
|
}
|
|
1797
|
+
const fallbackMessage = resolveEmptyAssistantFallbackMessage(outcome.reason);
|
|
1782
1798
|
result = {
|
|
1783
1799
|
...result,
|
|
1784
|
-
content:
|
|
1800
|
+
content: fallbackMessage,
|
|
1785
1801
|
// 只打标记不抛错:交互侧仍照常显示诊断文案(零行为变化)。
|
|
1786
1802
|
// 上层(后台 run 编排者)据 emptyAssistantFallbackReason 判断
|
|
1787
1803
|
// 是否把本轮结算为 failed。见 LocalAgentTurnResult 注释。
|
|
1788
|
-
|
|
1804
|
+
errorMessage: fallbackMessage,
|
|
1805
|
+
emptyAssistantFallbackReason: outcome.reason,
|
|
1806
|
+
emptyAssistantRepairUsed
|
|
1789
1807
|
};
|
|
1790
1808
|
break;
|
|
1791
1809
|
}
|
|
@@ -2009,12 +2027,17 @@ ${reasoningTailLog}
|
|
|
2009
2027
|
}
|
|
2010
2028
|
result = result;
|
|
2011
2029
|
if (!skipFinalAppend) {
|
|
2030
|
+
const truncatedReasoningTailLog = resolveTruncatedReasoningTailLog(
|
|
2031
|
+
result.emptyAssistantFallbackReason,
|
|
2032
|
+
result.reasoning_content
|
|
2033
|
+
);
|
|
2012
2034
|
messages.push({
|
|
2013
2035
|
role: "assistant",
|
|
2014
2036
|
content: result.content,
|
|
2015
2037
|
// 与中间轮(:561)一致带上 reasoning_content,让 saveTurn 持久化思维链,
|
|
2016
2038
|
// 空轮/异常排查时能回看模型实际想了什么。
|
|
2017
|
-
...result.reasoning_content ? { reasoning_content: result.reasoning_content } : {}
|
|
2039
|
+
...result.reasoning_content ? { reasoning_content: result.reasoning_content } : {},
|
|
2040
|
+
...truncatedReasoningTailLog ? { thinkContent: truncatedReasoningTailLog } : {}
|
|
2018
2041
|
});
|
|
2019
2042
|
}
|
|
2020
2043
|
const turnMessages = applyPersistedTurnInput(
|
|
@@ -2105,7 +2128,12 @@ function buildResponsesRequestBody(body, model) {
|
|
|
2105
2128
|
messages: void 0,
|
|
2106
2129
|
max_tokens: void 0,
|
|
2107
2130
|
reasoning_effort: void 0,
|
|
2108
|
-
tool_choice: void 0
|
|
2131
|
+
tool_choice: void 0,
|
|
2132
|
+
// stream_options 是 chat.completions 专属参数;客户端按 chat 线构建的 body
|
|
2133
|
+
// 携带它(旧版本 runtime 或 wire 分流窗口期)经此处转 Responses 上游时必须
|
|
2134
|
+
// 剥离,否则 OpenAI 直接 400 Unknown parameter: 'stream_options.include_usage'。
|
|
2135
|
+
// Responses 线天然在流末返回 usage,无需 include_usage。
|
|
2136
|
+
stream_options: void 0
|
|
2109
2137
|
};
|
|
2110
2138
|
}
|
|
2111
2139
|
|
|
@@ -2276,9 +2304,13 @@ function buildOpenAiCompatibleChatCompletionRequest(args) {
|
|
|
2276
2304
|
stream: args.stream ?? false,
|
|
2277
2305
|
...args.providerConfig.requestOptions,
|
|
2278
2306
|
...args.tools && args.tools.length > 0 ? { tools: args.tools } : {},
|
|
2279
|
-
...!isResponses && args.stream ? getUsageRequestOptions(args.providerConfig.provider, { api: "chat-completions" }) : {}
|
|
2307
|
+
...!isResponses && args.stream ? getUsageRequestOptions(args.providerConfig.usageProvider ?? args.providerConfig.provider, { api: "chat-completions" }) : {}
|
|
2280
2308
|
};
|
|
2281
|
-
const body = isResponses ? buildResponsesRequestBody(rawBody, args.providerConfig.model) :
|
|
2309
|
+
const body = isResponses ? buildResponsesRequestBody(rawBody, args.providerConfig.model) : normalizeChatCompletionsBodyForProvider({
|
|
2310
|
+
body: rawBody,
|
|
2311
|
+
provider: args.providerConfig.provider,
|
|
2312
|
+
model: args.providerConfig.model
|
|
2313
|
+
});
|
|
2282
2314
|
const endpoint = args.providerConfig.endpoint;
|
|
2283
2315
|
const headers = {
|
|
2284
2316
|
"Content-Type": "application/json",
|
|
@@ -2342,6 +2374,11 @@ function parseOpenAiCompatibleChatCompletionResponse(args) {
|
|
|
2342
2374
|
}
|
|
2343
2375
|
function processOpenAiCompatibleSseEvent(event, state) {
|
|
2344
2376
|
for (const line of event.split("\n")) {
|
|
2377
|
+
const trimmed = line.trim();
|
|
2378
|
+
if (trimmed.startsWith("data:") && trimmed.slice(5).trim() === "[DONE]") {
|
|
2379
|
+
state.sawDone = true;
|
|
2380
|
+
continue;
|
|
2381
|
+
}
|
|
2345
2382
|
const parsed = parseSseDataLineJson(line);
|
|
2346
2383
|
if (parsed == null) continue;
|
|
2347
2384
|
applyChatCompletionDelta(parsed, state);
|
|
@@ -2356,7 +2393,8 @@ async function readOpenAiCompatibleSseCompletion(args) {
|
|
|
2356
2393
|
thinkState: createThinkParserState(),
|
|
2357
2394
|
toolCallTextState: createToolCallTextParserState(),
|
|
2358
2395
|
onTextDelta: args.onTextDelta,
|
|
2359
|
-
onReasoningDelta: args.onReasoningDelta
|
|
2396
|
+
onReasoningDelta: args.onReasoningDelta,
|
|
2397
|
+
sawDone: false
|
|
2360
2398
|
};
|
|
2361
2399
|
for await (const frame of readSseFrames(args.response)) {
|
|
2362
2400
|
processOpenAiCompatibleSseEvent(frame, state);
|
|
@@ -2364,11 +2402,13 @@ async function readOpenAiCompatibleSseCompletion(args) {
|
|
|
2364
2402
|
flushChatCompletionStream(state);
|
|
2365
2403
|
throwIfChatCompletionStreamFailed(state);
|
|
2366
2404
|
const tool_calls = finalizeAccumulatedToolCalls(state.accumulatedToolCalls);
|
|
2405
|
+
const streamComplete = state.sawDone || !!state.usage || !!state.finishReason;
|
|
2367
2406
|
return {
|
|
2368
2407
|
content: state.content,
|
|
2369
2408
|
...state.reasoning ? { reasoning_content: state.reasoning } : {},
|
|
2370
2409
|
...tool_calls.length > 0 ? { tool_calls } : {},
|
|
2371
|
-
...state.usage ? { usage: state.usage
|
|
2410
|
+
...state.usage ? { usage: state.usage } : {},
|
|
2411
|
+
...streamComplete ? { stream_complete: true } : {},
|
|
2372
2412
|
...state.finishReason ? { finish_reason: state.finishReason } : {}
|
|
2373
2413
|
};
|
|
2374
2414
|
}
|
|
@@ -2493,7 +2533,8 @@ async function resolveOpenAiCompatibleProviderConfig(args) {
|
|
|
2493
2533
|
apiKey: plan.apiKey,
|
|
2494
2534
|
...plan.apiKeyHeader ? { apiKeyHeader: plan.apiKeyHeader } : {},
|
|
2495
2535
|
provider: plan.provider,
|
|
2496
|
-
requestOptions: plan.requestOptions
|
|
2536
|
+
requestOptions: plan.requestOptions,
|
|
2537
|
+
...plan.usageProvider ? { usageProvider: plan.usageProvider } : {}
|
|
2497
2538
|
};
|
|
2498
2539
|
}
|
|
2499
2540
|
|
|
@@ -2753,6 +2794,9 @@ function buildDialogMessageWriteOps(args) {
|
|
|
2753
2794
|
// 持久化思维链(reasoning):空轮/异常排查的关键证据,
|
|
2754
2795
|
// 回读由 dialogMessageRecordToAgentRuntimeMessage 还原。
|
|
2755
2796
|
...typeof message.reasoning_content === "string" ? { reasoning_content: message.reasoning_content } : {},
|
|
2797
|
+
// web 思考折叠可读的截断 reasoning 尾部(带 marker)。仅在截断
|
|
2798
|
+
// 兜底/告警轮由 localLoop 附加,正常轮无此字段。
|
|
2799
|
+
...typeof message.thinkContent === "string" ? { thinkContent: message.thinkContent } : {},
|
|
2756
2800
|
...message.role === "user" ? { userId: args.userId } : {},
|
|
2757
2801
|
...message.role === "assistant" ? {
|
|
2758
2802
|
agentKey: args.input.agentKey,
|
|
@@ -2767,6 +2811,20 @@ function buildDialogMessageWriteOps(args) {
|
|
|
2767
2811
|
};
|
|
2768
2812
|
});
|
|
2769
2813
|
}
|
|
2814
|
+
function buildEmptyAssistantWoundFields(result, existingDialog) {
|
|
2815
|
+
const reason = result.emptyAssistantFallbackReason;
|
|
2816
|
+
if (reason) {
|
|
2817
|
+
return {
|
|
2818
|
+
...result.errorMessage ? { errorMessage: result.errorMessage } : {},
|
|
2819
|
+
fallbackReason: reason,
|
|
2820
|
+
...typeof result.emptyAssistantRepairUsed === "boolean" ? { repairUsed: result.emptyAssistantRepairUsed } : {}
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
if (existingDialog?.fallbackReason || existingDialog?.errorMessage) {
|
|
2824
|
+
return { errorMessage: null, fallbackReason: null, repairUsed: null };
|
|
2825
|
+
}
|
|
2826
|
+
return {};
|
|
2827
|
+
}
|
|
2770
2828
|
function buildRuntimeCheckpointField(args) {
|
|
2771
2829
|
if (args.runtimeToolSurface) {
|
|
2772
2830
|
return {
|
|
@@ -2806,6 +2864,10 @@ function buildAgentRuntimeDialogWritePlan(args) {
|
|
|
2806
2864
|
const titleChanged = typeof args.titleOverride === "string" && args.titleOverride.trim().length > 0;
|
|
2807
2865
|
const titleUpdatedAtIso = titleChanged ? nowIso : existingTitleUpdatedAtMs > 0 ? new Date(existingTitleUpdatedAtMs).toISOString() : args.existingDialog?.createdAt ?? nowIso;
|
|
2808
2866
|
const { availableToolNames: _deprecatedAvailableToolNames, ...cleanExistingCheckpoint } = asRecordOrEmpty(args.existingDialog?.runtimeCheckpoint);
|
|
2867
|
+
const woundFields = buildEmptyAssistantWoundFields(
|
|
2868
|
+
args.input.result,
|
|
2869
|
+
args.existingDialog
|
|
2870
|
+
);
|
|
2809
2871
|
const dialogRecord = {
|
|
2810
2872
|
...asRecordOrEmpty(args.existingDialog),
|
|
2811
2873
|
id: dialogId,
|
|
@@ -2817,6 +2879,7 @@ function buildAgentRuntimeDialogWritePlan(args) {
|
|
|
2817
2879
|
titleSource: pickedTitle.titleSource,
|
|
2818
2880
|
titleUpdatedAt: titleUpdatedAtIso,
|
|
2819
2881
|
status: args.input.result.error === true ? "failed" : "done",
|
|
2882
|
+
...woundFields,
|
|
2820
2883
|
triggerType: `${args.runtimeHost}-local`,
|
|
2821
2884
|
executionMode: args.existingDialog?.executionMode ?? "foreground",
|
|
2822
2885
|
createdAt: args.existingDialog?.createdAt ?? nowIso,
|
|
@@ -3294,6 +3357,13 @@ var DEFAULT_LOCAL_TOOLS = /* @__PURE__ */ new Set([
|
|
|
3294
3357
|
"execShell",
|
|
3295
3358
|
"launchProcess",
|
|
3296
3359
|
"listProcesses",
|
|
3360
|
+
// ProcessTask follow-up tools (Phase 1). Same tier as listProcesses: they
|
|
3361
|
+
// observe/stop tasks the agent itself already spawned, so their blast radius
|
|
3362
|
+
// is strictly narrower than launchProcess (which is default-enabled).
|
|
3363
|
+
"taskWait",
|
|
3364
|
+
"taskLogs",
|
|
3365
|
+
"taskStop",
|
|
3366
|
+
"tasks",
|
|
3297
3367
|
// Scheduling tools: forking/observing sub-agents is a declared capability
|
|
3298
3368
|
// of capable agents, and the blast radius is strictly narrower than
|
|
3299
3369
|
// execShell (already default-enabled). Requiring an env allowlist for these
|
|
@@ -3609,10 +3679,44 @@ function spawnToWebStreams(options) {
|
|
|
3609
3679
|
}
|
|
3610
3680
|
|
|
3611
3681
|
// packages/agent-runtime/processTask.ts
|
|
3682
|
+
var PROCESS_TASK_TERMINAL_STATUSES = [
|
|
3683
|
+
"stopped",
|
|
3684
|
+
"exited",
|
|
3685
|
+
"failed"
|
|
3686
|
+
];
|
|
3687
|
+
function isProcessTaskTerminalStatus(status) {
|
|
3688
|
+
return typeof status === "string" && PROCESS_TASK_TERMINAL_STATUSES.includes(status);
|
|
3689
|
+
}
|
|
3690
|
+
function reportedTaskStatus(source, exitCode) {
|
|
3691
|
+
if (source === "killed") {
|
|
3692
|
+
return "stopped";
|
|
3693
|
+
}
|
|
3694
|
+
if (source === "exited") {
|
|
3695
|
+
return exitCode !== void 0 && exitCode !== 0 ? "failed" : "exited";
|
|
3696
|
+
}
|
|
3697
|
+
if (source === "started" || source === "promoted") {
|
|
3698
|
+
return "running";
|
|
3699
|
+
}
|
|
3700
|
+
return source;
|
|
3701
|
+
}
|
|
3702
|
+
var DEFAULT_TASK_EVENT_RETENTION_MS = 5 * 60 * 1e3;
|
|
3703
|
+
var DEFAULT_MAX_TASK_EVENTS_TASKS = 200;
|
|
3612
3704
|
var ProcessTaskEventLog = class {
|
|
3613
3705
|
events = /* @__PURE__ */ new Map();
|
|
3706
|
+
terminalTasks = /* @__PURE__ */ new Map();
|
|
3707
|
+
retentionMs;
|
|
3708
|
+
maxTasks;
|
|
3709
|
+
now;
|
|
3710
|
+
evictedCount = 0;
|
|
3711
|
+
activeOverflowCount = 0;
|
|
3712
|
+
constructor(options) {
|
|
3713
|
+
this.retentionMs = options?.retentionMs ?? DEFAULT_TASK_EVENT_RETENTION_MS;
|
|
3714
|
+
this.maxTasks = options?.maxTasks ?? DEFAULT_MAX_TASK_EVENTS_TASKS;
|
|
3715
|
+
this.now = options?.now ?? Date.now;
|
|
3716
|
+
}
|
|
3614
3717
|
/** Append one event; assigns the next monotonic seq for the task. */
|
|
3615
3718
|
append(input) {
|
|
3719
|
+
const currentTime = this.now();
|
|
3616
3720
|
const list = this.events.get(input.taskId) ?? [];
|
|
3617
3721
|
const lastSeq = list.length > 0 ? list[list.length - 1].seq : 0;
|
|
3618
3722
|
const event = Object.freeze({
|
|
@@ -3620,23 +3724,79 @@ var ProcessTaskEventLog = class {
|
|
|
3620
3724
|
seq: lastSeq + 1,
|
|
3621
3725
|
type: input.type,
|
|
3622
3726
|
pid: input.pid,
|
|
3623
|
-
createdAt:
|
|
3727
|
+
createdAt: currentTime,
|
|
3624
3728
|
...input.exitCode !== void 0 ? { exitCode: input.exitCode } : {}
|
|
3625
3729
|
});
|
|
3626
3730
|
list.push(event);
|
|
3627
3731
|
this.events.set(input.taskId, list);
|
|
3732
|
+
if (input.type === "exited" || input.type === "killed") {
|
|
3733
|
+
this.terminalTasks.set(input.taskId, currentTime);
|
|
3734
|
+
}
|
|
3735
|
+
this.evict(currentTime);
|
|
3628
3736
|
return { ...event };
|
|
3629
3737
|
}
|
|
3630
|
-
/**
|
|
3738
|
+
/**
|
|
3739
|
+
* All events of the task with `seq > cursor` (default 0 = from the start).
|
|
3740
|
+
*
|
|
3741
|
+
* NOTE for cursor consumers (Phase 1 taskWait/taskLogs): an empty array is
|
|
3742
|
+
* ambiguous — it means either "no new events yet" or "the whole task was
|
|
3743
|
+
* evicted" (retention is per-taskId, never partial, so a cursor can never
|
|
3744
|
+
* land in a hole). Do NOT treat empty as "still running and idle": pair the
|
|
3745
|
+
* read with `hasTask(taskId)` to tell the two apart, otherwise a wait loop
|
|
3746
|
+
* can hang forever on an evicted task. Eviction only ever happens after a
|
|
3747
|
+
* terminal event plus the retention delay, so a live task is always readable.
|
|
3748
|
+
*/
|
|
3631
3749
|
read(taskId, cursor = 0) {
|
|
3632
3750
|
return (this.events.get(taskId) ?? []).filter((event) => event.seq > cursor).map((event) => ({ ...event }));
|
|
3633
3751
|
}
|
|
3752
|
+
/**
|
|
3753
|
+
* Whether the task's event trail is still retained. Lets a cursor consumer
|
|
3754
|
+
* disambiguate the empty result of `read()` (see its note).
|
|
3755
|
+
*/
|
|
3756
|
+
hasTask(taskId) {
|
|
3757
|
+
return this.events.has(taskId);
|
|
3758
|
+
}
|
|
3634
3759
|
latestSeq(taskId) {
|
|
3635
3760
|
const list = this.events.get(taskId);
|
|
3636
3761
|
return list && list.length > 0 ? list[list.length - 1].seq : 0;
|
|
3637
3762
|
}
|
|
3763
|
+
getStats() {
|
|
3764
|
+
return {
|
|
3765
|
+
taskCount: this.events.size,
|
|
3766
|
+
terminalTaskCount: this.terminalTasks.size,
|
|
3767
|
+
activeTaskCount: this.events.size - this.terminalTasks.size,
|
|
3768
|
+
evictedCount: this.evictedCount,
|
|
3769
|
+
activeOverflowCount: this.activeOverflowCount
|
|
3770
|
+
};
|
|
3771
|
+
}
|
|
3638
3772
|
clear() {
|
|
3639
3773
|
this.events.clear();
|
|
3774
|
+
this.terminalTasks.clear();
|
|
3775
|
+
this.evictedCount = 0;
|
|
3776
|
+
this.activeOverflowCount = 0;
|
|
3777
|
+
}
|
|
3778
|
+
evict(currentTime) {
|
|
3779
|
+
for (const [taskId, terminalTime] of this.terminalTasks.entries()) {
|
|
3780
|
+
if (currentTime - terminalTime >= this.retentionMs) {
|
|
3781
|
+
this.events.delete(taskId);
|
|
3782
|
+
this.terminalTasks.delete(taskId);
|
|
3783
|
+
this.evictedCount += 1;
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3786
|
+
if (this.events.size > this.maxTasks) {
|
|
3787
|
+
const sortedTerminal = Array.from(this.terminalTasks.entries()).sort((a, b) => a[1] - b[1]);
|
|
3788
|
+
for (const [taskId] of sortedTerminal) {
|
|
3789
|
+
if (this.events.size <= this.maxTasks) {
|
|
3790
|
+
break;
|
|
3791
|
+
}
|
|
3792
|
+
this.events.delete(taskId);
|
|
3793
|
+
this.terminalTasks.delete(taskId);
|
|
3794
|
+
this.evictedCount += 1;
|
|
3795
|
+
}
|
|
3796
|
+
if (this.events.size > this.maxTasks) {
|
|
3797
|
+
this.activeOverflowCount += 1;
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3640
3800
|
}
|
|
3641
3801
|
};
|
|
3642
3802
|
|
|
@@ -3649,7 +3809,10 @@ function mintTaskId(pid) {
|
|
|
3649
3809
|
var ProcessRegistry = class {
|
|
3650
3810
|
processes = /* @__PURE__ */ new Map();
|
|
3651
3811
|
byTaskId = /* @__PURE__ */ new Map();
|
|
3652
|
-
eventLog
|
|
3812
|
+
eventLog;
|
|
3813
|
+
constructor(eventLogOptions) {
|
|
3814
|
+
this.eventLog = new ProcessTaskEventLog(eventLogOptions);
|
|
3815
|
+
}
|
|
3653
3816
|
/**
|
|
3654
3817
|
* Pre-register an envelope right after a successful spawn and emit the
|
|
3655
3818
|
* `started` event. Returns the stored record (with its stable taskId).
|
|
@@ -3704,6 +3867,15 @@ var ProcessRegistry = class {
|
|
|
3704
3867
|
latestTaskSeq(taskId) {
|
|
3705
3868
|
return this.eventLog.latestSeq(taskId);
|
|
3706
3869
|
}
|
|
3870
|
+
/**
|
|
3871
|
+
* Whether the task's event trail is still retained. Cursor consumers MUST
|
|
3872
|
+
* pair this with getTaskEvents(): an empty read means either "no new events"
|
|
3873
|
+
* or "the whole trail was evicted" (§1.1), and only this call tells them
|
|
3874
|
+
* apart — without it a wait loop hangs forever on an evicted task.
|
|
3875
|
+
*/
|
|
3876
|
+
hasTaskEvents(taskId) {
|
|
3877
|
+
return this.eventLog.hasTask(taskId);
|
|
3878
|
+
}
|
|
3707
3879
|
/**
|
|
3708
3880
|
* Timeout-detach promotion: mark the pre-registered envelope as a background
|
|
3709
3881
|
* task. Same record, same taskId, no re-execution, no second registration.
|
|
@@ -3718,9 +3890,19 @@ var ProcessRegistry = class {
|
|
|
3718
3890
|
}
|
|
3719
3891
|
return { ...item };
|
|
3720
3892
|
}
|
|
3893
|
+
/**
|
|
3894
|
+
* Terminate a background process group and update its status to "stopped".
|
|
3895
|
+
*
|
|
3896
|
+
* Invariant (§1.3): Transient foreground envelopes (workspaceShell grace
|
|
3897
|
+
* period before timeout detach) are NOT stoppable through this entry point;
|
|
3898
|
+
* their lifecycle belongs to the foreground runner (abort/timeout). Calling
|
|
3899
|
+
* kill() on a transient entry does not signal the process, does not emit a
|
|
3900
|
+
* "killed" event, and returns false.
|
|
3901
|
+
*/
|
|
3721
3902
|
kill(pid, signal = "SIGTERM") {
|
|
3722
3903
|
const item = this.processes.get(pid);
|
|
3723
3904
|
if (!item) return false;
|
|
3905
|
+
if (item.transient) return false;
|
|
3724
3906
|
if (item.status === "running") {
|
|
3725
3907
|
try {
|
|
3726
3908
|
process.kill(-item.pgid, signal);
|
|
@@ -4313,6 +4495,242 @@ ${stderr.trim()}` : "",
|
|
|
4313
4495
|
};
|
|
4314
4496
|
}
|
|
4315
4497
|
|
|
4498
|
+
// packages/agent-runtime/processTaskTools.ts
|
|
4499
|
+
var TASK_WAIT_DEFAULT_TIMEOUT_MS = 6e4;
|
|
4500
|
+
var TASK_WAIT_MAX_TIMEOUT_MS = 5 * 6e4;
|
|
4501
|
+
var TASK_WAIT_POLL_INTERVAL_MS = 250;
|
|
4502
|
+
var TASK_STOP_GRACE_MS = 2e3;
|
|
4503
|
+
var TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set(["exited", "killed"]);
|
|
4504
|
+
function defaultSleep(ms) {
|
|
4505
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
4506
|
+
}
|
|
4507
|
+
function defaultSignalSender(pid, signal) {
|
|
4508
|
+
process.kill(pid, signal);
|
|
4509
|
+
}
|
|
4510
|
+
function statusOf(record) {
|
|
4511
|
+
return reportedTaskStatus(record.status, record.exitCode);
|
|
4512
|
+
}
|
|
4513
|
+
function inspectTask(registry2, taskId) {
|
|
4514
|
+
const record = registry2.getByTaskId(taskId);
|
|
4515
|
+
const hasEvents = registry2.hasTaskEvents(taskId);
|
|
4516
|
+
return { record, hasEvents, known: hasEvents || record !== void 0 };
|
|
4517
|
+
}
|
|
4518
|
+
function notFoundDetail(taskId) {
|
|
4519
|
+
return `No task ${taskId} is known: it was never started, or both its envelope and its event trail have been dropped. Call tasks to list current handles.`;
|
|
4520
|
+
}
|
|
4521
|
+
function evictedDetail(taskId) {
|
|
4522
|
+
return `Event trail of ${taskId} is gone (retention window elapsed). No further events will appear; do not wait again.`;
|
|
4523
|
+
}
|
|
4524
|
+
function lastTerminalEvent(events) {
|
|
4525
|
+
for (let i = events.length - 1; i >= 0; i -= 1) {
|
|
4526
|
+
const event = events[i];
|
|
4527
|
+
if (TERMINAL_EVENT_TYPES.has(event.type)) return event;
|
|
4528
|
+
}
|
|
4529
|
+
return void 0;
|
|
4530
|
+
}
|
|
4531
|
+
function resolveTaskWaitTimeoutMs(raw) {
|
|
4532
|
+
const value = typeof raw === "number" ? raw : typeof raw === "string" && raw.trim() !== "" ? Number(raw) : Number.NaN;
|
|
4533
|
+
if (!Number.isFinite(value)) {
|
|
4534
|
+
return { timeoutMs: TASK_WAIT_DEFAULT_TIMEOUT_MS, clamped: false };
|
|
4535
|
+
}
|
|
4536
|
+
if (value <= 0) return { timeoutMs: 0, clamped: value < 0 };
|
|
4537
|
+
if (value > TASK_WAIT_MAX_TIMEOUT_MS) {
|
|
4538
|
+
return { timeoutMs: TASK_WAIT_MAX_TIMEOUT_MS, clamped: true };
|
|
4539
|
+
}
|
|
4540
|
+
return { timeoutMs: value, clamped: false };
|
|
4541
|
+
}
|
|
4542
|
+
async function runTaskWait(args) {
|
|
4543
|
+
const { registry: registry2, taskId } = args;
|
|
4544
|
+
const now = args.now ?? Date.now;
|
|
4545
|
+
const sleep = args.sleep ?? defaultSleep;
|
|
4546
|
+
const pollIntervalMs = Math.max(1, args.pollIntervalMs ?? TASK_WAIT_POLL_INTERVAL_MS);
|
|
4547
|
+
const { timeoutMs, clamped } = resolveTaskWaitTimeoutMs(args.timeoutMs);
|
|
4548
|
+
const initial = inspectTask(registry2, taskId);
|
|
4549
|
+
if (!initial.known) {
|
|
4550
|
+
return { outcome: "not-found", taskId, detail: notFoundDetail(taskId) };
|
|
4551
|
+
}
|
|
4552
|
+
const startedAt = now();
|
|
4553
|
+
const deadline = startedAt + timeoutMs;
|
|
4554
|
+
const maxPolls = Math.ceil(timeoutMs / pollIntervalMs) + 2;
|
|
4555
|
+
for (let poll = 0; poll < maxPolls; poll += 1) {
|
|
4556
|
+
const events = registry2.getTaskEvents(taskId, 0);
|
|
4557
|
+
if (!registry2.hasTaskEvents(taskId)) {
|
|
4558
|
+
const record = registry2.getByTaskId(taskId);
|
|
4559
|
+
return {
|
|
4560
|
+
outcome: "evicted",
|
|
4561
|
+
taskId,
|
|
4562
|
+
cursor: 0,
|
|
4563
|
+
events: [],
|
|
4564
|
+
...record ? { status: statusOf(record) } : {},
|
|
4565
|
+
detail: evictedDetail(taskId)
|
|
4566
|
+
};
|
|
4567
|
+
}
|
|
4568
|
+
const terminal = lastTerminalEvent(events);
|
|
4569
|
+
if (terminal) {
|
|
4570
|
+
return {
|
|
4571
|
+
outcome: "terminal",
|
|
4572
|
+
taskId,
|
|
4573
|
+
status: reportedTaskStatus(terminal.type, terminal.exitCode),
|
|
4574
|
+
...terminal.exitCode !== void 0 ? { exitCode: terminal.exitCode } : {},
|
|
4575
|
+
cursor: registry2.latestTaskSeq(taskId),
|
|
4576
|
+
events,
|
|
4577
|
+
waitedMs: Math.max(0, now() - startedAt)
|
|
4578
|
+
};
|
|
4579
|
+
}
|
|
4580
|
+
if (now() >= deadline) {
|
|
4581
|
+
return {
|
|
4582
|
+
outcome: "timeout",
|
|
4583
|
+
taskId,
|
|
4584
|
+
status: "running",
|
|
4585
|
+
cursor: registry2.latestTaskSeq(taskId),
|
|
4586
|
+
events,
|
|
4587
|
+
waitedMs: Math.max(0, now() - startedAt),
|
|
4588
|
+
timeoutMs,
|
|
4589
|
+
...clamped ? { timeoutClamped: true } : {}
|
|
4590
|
+
};
|
|
4591
|
+
}
|
|
4592
|
+
await sleep(Math.min(pollIntervalMs, Math.max(1, deadline - now())));
|
|
4593
|
+
}
|
|
4594
|
+
return {
|
|
4595
|
+
outcome: "timeout",
|
|
4596
|
+
taskId,
|
|
4597
|
+
status: "running",
|
|
4598
|
+
cursor: registry2.latestTaskSeq(taskId),
|
|
4599
|
+
events: registry2.getTaskEvents(taskId, 0),
|
|
4600
|
+
waitedMs: Math.max(0, now() - startedAt),
|
|
4601
|
+
timeoutMs,
|
|
4602
|
+
...clamped ? { timeoutClamped: true } : {}
|
|
4603
|
+
};
|
|
4604
|
+
}
|
|
4605
|
+
function runTaskLogs(args) {
|
|
4606
|
+
const { registry: registry2, taskId } = args;
|
|
4607
|
+
const cursorRaw = typeof args.cursor === "number" ? args.cursor : typeof args.cursor === "string" && args.cursor.trim() !== "" ? Number(args.cursor) : Number.NaN;
|
|
4608
|
+
const cursor = Number.isFinite(cursorRaw) && cursorRaw > 0 ? Math.floor(cursorRaw) : 0;
|
|
4609
|
+
const { record, hasEvents, known } = inspectTask(registry2, taskId);
|
|
4610
|
+
if (!known) {
|
|
4611
|
+
return { outcome: "not-found", taskId, detail: notFoundDetail(taskId) };
|
|
4612
|
+
}
|
|
4613
|
+
if (!hasEvents) {
|
|
4614
|
+
return {
|
|
4615
|
+
outcome: "evicted",
|
|
4616
|
+
taskId,
|
|
4617
|
+
cursor: 0,
|
|
4618
|
+
events: [],
|
|
4619
|
+
...record ? { status: statusOf(record) } : {},
|
|
4620
|
+
detail: evictedDetail(taskId)
|
|
4621
|
+
};
|
|
4622
|
+
}
|
|
4623
|
+
const events = registry2.getTaskEvents(taskId, cursor);
|
|
4624
|
+
const allEvents = registry2.getTaskEvents(taskId, 0);
|
|
4625
|
+
const terminal = lastTerminalEvent(allEvents);
|
|
4626
|
+
const status = terminal ? reportedTaskStatus(terminal.type, terminal.exitCode) : record ? statusOf(record) : "running";
|
|
4627
|
+
return {
|
|
4628
|
+
outcome: "ok",
|
|
4629
|
+
taskId,
|
|
4630
|
+
cursor: registry2.latestTaskSeq(taskId),
|
|
4631
|
+
events,
|
|
4632
|
+
status,
|
|
4633
|
+
terminal: isProcessTaskTerminalStatus(status)
|
|
4634
|
+
};
|
|
4635
|
+
}
|
|
4636
|
+
function formatTaskLogsContent(result, options) {
|
|
4637
|
+
const full = JSON.stringify(result);
|
|
4638
|
+
const limit = options?.outputLimit && options.outputLimit > 0 ? options.outputLimit : void 0;
|
|
4639
|
+
const effectiveLimit = limit ?? 2e4;
|
|
4640
|
+
if (full.length <= effectiveLimit) return { content: full };
|
|
4641
|
+
try {
|
|
4642
|
+
const spill = spillToolOutput({
|
|
4643
|
+
content: full,
|
|
4644
|
+
toolName: "taskLogs",
|
|
4645
|
+
workspaceRoot: options?.workspaceRoot
|
|
4646
|
+
});
|
|
4647
|
+
const omitted = result.outcome === "ok" ? result.events.length : 0;
|
|
4648
|
+
const head = JSON.stringify({
|
|
4649
|
+
...result,
|
|
4650
|
+
events: [],
|
|
4651
|
+
eventsOmitted: omitted,
|
|
4652
|
+
logRef: spill.displayPath
|
|
4653
|
+
});
|
|
4654
|
+
return {
|
|
4655
|
+
content: `${head}${formatToolOverflowMarker({
|
|
4656
|
+
spillRef: spill.displayPath,
|
|
4657
|
+
totalChars: spill.totalChars,
|
|
4658
|
+
totalLines: spill.totalLines,
|
|
4659
|
+
omittedChars: Math.max(0, full.length - head.length),
|
|
4660
|
+
toolName: "taskLogs"
|
|
4661
|
+
})}`.trimEnd(),
|
|
4662
|
+
logRef: spill.displayPath
|
|
4663
|
+
};
|
|
4664
|
+
} catch {
|
|
4665
|
+
return { content: truncateToolOutput(full, effectiveLimit) };
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
function isProcessGroupAlive(pgid, kill = defaultSignalSender) {
|
|
4669
|
+
try {
|
|
4670
|
+
kill(-pgid, 0);
|
|
4671
|
+
return true;
|
|
4672
|
+
} catch (error) {
|
|
4673
|
+
return error.code === "EPERM";
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
async function runTaskStop(args) {
|
|
4677
|
+
const { registry: registry2, taskId } = args;
|
|
4678
|
+
const sleep = args.sleep ?? defaultSleep;
|
|
4679
|
+
const kill = args.kill ?? defaultSignalSender;
|
|
4680
|
+
const graceMs = Math.max(0, args.graceMs ?? TASK_STOP_GRACE_MS);
|
|
4681
|
+
const record = registry2.getByTaskId(taskId);
|
|
4682
|
+
if (!record) {
|
|
4683
|
+
return { outcome: "not-found", taskId, detail: notFoundDetail(taskId) };
|
|
4684
|
+
}
|
|
4685
|
+
const termed = registry2.kill(record.pid, "SIGTERM");
|
|
4686
|
+
if (!termed) {
|
|
4687
|
+
const reason = record.transient ? "transient-foreground" : record.status !== "running" ? "already-terminal" : "kill-refused";
|
|
4688
|
+
const detail = reason === "transient-foreground" ? `${taskId} is a foreground command still inside its grace window, not a background task; its lifecycle belongs to the running execShell call.` : reason === "already-terminal" ? `${taskId} is already ${statusOf(record)}; nothing to stop.` : `Registry refused to stop ${taskId}.`;
|
|
4689
|
+
return {
|
|
4690
|
+
outcome: "not-stoppable",
|
|
4691
|
+
taskId,
|
|
4692
|
+
pid: record.pid,
|
|
4693
|
+
status: statusOf(record),
|
|
4694
|
+
reason,
|
|
4695
|
+
detail
|
|
4696
|
+
};
|
|
4697
|
+
}
|
|
4698
|
+
if (graceMs > 0) await sleep(graceMs);
|
|
4699
|
+
if (!isProcessGroupAlive(record.pgid, kill)) {
|
|
4700
|
+
return {
|
|
4701
|
+
outcome: "stopped",
|
|
4702
|
+
taskId,
|
|
4703
|
+
pid: record.pid,
|
|
4704
|
+
status: reportedTaskStatus("killed"),
|
|
4705
|
+
signal: "SIGTERM",
|
|
4706
|
+
escalated: false
|
|
4707
|
+
};
|
|
4708
|
+
}
|
|
4709
|
+
try {
|
|
4710
|
+
kill(-record.pgid, "SIGKILL");
|
|
4711
|
+
} catch {
|
|
4712
|
+
}
|
|
4713
|
+
return {
|
|
4714
|
+
outcome: "stopped",
|
|
4715
|
+
taskId,
|
|
4716
|
+
pid: record.pid,
|
|
4717
|
+
status: reportedTaskStatus("killed"),
|
|
4718
|
+
signal: "SIGKILL",
|
|
4719
|
+
escalated: true
|
|
4720
|
+
};
|
|
4721
|
+
}
|
|
4722
|
+
function runTasks(args) {
|
|
4723
|
+
const tasks = args.registry.listBackground().map((record) => ({
|
|
4724
|
+
taskId: record.taskId,
|
|
4725
|
+
pid: record.pid,
|
|
4726
|
+
label: record.label,
|
|
4727
|
+
status: statusOf(record),
|
|
4728
|
+
startedAt: record.startedAt,
|
|
4729
|
+
persist: record.persist
|
|
4730
|
+
}));
|
|
4731
|
+
return { tasks, count: tasks.length };
|
|
4732
|
+
}
|
|
4733
|
+
|
|
4316
4734
|
// packages/agent-runtime/capabilities/execShellCapability.ts
|
|
4317
4735
|
function buildExecShellToolDefinition(toolName = "execShell") {
|
|
4318
4736
|
return {
|
|
@@ -4452,9 +4870,21 @@ var WORKSPACE_TOOL_NAMES = [
|
|
|
4452
4870
|
"captureVisualState",
|
|
4453
4871
|
"execShell",
|
|
4454
4872
|
"launchProcess",
|
|
4455
|
-
"listProcesses"
|
|
4873
|
+
"listProcesses",
|
|
4874
|
+
"taskWait",
|
|
4875
|
+
"taskLogs",
|
|
4876
|
+
"taskStop",
|
|
4877
|
+
"tasks"
|
|
4878
|
+
];
|
|
4879
|
+
var SHELL_TOOL_NAMES = [
|
|
4880
|
+
"execShell",
|
|
4881
|
+
"launchProcess",
|
|
4882
|
+
"listProcesses",
|
|
4883
|
+
"taskWait",
|
|
4884
|
+
"taskLogs",
|
|
4885
|
+
"taskStop",
|
|
4886
|
+
"tasks"
|
|
4456
4887
|
];
|
|
4457
|
-
var SHELL_TOOL_NAMES = ["execShell", "launchProcess", "listProcesses"];
|
|
4458
4888
|
var WORKSPACE_TOOL_NAME_SET = new Set(WORKSPACE_TOOL_NAMES);
|
|
4459
4889
|
function buildWorkspacePathProperty() {
|
|
4460
4890
|
return {
|
|
@@ -4678,6 +5108,87 @@ function buildListProcessesTool() {
|
|
|
4678
5108
|
}
|
|
4679
5109
|
};
|
|
4680
5110
|
}
|
|
5111
|
+
function buildTaskWaitTool() {
|
|
5112
|
+
return {
|
|
5113
|
+
type: "function",
|
|
5114
|
+
function: {
|
|
5115
|
+
name: "taskWait",
|
|
5116
|
+
description: 'Block until a background task (from launchProcess, or an execShell command that detached) reaches a terminal state, or until timeoutMs elapses. Returns {outcome, status, exitCode?, cursor, events}: outcome "terminal" with status exited|failed|stopped when it finished, outcome "timeout" with status "running" when it is still going (call again to keep waiting), outcome "not-found" for an unknown taskId, or outcome "evicted" when the event trail aged out (never wait again in that case). `cursor` is the highest event seq covered by this response \u2014 pass it to taskLogs to read only newer events.',
|
|
5117
|
+
parameters: {
|
|
5118
|
+
type: "object",
|
|
5119
|
+
properties: {
|
|
5120
|
+
taskId: {
|
|
5121
|
+
type: "string",
|
|
5122
|
+
minLength: 1,
|
|
5123
|
+
description: "Task id returned by launchProcess or by a detached execShell result."
|
|
5124
|
+
},
|
|
5125
|
+
timeoutMs: {
|
|
5126
|
+
type: "number",
|
|
5127
|
+
description: "Wait budget in milliseconds. Defaults to 60000; values above 300000 are clamped to 300000."
|
|
5128
|
+
}
|
|
5129
|
+
},
|
|
5130
|
+
required: ["taskId"]
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
};
|
|
5134
|
+
}
|
|
5135
|
+
function buildTaskLogsTool() {
|
|
5136
|
+
return {
|
|
5137
|
+
type: "function",
|
|
5138
|
+
function: {
|
|
5139
|
+
name: "taskLogs",
|
|
5140
|
+
description: "Read a background task's lifecycle events incrementally. Returns {outcome, status, cursor, events} where events are the started|promoted|exited|killed records with seq greater than the cursor you passed, and the returned `cursor` is the new high-water mark to pass next time (omit cursor to read from the beginning; repeating the same cursor is idempotent). Oversized output is spilled to a file and reported as `logRef`, which you can open with readFile.",
|
|
5141
|
+
parameters: {
|
|
5142
|
+
type: "object",
|
|
5143
|
+
properties: {
|
|
5144
|
+
taskId: {
|
|
5145
|
+
type: "string",
|
|
5146
|
+
minLength: 1,
|
|
5147
|
+
description: "Task id returned by launchProcess or by a detached execShell result."
|
|
5148
|
+
},
|
|
5149
|
+
cursor: {
|
|
5150
|
+
type: "number",
|
|
5151
|
+
description: "Last event seq you already consumed; only events with a higher seq are returned. Defaults to 0 (all retained events)."
|
|
5152
|
+
}
|
|
5153
|
+
},
|
|
5154
|
+
required: ["taskId"]
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
5157
|
+
};
|
|
5158
|
+
}
|
|
5159
|
+
function buildTaskStopTool() {
|
|
5160
|
+
return {
|
|
5161
|
+
type: "function",
|
|
5162
|
+
function: {
|
|
5163
|
+
name: "taskStop",
|
|
5164
|
+
description: 'Stop a background task: SIGTERM to its process group, then SIGKILL if it is still alive after a short grace window. Returns {outcome, status, signal, escalated}: outcome "stopped" with status "stopped" on success, or outcome "not-stoppable" (already finished, or a foreground command that is not a background task) or "not-found". Never reports success without signalling.',
|
|
5165
|
+
parameters: {
|
|
5166
|
+
type: "object",
|
|
5167
|
+
properties: {
|
|
5168
|
+
taskId: {
|
|
5169
|
+
type: "string",
|
|
5170
|
+
minLength: 1,
|
|
5171
|
+
description: "Task id returned by launchProcess or by a detached execShell result."
|
|
5172
|
+
}
|
|
5173
|
+
},
|
|
5174
|
+
required: ["taskId"]
|
|
5175
|
+
}
|
|
5176
|
+
}
|
|
5177
|
+
};
|
|
5178
|
+
}
|
|
5179
|
+
function buildTasksTool() {
|
|
5180
|
+
return {
|
|
5181
|
+
type: "function",
|
|
5182
|
+
function: {
|
|
5183
|
+
name: "tasks",
|
|
5184
|
+
description: "List background tasks you can still wait on, read logs from, or stop. Returns {count, tasks: {taskId, pid, label, status, startedAt, persist}[]}. Use it to recover a taskId you lost track of; foreground commands still running inside execShell are not listed.",
|
|
5185
|
+
parameters: {
|
|
5186
|
+
type: "object",
|
|
5187
|
+
properties: {}
|
|
5188
|
+
}
|
|
5189
|
+
}
|
|
5190
|
+
};
|
|
5191
|
+
}
|
|
4681
5192
|
function buildWorkspaceToolDefinition(toolName) {
|
|
4682
5193
|
if (toolName === "readFile") {
|
|
4683
5194
|
return buildReadWorkspaceFileTool();
|
|
@@ -4695,6 +5206,10 @@ function buildWorkspaceToolDefinition(toolName) {
|
|
|
4695
5206
|
if (toolName === "execShell") return buildExecShellTool(toolName);
|
|
4696
5207
|
if (toolName === "launchProcess") return buildLaunchProcessTool();
|
|
4697
5208
|
if (toolName === "listProcesses") return buildListProcessesTool();
|
|
5209
|
+
if (toolName === "taskWait") return buildTaskWaitTool();
|
|
5210
|
+
if (toolName === "taskLogs") return buildTaskLogsTool();
|
|
5211
|
+
if (toolName === "taskStop") return buildTaskStopTool();
|
|
5212
|
+
if (toolName === "tasks") return buildTasksTool();
|
|
4698
5213
|
return null;
|
|
4699
5214
|
}
|
|
4700
5215
|
function filterDeclaredWorkspaceToolNames(args) {
|
|
@@ -6097,6 +6612,91 @@ async function listProcessesTool(args) {
|
|
|
6097
6612
|
}
|
|
6098
6613
|
};
|
|
6099
6614
|
}
|
|
6615
|
+
function requireTaskId(parsed) {
|
|
6616
|
+
return readTrimmedString2(parsed.taskId);
|
|
6617
|
+
}
|
|
6618
|
+
function missingTaskIdResult(toolName) {
|
|
6619
|
+
return {
|
|
6620
|
+
content: JSON.stringify({
|
|
6621
|
+
outcome: "invalid-arguments",
|
|
6622
|
+
detail: `${toolName} requires a taskId (see tasks for current handles).`
|
|
6623
|
+
}),
|
|
6624
|
+
metadata: { status: "invalid-arguments", tool: toolName }
|
|
6625
|
+
};
|
|
6626
|
+
}
|
|
6627
|
+
async function taskWaitTool(args) {
|
|
6628
|
+
const parsed = parseWorkspaceToolArguments(args.call.arguments);
|
|
6629
|
+
const taskId = requireTaskId(parsed);
|
|
6630
|
+
if (!taskId) return missingTaskIdResult(args.call.name);
|
|
6631
|
+
const result = await runTaskWait({
|
|
6632
|
+
taskId,
|
|
6633
|
+
timeoutMs: parsed.timeoutMs,
|
|
6634
|
+
registry: getProcessRegistry(),
|
|
6635
|
+
...args.pollIntervalMs !== void 0 ? { pollIntervalMs: args.pollIntervalMs } : {}
|
|
6636
|
+
});
|
|
6637
|
+
return {
|
|
6638
|
+
content: JSON.stringify(result),
|
|
6639
|
+
metadata: {
|
|
6640
|
+
taskId,
|
|
6641
|
+
outcome: result.outcome,
|
|
6642
|
+
..."status" in result && result.status ? { status: result.status } : {},
|
|
6643
|
+
..."cursor" in result ? { cursor: result.cursor } : {},
|
|
6644
|
+
..."exitCode" in result && result.exitCode !== void 0 ? { exitCode: result.exitCode } : {}
|
|
6645
|
+
}
|
|
6646
|
+
};
|
|
6647
|
+
}
|
|
6648
|
+
async function taskLogsTool(args) {
|
|
6649
|
+
const parsed = parseWorkspaceToolArguments(args.call.arguments);
|
|
6650
|
+
const taskId = requireTaskId(parsed);
|
|
6651
|
+
if (!taskId) return missingTaskIdResult(args.call.name);
|
|
6652
|
+
const result = runTaskLogs({
|
|
6653
|
+
taskId,
|
|
6654
|
+
cursor: parsed.cursor,
|
|
6655
|
+
registry: getProcessRegistry()
|
|
6656
|
+
});
|
|
6657
|
+
const rendered = formatTaskLogsContent(result, {
|
|
6658
|
+
...args.commandOutputLimit !== void 0 ? { outputLimit: args.commandOutputLimit } : {},
|
|
6659
|
+
workspaceRoot: args.workspaceRoot
|
|
6660
|
+
});
|
|
6661
|
+
return {
|
|
6662
|
+
content: rendered.content,
|
|
6663
|
+
metadata: {
|
|
6664
|
+
taskId,
|
|
6665
|
+
outcome: result.outcome,
|
|
6666
|
+
..."status" in result && result.status ? { status: result.status } : {},
|
|
6667
|
+
..."cursor" in result ? { cursor: result.cursor } : {},
|
|
6668
|
+
..."events" in result ? { eventCount: result.events.length } : {},
|
|
6669
|
+
...rendered.logRef ? { logRef: rendered.logRef } : {}
|
|
6670
|
+
}
|
|
6671
|
+
};
|
|
6672
|
+
}
|
|
6673
|
+
async function taskStopTool(args) {
|
|
6674
|
+
const parsed = parseWorkspaceToolArguments(args.call.arguments);
|
|
6675
|
+
const taskId = requireTaskId(parsed);
|
|
6676
|
+
if (!taskId) return missingTaskIdResult(args.call.name);
|
|
6677
|
+
const result = await runTaskStop({
|
|
6678
|
+
taskId,
|
|
6679
|
+
registry: getProcessRegistry(),
|
|
6680
|
+
...args.graceMs !== void 0 ? { graceMs: args.graceMs } : {}
|
|
6681
|
+
});
|
|
6682
|
+
return {
|
|
6683
|
+
content: JSON.stringify(result),
|
|
6684
|
+
metadata: {
|
|
6685
|
+
taskId,
|
|
6686
|
+
outcome: result.outcome,
|
|
6687
|
+
..."status" in result ? { status: result.status } : {},
|
|
6688
|
+
..."pid" in result ? { pid: result.pid } : {},
|
|
6689
|
+
..."signal" in result ? { signal: result.signal } : {}
|
|
6690
|
+
}
|
|
6691
|
+
};
|
|
6692
|
+
}
|
|
6693
|
+
async function tasksTool(_args) {
|
|
6694
|
+
const result = runTasks({ registry: getProcessRegistry() });
|
|
6695
|
+
return {
|
|
6696
|
+
content: JSON.stringify(result),
|
|
6697
|
+
metadata: { count: result.count, tasks: result.tasks }
|
|
6698
|
+
};
|
|
6699
|
+
}
|
|
6100
6700
|
function createLocalWorkspaceToolExecutors(args) {
|
|
6101
6701
|
const fileAccess = args.confirmExternalFileAccess ? { confirmExternalFileAccess: args.confirmExternalFileAccess } : {};
|
|
6102
6702
|
const readFileLedger = /* @__PURE__ */ new Map();
|
|
@@ -6151,7 +6751,15 @@ function createLocalWorkspaceToolExecutors(args) {
|
|
|
6151
6751
|
}),
|
|
6152
6752
|
listProcesses: (call) => listProcessesTool({
|
|
6153
6753
|
call
|
|
6154
|
-
})
|
|
6754
|
+
}),
|
|
6755
|
+
taskWait: (call) => taskWaitTool({ call }),
|
|
6756
|
+
taskLogs: (call) => taskLogsTool({
|
|
6757
|
+
call,
|
|
6758
|
+
workspaceRoot: args.workspaceRoot,
|
|
6759
|
+
...args.commandOutputLimit !== void 0 ? { commandOutputLimit: args.commandOutputLimit } : {}
|
|
6760
|
+
}),
|
|
6761
|
+
taskStop: (call) => taskStopTool({ call }),
|
|
6762
|
+
tasks: (call) => tasksTool({ call })
|
|
6155
6763
|
};
|
|
6156
6764
|
}
|
|
6157
6765
|
|
|
@@ -6289,7 +6897,7 @@ function buildLoadSkillExecutor(args) {
|
|
|
6289
6897
|
const { resolveSkillByName } = await import("./skillDiscovery-COX56OBO.js");
|
|
6290
6898
|
const resolved = resolveSkillByName(args.cwd, name);
|
|
6291
6899
|
if (!resolved) {
|
|
6292
|
-
const { resolveCodingBuiltinSlug, buildCodingSkillContentBySlug } = await import("./codingSkills-
|
|
6900
|
+
const { resolveCodingBuiltinSlug, buildCodingSkillContentBySlug } = await import("./codingSkills-BYQI6EPT.js");
|
|
6293
6901
|
const builtinSlug = resolveCodingBuiltinSlug(name);
|
|
6294
6902
|
if (builtinSlug) {
|
|
6295
6903
|
const body = buildCodingSkillContentBySlug(builtinSlug);
|