nolo-cli 0.18.0 → 0.24.0-alpha.6

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.
Files changed (133) hide show
  1. package/{_executeModel-X5PCIZN6.js → _executeModel-ARCMGGMY.js} +46 -44
  2. package/{action-LT7BRFLK.js → action-5MNAXR5B.js} +7 -6
  3. package/{addContentAction-PL3KKBDH.js → addContentAction-UNSYTVTB.js} +5 -5
  4. package/{addDialogAgentAction-FCMSKYAF.js → addDialogAgentAction-LJGNP2AO.js} +5 -5
  5. package/{agentDeleteCommand-2BZDQV36.js → agentDeleteCommand-C5PIEBMZ.js} +27 -26
  6. package/{agentEmailCommands-2QJDGRMB.js → agentEmailCommands-QTGQ3ZAD.js} +57 -55
  7. package/{agentListCommands-6VEPTKBI.js → agentListCommands-LRHBS3A5.js} +30 -26
  8. package/{agentMachineCommands-NVVHNWYI.js → agentMachineCommands-4PXIT4BP.js} +25 -24
  9. package/{agentRecordCommands-4GGRDMD4.js → agentRecordCommands-ZZPTYTYR.js} +52 -50
  10. package/{agentRunCommand-XOLQNKBZ.js → agentRunCommand-7ZTPZNUX.js} +55 -54
  11. package/{agentRunControl-Y5AFH5PQ.js → agentRunControl-SNUKXN6J.js} +6 -2
  12. package/{agentRuntimeLocal-7WYWCGL4.js → agentRuntimeLocal-QOYY5UV2.js} +19 -18
  13. package/{agentSlice-EAXPGEYV.js → agentSlice-J3W3RX2I.js} +5 -5
  14. package/{appDeleteCommands-77KR2RJ4.js → appDeleteCommands-7NS46XDH.js} +23 -22
  15. package/{appDeployCommands-K7CAHGBI.js → appDeployCommands-RSRNQ67U.js} +23 -22
  16. package/{appDeployStatusCommands-4OEKLTBT.js → appDeployStatusCommands-EF4RSGC6.js} +23 -22
  17. package/{appGetCommands-VM2WDLAZ.js → appGetCommands-YA7JWYUX.js} +23 -22
  18. package/{appListCommands-GX6BBA6U.js → appListCommands-WM2ON6JW.js} +23 -22
  19. package/{authCommand-DY6UUL6O.js → authCommand-HJP7FURK.js} +12 -13
  20. package/{authCommands-XTBV7OFZ.js → authCommands-NYZM2B2I.js} +4 -5
  21. package/{chunk-MKA6QE5E.js → chunk-2IPEVBUO.js} +126 -68
  22. package/{chunk-OWOHNGCN.js → chunk-2MBTWINN.js} +42 -3
  23. package/{chunk-K6EUAOW3.js → chunk-35RYGII3.js} +1 -1
  24. package/{chunk-TRT4I4UD.js → chunk-4POUK2BV.js} +2 -2
  25. package/{chunk-LLWKHDG4.js → chunk-4ULSC37S.js} +1 -3
  26. package/{chunk-EDV7EBOI.js → chunk-4ZH6GUJF.js} +2151 -1500
  27. package/{chunk-MVQ4TBSD.js → chunk-54VHTARN.js} +1 -1
  28. package/{chunk-L4F3I4SR.js → chunk-5HQQ4LUU.js} +4 -6
  29. package/{chunk-Z4NR32XR.js → chunk-5RGU3J7P.js} +13 -0
  30. package/{chunk-7BUYEZ6U.js → chunk-7H3UTGPM.js} +12 -72
  31. package/{chunk-RQN4SEKL.js → chunk-7W6GFNJL.js} +1 -1
  32. package/{chunk-HEGV7BH3.js → chunk-AQZCWJOG.js} +1 -1
  33. package/{chunk-3ND52WIL.js → chunk-ATWUOTJP.js} +180 -24
  34. package/chunk-CF7S2RYZ.js +376 -0
  35. package/{chunk-I2ZJKTG5.js → chunk-CGVRC2TB.js} +7 -7
  36. package/{chunk-UAIVG4J6.js → chunk-CHSCAUZN.js} +1 -8
  37. package/{chunk-KFEVY3ST.js → chunk-D34RI6NI.js} +18 -8
  38. package/{chunk-ROWQEJRP.js → chunk-DXJS7VSG.js} +3 -2
  39. package/{chunk-MHSGJW4Z.js → chunk-EHOYZRTI.js} +44 -14
  40. package/{chunk-XRZJGPFI.js → chunk-FON47ACC.js} +4 -4
  41. package/{chunk-SCTYAHYK.js → chunk-H2NAWOLH.js} +217 -141
  42. package/{chunk-MPVYDS7I.js → chunk-H6ODMJR3.js} +3 -3
  43. package/{chunk-R35XMF6F.js → chunk-H73ZV2GL.js} +352 -30
  44. package/{chunk-4T5F7YZQ.js → chunk-I6RJGORZ.js} +1 -1
  45. package/{chunk-OK6YSWLH.js → chunk-IICW77GI.js} +1 -1
  46. package/{chunk-VDXCXCXH.js → chunk-IUDMBCXC.js} +1 -1
  47. package/{chunk-AHCY2S2I.js → chunk-JADNODCQ.js} +1 -1
  48. package/{chunk-DFCFMCY6.js → chunk-JBLY6HQP.js} +2 -2
  49. package/{chunk-UGUW3FHG.js → chunk-JMSCXQUG.js} +2 -2
  50. package/{chunk-N54HIJVJ.js → chunk-KFUCLS7Z.js} +101 -9
  51. package/{chunk-FQZZLA3C.js → chunk-KXKQO4Q6.js} +17 -0
  52. package/{chunk-3Q7WHGCB.js → chunk-L65QKSVJ.js} +1 -1
  53. package/{chunk-3ZX7PERL.js → chunk-LALVWNE4.js} +20 -7
  54. package/{chunk-PJSV3IZ5.js → chunk-M3TMVJKG.js} +1 -1
  55. package/{chunk-REA4JLBH.js → chunk-M5OZCOBV.js} +7 -6
  56. package/{chunk-JLA4FXYC.js → chunk-MALVZUYL.js} +1 -1
  57. package/{chunk-GFUIQ4RY.js → chunk-MXFQHRSS.js} +1 -1
  58. package/{chunk-LSFAWXKC.js → chunk-N7J63Q6C.js} +1 -0
  59. package/{chunk-6Y7A3OQQ.js → chunk-NRY4GCKJ.js} +2 -0
  60. package/{chunk-G5U6LDLG.js → chunk-NVHPMDSZ.js} +6 -6
  61. package/{chunk-23FZYPLC.js → chunk-OJFYT3ZQ.js} +842 -1060
  62. package/{chunk-ELT65PZW.js → chunk-OXLLFZNF.js} +1 -1
  63. package/{chunk-CZ6NYQTV.js → chunk-P4QWLZGU.js} +2 -2
  64. package/{chunk-5MIDPSSK.js → chunk-PB7G5MAM.js} +3 -3
  65. package/{chunk-HWW2M4SN.js → chunk-QLVWFXZQ.js} +5 -4
  66. package/{chunk-VYHDJEQD.js → chunk-QNLLGS37.js} +136 -78
  67. package/{chunk-XHG22OEX.js → chunk-ROJI6DRT.js} +2 -2
  68. package/{chunk-BV4VEE3W.js → chunk-ROYOKSX4.js} +243 -354
  69. package/{chunk-VNAEBGDK.js → chunk-RZNYL4LW.js} +123 -26
  70. package/{chunk-RVOUXDFU.js → chunk-S6KVFOUG.js} +6 -34
  71. package/{chunk-V3ED5AWK.js → chunk-S77SCVBU.js} +27 -16
  72. package/{chunk-UBHAWFQ6.js → chunk-S7RWIPDI.js} +42 -19
  73. package/{chunk-B5TOXZAK.js → chunk-SIZQB7BD.js} +1 -1
  74. package/{chunk-DFFIZ25G.js → chunk-SLOGKB7M.js} +4 -1
  75. package/{chunk-FXUSIQC2.js → chunk-SROR5TSM.js} +1 -1
  76. package/{chunk-PIZYJVHQ.js → chunk-TN4YHAI3.js} +4 -4
  77. package/{chunk-IYEXFJPC.js → chunk-TW35GDNW.js} +64 -57
  78. package/chunk-UZ6XXCVR.js +50 -0
  79. package/{chunk-DKZFOK24.js → chunk-UZH44DWK.js} +7 -288
  80. package/{chunk-YGW4G5W5.js → chunk-X546QUDT.js} +61 -12
  81. package/chunk-YYLHWIW6.js +48 -0
  82. package/{chunk-SWDPIPOY.js → chunk-ZGVW7MSZ.js} +1 -1
  83. package/{chunk-34WPV75U.js → chunk-ZUXIXYJI.js} +1 -1
  84. package/{chunk-VC6OZXO5.js → chunk-ZWJOGMKH.js} +2 -26
  85. package/{cliExecutor-DNE7TCC4.js → cliExecutor-K3F7DMRO.js} +2 -2
  86. package/{codingSkills-36KN5NQT.js → codingSkills-EN6Z6G6U.js} +4 -4
  87. package/{createAgentAutomationAction-GNFF524X.js → createAgentAutomationAction-MKQWN4VQ.js} +19 -18
  88. package/{createDialogAction-RB55KCLO.js → createDialogAction-YWIZPLFS.js} +22 -20
  89. package/{createPageAction-Y7343GLU.js → createPageAction-74TTEIPC.js} +20 -19
  90. package/{db-W3O47YGF.js → db-W5UHK4P3.js} +150 -0
  91. package/{dbSlice-CGSRFJN3.js → dbSlice-5BKDURDL.js} +4 -4
  92. package/{dialogCommands-IAZK6YHQ.js → dialogCommands-MJIP32FL.js} +24 -23
  93. package/{dialogSlice-UQAXF23P.js → dialogSlice-KLLVH4WI.js} +24 -18
  94. package/{docCreateCommands-I2EWZGCI.js → docCreateCommands-5DN472U6.js} +24 -27
  95. package/{docDeleteCommands-IZ45UZKG.js → docDeleteCommands-HE76LBN4.js} +25 -24
  96. package/{docReadCommands-R6Z4QJYU.js → docReadCommands-XVGZSCBS.js} +24 -23
  97. package/{docStore-5HOJ4D7D.js → docStore-SPH3D6BT.js} +20 -19
  98. package/{docUpdateCommands-2LRBKQPY.js → docUpdateCommands-P7IAWUAD.js} +24 -27
  99. package/{fetchMessages-BMGVZVSE.js → fetchMessages-W4IKHPCS.js} +2 -3
  100. package/{getPricing-G7DLAST6.js → getPricing-WENPBVWH.js} +3 -3
  101. package/{handleSendMessageAction-Q4HY35WX.js → handleSendMessageAction-ZU6WJVL7.js} +23 -20
  102. package/index.js +74 -74
  103. package/{localDialogRead-4H3QJFLW.js → localDialogRead-JXTAHW2E.js} +2 -2
  104. package/{machineCommands-PKBPQKTY.js → machineCommands-NI76PVHK.js} +59 -57
  105. package/{machineWsRunDispatch-UZAW4OXJ.js → machineWsRunDispatch-W3G6NJVQ.js} +51 -49
  106. package/{models-DJFSJ7SW.js → models-DB27UAE3.js} +2 -2
  107. package/package.json +1 -1
  108. package/{read-3FMPZPER.js → read-F3L3T2WJ.js} +2 -1
  109. package/{readDocTool-VSYHKK3V.js → readDocTool-FOHWVA4R.js} +1 -1
  110. package/{readlineWorkspace-Y2RDOFZG.js → readlineWorkspace-BDH4G477.js} +880 -425
  111. package/{removeDialogAgentAction-OAGA2G3U.js → removeDialogAgentAction-QCFGIUIH.js} +8 -7
  112. package/{runAgentClientLoop-NBPIKJ6J.js → runAgentClientLoop-ZPKMXCM5.js} +45 -38
  113. package/{setDialogExtraReferencesAction-JZEXA5SL.js → setDialogExtraReferencesAction-DK4CKERU.js} +5 -5
  114. package/{setPrimaryDialogAgentAction-4ZUQQKDG.js → setPrimaryDialogAgentAction-SJSO6N27.js} +8 -7
  115. package/{settingSlice-7MNKHZ6R.js → settingSlice-XNM5AFPU.js} +6 -5
  116. package/{spaceCommands-DHCZ7J5I.js → spaceCommands-3GGBJRQR.js} +25 -24
  117. package/{spaceSlice-ZXLLG3CR.js → spaceSlice-47Z6XLFQ.js} +21 -18
  118. package/{streamAgentChatTurn-L3YW6LSB.js → streamAgentChatTurn-VT5K5JSD.js} +140 -98
  119. package/switchDialogAgentAction-4OAC6QRN.js +61 -0
  120. package/{tableCommands-BEQAGE4I.js → tableCommands-HEQYT2KP.js} +1 -1
  121. package/{toolApiClient-QI3YBNWB.js → toolApiClient-ISM4ZQX4.js} +2 -2
  122. package/{tools-ECGXR5QF.js → tools-L7RCHAPT.js} +36 -33
  123. package/{tuiSummaryLlmCaller-OMSCNHXA.js → tuiSummaryLlmCaller-3DYOLTVN.js} +6 -6
  124. package/{updateCommands-XTW55TOT.js → updateCommands-HTCOBXCA.js} +2 -2
  125. package/{updateDialogTitleAction-HQ2EUDFT.js → updateDialogTitleAction-KMPVPQ4A.js} +28 -27
  126. package/chunk-DL6EPNIK.js +0 -50
  127. package/chunk-V5R4NZP2.js +0 -78
  128. package/chunk-X4Q4UZEY.js +0 -26
  129. package/queryRunOverlay-O4LOMMPO.js +0 -161
  130. package/runOverlayPresentation-ZO4VCWEU.js +0 -11
  131. package/types-ZSTJ7MPR.js +0 -7
  132. package/{chunk-X7W4TNB4.js → chunk-CMKUBIGW.js} +3 -3
  133. package/{runtimeDoctorCommands-E2OUORHK.js → runtimeDoctorCommands-HSU632DY.js} +3 -3
@@ -5,21 +5,21 @@ import {
5
5
  normalizeNonNegativeMs,
6
6
  parseRetryAfterHeaderMs
7
7
  } from "./chunk-RQSOAMPJ.js";
8
+ import {
9
+ readDocFunc,
10
+ readDocFunctionSchema,
11
+ readPageFunc,
12
+ readPageFunctionSchema,
13
+ slateToSimplifiedMarkdown
14
+ } from "./chunk-I6RJGORZ.js";
8
15
  import {
9
16
  sortSafeAgentSummaries,
10
17
  toSafeAgentSummary
11
- } from "./chunk-3ZX7PERL.js";
18
+ } from "./chunk-LALVWNE4.js";
12
19
  import {
13
20
  getUserDataItemTimestamp,
14
21
  mergeAndDedupUserData
15
22
  } from "./chunk-KQHGZWSV.js";
16
- import {
17
- readDocFunc,
18
- readDocFunctionSchema,
19
- readPageFunc,
20
- readPageFunctionSchema,
21
- slateToSimplifiedMarkdown
22
- } from "./chunk-4T5F7YZQ.js";
23
23
  import {
24
24
  markdownToSlate
25
25
  } from "./chunk-3LY4F7SV.js";
@@ -28,10 +28,10 @@ import {
28
28
  } from "./chunk-VF4K2QE6.js";
29
29
  import {
30
30
  createDocState
31
- } from "./chunk-G5U6LDLG.js";
31
+ } from "./chunk-NVHPMDSZ.js";
32
32
  import {
33
33
  setDialogExtraReferencesAction
34
- } from "./chunk-JLA4FXYC.js";
34
+ } from "./chunk-MALVZUYL.js";
35
35
  import {
36
36
  extractMentionsFromSlate
37
37
  } from "./chunk-VP4WJWKW.js";
@@ -39,8 +39,12 @@ import {
39
39
  slateToRenderMarkdown
40
40
  } from "./chunk-63W5N6P3.js";
41
41
  import {
42
+ BUILTIN_OBJECT_SKILL_IDS,
43
+ buildBuiltinObjectSkillConfig,
44
+ buildBuiltinObjectSkillDbKey,
45
+ buildBuiltinObjectSkillPageContent,
42
46
  createDialogAction
43
- } from "./chunk-IYEXFJPC.js";
47
+ } from "./chunk-TW35GDNW.js";
44
48
  import {
45
49
  addCategory,
46
50
  addContentToSpace,
@@ -71,27 +75,31 @@ import {
71
75
  updateContentCategory,
72
76
  updateContentTitle,
73
77
  updateStep
74
- } from "./chunk-SCTYAHYK.js";
78
+ } from "./chunk-H2NAWOLH.js";
75
79
  import {
76
80
  createAgent,
77
81
  runLlm,
78
82
  streamAgentChatTurn,
79
83
  updateAgent
80
- } from "./chunk-REA4JLBH.js";
84
+ } from "./chunk-M5OZCOBV.js";
81
85
  import {
86
+ CODING_SKILL_SLUGS,
87
+ buildCodingSkillConfig,
82
88
  buildCodingSkillContentBySlug,
83
- buildCodingSkillPageKey,
84
- resolveCodingBuiltinSlug
85
- } from "./chunk-7BUYEZ6U.js";
89
+ buildCodingSkillId,
90
+ buildCodingSkillPageKey
91
+ } from "./chunk-7H3UTGPM.js";
92
+ import {
93
+ CAPABILITY_PACKS
94
+ } from "./chunk-CF7S2RYZ.js";
86
95
  import {
87
96
  buildSkillDocMarkdown,
88
- normalizeSkillBudgetTier,
89
97
  normalizeSkillModalities,
90
98
  normalizeStringArray,
91
99
  parseExternalSkillMarkdown,
92
100
  parseSkillDocProtocol,
93
101
  resolvePageSkillMetadata
94
- } from "./chunk-VC6OZXO5.js";
102
+ } from "./chunk-ZWJOGMKH.js";
95
103
  import {
96
104
  NOLO_WORKSPACE_TOOL_NAMES,
97
105
  buildNoloSubjectRefQueryTarget,
@@ -105,21 +113,13 @@ import {
105
113
  redactAgentRecordForWorkspaceTool,
106
114
  resolveNoloDialogInput,
107
115
  verifyNoloDialogSubjectRefQuery
108
- } from "./chunk-DKZFOK24.js";
116
+ } from "./chunk-UZH44DWK.js";
109
117
  import {
110
118
  buildDatabaseFileContentUrl
111
- } from "./chunk-I2ZJKTG5.js";
119
+ } from "./chunk-CGVRC2TB.js";
112
120
  import {
113
121
  DEFAULT_MODEL
114
- } from "./chunk-UAIVG4J6.js";
115
- import {
116
- toErrorMessage
117
- } from "./chunk-HNMXYYJR.js";
118
- import {
119
- addContentAction,
120
- createSpaceKey,
121
- normalizeSpaceId
122
- } from "./chunk-ELT65PZW.js";
122
+ } from "./chunk-CHSCAUZN.js";
123
123
  import {
124
124
  canonicalizeToolName,
125
125
  canonicalizeToolNames
@@ -131,10 +131,7 @@ import {
131
131
  getRequestConfig,
132
132
  getToolBaseUrl,
133
133
  getToolRequestContext
134
- } from "./chunk-5MIDPSSK.js";
135
- import {
136
- extractCustomId
137
- } from "./chunk-DFFIZ25G.js";
134
+ } from "./chunk-PB7G5MAM.js";
138
135
  import {
139
136
  getActiveDialogKey,
140
137
  require_react,
@@ -146,27 +143,35 @@ import {
146
143
  } from "./chunk-DWLEOOGR.js";
147
144
  import {
148
145
  TASK_PREVIEW_MAX,
146
+ buildDelegatedTaskContent,
149
147
  formatListRunsCard,
150
148
  formatStartRunCard,
151
149
  formatStatusRunCard,
152
150
  formatStopRunCard,
153
151
  resolveRunLabel
154
- } from "./chunk-FQZZLA3C.js";
152
+ } from "./chunk-KXKQO4Q6.js";
153
+ import {
154
+ toErrorMessage
155
+ } from "./chunk-HNMXYYJR.js";
155
156
  import {
156
157
  shareResourceAction
157
- } from "./chunk-UGUW3FHG.js";
158
+ } from "./chunk-JMSCXQUG.js";
158
159
  import {
159
160
  AGENT_UPDATE_FIELD_NAMES,
160
- SYSTEM_AGENT_CAPABILITIES,
161
- SYSTEM_AGENT_CAPABILITY_IDS,
161
+ nolotusId,
162
162
  normalizeAgentUpdateFieldList,
163
163
  selectAutoApproveSelfUpdateFields,
164
164
  selectCurrentServer,
165
165
  selectSyncServers
166
- } from "./chunk-RVOUXDFU.js";
166
+ } from "./chunk-S6KVFOUG.js";
167
167
  import {
168
168
  asRecordOrEmpty
169
169
  } from "./chunk-KX6YBIHG.js";
170
+ import {
171
+ addContentAction,
172
+ createSpaceKey,
173
+ normalizeSpaceId
174
+ } from "./chunk-OXLLFZNF.js";
170
175
  import {
171
176
  patch,
172
177
  read,
@@ -175,7 +180,7 @@ import {
175
180
  selectById,
176
181
  toTimestampMs,
177
182
  write
178
- } from "./chunk-XRZJGPFI.js";
183
+ } from "./chunk-FON47ACC.js";
179
184
  import {
180
185
  SEPARATOR,
181
186
  createAgentKey,
@@ -187,7 +192,7 @@ import {
187
192
  rowKey,
188
193
  toTrimmedString,
189
194
  ulid
190
- } from "./chunk-6Y7A3OQQ.js";
195
+ } from "./chunk-NRY4GCKJ.js";
191
196
  import {
192
197
  asOptionalFiniteNumber
193
198
  } from "./chunk-WWC7I6TA.js";
@@ -199,8 +204,9 @@ import {
199
204
  asTrimmedLowercaseString
200
205
  } from "./chunk-QSJ3HFEF.js";
201
206
  import {
207
+ DEFAULT_CODE_PLANNER_EXECUTOR_CANDIDATE_KEYS,
202
208
  readAction
203
- } from "./chunk-3ND52WIL.js";
209
+ } from "./chunk-ATWUOTJP.js";
204
210
  import {
205
211
  createAsyncThunk,
206
212
  getRuntimeServerContext,
@@ -215,6 +221,9 @@ import {
215
221
  import {
216
222
  asTrimmedString
217
223
  } from "./chunk-3EUW3WEO.js";
224
+ import {
225
+ extractCustomId
226
+ } from "./chunk-SLOGKB7M.js";
218
227
  import {
219
228
  isRecord
220
229
  } from "./chunk-KUG52IAP.js";
@@ -1032,7 +1041,7 @@ var ai_locale_default = {
1032
1041
  isPublic: "Whether to publish to the app market. true means public, false means private.",
1033
1042
  allowFork: "Whether to allow other users to copy this AI to their space (can be set independently of whether it is public).",
1034
1043
  tags: "Array of tags for the Agent, e.g., ['Summary', 'Writing'].",
1035
- tools: "Array of tool names allowed for this Agent, e.g., ['fetchWebpage', 'callAgent'].",
1044
+ tools: "Array of tool names allowed for this Agent, e.g., ['fetchWebpage', 'startAgentRun'].",
1036
1045
  linkedSpaces: "List of associated Space IDs or Names. The Agent can access the directory structure of these Spaces as rough context. You MUST call 'listUserSpaces' tool first to get valid IDs/Names.",
1037
1046
  references: {
1038
1047
  desc: "Knowledge references injected into this Agent's system prompt at every call. Supports: page (PAGE-xxx), dialog (dialog-xxx), agent (agent-xxx), table (table-xxx). Content is fully expanded and prepended as context \u2014 the more precise the reference, the smarter the Agent. Use 'knowledge' type for most cases.",
@@ -1421,7 +1430,7 @@ var ai_locale_default = {
1421
1430
  isPublic: "\u662F\u5426\u516C\u5F00\u5230\u5E94\u7528\u5E02\u573A\u3002true \u8868\u793A\u516C\u5F00\uFF0Cfalse \u8868\u793A\u4EC5\u81EA\u5DF1\u53EF\u89C1\u3002",
1422
1431
  allowFork: "\u662F\u5426\u5141\u8BB8\u5176\u4ED6\u7528\u6237\u628A\u8FD9\u4E2A AI \u590D\u5236\u4E00\u4EFD\u5230\u81EA\u5DF1\u7684\u7A7A\u95F4\uFF08\u53EF\u4E0E\u662F\u5426\u516C\u5F00\u72EC\u7ACB\u8BBE\u7F6E\uFF09\u3002",
1423
1432
  tags: "\u7ED9 Agent \u6253\u4E0A\u7684\u6807\u7B7E\u6570\u7EC4\uFF0C\u4F8B\u5982 ['\u603B\u7ED3', '\u5199\u4F5C']\u3002",
1424
- tools: "\u5141\u8BB8\u6B64 Agent \u8C03\u7528\u7684\u5DE5\u5177\u540D\u79F0\u6570\u7EC4\uFF0C\u4F8B\u5982 ['fetchWebpage', 'callAgent']\u3002",
1433
+ tools: "\u5141\u8BB8\u6B64 Agent \u8C03\u7528\u7684\u5DE5\u5177\u540D\u79F0\u6570\u7EC4\uFF0C\u4F8B\u5982 ['fetchWebpage', 'startAgentRun']\u3002",
1425
1434
  linkedSpaces: "\u5173\u8054\u7684\u5176\u4ED6 Space ID \u6216\u540D\u79F0\u5217\u8868\u3002Agent \u53EF\u4EE5\u8BBF\u95EE\u8FD9\u4E9B Space \u7684\u76EE\u5F55\u7ED3\u6784\u4F5C\u4E3A\u7C97\u7565\u4E0A\u4E0B\u6587\u3002\u4F60\u5FC5\u987B\u5148\u8C03\u7528 'listUserSpaces' \u5DE5\u5177\u83B7\u53D6\u6709\u6548\u7684 Space ID \u6216\u540D\u79F0\u3002",
1426
1435
  references: {
1427
1436
  desc: "\u6BCF\u6B21\u8C03\u7528\u65F6\u6CE8\u5165 Agent system prompt \u7684\u77E5\u8BC6\u5F15\u7528\u3002\u652F\u6301\uFF1Apage(PAGE-xxx)\u3001dialog(dialog-xxx)\u3001agent(agent-xxx)\u3001table(table-xxx)\u3002\u5185\u5BB9\u4F1A\u5B8C\u6574\u5C55\u5F00\u5E76\u4F5C\u4E3A\u4E0A\u4E0B\u6587\u524D\u7F6E\u2014\u2014\u5F15\u7528\u8D8A\u7CBE\u51C6\uFF0CAgent \u8D8A\u667A\u80FD\u3002\u5927\u591A\u6570\u60C5\u51B5\u7528 'knowledge' \u7C7B\u578B\u5373\u53EF\u3002",
@@ -2339,7 +2348,7 @@ var chat_locale_default = {
2339
2348
  listAgents: "List agents",
2340
2349
  readAgent: "Read agent",
2341
2350
  loadSkill: "Load skill",
2342
- callAgent: "Call agent"
2351
+ startAgentRun: "Start agent run"
2343
2352
  },
2344
2353
  gemini: {
2345
2354
  title: "Image Generation",
@@ -2382,7 +2391,7 @@ var chat_locale_default = {
2382
2391
  loading: "Loading child runs\u2026",
2383
2392
  loadFailed: "Failed to load",
2384
2393
  retry: "Retry",
2385
- empty: "This dialog has no background child runs yet. They appear here after callAgent(background: true).",
2394
+ empty: "This dialog has no background child runs yet. They appear here after startAgentRun (async dispatch).",
2386
2395
  statusPending: "Pending",
2387
2396
  statusRunning: "Running",
2388
2397
  statusDone: "Done",
@@ -2696,7 +2705,7 @@ var chat_locale_default = {
2696
2705
  listAgents: "\u5217\u51FA\u52A9\u624B",
2697
2706
  readAgent: "\u8BFB\u53D6\u52A9\u624B",
2698
2707
  loadSkill: "\u52A0\u8F7D\u6280\u80FD",
2699
- callAgent: "\u8C03\u7528\u52A9\u624B"
2708
+ startAgentRun: "\u542F\u52A8\u5B50\u4EFB\u52A1"
2700
2709
  },
2701
2710
  gemini: {
2702
2711
  title: "\u56FE\u50CF\u751F\u6210",
@@ -2739,7 +2748,7 @@ var chat_locale_default = {
2739
2748
  loading: "\u6B63\u5728\u52A0\u8F7D\u5B50\u4EFB\u52A1\u2026",
2740
2749
  loadFailed: "\u52A0\u8F7D\u5931\u8D25",
2741
2750
  retry: "\u91CD\u8BD5",
2742
- empty: "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u540E\u53F0\u5B50\u4EFB\u52A1\u3002\u901A\u8FC7 callAgent(background: true) \u542F\u52A8\u540E\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002",
2751
+ empty: "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u540E\u53F0\u5B50\u4EFB\u52A1\u3002\u901A\u8FC7 startAgentRun \u5F02\u6B65\u6D3E\u53D1\u542F\u52A8\u540E\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002",
2743
2752
  statusPending: "\u6392\u961F\u4E2D",
2744
2753
  statusRunning: "\u8FD0\u884C\u4E2D",
2745
2754
  statusDone: "\u5DF2\u5B8C\u6210",
@@ -3043,7 +3052,7 @@ var chat_locale_default = {
3043
3052
  listAgents: "\u5217\u51FA\u52A9\u624B",
3044
3053
  readAgent: "\u8B80\u53D6\u52A9\u624B",
3045
3054
  loadSkill: "\u8F09\u5165\u6280\u80FD",
3046
- callAgent: "\u547C\u53EB\u52A9\u624B"
3055
+ startAgentRun: "\u555F\u52D5\u5B50\u4EFB\u52D9"
3047
3056
  },
3048
3057
  gemini: {
3049
3058
  title: "\u5716\u50CF\u751F\u6210",
@@ -3086,7 +3095,7 @@ var chat_locale_default = {
3086
3095
  loading: "\u6B63\u5728\u8F09\u5165\u5B50\u4EFB\u52D9\u2026",
3087
3096
  loadFailed: "\u8F09\u5165\u5931\u6557",
3088
3097
  retry: "\u91CD\u8A66",
3089
- empty: "\u76EE\u524D\u5C0D\u8A71\u9084\u6C92\u6709\u5F8C\u53F0\u5B50\u4EFB\u52D9\u3002\u900F\u904E callAgent(background: true) \u555F\u52D5\u5F8C\u6703\u51FA\u73FE\u5728\u9019\u88E1\u3002",
3098
+ empty: "\u76EE\u524D\u5C0D\u8A71\u9084\u6C92\u6709\u5F8C\u53F0\u5B50\u4EFB\u52D9\u3002\u900F\u904E startAgentRun \u975E\u540C\u6B65\u6D3E\u767C\u555F\u52D5\u5F8C\u6703\u51FA\u73FE\u5728\u9019\u88E1\u3002",
3090
3099
  statusPending: "\u6392\u968A\u4E2D",
3091
3100
  statusRunning: "\u904B\u884C\u4E2D",
3092
3101
  statusDone: "\u5DF2\u5B8C\u6210",
@@ -3334,7 +3343,7 @@ var chat_locale_default = {
3334
3343
  listAgents: "\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u4E00\u89A7",
3335
3344
  readAgent: "\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u8AAD\u307F\u53D6\u308A",
3336
3345
  loadSkill: "\u30B9\u30AD\u30EB\u3092\u8AAD\u307F\u8FBC\u307F",
3337
- callAgent: "\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u547C\u3073\u51FA\u3057"
3346
+ startAgentRun: "\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u5B9F\u884C"
3338
3347
  },
3339
3348
  gemini: {
3340
3349
  title: "\u753B\u50CF\u751F\u6210",
@@ -3377,7 +3386,7 @@ var chat_locale_default = {
3377
3386
  loading: "\u5B50\u30BF\u30B9\u30AF\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026",
3378
3387
  loadFailed: "\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
3379
3388
  retry: "\u518D\u8A66\u884C",
3380
- empty: "\u3053\u306E\u4F1A\u8A71\u306B\u306F\u307E\u3060\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u5B50\u30BF\u30B9\u30AF\u304C\u3042\u308A\u307E\u305B\u3093\u3002callAgent(background: true) \u3067\u8D77\u52D5\u3059\u308B\u3068\u3053\u3053\u306B\u8868\u793A\u3055\u308C\u307E\u3059\u3002",
3389
+ empty: "\u3053\u306E\u4F1A\u8A71\u306B\u306F\u307E\u3060\u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u5B50\u30BF\u30B9\u30AF\u304C\u3042\u308A\u307E\u305B\u3093\u3002startAgentRun\uFF08\u975E\u540C\u671F\uFF09\u3067\u8D77\u52D5\u3059\u308B\u3068\u3053\u3053\u306B\u8868\u793A\u3055\u308C\u307E\u3059\u3002",
3381
3390
  statusPending: "\u5F85\u6A5F\u4E2D",
3382
3391
  statusRunning: "\u5B9F\u884C\u4E2D",
3383
3392
  statusDone: "\u5B8C\u4E86",
@@ -5564,6 +5573,7 @@ var interface_locale_default = {
5564
5573
  },
5565
5574
  publicAgents: {
5566
5575
  loadFailed: "Failed to load AI assistants",
5576
+ removedFromPlaza: "{{count}} AI removed from the plaza",
5567
5577
  searchPlaceholder: "Search AI assistants...",
5568
5578
  sortLabel: "Sort:",
5569
5579
  sortRecommended: "Recommended",
@@ -6793,6 +6803,7 @@ var interface_locale_default = {
6793
6803
  },
6794
6804
  publicAgents: {
6795
6805
  loadFailed: "\u52A0\u8F7D\u5217\u8868\u5931\u8D25",
6806
+ removedFromPlaza: "\u6709 {{count}} \u4E2A AI \u5DF2\u4ECE\u5E7F\u573A\u4E0B\u67B6",
6796
6807
  searchPlaceholder: "\u641C\u7D22 AI...",
6797
6808
  sortLabel: "\u6392\u5E8F:",
6798
6809
  sortRecommended: "\u63A8\u8350",
@@ -8022,6 +8033,7 @@ var interface_locale_default = {
8022
8033
  },
8023
8034
  publicAgents: {
8024
8035
  loadFailed: "\u8F09\u5165\u5217\u8868\u5931\u6557",
8036
+ removedFromPlaza: "\u6709 {{count}} \u500B AI \u5DF2\u5F9E\u5EE3\u5834\u4E0B\u67B6",
8025
8037
  searchPlaceholder: "\u641C\u5C0B AI...",
8026
8038
  sortLabel: "\u6392\u5E8F:",
8027
8039
  sortRecommended: "\u63A8\u85A6",
@@ -9170,6 +9182,7 @@ var interface_locale_default = {
9170
9182
  },
9171
9183
  publicAgents: {
9172
9184
  loadFailed: "\u4E00\u89A7\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
9185
+ removedFromPlaza: "{{count}} \u500B\u306E AI \u304C\u5E83\u5834\u304B\u3089\u524A\u9664\u3055\u308C\u307E\u3057\u305F",
9173
9186
  searchPlaceholder: "AI\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u3092\u691C\u7D22...",
9174
9187
  sortLabel: "\u4E26\u3073\u66FF\u3048:",
9175
9188
  sortRecommended: "\u304A\u3059\u3059\u3081",
@@ -11227,304 +11240,6 @@ instance.use(initReactI18next).init({
11227
11240
  });
11228
11241
  var i18n_default = instance;
11229
11242
 
11230
- // packages/ai/tools/toolPacks.ts
11231
- var TOOL_PACKS = {
11232
- // L1 - 核心:交互 + 自我更新,所有 Agent 必有。
11233
- // rememberMemory 已移至「长期记忆」能力包(defaultEnabled:true),用户可单关。
11234
- CORE: ["ask_user", "read", "searchDialogMessages", "createDoc", "updateDoc", "search_workspace", "search_all_spaces", "updateSelf", "queryModelUsage", "queryUserGrowthReport", "createAgentAutomation", "notifyUser"],
11235
- // L2 - 联网搜索:与 CAPABILITY_PACKS「web-search」对齐。
11236
- // 社交读工具属于「social-reader」包,不得因 exa_search 被旁路注入。
11237
- LIGHT_WEB: ["exa_search", "fetchWebpage"],
11238
- // L3 - 深度浏览器:全套复杂网页交互(与「full-browser」包对齐)
11239
- FULL_BROWSER: [
11240
- "browser_openSession",
11241
- "browser_closeSession",
11242
- "browser_click",
11243
- "browser_typeText",
11244
- "browser_readContent",
11245
- "browser_selectOption",
11246
- "fetchWebpage"
11247
- ]
11248
- };
11249
- var SYSTEM_AGENT_CAPABILITY_PACKS = SYSTEM_AGENT_CAPABILITIES.map((capability) => ({ ...capability }));
11250
- var CAPABILITY_PACKS = [
11251
- ...SYSTEM_AGENT_CAPABILITY_PACKS,
11252
- {
11253
- id: "long-term-memory",
11254
- label: "\u957F\u671F\u8BB0\u5FC6",
11255
- description: "\u5BF9\u8BDD\u524D\u81EA\u52A8\u8F7D\u5165\u9AD8\u76F8\u5173\u8BB0\u5FC6\uFF0C\u5E76\u5141\u8BB8 agent \u6309\u9700\u67E5\u8BE2\u6216\u5199\u5165\u957F\u671F\u8BB0\u5FC6\u3002",
11256
- tools: ["queryMemory", "rememberMemory"],
11257
- defaultEnabled: true,
11258
- icon: "\u{1F9E0}"
11259
- },
11260
- {
11261
- id: "full-browser",
11262
- label: "\u6DF1\u5EA6\u6D4F\u89C8\u5668",
11263
- description: "\u5B8C\u6574\u6D4F\u89C8\u5668\u81EA\u52A8\u5316\uFF1A\u6253\u5F00\u9875\u9762\u3001\u70B9\u51FB\u3001\u8F93\u5165\u3001\u8BFB\u53D6\u52A8\u6001\u6E32\u67D3\u5185\u5BB9\u3002",
11264
- tools: TOOL_PACKS.FULL_BROWSER,
11265
- defaultEnabled: false,
11266
- icon: "\u{1F5A5}"
11267
- },
11268
- {
11269
- id: "social-reader",
11270
- label: "\u793E\u4EA4\u5185\u5BB9\u8BFB\u53D6",
11271
- description: "\u8BFB\u53D6 X/Twitter \u5E16\u5B50\u3001\u5C0F\u7EA2\u4E66\u7528\u6237\u753B\u50CF\u7B49\u793E\u4EA4\u5E73\u53F0\u5185\u5BB9\u3002",
11272
- tools: ["read_x_post", "read_xhs_profile"],
11273
- defaultEnabled: false,
11274
- icon: "\u{1F4E1}"
11275
- },
11276
- {
11277
- id: "code",
11278
- label: "\u4EE3\u7801\u6267\u884C",
11279
- description: "\u8BFB\u5199\u4EE3\u7801\u6587\u4EF6\u3001\u641C\u7D22\u4EE3\u7801\u5E93\u3001\u6267\u884C shell \u547D\u4EE4\u2014\u2014\u8BA9 agent \u80FD\u6539\u4EE3\u7801\u3001\u8DD1\u6D4B\u8BD5\u3002",
11280
- tools: [
11281
- "readFile",
11282
- "writeFile",
11283
- "editFile",
11284
- "applyEdit",
11285
- "applyLineEdits",
11286
- "codeSearch",
11287
- "globFiles",
11288
- "searchFiles",
11289
- "listFiles",
11290
- "execShell",
11291
- "launchProcess",
11292
- "listProcesses"
11293
- ],
11294
- defaultEnabled: false,
11295
- icon: "\u{1F4BB}",
11296
- promptPatch: `# \u4EE3\u7801\u6267\u884C\u80FD\u529B\u5305 \u2014 \u64CD\u4F5C\u7EAA\u5F8B
11297
-
11298
- ## \u6548\u7387\u4F18\u5148\uFF08\u7701 token\uFF09
11299
- - \u4E0D\u590D\u8FF0\u9700\u6C42\uFF0C\u4E0D\u89E3\u91CA\u300C\u6253\u7B97\u600E\u4E48\u505A\u300D\uFF0C\u76F4\u63A5\u52A8\u624B\u3002\u6539\u5B8C\u53EA\u7528\u4E00\u4E24\u53E5\u8BDD\u8BF4\u6E05\u300C\u6539\u4E86\u4EC0\u4E48\u3001\u53BB\u54EA\u770B\u300D\u3002
11300
- - \u601D\u8003\u7B80\u77ED\uFF1A\u5B9A\u4F4D\u95EE\u9898\u5373\u53EF\uFF0C\u4E0D\u505A\u957F\u7BC7\u63A8\u6F14\u3002
11301
- - \u5C0F\u6539\u52A8\u8D70\u6700\u77ED\u8DEF\u5F84\uFF1AsearchFiles/globFiles \u5B9A\u4F4D \u2192 readFile \u786E\u8BA4 \u2192 editFile \u7CBE\u786E\u66FF\u6362\u3002\u80FD\u4E00\u6B21\u547D\u4E2D\u5C31\u4E0D\u8981\u53CD\u590D\u8BFB\u6587\u4EF6\u3002
11302
- - \u5DF2\u7ECF\u77E5\u9053\u6587\u4EF6\u548C\u4F4D\u7F6E\u65F6\uFF0C\u8DF3\u8FC7\u591A\u4F59\u7684 search/read\uFF0C\u76F4\u63A5 edit\u3002
11303
- - \u7981\u6B62\u4E3A\u4E00\u4E2A\u5C0F\u6539\u52A8\u6574\u9875\u91CD\u5199\u6216\u8FDE\u5E26\u6539\u52A8\u672A\u547D\u4E2D\u7684\u90E8\u5206\u3002
11304
-
11305
- ## \u4EE3\u7801\u4FEE\u6539\u7EAA\u5F8B
11306
- - \u7F16\u8F91\u524D\u5148 readFile \u786E\u8BA4\u5F53\u524D\u5185\u5BB9\uFF0C\u907F\u514D stale hash \u9519\u8BEF\u3002
11307
- - \u53EA\u78B0\u4EFB\u52A1\u4E66\u5217\u51FA\u7684\u6587\u4EF6\uFF1B\u6539\u5B8C\u7528 \`git status --short\` \u81EA\u67E5\uFF0C\u82E5\u6539\u5230\u6E05\u5355\u5916\u6587\u4EF6\uFF0C\u5982\u5B9E\u62A5\u544A\u3002
11308
- - \u4E0D\u8981 \`git add\` / \`git commit\` / \`git push\` / \`git stash\` / \`git reset\` / \`git checkout\` / \`git clean\`\u2014\u2014\u6539\u52A8\u7559\u5728\u5DE5\u4F5C\u533A\uFF0C\u63D0\u4EA4\u7531\u8C03\u7528\u65B9\u9A8C\u6536\u540E\u5904\u7406\u3002\u4ED3\u5E93\u5E38\u6709\u591A\u4E2A\u4F1A\u8BDD\u5171\u7528\u4E00\u4E2A checkout\uFF0C\u4F60\u4E00\u63D0\u4EA4\u5C31\u4F1A\u628A\u522B\u4EBA\u7684\u5728\u9014\u6587\u4EF6\u5377\u8FDB\u6765\u3002
11309
- - \u53EA\u8DD1\u4EFB\u52A1\u91CC\u5217\u51FA\u7684\u6D4B\u8BD5\u6587\u4EF6\uFF0C\u4E0D\u8981\u8DD1 broader \u6D4B\u8BD5\uFF08broaden \u6D4B\u8BD5\u7684\u5931\u8D25\u662F\u9884\u5B58\u7684\uFF0C\u548C\u4F60\u7684\u6539\u52A8\u65E0\u5173\uFF09\u3002
11310
-
11311
- ## Review \u7EAA\u5F8B\uFF08commit \u524D\u786C\u95E8\uFF09
11312
- - \u9664 \u22642 \u6B65\u96F6\u903B\u8F91\u98CE\u9669\u7684\u673A\u68B0\u6539\u52A8\uFF08\u9519\u522B\u5B57/\u683C\u5F0F/CSS \u5FAE\u8C03\uFF09\u5916\uFF0C\u6240\u6709\u4EE3\u7801\u53D8\u66F4 commit \u524D\u5FC5\u987B\u5148\u6D3E**\u5176\u4ED6 agent**\uFF08\u4E0D\u540C\u6A21\u578B\u5BB6\u65CF\u4F18\u5148\uFF09review \u5DE5\u4F5C\u533A diff\uFF08\`git diff\`\uFF0C\u672A\u63D0\u4EA4\u7684\u6539\u52A8\uFF09\u3002reviewer \u4E0D\u53EF\u662F\u81EA\u5DF1\u3002\u65E0 review \u4E0D commit\u2014\u2014\u8FD9\u662F\u786C\u95E8\uFF0C\u4E0D\u662F\u5EFA\u8BAE\u3002
11313
- - \u6D3E\u53D1\u8D70 \`startAgentRun(agentKey, task, { ephemeral: true })\`\uFF08web/\u684C\u9762\u7AEF\u6CA1\u6709 nolo CLI\uFF0C\u6240\u6709 host \u90FD\u6709\u8FD9\u4E2A\u5DE5\u5177\uFF09\u3002ephemeral \u8BA9 review \u5B8C\u6210\u540E\u4E0D\u7559 dialog \u8BB0\u5F55\u3002
11314
- - task \u91CC\u5FC5\u987B\u5199\u660E\u5BA1\u67E5\u5BF9\u8C61\uFF08\`git diff\` \u770B\u5DE5\u4F5C\u533A\u6539\u52A8\uFF0C\u6216 \`git diff alpha...HEAD\` \u770B\u5DF2\u63D0\u4EA4\u6539\u52A8\uFF09\uFF0C\u5426\u5219 reviewer \u4E0D\u77E5\u9053\u5BA1\u4EC0\u4E48\u3002
11315
- - \u6309\u89D2\u8272\u52A0\u8F7D\u5BF9\u5E94 skill\uFF1Areviewer \u5148 \`loadSkill("coding-review")\` \u62FF\u901A\u7528\u6D41\u7A0B\uFF0C\u518D\u6309\u89D2\u8272 \`loadSkill("coding-review-<role>")\` \u62FF\u68C0\u67E5\u9879\u3002\u89D2\u8272\u6E05\u5355\uFF1Acode-quality\uFF08**\u5FC5\u8DD1**\uFF09/ architecture\uFF08**\u5355\u72EC\u6D3E\u53D1**\uFF0C\u4E2D\u7EA7\u4EE5\u4E0A\u95EE\u9898\uFF09/ security\uFF08\u6309\u9700 + \u5B89\u5168\u654F\u611F\u89E6\u53D1\u5FC5\u8DD1\uFF09/ frontend-ux\uFF08\u6D89\u53CA UI \u65F6\uFF09/ backend-data\uFF08\u6D89\u53CA server \u65F6\uFF09\u3002\u89D2\u8272\u5207\u5272\u7684\u76EE\u7684\u662F\u6CE8\u610F\u529B\u9694\u79BB\u2014\u2014\u6BCF\u4E2A\u89D2\u8272\u53EA\u76EF\u81EA\u5DF1\u7684\u68C0\u67E5\u9762\uFF0C\u6309\u9700\u542F\u7528\uFF0C\u907F\u514D\u4E00\u4E2A reviewer \u80CC\u6240\u6709\u89D2\u8272\u5BFC\u81F4\u6CE8\u610F\u529B\u7A00\u91CA\u3002
11316
- - Verdict \u6807\u51C6\uFF1AAPPROVE\uFF08\u65E0 CRITICAL \u6216 HIGH\uFF09\u2192 \u53EF commit\uFF1BWARNING\uFF08\u4EC5 HIGH\uFF09\u2192 \u62A5\u544A owner \u51B3\u5B9A\uFF1BBLOCK\uFF08\u6709 CRITICAL\uFF09\u2192 \u5FC5\u987B\u5148\u4FEE\u3002
11317
- - review \u53EF\u80FD\u591A\u8F6E\u6536\u655B\uFF08\u6709 finding\u2192\u4FEE\u2192\u518D\u5BA1\u2192\u76F4\u5230 APPROVE\uFF09\u3002\u6BCF\u8F6E review \u662F\u65E0\u4E0A\u4E0B\u6587\u7684\u2014\u2014reviewer \u53EA\u770B\u5F53\u524D\u5DE5\u4F5C\u533A diff\uFF0C\u4E0D\u5E26\u4E0A\u4E00\u8F6E finding \u8BB0\u5FC6\u3002
11318
- - \u82E5\u5904\u4E8E\u5355 Agent \u72EC\u5360\u73AF\u5883\u3001\u5176\u4ED6 agent \u4E0D\u53EF\u8FBE\u3001\u6216\u7528\u6237\u660E\u786E\u8981\u6C42\u76F4\u63A5\u63D0\u4EA4\uFF0C\u5141\u8BB8\u5E26\u539F\u56E0\u8DF3\u8FC7\uFF08commit message \u6CE8\u660E [no-review: \u539F\u56E0]\uFF09\uFF0C\u4F46\u9ED8\u8BA4\u5FC5\u987B\u6D3E review\u3002`
11319
- },
11320
- {
11321
- id: "skills",
11322
- label: "\u6280\u80FD\u52A0\u8F7D",
11323
- description: "\u6309\u540D\u52A0\u8F7D\u5DE5\u4F5C\u533A\u6280\u80FD\uFF08SKILL.md\uFF09\u5E76\u8BFB\u53D6\u6280\u80FD\u6587\u6863\u2014\u2014\u8BA9 agent \u5728\u9700\u8981\u65F6\u628A\u5BF9\u5E94\u6280\u80FD\u7684\u65B9\u6CD5\u8BBA\u3001\u547D\u4EE4\u548C\u6D41\u7A0B\u62C9\u8FDB\u4E0A\u4E0B\u6587\u518D\u6267\u884C\u3002",
11324
- tools: ["loadSkill", "readSkillDoc"],
11325
- defaultEnabled: true,
11326
- icon: "\u{1F4DA}"
11327
- },
11328
- {
11329
- id: "app-builder",
11330
- label: "\u5E94\u7528\u6784\u5EFA",
11331
- description: "\u6784\u5EFA/\u4FEE\u6539/\u53D1\u5E03 Web \u5E94\u7528\uFF1A\u8BFB\u53D6\u5E94\u7528\u6E90\u7801\u3001\u5B9A\u70B9\u4FEE\u6539\u3001\u9884\u68C0\u3001\u90E8\u7F72\uFF0C\u65E0\u9700\u7F16\u7A0B\u7ECF\u9A8C\u3002",
11332
- tools: [
11333
- "appRead",
11334
- "appFileList",
11335
- "appFileSearch",
11336
- "appFileRead",
11337
- "appFileReplace",
11338
- "appFileWrite",
11339
- "appPreflight",
11340
- "appDeploy",
11341
- "appList",
11342
- "appDelete",
11343
- "createTable",
11344
- "addTableRow",
11345
- "addTableRows",
11346
- "queryTableRows",
11347
- "updateTableRow",
11348
- "deleteTableRow",
11349
- "openAIGptImage"
11350
- ],
11351
- defaultEnabled: false,
11352
- icon: "\u{1F5A5}",
11353
- promptPatch: `# \u5E94\u7528\u6784\u5EFA\u80FD\u529B\u5305 \u2014 \u64CD\u4F5C\u7EAA\u5F8B
11354
-
11355
- ## \u6548\u7387\u4F18\u5148\uFF08\u7701 token\uFF09
11356
- - \u4E0D\u590D\u8FF0\u7528\u6237\u9700\u6C42\uFF0C\u4E0D\u89E3\u91CA\u4F60\u300C\u6253\u7B97\u600E\u4E48\u505A\u300D\uFF0C\u76F4\u63A5\u52A8\u624B\u3002\u6539\u5B8C\u53EA\u7528\u4E00\u4E24\u53E5\u8BDD\u8BF4\u6E05\u300C\u6539\u4E86\u4EC0\u4E48\u3001\u53BB\u54EA\u770B\u300D\u3002
11357
- - \u601D\u8003\u7B80\u77ED\uFF1A\u5B9A\u4F4D\u95EE\u9898\u5373\u53EF\uFF0C\u4E0D\u505A\u957F\u7BC7\u63A8\u6F14\u3002
11358
- - \u5C0F\u6539\u52A8\uFF08\u6539\u6587\u5B57\u3001\u989C\u8272\u3001\u95F4\u8DDD\u3001\u5706\u89D2\u3001\u5355\u4E2A\u7EC4\u4EF6\uFF09\u8D70\u6700\u77ED\u8DEF\u5F84\uFF1A\`appFileSearch\` \u6216 \`appFileRead\` \u5B9A\u4F4D \u2192 \`appFileReplace\` \u7CBE\u786E\u66FF\u6362 \u2192 \`appPreflight\` \u2192 \`appDeploy\`\u3002\u80FD\u4E00\u6B21\u547D\u4E2D\u5C31\u4E0D\u8981\u53CD\u590D\u8BFB\u6587\u4EF6\u3002
11359
- - \u5DF2\u7ECF\u77E5\u9053\u6587\u4EF6\u548C\u4F4D\u7F6E\u65F6\uFF0C\u8DF3\u8FC7\u591A\u4F59\u7684 search/read\uFF0C\u76F4\u63A5 replace\u3002
11360
- - \u7981\u6B62\u4E3A\u4E00\u4E2A\u5C0F\u6539\u52A8\u6574\u9875\u91CD\u5199\u6216\u8FDE\u5E26\u6539\u52A8\u672A\u547D\u4E2D\u7684\u90E8\u5206\u3002
11361
-
11362
- ## \u5B9A\u70B9\u4FEE\u6539
11363
- - \u5982\u679C\u4E0A\u4E0B\u6587\u91CC\u5E26\u6709\u7528\u6237\u300C\u9009\u4E2D\u7684\u5143\u7D20\u300D\uFF08cssPath / HTML \u7247\u6BB5 / \u6E90\u7801\u4F4D\u7F6E\uFF09\uFF0C\u76F4\u63A5\u636E\u6B64\u5B9A\u4F4D\uFF0C\u4E0D\u8981\u518D\u5168\u5C40\u641C\u7D22\u3002
11364
- - \u4FEE\u6539\u6536\u655B\u5728\u547D\u4E2D\u7684\u5143\u7D20\u53CA\u5176\u6837\u5F0F\u6765\u6E90\uFF08\u7EC4\u4EF6 / \u7C7B / design token\uFF09\u3002
11365
-
11366
- ## \u6301\u7EED\u8FED\u4EE3\u6D41\u7A0B
11367
- - \u7528\u6237\u8981\u6539\u529F\u80FD\u6216\u6837\u5F0F\u65F6\uFF0C\u5148\u7528 appList \u627E\u5230\u76EE\u6807\u5E94\u7528\uFF0C\u518D\u7528 appRead \u5224\u65AD\u5F53\u524D\u662F\u6E90\u7801\u5DE5\u4F5C\u533A\u8FD8\u662F\u90E8\u7F72\u4EA7\u7269\uFF1B\u4E00\u65E6\u62FF\u5230 appId\uFF0C\u540E\u7EED\u90FD\u5FC5\u987B\u590D\u7528\u540C\u4E00\u4E2A appId\u3002
11368
- - \u6BCF\u6B21\u4FEE\u6539\u540E\uFF1AappPreflight \u2192 appDeploy\uFF1BappDeploy \u5FC5\u987B\u7EE7\u7EED\u4F20\u540C\u4E00\u4E2A appId\u3002
11369
- - \u6536\u5230 repairPlan \u5C31\u76F4\u63A5\u4FEE\uFF1A\u6309\u8FD4\u56DE issues \u5B9A\u70B9\u4FEE\u590D\u5E76\u91CD\u65B0\u9884\u68C0\uFF0C\u4E0D\u8981\u6574\u7AD9\u91CD\u5199\uFF0C\u4E5F\u4E0D\u8981\u5148\u95EE\u7528\u6237\u8981\u4E0D\u8981\u4FEE\u3002
11370
-
11371
- ## Nolo React SSR \u7EF4\u62A4\u7EAA\u5F8B\uFF08\u5F53\u524D\u9ED8\u8BA4\u8DEF\u5F84\uFF09
11372
- - \u65B0\u5EFA\u548C\u7EF4\u62A4\u7684\u5E94\u7528\u4F18\u5148\u8D70 Nolo React SSR\uFF08framework: "nolo-react", renderMode: "ssr"\uFF09\u3002
11373
- - \u5F53 appRead \u8FD4\u56DE workspaceRef / sourceFiles / sourceOmitted \u65F6\uFF0C\u4E0D\u8981\u6574\u7AD9\u91CD\u5199\uFF1B\u4F7F\u7528\u53D7\u9650 workspace \u6587\u4EF6\u5DE5\u5177\uFF1AappFileList / appFileSearch / appFileRead / appFileReplace / appFileWrite\u3002
11374
- - \u5C0F\u6539\u52A8\u5FC5\u987B\u4F18\u5148 appFileReplace\uFF1B\u53EA\u6709\u65B0\u5EFA\u6587\u4EF6\u6216\u786E\u5B9E\u9700\u8981\u6574\u6587\u4EF6\u91CD\u5199\u65F6\u624D appFileWrite\u3002
11375
- - \u4E0D\u8981\u9759\u9ED8\u628A nolo-react \u5E94\u7528\u9000\u56DE react-spa \u6216\u5355\u6587\u4EF6 Worker\u3002
11376
- - \u89C6\u89C9\u5FAE\u8C03\u4F18\u5148\u6539 theme / tokens / design system\uFF1B\u65E7\u5199\u6CD5\u5E94\u7528\u53EF\u5148\u505A\u6700\u5C0F token \u8FC1\u79FB\uFF0C\u518D\u6539\u89C6\u89C9\u53C2\u6570\u3002
11377
-
11378
- ## \u8868\u5355 / \u6570\u636E\u6536\u96C6
11379
- - \u7559\u8A00\u3001\u8054\u7CFB\u8868\u5355\u3001\u9884\u7EA6\u3001\u8BA2\u9605\u3001\u53CD\u9988\u6536\u96C6\u4F18\u5148\u7528\u8868\u5DE5\u5177\uFF0C\u4E0D\u8981\u81EA\u5DF1\u53D1\u660E JSON \u6587\u4EF6\u5B58\u50A8\u3002
11380
- - \u516C\u5F00\u7F51\u9875\u8868\u5355\u5148 createTable\uFF0C\u5E76\u914D\u7F6E publicIntake\uFF08enabled\u3001slug\u3001allowedFields\u3001requiredFields\u3001\u53EF\u9009 honeypotField\uFF09\u3002
11381
- - \u516C\u5F00\u8BBF\u5BA2\u63D0\u4EA4\u53EA\u80FD\u8C03\u7528 /api/table/public-submit\uFF1B\u4E0D\u8981\u628A tenantId\u3001tableId\u3001token \u5199\u8FDB\u516C\u5F00\u5E94\u7528\u4EE3\u7801\u3002
11382
-
11383
- ## \u9879\u76EE\u7D20\u6750
11384
- - \u9996\u9875\u63D2\u753B\u3001\u5C01\u9762\u3001\u6A2A\u5E45\u3001\u6309\u94AE\u56FE\u6807\u7B49\u89C6\u89C9\u7D20\u6750\uFF0C\u4F18\u5148 openAIGptImage\uFF0C\u518D\u63A5\u5165\u5E94\u7528\u3002
11385
-
11386
- ## \u901A\u9053\u5F02\u5E38\u6B62\u635F
11387
- - \u5982\u679C\u5DE5\u5177\u8FD4\u56DE HTML / \u975E JSON / transport failure / retryable=false\uFF0C\u505C\u6B62\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF4\u660E\u662F\u5E73\u53F0\u901A\u9053\u5F02\u5E38\u3002
11388
-
11389
- ## \u7F3A\u5C11\u6E90\u7801\u8981\u8BF4\u660E\u98CE\u9669
11390
- - \u5982\u679C appRead \u8BFB\u51FA\u6765\u7684\u662F HTML \u58F3\u3001importmap\u3001\u538B\u7F29 bundle\uFF0C\u5FC5\u987B\u5148\u544A\u77E5\u7528\u6237\u5F53\u524D\u66F4\u50CF\u90E8\u7F72\u4EA7\u7269\u800C\u4E0D\u662F\u53EF\u7EF4\u62A4\u6E90\u7801\uFF0C\u5F97\u5230\u786E\u8BA4\u540E\u518D\u7EE7\u7EED\u5927\u6539\u3002
11391
-
11392
- ## \u90E8\u7F72\u5E94\u7B54\u6A21\u677F
11393
- \u90E8\u7F72\u6210\u529F\u540E\uFF1A
11394
- "\u2705 \u4F60\u7684\u5E94\u7528\u5DF2\u7ECF\u597D\u4E86\uFF01
11395
-
11396
- \u{1F517} \u8BBF\u95EE\u94FE\u63A5\uFF1A[URL]
11397
-
11398
- \u8FD9\u4E2A\u5E94\u7528\u53EF\u4EE5\u5E2E\u4F60 [\u4E00\u53E5\u8BDD\u529F\u80FD\u63CF\u8FF0]\u3002\u60F3\u8981\u4FEE\u6539\u6216\u6DFB\u52A0\u529F\u80FD\uFF0C\u76F4\u63A5\u544A\u8BC9\u6211\u5C31\u884C\uFF01"`
11399
- },
11400
- {
11401
- id: "video-transcription",
11402
- label: "\u89C6\u9891\u8F6C\u5199",
11403
- description: "\u8D34\u89C6\u9891\u94FE\u63A5\u5373\u53EF\u8F6C\u5199\u4E3A\u5E26\u6807\u70B9\u6587\u672C\u4E0E SRT\u3002\u652F\u6301 B \u7AD9\u5206 P\uFF08\u9ED8\u8BA4\u5168\u90E8\u5904\u7406\uFF09\u3001YouTube \u7B49\uFF1B\u6296\u97F3\u8BF7\u5728\u684C\u9762\u7AEF\u6D4F\u89C8\u5668\u4F7F\u7528\u3002",
11404
- tools: ["transcribeVideo"],
11405
- defaultEnabled: false,
11406
- icon: "\u{1F3AC}",
11407
- promptPatch: `# \u89C6\u9891\u8F6C\u5199\u80FD\u529B\u5305
11408
-
11409
- ## \u7528\u6CD5
11410
- - \u7528\u6237\u8D34\u4E0A\u89C6\u9891\u94FE\u63A5\u65F6\uFF0C\u76F4\u63A5\u8C03\u7528 \`transcribeVideo({ url })\`\uFF0C\u4E0D\u8981\u5148\u95EE\u8981\u4E0D\u8981\u8F6C\u5199\u3002
11411
- - B \u7AD9\u5206 P / \u5408\u96C6\uFF1A\u7F3A\u7701\u5904\u7406\u5168\u90E8\uFF1B\u82E5\u7528\u6237\u6307\u5B9A\u300C\u53EA\u8981\u7B2C 3\u30014 \u96C6\u300D\u5219\u4F20 \`p: [3, 4]\`\u3002
11412
- - \u8FD4\u56DE\u91CC\u7684 \`processedParts\` / \`availableParts\` \u5FC5\u987B\u5411\u7528\u6237\u8BF4\u6E05\u695A\uFF0C\u907F\u514D\u9759\u9ED8\u4E22\u5206 P\u3002
11413
- - \u6296\u97F3\u82E5\u62A5\u300C\u8BE5\u5E73\u53F0\u9700\u8981\u767B\u5F55\u6001\uFF0C\u8BF7\u5728\u684C\u9762\u7AEF\u6D4F\u89C8\u5668\u4E2D\u4F7F\u7528\u300D\uFF0C\u63D0\u793A\u7528\u6237\u6539\u8D70\u684C\u9762\u7AEF\u6D4F\u89C8\u80FD\u529B\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u4F20 cookie\u3002
11414
- `
11415
- }
11416
- ];
11417
- var CAPABILITY_PACK_BY_ID = CAPABILITY_PACKS.reduce(
11418
- (acc, pack) => {
11419
- acc[pack.id] = pack;
11420
- return acc;
11421
- },
11422
- {}
11423
- );
11424
- var PACK_MANAGED_TOOLS = new Set(
11425
- CAPABILITY_PACKS.flatMap((pack) => pack.tools)
11426
- );
11427
- var DEFAULT_ENABLED_PACKS = CAPABILITY_PACKS.filter(
11428
- (pack) => pack.defaultEnabled
11429
- ).map((pack) => pack.id);
11430
- var ALWAYS_ON_PACK_IDS = [
11431
- "long-term-memory",
11432
- "skills"
11433
- ];
11434
- function resolveEffectiveEnabledPacks(args) {
11435
- const base = args.enabledPacks ?? [];
11436
- if (args.declaredOnly === true) return [...base];
11437
- return [
11438
- .../* @__PURE__ */ new Set([
11439
- ...base,
11440
- ...base.length === 0 ? args.emptyFallbackPacks ?? [] : [],
11441
- ...args.hostPacks ?? [],
11442
- ...ALWAYS_ON_PACK_IDS
11443
- ])
11444
- ];
11445
- }
11446
- var SYSTEM_BUILTIN_SKILL_PACK_IDS = SYSTEM_AGENT_CAPABILITY_IDS;
11447
- var DEFAULT_MOUNT_SYSTEM_CAPABILITY_IDS = ["agent-orchestration"];
11448
- function getDefaultSystemCapabilityTools() {
11449
- const ids = DEFAULT_MOUNT_SYSTEM_CAPABILITY_IDS;
11450
- return SYSTEM_AGENT_CAPABILITY_PACKS.filter((pack) => ids.includes(pack.id)).flatMap((pack) => [...pack.tools]);
11451
- }
11452
- function addDefaultSystemCapabilityTools(toolNames) {
11453
- return [.../* @__PURE__ */ new Set([...toolNames, ...getDefaultSystemCapabilityTools()])];
11454
- }
11455
- function applySystemBuiltinSkillFilter(toolNames, systemBuiltinSkills) {
11456
- if (!systemBuiltinSkills) return toolNames;
11457
- const disabledToolSet = /* @__PURE__ */ new Set();
11458
- for (const packId of SYSTEM_BUILTIN_SKILL_PACK_IDS) {
11459
- const enabled = systemBuiltinSkills[packId];
11460
- if (enabled === false) {
11461
- const pack = CAPABILITY_PACK_BY_ID[packId];
11462
- if (pack) pack.tools.forEach((t) => disabledToolSet.add(t));
11463
- }
11464
- }
11465
- if (disabledToolSet.size === 0) return toolNames;
11466
- return toolNames.filter((t) => !disabledToolSet.has(t));
11467
- }
11468
- function expandEnabledPacks(enabledPacks, explicitTools = []) {
11469
- const packTools = (enabledPacks ?? []).map((id) => CAPABILITY_PACK_BY_ID[id]?.tools ?? []).flat();
11470
- return [.../* @__PURE__ */ new Set([...packTools, ...explicitTools ?? []])];
11471
- }
11472
- function expandEnabledPackPromptPatches(enabledPacks) {
11473
- return (enabledPacks ?? []).map((id) => CAPABILITY_PACK_BY_ID[id]?.promptPatch).filter((patch2) => typeof patch2 === "string" && patch2.length > 0);
11474
- }
11475
- function appendEnabledPackPromptPatches(prompt, enabledPacks) {
11476
- const patches = expandEnabledPackPromptPatches(enabledPacks);
11477
- if (patches.length === 0) return prompt ?? void 0;
11478
- const base = typeof prompt === "string" ? prompt.trim() : "";
11479
- const addition = patches.join("\n\n");
11480
- if (!base) return addition;
11481
- if (base.includes(addition)) return base;
11482
- return `${base}
11483
-
11484
- ${addition}`;
11485
- }
11486
- var FORCED_TOOLS = ["ask_user"];
11487
- function applyDisabledTools(toolNames, disabledTools) {
11488
- if (!Array.isArray(disabledTools) || disabledTools.length === 0) {
11489
- return toolNames;
11490
- }
11491
- const disabled = new Set(disabledTools);
11492
- const forced = new Set(FORCED_TOOLS);
11493
- return toolNames.filter((name) => !disabled.has(name) || forced.has(name));
11494
- }
11495
- var WEB_SEARCH_TOOL_NAMES = /* @__PURE__ */ new Set([
11496
- "fetchWebpage",
11497
- "exa_search",
11498
- "firecrawl_scrape",
11499
- "firecrawl_search"
11500
- ]);
11501
- function isWebSearchTool(name) {
11502
- return WEB_SEARCH_TOOL_NAMES.has(name);
11503
- }
11504
- function isBrowserTool(name) {
11505
- return name.startsWith("browser_");
11506
- }
11507
- function addDefaultLightWebToolsForConfiguredAgents(toolNames, agentConfig) {
11508
- const explicitToolNames = Array.isArray(
11509
- agentConfig?.toolSurface?.explicitToolNames
11510
- ) ? agentConfig.toolSurface.explicitToolNames : agentConfig?.toolNames;
11511
- if (!Array.isArray(explicitToolNames) || explicitToolNames.length === 0)
11512
- return toolNames;
11513
- const webSearch = explicitToolNames.some(isWebSearchTool);
11514
- if (!webSearch) return toolNames;
11515
- return [.../* @__PURE__ */ new Set([...toolNames, ...TOOL_PACKS.LIGHT_WEB])];
11516
- }
11517
- function applyDefaultWebToolPacks(args) {
11518
- const enhanced = new Set(args.toolNames);
11519
- if (!args.skipWeb && args.toolNames.some(isWebSearchTool)) {
11520
- TOOL_PACKS.LIGHT_WEB.forEach((t) => enhanced.add(t));
11521
- }
11522
- if (args.toolNames.some(isBrowserTool)) {
11523
- TOOL_PACKS.FULL_BROWSER.forEach((t) => enhanced.add(t));
11524
- }
11525
- return [...enhanced];
11526
- }
11527
-
11528
11243
  // packages/ai/tools/agent/createAgentTool.ts
11529
11244
  var HOSTED_EXEC_RUNTIME_TOOL_POLICY = {
11530
11245
  version: 1,
@@ -11532,7 +11247,7 @@ var HOSTED_EXEC_RUNTIME_TOOL_POLICY = {
11532
11247
  workspace: { mode: "lease" }
11533
11248
  };
11534
11249
  var findModelConfig = async (modelName, provider) => {
11535
- const { ALL_MODELS } = await import("./models-DJFSJ7SW.js");
11250
+ const { ALL_MODELS } = await import("./models-DB27UAE3.js");
11536
11251
  const name = toTrimmedString(modelName);
11537
11252
  const prov = toTrimmedString(provider ?? "");
11538
11253
  if (!name) return null;
@@ -11773,7 +11488,7 @@ var buildFormDataFromArgs = async (args) => {
11773
11488
  const trimmedModel = toTrimmedString(model);
11774
11489
  const trimmedProvider = toTrimmedString(provider);
11775
11490
  const modelConfig = await findModelConfig(trimmedModel, trimmedProvider);
11776
- const { getModelPricing } = await import("./getPricing-G7DLAST6.js");
11491
+ const { getModelPricing } = await import("./getPricing-WENPBVWH.js");
11777
11492
  const normalizedTools = tools ?? [];
11778
11493
  const resolvedRuntimeToolPolicy = runtimeToolPolicy ?? (normalizedTools.includes("execShell") ? HOSTED_EXEC_RUNTIME_TOOL_POLICY : void 0);
11779
11494
  const formData = {
@@ -12349,14 +12064,7 @@ var buildSkillDocFromArgs = (args) => {
12349
12064
  requiredSkills: normalizeStringArray(args.requiredSkills),
12350
12065
  recommendedSkills: normalizeStringArray(args.recommendedSkills),
12351
12066
  promptPatch: asOptionalTrimmedString(args.promptPatch),
12352
- budgetTier: normalizeSkillBudgetTier(args.budgetTier) ?? "medium",
12353
- dispatchPreferred: args.dispatchPreferred === true,
12354
- modalities: normalizeSkillModalities(args.modalities) ?? ["text"],
12355
- preferredAgents: normalizeStringArray(args.preferredAgents),
12356
- discover: normalizeStringArray(args.discoverKeywords)?.length || normalizeStringArray(args.discoverExamples)?.length ? {
12357
- keywords: normalizeStringArray(args.discoverKeywords),
12358
- examples: normalizeStringArray(args.discoverExamples)
12359
- } : void 0
12067
+ modalities: normalizeSkillModalities(args.modalities) ?? ["text"]
12360
12068
  };
12361
12069
  const evalCases = normalizeEvalCases(args.evalCases);
12362
12070
  const evalConfig = evalCases ? {
@@ -12483,35 +12191,11 @@ var createSkillDocFunctionSchema = {
12483
12191
  type: "string",
12484
12192
  description: "\u53EF\u9009\uFF1A\u9644\u52A0\u5230 system prompt \u7684\u6280\u80FD\u63D0\u793A\u3002"
12485
12193
  },
12486
- budgetTier: {
12487
- type: "string",
12488
- enum: ["low", "medium", "high"],
12489
- description: "\u53EF\u9009\uFF1A\u8BE5 skill \u7684\u9884\u7B97\u7B49\u7EA7\u3002"
12490
- },
12491
- dispatchPreferred: {
12492
- type: "boolean",
12493
- description: "\u53EF\u9009\uFF1A\u662F\u5426\u5EFA\u8BAE\u4F18\u5148\u8D70 agent dispatch \u800C\u4E0D\u662F\u76F4\u63A5\u672C agent \u6267\u884C\u3002"
12494
- },
12495
12194
  modalities: {
12496
12195
  type: "array",
12497
12196
  items: { type: "string", enum: ["text", "image", "video", "audio", "3d"] },
12498
12197
  description: "\u53EF\u9009\uFF1A\u8BE5 skill \u6D89\u53CA\u7684\u6A21\u6001\u3002"
12499
12198
  },
12500
- preferredAgents: {
12501
- type: "array",
12502
- items: { type: "string" },
12503
- description: "\u53EF\u9009\uFF1A\u66F4\u9002\u5408\u6267\u884C\u8BE5 skill \u7684 agent \u540D\u79F0\u6216 key\u3002"
12504
- },
12505
- discoverKeywords: {
12506
- type: "array",
12507
- items: { type: "string" },
12508
- description: "\u53EF\u9009\uFF1A\u89E6\u53D1/\u53D1\u73B0\u5173\u952E\u5B57\u3002"
12509
- },
12510
- discoverExamples: {
12511
- type: "array",
12512
- items: { type: "string" },
12513
- description: "\u53EF\u9009\uFF1A\u793A\u4F8B\u4EFB\u52A1\u6216\u95EE\u6CD5\u3002"
12514
- },
12515
12199
  evalCases: {
12516
12200
  type: "array",
12517
12201
  items: {
@@ -12914,8 +12598,6 @@ async function importSkillFunc(args, thunkApi) {
12914
12598
  description,
12915
12599
  triggerMode: "explicit",
12916
12600
  toolNames: normalizedTools,
12917
- budgetTier: "medium",
12918
- dispatchPreferred: false,
12919
12601
  modalities: ["text"]
12920
12602
  };
12921
12603
  const importedBody = [
@@ -12954,374 +12636,1207 @@ Imported from: ${url}` : ""
12954
12636
  });
12955
12637
  }
12956
12638
 
12957
- // packages/ai/tools/loadSkillTool.ts
12958
- var loadSkillFunctionSchema = {
12959
- name: "loadSkill",
12960
- description: [
12961
- "\u6309\u540D\u79F0\u52A0\u8F7D\u4E00\u4E2A\u5DF2\u4FDD\u5B58\u7684 skill \u6587\u6863\uFF0C\u8FD4\u56DE\u5176\u5B8C\u6574\u6307\u4EE4\u6B63\u6587\u3002",
12962
- "name \u4F7F\u7528 skill \u4FDD\u5B58\u65F6\u5199\u5165 skill-config \u7684 name\uFF08\u4E5F\u63A5\u53D7 skillId\uFF09\u3002",
12963
- "\u627E\u4E0D\u5230\u5BF9\u5E94 skill \u65F6\u8FD4\u56DE\u5F53\u524D\u53EF\u7528\u7684 skill \u540D\u79F0\u5217\u8868\uFF08\u4E0D\u62A5\u9519\uFF09\u3002",
12964
- '\u7CFB\u7EDF\u5185\u7F6E\u5199\u4EE3\u7801\u6280\u80FD\uFF1A\u5BF9\u8BDD\u8F6C\u5411\u5199\u4EE3\u7801\u65F6\u7528 loadSkill("coding") \u8F7D\u5165\u5199\u4EE3\u7801\u80FD\u529B\u4E0E\u4EE3\u7801\u5BA1\u67E5\u7EAA\u5F8B\uFF08\u542B review \u89D2\u8272\u5207\u5272\uFF09\u3002'
12965
- ].join("\n"),
12966
- parameters: {
12967
- type: "object",
12968
- properties: {
12969
- name: {
12970
- type: "string",
12971
- description: "\u8981\u52A0\u8F7D\u7684 skill \u540D\u79F0\u3002"
12972
- }
12973
- },
12974
- required: ["name"]
12639
+ // packages/ai/skills/specialistSkills.ts
12640
+ var SPECIALIST_SKILL_SLUGS = [
12641
+ "feedback",
12642
+ "agent-creator",
12643
+ "app-builder"
12644
+ ];
12645
+ function deterministicId(prefix, seed) {
12646
+ let h = 2166136261;
12647
+ for (let i = 0; i < seed.length; i++) {
12648
+ h ^= seed.charCodeAt(i);
12649
+ h = h * 16777619 >>> 0;
12975
12650
  }
12976
- };
12977
- var getRuntime = (thunkApi) => {
12978
- const state = thunkApi?.getState?.();
12979
- return state ? selectRuntimeSnapshot(state) : null;
12980
- };
12981
- var authHeaders = (token) => token ? { Authorization: `Bearer ${token}` } : {};
12982
- async function readRemoteRecord(args) {
12983
- const serverBase = normalizeServerOrigin(args.serverBase);
12984
- if (!serverBase || !args.token) return null;
12985
- const response = await fetch(
12986
- `${serverBase}/api/v1/db/read/${encodeURIComponent(args.dbKey)}?includeDeleted=true`,
12987
- { headers: authHeaders(args.token) }
12988
- );
12989
- if (!response.ok) return null;
12990
- const payload = await response.json().catch(() => null);
12991
- return payload?.data ?? payload;
12651
+ const suffix = h.toString(36).toUpperCase().padStart(14, "0");
12652
+ return (prefix + suffix).slice(0, 26);
12992
12653
  }
12993
- function matchSkillCandidate(candidates, requestedName) {
12994
- return candidates.find(
12995
- (candidate) => candidate.name === requestedName || candidate.skillId === requestedName
12996
- );
12654
+ function normalizeSkillSeed(input) {
12655
+ return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
12997
12656
  }
12998
- function collectSkillCandidatesFromSpace(space) {
12999
- if (!space?.contents || typeof space.contents !== "object") return [];
13000
- const candidates = [];
13001
- for (const [entryKey, value] of Object.entries(space.contents)) {
13002
- if (!isRecord(value)) continue;
13003
- const skillSummary = value.skillSummary;
13004
- if (!isSkillSummaryMarker(skillSummary)) continue;
13005
- const name = asTrimmedString(skillSummary.name);
13006
- if (!name) continue;
13007
- candidates.push({
13008
- dbKey: entryKey,
13009
- name,
13010
- skillId: asOptionalTrimmedString(skillSummary.skillId) ?? void 0
13011
- });
13012
- }
13013
- return candidates;
12657
+ function buildSpecialistSkillId(slug) {
12658
+ return deterministicId("01SK", normalizeSkillSeed(slug) || slug);
13014
12659
  }
13015
- function extractSkillBody(page) {
13016
- return parseSkillDocProtocol(page?.content ?? "").content;
12660
+ function buildSpecialistSkillPageKey(userId, slug) {
12661
+ return `page-${userId}-${buildSpecialistSkillId(slug)}`;
13017
12662
  }
13018
- async function listSkillCandidates(thunkApi) {
13019
- const runtime = getRuntime(thunkApi);
13020
- const serverBase = runtime?.currentServer;
13021
- const token = runtime?.currentToken;
13022
- const userId = runtime?.currentUserId;
13023
- if (!serverBase || !token || !userId) return [];
13024
- const membershipsResponse = await fetch(
13025
- `${normalizeServerOrigin(serverBase)}/rpc/getUserSpaceMemberships`,
13026
- {
13027
- method: "POST",
13028
- headers: {
13029
- "Content-Type": "application/json",
13030
- ...authHeaders(token)
13031
- },
13032
- body: JSON.stringify({ userId })
13033
- }
13034
- ).catch(() => null);
13035
- if (!membershipsResponse?.ok) return [];
13036
- const memberships = await membershipsResponse.json().catch(() => []);
13037
- if (!Array.isArray(memberships)) return [];
13038
- const candidates = [];
13039
- for (const membership of memberships) {
13040
- const spaceId = asTrimmedString(membership?.spaceId);
13041
- if (!spaceId) continue;
13042
- const space = await readRemoteRecord({
13043
- serverBase,
13044
- token,
13045
- dbKey: createSpaceKey.space(spaceId)
13046
- });
13047
- if (!space) continue;
13048
- candidates.push(...collectSkillCandidatesFromSpace(space));
12663
+ var SPECIALIST_SKILL_SEEDS = [
12664
+ {
12665
+ slug: "feedback",
12666
+ title: "feedback",
12667
+ description: "\u53CD\u9988\u6536\u96C6\uFF1A\u628A\u7528\u6237\u7684\u529F\u80FD\u9700\u6C42\u3001\u95EE\u9898\u53CD\u9988\u548C\u4F53\u9A8C\u5EFA\u8BAE\u89C4\u8303\u8BB0\u5F55\u5230\u7528\u6237\u53CD\u9988\u8868\uFF1B\u7D27\u6025\u53CD\u9988\u540C\u65F6\u5199\u5165\u4EFB\u52A1\u770B\u677F\u5E76\u901A\u77E5\u3002",
12668
+ body: [
12669
+ "\u4F60\u662F\u201C\u53CD\u9988\u5165\u53E3\u201DAgent\uFF0C\u8D1F\u8D23\u6536\u96C6\u7528\u6237\u7684\u65B0\u529F\u80FD\u9700\u6C42\u3001\u95EE\u9898\u53CD\u9988\u548C\u4F53\u9A8C\u5EFA\u8BAE\uFF0C\u5E76\u5C06\u5176\u89C4\u8303\u8BB0\u5F55\u5230\u6307\u5B9A\u8868\u683C\u4E2D\u3002",
12670
+ "",
12671
+ "\u4F60\u7684\u76EE\u6807\uFF1A",
12672
+ "1. \u4E3B\u52A8\u5F15\u5BFC\u7528\u6237\u63CF\u8FF0\u9047\u5230\u7684\u95EE\u9898\u3001\u60F3\u8981\u7684\u65B0\u529F\u80FD\u6216\u6539\u8FDB\u5EFA\u8BAE\u3002",
12673
+ "2. \u6BCF\u6B21\u6536\u5230\u53CD\u9988\u540E\uFF0C\u5148\u505A\u6781\u7B80\u6F84\u6E05\uFF1B\u5982\u679C\u4FE1\u606F\u5DF2\u7ECF\u8DB3\u591F\uFF0C\u5C31\u4E0D\u8981\u8FFD\u95EE\u8FC7\u591A\u3002",
12674
+ "3. \u5C06\u53CD\u9988\u6574\u7406\u6210\u7ED3\u6784\u5316\u4FE1\u606F\uFF0C\u5199\u5165\u201C\u7528\u6237\u53CD\u9988\u201D\u8868\u3002",
12675
+ `4. \u5982\u679C\u53CD\u9988\u8FBE\u5230\u201C\u7D27\u6025\u201D\u7EA7\u522B\uFF0C\u9664\u5199\u5165\u7528\u6237\u53CD\u9988\u8868\u5916\uFF0C\u8FD8\u8981\u76F4\u63A5\u5199\u5165 Nolo \u4EFB\u52A1\u770B\u677F\uFF0C\u5E76\u901A\u77E5\u7528\u6237 ${nolotusId}\u3002`,
12676
+ "5. \u8BB0\u5F55\u63D0\u4EA4\u53CD\u9988\u7684\u7528\u6237 ID\uFF0C\u65B9\u4FBF\u4EFB\u52A1\u5B8C\u6210\u6216\u8FDB\u5165 main \u540E\u901A\u77E5\u539F\u7528\u6237\u3002",
12677
+ "6. \u56DE\u590D\u98CE\u683C\u7B80\u6D01\u3001\u81EA\u7136\u3001\u50CF\u4EA7\u54C1\u56E2\u961F\u7684\u53CD\u9988\u6536\u96C6\u5165\u53E3\u3002",
12678
+ "",
12679
+ "\u5DE5\u4F5C\u89C4\u5219\uFF1A",
12680
+ "- \u4F18\u5148\u5224\u65AD\u53CD\u9988\u7C7B\u578B\uFF1A\u529F\u80FD\u9700\u6C42 / \u95EE\u9898\u53CD\u9988 / \u4F53\u9A8C\u5EFA\u8BAE / \u5176\u4ED6\u3002",
12681
+ "- \u9ED8\u8BA4\u72B6\u6001\u5199\u4E3A\u201C\u5F85\u5904\u7406\u201D\u3002",
12682
+ "- \u6839\u636E\u5185\u5BB9\u7C97\u7565\u5224\u65AD\u4F18\u5148\u7EA7\uFF1A",
12683
+ " - \u6570\u636E\u4E22\u5931\u3001\u65E0\u6CD5\u767B\u5F55\u3001\u65E0\u6CD5\u6253\u5F00\u4E3B\u5165\u53E3\u3001\u6838\u5FC3\u7F16\u8F91/\u521B\u5EFA/\u652F\u4ED8/\u4FDD\u5B58\u5B8C\u5168\u4E0D\u53EF\u7528\u3001\u963B\u65AD\u5927\u90E8\u5206\u7528\u6237\u6838\u5FC3\u6D41\u7A0B -> \u7D27\u6025",
12684
+ " - \u660E\u663E\u5F71\u54CD\u6B63\u5E38\u4F7F\u7528\u3001\u65E0\u6CD5\u5B8C\u6210\u67D0\u4E2A\u6838\u5FC3\u6D41\u7A0B\u3001\u4E25\u91CD\u4FDD\u5B58\u5931\u8D25 -> \u9AD8",
12685
+ " - \u4E00\u822C bug\u3001\u660E\u786E\u9700\u6C42\u3001\u5F71\u54CD\u5E38\u7528\u7F16\u8F91/\u521B\u5EFA\u6D41\u7A0B -> \u4E2D",
12686
+ " - \u666E\u901A\u5EFA\u8BAE\u6216\u8F7B\u5FAE\u4F53\u9A8C\u95EE\u9898 -> \u4F4E",
12687
+ "- \u5982\u679C\u7CFB\u7EDF\u6216\u5DE5\u5177\u4E0A\u4E0B\u6587\u80FD\u63D0\u4F9B\u5F53\u524D\u7528\u6237 ID\uFF0C\u628A\u5B83\u5199\u5165 submitterUserId\uFF1B\u5982\u679C\u770B\u4E0D\u5230\u7528\u6237 ID\uFF0C\u53EF\u4EE5\u7559\u7A7A\uFF0C\u670D\u52A1\u7AEF\u4F1A\u515C\u5E95\u8865\u5199\u3002",
12688
+ "- \u5982\u679C\u7528\u6237\u6CA1\u6709\u63D0\u4F9B\u8054\u7CFB\u65B9\u5F0F\uFF0C\u4E0D\u8981\u5F3A\u6C42\uFF0C\u53EF\u7559\u7A7A\u3002",
12689
+ "- \u5982\u679C\u7528\u6237\u63D0\u4F9B\u4E86\u7AEF\u3001\u9875\u9762\u3001\u7248\u672C\u3001\u670D\u52A1\u5668\u3001\u6D4F\u89C8\u5668\u3001\u622A\u56FE\u8BF4\u660E\u3001\u590D\u73B0\u6B65\u9AA4\u3001\u671F\u671B\u7ED3\u679C\u3001\u5B9E\u9645\u7ED3\u679C\uFF0C\u8981\u5C3D\u91CF\u5199\u8FDB\u5BF9\u5E94\u5B57\u6BB5\u3002",
12690
+ "- \u5982\u679C\u7F3A\u5C11\u5173\u952E\u4FE1\u606F\u4F46\u4ECD\u80FD\u7406\u89E3\u6838\u5FC3\u53CD\u9988\uFF0C\u5148\u8BB0\u5F55\uFF0C\u4E0D\u8981\u56E0\u4E3A\u5B57\u6BB5\u4E0D\u5168\u800C\u963B\u585E\u3002",
12691
+ "- source \u56FA\u5B9A\u5199\u201C\u53CD\u9988\u5165\u53E3\u201D\u3002",
12692
+ "- createdAtNote \u5199\u201C\u7531\u53CD\u9988\u5165\u53E3\u8BB0\u5F55\u201D\u3002",
12693
+ "",
12694
+ "\u666E\u901A\u5199\u8868\u89C4\u5219\uFF1A",
12695
+ "- \u975E\u7D27\u6025\u53CD\u9988\u53EA\u8C03\u7528\u4E00\u6B21 addTableRow\uFF0C\u5199\u5165\u7528\u6237\u53CD\u9988\u8868\uFF1B\u6210\u529F\u5199\u5165\u540E\u4E0D\u8981\u91CD\u590D\u5199\u5165\u540C\u4E00\u5185\u5BB9\u3002",
12696
+ `- \u4F7F\u7528 addTableRow \u5DE5\u5177\uFF0C\u628A\u53CD\u9988\u5199\u5165 dbKey \u4E3A meta-${nolotusId}-01NOLOFEEDBACKT000000000R1 \u7684\u8868\u3002`,
12697
+ `- \u663E\u5F0F\u4F20\u5165 tenantId="${nolotusId}" \u548C tableId="01NOLOFEEDBACKT000000000R1"\u3002`,
12698
+ "- \u5B57\u6BB5\u6620\u5C04\uFF1A",
12699
+ " - content: \u7528\u6237\u53CD\u9988\u5185\u5BB9\u7684\u7B80\u6D01\u6574\u7406\u7248\uFF0C\u4FDD\u7559\u5177\u4F53\u5BF9\u8C61\u548C\u75C7\u72B6",
12700
+ " - feedbackType: \u53CD\u9988\u7C7B\u578B",
12701
+ " - status: \u56FA\u5B9A\u4E3A\u201C\u5F85\u5904\u7406\u201D",
12702
+ " - priority: \u6309\u89C4\u5219\u5224\u65AD",
12703
+ " - contact: \u7528\u6237\u4E3B\u52A8\u63D0\u4F9B\u7684\u8054\u7CFB\u65B9\u5F0F\uFF0C\u6CA1\u6709\u5C31\u7559\u7A7A",
12704
+ " - source: \u56FA\u5B9A\u4E3A\u201C\u53CD\u9988\u5165\u53E3\u201D",
12705
+ " - submitterUserId: \u5F53\u524D\u63D0\u4EA4\u53CD\u9988\u7684\u7528\u6237 ID\uFF1B\u770B\u4E0D\u5230\u5C31\u7559\u7A7A\uFF0C\u670D\u52A1\u7AEF\u4F1A\u8865\u5199",
12706
+ " - environment: \u7528\u6237\u4E3B\u52A8\u63D0\u5230\u7684\u7AEF\u3001\u670D\u52A1\u5668\u3001\u9875\u9762\u3001\u6D4F\u89C8\u5668\u3001\u7CFB\u7EDF\u6216\u7248\u672C\uFF1B\u6CA1\u6709\u5C31\u7559\u7A7A",
12707
+ " - reproductionSteps: \u7528\u6237\u63CF\u8FF0\u7684\u590D\u73B0\u6B65\u9AA4\uFF1B\u6CA1\u6709\u5C31\u7559\u7A7A",
12708
+ " - expectedResult: \u7528\u6237\u8868\u8FBE\u7684\u671F\u671B\u884C\u4E3A\uFF1B\u6CA1\u6709\u5C31\u7559\u7A7A",
12709
+ " - actualResult: \u7528\u6237\u8868\u8FBE\u7684\u5B9E\u9645\u5F02\u5E38\uFF1B\u6CA1\u6709\u5C31\u7559\u7A7A",
12710
+ " - userImpact: \u5BF9\u7528\u6237\u6D41\u7A0B\u7684\u5F71\u54CD\uFF1B\u6CA1\u6709\u5C31\u6839\u636E\u5185\u5BB9\u7B80\u77ED\u5F52\u7EB3",
12711
+ " - createdAtNote: \u56FA\u5B9A\u4E3A\u201C\u7531\u53CD\u9988\u5165\u53E3\u8BB0\u5F55\u201D",
12712
+ "",
12713
+ "\u7D27\u6025\u53CD\u9988\u989D\u5916\u89C4\u5219\uFF1A",
12714
+ "- \u5F53 priority \u5224\u65AD\u4E3A\u201C\u7D27\u6025\u201D\u65F6\uFF0C\u5141\u8BB8\u989D\u5916\u8C03\u7528\u4E00\u6B21 addTableRow\uFF0C\u628A\u540C\u4E00\u4E8B\u9879\u76F4\u63A5\u5199\u5165 Nolo \u4EFB\u52A1\u770B\u677F\u3002",
12715
+ `- \u4EFB\u52A1\u770B\u677F\u56FA\u5B9A\u4E3A tenantId="${nolotusId}", tableId="NOLOTASKBOARD", dbKey="meta-${nolotusId}-NOLOTASKBOARD"\u3002`,
12716
+ "- \u4EFB\u52A1\u770B\u677F\u5B57\u6BB5\uFF1A",
12717
+ " - title: \u7528\u201CURGENT \u53CD\u9988\uFF1A\u201D\u5F00\u5934\uFF0C\u540E\u63A5\u95EE\u9898\u4E3B\u9898",
12718
+ " - status: \u201C\u5F85\u5904\u7406\u201D",
12719
+ " - priority: \u201C\u7D27\u6025\u201D",
12720
+ " - executionMode: \u201C\u7ACB\u5373\u6267\u884C\u201D",
12721
+ " - owner: \u201Cnolo \u9879\u76EE\u7ECF\u7406\u201D",
12722
+ " - source: \u201C\u53CD\u9988\u5165\u53E3\u201D",
12723
+ " - feedbackSubmitterUserId: \u5F53\u524D\u63D0\u4EA4\u53CD\u9988\u7684\u7528\u6237 ID\uFF1B\u770B\u4E0D\u5230\u5C31\u7559\u7A7A\uFF0C\u670D\u52A1\u7AEF\u4F1A\u8865\u5199",
12724
+ " - acceptance: \u590D\u8FF0\u53EF\u9A8C\u8BC1\u7684\u4FEE\u590D\u6807\u51C6",
12725
+ " - progress: \u201C\u7531\u53CD\u9988\u5165\u53E3\u6839\u636E\u7D27\u6025\u53CD\u9988\u81EA\u52A8\u5165\u8868\uFF0C\u7B49\u5F85\u9879\u76EE\u7ECF\u7406\u5206\u6D3E\u3002\u201D",
12726
+ " - codeStatus: \u201C\u672A\u5F00\u59CB\u201D",
12727
+ "- \u7D27\u6025\u53CD\u9988\u5199\u5165\u4EFB\u52A1\u8868\u540E\uFF0C\u8C03\u7528 notifyUser\uFF1A",
12728
+ " - title: \u201C\u7D27\u6025\u53CD\u9988\u5DF2\u8FDB\u5165\u4EFB\u52A1\u8868\u201D",
12729
+ " - message: \u7B80\u8981\u8BF4\u660E\u53CD\u9988\u5185\u5BB9\u548C\u4EFB\u52A1\u8868\u72B6\u6001",
12730
+ " - severity: \u201Ccritical\u201D",
12731
+ ` - targetUserId: "${nolotusId}"`,
12732
+ "- \u5982\u679C notifyUser \u5DE5\u5177\u8FD4\u56DE\u9519\u8BEF\uFF0C\u4E0D\u8981\u91CD\u590D\u5199\u4EFB\u52A1\u8868\uFF1B\u5728\u56DE\u590D\u4E2D\u8BF4\u660E\u201C\u5DF2\u8FDB\u5165\u4EFB\u52A1\u8868\uFF0C\u901A\u77E5\u53D1\u9001\u5931\u8D25/\u5F85\u91CD\u8BD5\u201D\u3002",
12733
+ "",
12734
+ "\u4EA4\u4E92\u89C4\u5219\uFF1A",
12735
+ "- \u5982\u679C\u7528\u6237\u53EA\u8BF4\u201C\u6709\u95EE\u9898\u201D\u201C\u60F3\u63D0\u9700\u6C42\u201D\u8FD9\u7C7B\u4E0D\u5B8C\u6574\u8868\u8FBE\uFF0C\u5148\u7528\u4E00\u53E5\u8BDD\u8FFD\u95EE\u6700\u5173\u952E\u7684\u4FE1\u606F\u3002",
12736
+ "- \u5982\u679C\u7528\u6237\u5DF2\u7ECF\u6E05\u695A\u63CF\u8FF0\u95EE\u9898\u6216\u9700\u6C42\uFF0C\u76F4\u63A5\u8BB0\u5F55\uFF0C\u4E0D\u8981\u8FDB\u884C\u5197\u957F\u5206\u6790\u3002",
12737
+ "- \u6210\u529F\u8BB0\u5F55\u540E\uFF0C\u660E\u786E\u544A\u8BC9\u7528\u6237\u201C\u5DF2\u7ECF\u5E2E\u4F60\u8BB0\u4E0B\u201D\uFF0C\u5E76\u7528\u4E00\u53E5\u8BDD\u590D\u8FF0\u6838\u5FC3\u5185\u5BB9\u3002",
12738
+ "- \u7D27\u6025\u53CD\u9988\u6210\u529F\u8FDB\u5165\u4EFB\u52A1\u8868\u540E\uFF0C\u544A\u8BC9\u7528\u6237\u201C\u5DF2\u6309\u7D27\u6025\u53CD\u9988\u8FDB\u5165\u4EFB\u52A1\u8868\u201D\u3002",
12739
+ "- \u4E0D\u8981\u627F\u8BFA\u4E00\u5B9A\u4FEE\u590D\u3001\u4E00\u5B9A\u5F00\u53D1\uFF0C\u53EA\u627F\u8BFA\u201C\u5DF2\u8BB0\u5F55\u53CD\u9988\u201D\u6216\u201C\u5DF2\u8FDB\u5165\u4EFB\u52A1\u8868\u201D\u3002"
12740
+ ].join("\n"),
12741
+ toolNames: ["addTableRow", "notifyUser"]
12742
+ },
12743
+ {
12744
+ slug: "agent-creator",
12745
+ title: "agent-creator",
12746
+ description: "\u521B\u5EFA Agent\uFF1A\u901A\u8FC7\u5BF9\u8BDD\u628A\u7528\u6237\u7684\u60F3\u6CD5\u62C6\u6210 prompt\u3001\u77E5\u8BC6\u3001\u5DE5\u5177\u3001skill/workflow \u548C eval\uFF0C\u751F\u6210\u53EF\u9884\u89C8\u8349\u7A3F\u5E76\u5728\u7528\u6237\u786E\u8BA4\u540E\u521B\u5EFA\u771F\u5B9E Agent\u3002",
12747
+ body: [
12748
+ "\u4F60\u662F Nolo \u7684 AI \u521B\u5EFA\u52A9\u624B\uFF0C\u53EA\u8D1F\u8D23\u901A\u8FC7\u5BF9\u8BDD\u5E2E\u52A9\u7528\u6237\u521B\u5EFA\u6216\u8C03\u6574\u4E00\u4E2A\u65B0\u7684 Agent\u3002",
12749
+ "\u6838\u5FC3\u539F\u5219\uFF1AAgent = prompt + knowledge + tools + skills/workflows + eval \u7684\u53EF\u8FD0\u884C\u5C01\u88C5\u3002",
12750
+ "\u521B\u5EFA\u6D41\u7A0B\u8981\u5E2E\u52A9\u7528\u6237\u628A\u4E13\u4E1A\u7ECF\u9A8C\u62C6\u5230\u5DF2\u6709\u8D44\u4EA7\u91CC\uFF0C\u4E0D\u8981\u628A\u6240\u6709\u7ECF\u9A8C\u90FD\u585E\u8FDB prompt\u3002",
12751
+ "\u5148\u7406\u89E3\u7528\u6237\u60F3\u8BA9\u8FD9\u4E2A AI \u670D\u52A1\u8C01\u3001\u5B8C\u6210\u4EC0\u4E48\u4EFB\u52A1\u3001\u4F7F\u7528\u4EC0\u4E48\u8BED\u6C14\u3001\u9700\u8981\u54EA\u4E9B\u80FD\u529B\u3001\u662F\u5426\u9700\u8981\u77E5\u8BC6\u5F15\u7528\uFF0C\u4EE5\u53CA\u662F\u5426\u9002\u5408\u516C\u5F00\u3002",
12752
+ "\u62C6\u89E3\u80FD\u529B\u65F6\u533A\u5206\uFF1Aprompt \u8D1F\u8D23\u89D2\u8272\u548C\u884C\u4E3A\u8FB9\u754C\uFF1Bknowledge/references \u8D1F\u8D23\u8D44\u6599\u6765\u6E90\uFF1Btools \u8D1F\u8D23\u52A8\u4F5C\uFF1Bskills/workflows \u8D1F\u8D23\u7A33\u5B9A\u6D41\u7A0B\u548C\u4E13\u5BB6\u65B9\u6CD5\uFF1Beval \u8D1F\u8D23\u6210\u529F/\u5931\u8D25\u6837\u4F8B\u548C\u9A8C\u6536\u3002",
12753
+ "\u5F53\u4FE1\u606F\u8DB3\u591F\u5F62\u6210\u521D\u7248\u914D\u7F6E\u65F6\uFF0C\u5148\u8C03\u7528 prepareAgentDraft\uFF0C\u751F\u6210\u53EF\u9884\u89C8\u8349\u7A3F\uFF1B\u4FE1\u606F\u4E0D\u8DB3\u65F6\u6BCF\u6B21\u53EA\u95EE\u4E00\u4E2A\u5173\u952E\u95EE\u9898\u3002",
12754
+ "prepareAgentDraft \u53EA\u751F\u6210\u8349\u7A3F\uFF0C\u4E0D\u4EE3\u8868\u5DF2\u7ECF\u521B\u5EFA\u771F\u5B9E Agent\u3002",
12755
+ "\u5982\u679C\u7528\u6237\u63CF\u8FF0\u4E86\u7A33\u5B9A\u6D41\u7A0B\u3001\u4E13\u5BB6\u65B9\u6CD5\u6216\u64CD\u4F5C\u6B65\u9AA4\uFF0C\u5148\u653E\u8FDB suggestedSkillIdeas / suggestedWorkflowIdeas\uFF1B\u7528\u6237\u660E\u786E\u786E\u8BA4\u8981\u6C89\u6DC0\u6D41\u7A0B\u540E\uFF0C\u624D\u53EF\u7528 createSkillDoc \u6216 updateDoc \u521B\u5EFA/\u66F4\u65B0 skill \u6216 workflow \u6587\u6863\uFF0C\u518D\u7528 updateAgent \u6302\u5230 references\u3002",
12756
+ "\u5982\u679C\u7528\u6237\u63CF\u8FF0\u4E86\u9A8C\u6536\u3001\u5931\u8D25\u8FB9\u754C\u6216\u771F\u5B9E\u6848\u4F8B\uFF0C\u5148\u653E\u8FDB suggestedEvalCases\uFF1B\u9ED8\u8BA4\u53EA\u751F\u6210 eval case \u8349\u7A3F\uFF0C\u4E0D\u8981\u81EA\u52A8\u8DD1 live eval\uFF0C\u4E5F\u4E0D\u8981\u6697\u4E2D\u4EA7\u751F\u4ED8\u8D39\u8BC4\u4F30\u3002",
12757
+ "\u8349\u7A3F\u5C55\u793A\u540E\uFF0C\u7B49\u5F85\u7528\u6237\u660E\u786E\u786E\u8BA4\uFF0C\u4F8B\u5982\u201C\u786E\u8BA4\u521B\u5EFA\u201D\u201C\u5C31\u6309\u8FD9\u4E2A\u521B\u5EFA\u201D\u201C\u521B\u5EFA\u8FD9\u4E2A AI\u201D\u3002",
12758
+ "\u53EA\u6709\u5F97\u5230\u660E\u786E\u786E\u8BA4\u540E\uFF0C\u624D\u8C03\u7528 createAgent \u521B\u5EFA\u771F\u5B9E Agent\u3002",
12759
+ "\u7528\u6237\u53EA\u662F\u8BA8\u8BBA\u3001\u8865\u5145\u3001\u4FEE\u6539\u6216\u8BF4\u201C\u5148\u770B\u770B\u201D\u65F6\uFF0C\u4E0D\u8981\u8C03\u7528 createAgent\u3002",
12760
+ "\u9ED8\u8BA4\u6A21\u578B\u4F7F\u7528 provider=nolo, model=deepseek-v4-flash\uFF1B\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u4E14\u5E73\u53F0\u5DF2\u77E5\u652F\u6301\uFF0C\u4E0D\u8981\u9009\u62E9 Claude/Anthropic \u7B49\u5F53\u524D runtime \u4E0D\u652F\u6301\u7684 provider\u3002",
12761
+ "\u516C\u5F00\u72B6\u6001\u4FDD\u6301\u4FDD\u5B88\uFF1A\u4F60\u53EF\u4EE5\u5EFA\u8BAE\u516C\u5F00\uFF0C\u4F46\u53EA\u6709\u7528\u6237\u660E\u786E\u8981\u6C42\u516C\u5F00\u53D1\u5E03\u65F6\uFF0CcreateAgent \u7684 isPublic \u624D\u80FD\u4E3A true\u3002",
12762
+ "\u5982\u679C\u7528\u6237\u60F3\u624B\u52A8\u5FAE\u8C03\u6A21\u578B\u3001\u5DE5\u5177\u3001\u77E5\u8BC6\u5F15\u7528\u6216\u53D1\u5E03\u72B6\u6001\uFF0C\u53EF\u4EE5\u5F15\u5BFC\u7528\u6237\u8FDB\u5165 /create/agent \u9AD8\u7EA7\u7F16\u8F91\u9875\u3002"
12763
+ ].join("\n"),
12764
+ toolNames: [
12765
+ "prepareAgentDraft",
12766
+ "createAgent",
12767
+ "createSkillDoc",
12768
+ "readDoc",
12769
+ "updateDoc",
12770
+ "updateAgent"
12771
+ ]
12772
+ },
12773
+ {
12774
+ slug: "app-builder",
12775
+ title: "app-builder",
12776
+ description: "\u5E94\u7528\u6784\u5EFA\uFF1A\u5E2E\u7528\u6237\u6784\u5EFA\u548C\u4FEE\u6539 Web \u5E94\u7528\uFF08\u54C1\u724C\u7AD9\u3001\u535A\u5BA2\u3001\u9884\u7EA6\u7AD9\u3001\u4F5C\u54C1\u96C6\u3001\u77E5\u8BC6\u7AD9\u3001\u8F7B\u5DE5\u5177\uFF09\uFF0C\u652F\u6301\u5BF9\u8BDD\u521B\u5EFA\u3001\u8FED\u4EE3\u4FEE\u6539\u3001\u9884\u68C0\u548C\u53D1\u5E03\uFF0C\u65E0\u9700\u7F16\u7A0B\u7ECF\u9A8C\u3002",
12777
+ body: [
12778
+ "\u4F60\u662F\u300C\u5E94\u7528\u6784\u5EFA\u52A9\u624B\u300D\uFF0C\u5E2E\u7528\u6237\u6784\u5EFA\u548C\u4FEE\u6539 Web \u5E94\u7528\u3002\u6838\u5FC3\u539F\u5219\uFF1A**\u7528\u6700\u5C11\u7684\u6B65\u9AA4\u548C\u6700\u5C11\u7684\u8BDD\u628A\u4E8B\u505A\u6210**\u3002",
12779
+ "",
12780
+ "## \u89D2\u8272",
12781
+ "- \u670D\u52A1\u5BF9\u8C61\uFF1A\u6CA1\u6709\u7F16\u7A0B\u7ECF\u9A8C\u7684\u7528\u6237\u3002\u8BED\u6C14\u8F7B\u677E\u53CB\u597D\uFF0C\u907F\u514D\u6280\u672F\u672F\u8BED\uFF08Worker\u3001JavaScript\u3001API \u7B49\uFF09\u3002",
12782
+ "- \u9664\u975E\u7528\u6237\u660E\u786E\u8981\u770B\u4EE3\u7801\uFF0C\u5426\u5219\u4E0D\u5C55\u793A\u5927\u6BB5\u4EE3\u7801\u3002",
12783
+ "- \u4F18\u5148\u6536\u655B\u6210\u5185\u5BB9\u9A71\u52A8\u7684\u7F51\u7AD9\u578B\u5C0F\u5E94\u7528\uFF1A\u54C1\u724C\u7AD9\u3001\u535A\u5BA2\u3001\u9884\u7EA6\u7AD9\u3001\u4F5C\u54C1\u96C6\u3001\u77E5\u8BC6\u7AD9\u3001\u8F7B\u5DE5\u5177\u3002",
12784
+ "",
12785
+ "## \u5DE5\u4F5C\u65B9\u5F0F",
12786
+ "1. \u7406\u89E3\u9700\u6C42\uFF1A\u7528\u7B80\u5355\u5BF9\u8BDD\u4E86\u89E3\u7528\u6237\u60F3\u8981\u4EC0\u4E48\uFF0C\u6700\u591A\u95EE 1-2 \u4E2A\u5173\u952E\u95EE\u9898\u3002",
12787
+ "2. \u81EA\u52A8\u6784\u5EFA\uFF1A\u6839\u636E\u63CF\u8FF0\u751F\u6210\u6216\u4FEE\u6539\u5E94\u7528\uFF0C\u7528\u6237\u9ED8\u8BA4\u4E0D\u9700\u8981\u770B\u5230\u4EE3\u7801\u3002",
12788
+ "3. \u7ED9\u51FA\u7ED3\u679C\uFF1A\u90E8\u7F72\u6210\u529F\u540E\u7ACB\u5373\u544A\u8BC9\u7528\u6237\u53EF\u8BBF\u95EE\u94FE\u63A5\uFF0C1-2 \u53E5\u8BDD\u8BF4\u660E\u5E94\u7528\u80FD\u505A\u4EC0\u4E48\u3002",
12789
+ "4. \u6301\u7EED\u8FED\u4EE3\uFF1A\u8981\u6539\u529F\u80FD\u6216\u6837\u5F0F\u65F6\uFF0C\u5148\u7528 appList \u627E\u5230\u76EE\u6807\u5E94\u7528\uFF0C\u518D\u6309\u300C\u5E94\u7528\u6784\u5EFA\u80FD\u529B\u5305\u300D\u7684\u64CD\u4F5C\u7EAA\u5F8B\u6267\u884C\uFF08\u6548\u7387\u4F18\u5148\u3001\u5B9A\u70B9\u4FEE\u6539\u3001SSR \u7EF4\u62A4\u3001\u9884\u68C0\u90E8\u7F72\uFF09\u3002",
12790
+ "",
12791
+ "## \u65B0\u5EFA\u5E94\u7528",
12792
+ "- \u63CF\u8FF0\u6E05\u6670\u5C31\u76F4\u63A5\u6784\u5EFA\u5E76\u90E8\u7F72\uFF0C\u7ED9\u51FA\u53EF\u8BBF\u95EE\u94FE\u63A5\u3002\u4E0D\u8981\u53CD\u95EE\u4E00\u5806\u7EC6\u8282\uFF0C\u5148\u505A\u51FA\u53EF\u7528\u7684\u7B2C\u4E00\u7248\u518D\u8FED\u4EE3\u3002",
12793
+ "",
12794
+ "## \u6536\u5C3E",
12795
+ "- \u90E8\u7F72\u6210\u529F\u540E\u4E00\u53E5\u8BDD\u7ED9\u94FE\u63A5\u5373\u53EF\u3002\u5931\u8D25\u5219\u6309\u8FD4\u56DE\u7684 issues \u5B9A\u70B9\u4FEE\u590D\u540E\u91CD\u8BD5\uFF0C\u4E0D\u8981\u505C\u4E0B\u6765\u95EE\u3002",
12796
+ "",
12797
+ "## \u5DE5\u5177",
12798
+ "- \u672C skill \u7684\u5DE5\u5177\uFF08app* / \u8868 / openAIGptImage \u7B49\uFF09\u7531\u300Capp-builder\u300D\u80FD\u529B\u5305\u6CE8\u5165",
12799
+ " \uFF08packages/ai/tools/toolPacks.ts \u7684 CAPABILITY_PACKS\uFF09\u3002\u82E5\u5F53\u524D runtime \u672A\u542F\u7528",
12800
+ " \u8BE5\u80FD\u529B\u5305\uFF0C\u5DE5\u5177\u9762\u4E0D\u4F1A\u5C55\u5F00\uFF0C\u9700\u8981\u5148\u786E\u8BA4\u8FD0\u884C\u73AF\u5883\u3002"
12801
+ ].join("\n"),
12802
+ toolNames: []
13049
12803
  }
13050
- return candidates;
12804
+ ];
12805
+ function seedBySlug(slug) {
12806
+ const seed = SPECIALIST_SKILL_SEEDS.find((item) => item.slug === slug);
12807
+ if (!seed) {
12808
+ throw new Error(`Unknown specialist skill slug: ${slug}`);
12809
+ }
12810
+ return seed;
12811
+ }
12812
+ function buildSpecialistSkillConfig(slug) {
12813
+ const seed = seedBySlug(slug);
12814
+ return {
12815
+ version: "0.1",
12816
+ kind: "skill",
12817
+ id: buildSpecialistSkillId(slug),
12818
+ name: seed.title,
12819
+ description: seed.description,
12820
+ ...seed.toolNames?.length ? { toolNames: [...seed.toolNames] } : {}
12821
+ };
12822
+ }
12823
+ function buildSpecialistSkillContentBySlug(slug) {
12824
+ const seed = seedBySlug(slug);
12825
+ const skillConfig = buildSpecialistSkillConfig(slug);
12826
+ return buildSkillDocMarkdown({
12827
+ body: seed.body,
12828
+ skillConfig
12829
+ });
13051
12830
  }
13052
- async function loadSkillFunc(args, thunkApi) {
13053
- const requestedName = asTrimmedString(args?.name);
13054
- if (!requestedName) throw new Error("loadSkill \u9700\u8981\u63D0\u4F9B name\u3002");
13055
- const candidates = await listSkillCandidates(thunkApi);
13056
- let matched = matchSkillCandidate(candidates, requestedName);
13057
- const builtinSlug = !matched ? resolveCodingBuiltinSlug(requestedName) : null;
13058
- if (builtinSlug) {
13059
- const runtime2 = getRuntime(thunkApi);
13060
- const userId = runtime2?.currentUserId;
13061
- const body2 = buildCodingSkillContentBySlug(builtinSlug);
13062
- const dbKey = userId ? buildCodingSkillPageKey(userId, builtinSlug) : builtinSlug;
13063
- if (userId) {
13064
- try {
13065
- const { ensureCodingSkills } = await import("./codingSkills-36KN5NQT.js");
13066
- await ensureCodingSkills(userId)(thunkApi?.dispatch ?? (() => Promise.resolve()));
13067
- } catch {
13068
- }
13069
- }
13070
- await persistLoadedSkillReference(thunkApi, dbKey, requestedName);
13071
- return {
13072
- rawData: {
13073
- success: true,
13074
- name: requestedName,
13075
- dbKey,
13076
- body: body2
13077
- },
13078
- displayData: `Skill "${requestedName}" loaded inline. Follow its instructions.
13079
12831
 
13080
- ${body2}`
13081
- };
12832
+ // packages/ai/skills/codePlannerSkills.ts
12833
+ var CODE_PLANNER_SKILL_SLUGS = [
12834
+ "code-planning",
12835
+ "search-first",
12836
+ "workspace-code",
12837
+ "web-research-lite",
12838
+ "dispatch-executors"
12839
+ ];
12840
+ var CODE_PLANNER_ROOT_SKILL_SLUG = "code-planning";
12841
+ function deterministicId2(prefix, seed) {
12842
+ let h = 2166136261;
12843
+ for (let i = 0; i < seed.length; i++) {
12844
+ h ^= seed.charCodeAt(i);
12845
+ h = h * 16777619 >>> 0;
13082
12846
  }
13083
- if (!matched) {
13084
- const availableNames = Array.from(
13085
- new Set(candidates.map((candidate) => candidate.name))
13086
- );
13087
- const availableText = availableNames.length ? availableNames.join(", ") : "(none)";
13088
- return {
13089
- rawData: {
13090
- success: false,
13091
- name: requestedName,
13092
- availableSkills: availableNames
13093
- },
13094
- displayData: `Skill "${requestedName}" not found. Available skills: ${availableText}`
13095
- };
12847
+ const suffix = h.toString(36).toUpperCase().padStart(14, "0");
12848
+ return (prefix + suffix).slice(0, 26);
12849
+ }
12850
+ function normalizeSkillSeed2(input) {
12851
+ return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
12852
+ }
12853
+ function buildCodePlannerSkillId(slug) {
12854
+ return deterministicId2("01SK", normalizeSkillSeed2(slug) || slug);
12855
+ }
12856
+ function buildCodePlannerSkillPageKey(userId, slug) {
12857
+ return `page-${userId}-${buildCodePlannerSkillId(slug)}`;
12858
+ }
12859
+ var CODE_PLANNER_ROOT_SKILL_ID = buildCodePlannerSkillId(
12860
+ CODE_PLANNER_ROOT_SKILL_SLUG
12861
+ );
12862
+ function buildDispatchExecutorsPromptPatch(candidateKeys = DEFAULT_CODE_PLANNER_EXECUTOR_CANDIDATE_KEYS) {
12863
+ const keys = candidateKeys.map((key) => key.trim()).filter(Boolean);
12864
+ if (keys.length === 0) {
12865
+ throw new Error("buildDispatchExecutorsPromptPatch requires at least one candidate key");
13096
12866
  }
13097
- const runtime = getRuntime(thunkApi);
13098
- const page = await readRemoteRecord({
13099
- serverBase: runtime?.currentServer,
13100
- token: runtime?.currentToken,
13101
- dbKey: matched.dbKey
13102
- });
13103
- const body = extractSkillBody(page);
13104
- await persistLoadedSkillReference(thunkApi, matched.dbKey, requestedName);
12867
+ return [
12868
+ "\u6D3E\u53D1\u534F\u8BAE\uFF1A",
12869
+ "- \u552F\u4E00\u771F\u5B9E\u5206\u6D3E\u901A\u9053\u662F startAgentRun\u3002\u7981\u6B62\u58F0\u79F0\u4F7F\u7528\u4E86\u672C\u673A CLI \u6216 nolo agent run\uFF08\u9664\u975E\u7528\u6237\u5F53\u524D\u4F1A\u8BDD\u672C\u8EAB\u5C31\u662F CLI\uFF09\u3002",
12870
+ "- \u9ED8\u8BA4\u6267\u884C\u5019\u9009\u662F\u4E0B\u5217\u5E73\u53F0\u516C\u5F00 Agent key\uFF08\u65E0\u56FA\u5B9A\u89D2\u8272\u3001\u65E0\u6253\u5206\uFF09\uFF0C\u6309\u987A\u5E8F\u4F18\u5148\u8003\u8651\uFF1B\u65E0\u9700\u5148\u505A\u53D1\u73B0\u8C03\u7528\uFF1A",
12871
+ ...keys.map((key, index) => ` ${index + 1}. ${key}`),
12872
+ "- started \u2260 completed\uFF1AstartAgentRun \u6210\u529F\u8FD4\u56DE\u771F\u5B9E runId\uFF08\u540C\u6B65 wait:true \u5219\u8FD4\u56DE\u7ED3\u679C\uFF09\u540E\u624D\u80FD\u8BF4\u300C\u5DF2\u542F\u52A8\u300D\uFF1B\u5F02\u6B65\u6D3E\u53D1\u6210\u529F\u53EA\u8868\u793A started\u3002",
12873
+ "- \u591A\u6587\u4EF6\u5B9E\u73B0\u3001\u5927\u91CD\u6784\u3001\u65B0\u5EFA\u6A21\u5757\u5E94\u6D3E\u53D1\u6267\u884C\u8005\uFF1B\u5355\u70B9\u5C0F\u6539\u53EF\u76F4\u63A5\u7528\u5DE5\u4F5C\u533A\u5DE5\u5177\u5B8C\u6210\u3002",
12874
+ "- \u4E0D\u8981\u5199\u6B7B owner \u79C1\u6709 agentKey\u3002"
12875
+ ].join("\n");
12876
+ }
12877
+ var CODE_PLANNER_SKILL_SEEDS = [
12878
+ {
12879
+ slug: "search-first",
12880
+ title: "search-first",
12881
+ description: "Search-first protocol for code work: repo before web; evaluate Adopt/Extend/Compose/Build.",
12882
+ body: [
12883
+ "# search-first",
12884
+ "",
12885
+ "Protocol-only skill. It does not grant tools by itself.",
12886
+ "Use workspace and web skills for actual reads/searches."
12887
+ ].join("\n"),
12888
+ triggerMode: "required",
12889
+ promptPatch: [
12890
+ "Search-first \u534F\u8BAE\uFF1A",
12891
+ "1. \u5148\u5728\u7ED1\u5B9A\u5DE5\u4F5C\u533A/\u4ED3\u5E93\u5185\u641C\u7D22\u76F8\u5173\u6A21\u5757\u3001\u6D4B\u8BD5\u3001guidance\u3001\u65E2\u6709 helper \u4E0E\u6A21\u5F0F\u3002",
12892
+ "2. \u4EC5\u5F53\u4ED3\u5E93\u5185\u4FE1\u606F\u4E0D\u8DB3\uFF0C\u6216\u9700\u8981\u6838\u5BF9 API/\u7248\u672C/\u5DF2\u77E5 issue \u65F6\uFF0C\u518D\u67E5\u4F9D\u8D56\u6E90\u7801\u3001\u5B98\u65B9\u6587\u6863\u3001GitHub\u3001Web\u3002",
12893
+ "3. \u8BC4\u4EF7\u8DEF\u5F84\uFF1AAdopt / Extend / Compose / Build\u3002\u9ED8\u8BA4\u4F18\u5148 Adopt/Extend/Compose\uFF1BBuild \u9700\u8BF4\u660E\u4E3A\u4F55\u4E0D\u591F\u3002",
12894
+ "4. \u4EA7\u51FA\u53EF\u6267\u884C\u8BA1\u5212\uFF1A\u76EE\u6807\u3001\u8FB9\u754C\u3001\u5173\u952E\u6587\u4EF6\u3001\u9A8C\u8BC1\u65B9\u5F0F\u3001\u98CE\u9669\uFF1B\u518D\u6309\u7528\u6237\u610F\u56FE\u51B3\u5B9A\u53EA\u7ED9\u8BA1\u5212\u3001\u81EA\u5DF1\u5C0F\u6539\uFF0C\u8FD8\u662F startAgentRun \u6D3E\u53D1\u3002",
12895
+ "5. \u5DE5\u5177\u9884\u7B97\uFF1A\u7B80\u5355\u95EE\u7B54\u5C3D\u91CF \u22645 \u6B21\u5DE5\u5177\u8C03\u7528\uFF1B\u7981\u6B62\u65E0\u76EE\u6807\u8FDE\u8BFB\u5927\u91CF\u6587\u4EF6\u3002",
12896
+ "6. \u4ECE\u672A\u8C03\u7528\u7684\u6E20\u9053\u7981\u6B62\u58F0\u79F0\u5DF2\u641C\u7D22/\u5DF2\u68C0\u67E5\u3002"
12897
+ ].join("\n")
12898
+ },
12899
+ {
12900
+ slug: "workspace-code",
12901
+ title: "workspace-code",
12902
+ description: "Workspace read/edit/shell protocol for local bound folders and repo inspection.",
12903
+ body: [
12904
+ "# workspace-code",
12905
+ "",
12906
+ "Declares local workspace tools and the honest fallback when they are unavailable."
12907
+ ].join("\n"),
12908
+ triggerMode: "required",
12909
+ toolNames: [
12910
+ "listFiles",
12911
+ "readFile",
12912
+ "globFiles",
12913
+ "searchFiles",
12914
+ "editFile",
12915
+ "execShell"
12916
+ ],
12917
+ promptPatch: [
12918
+ "\u5DE5\u4F5C\u533A\u534F\u8BAE\uFF1A",
12919
+ "- Desktop/Space \u4EE3\u7801\u5BF9\u8BDD\u4E2D\uFF0C\u7528\u6237\u8BF4\u300C\u5F53\u524D\u4EE3\u7801\u300D\u300C\u5F53\u524D\u6539\u52A8\u300D\u300C\u5F53\u524D\u5DE5\u4F5C\u533A\u300D\u300C\u8FD9\u4E2A\u9879\u76EE\u300D\u300C\u4ED3\u5E93\u91CC\u300D\uFF0C\u6216\u70B9\u540D\u4ED3\u5E93\u7EC4\u4EF6\uFF08\u5982\u300CCLI \u76F8\u5173\u300D\uFF09\u65F6\uFF0C\u9ED8\u8BA4\u6307\u7ED1\u5B9A\u5DE5\u4F5C\u533A\uFF1B\u7ACB\u5373\u7528\u5DE5\u4F5C\u533A/shell \u5DE5\u5177\u68C0\u67E5\u3002\u4EE3\u7801\u6539\u52A8 review \u65F6\u5148\u4ECE git status -sb\u3001diff/stat\u3001\u76F8\u5173 guidance/tests \u5165\u624B\u3002\u4E0D\u8981\u8981\u6C42\u7528\u6237\u7C98\u8D34\u4EE3\u7801/diff\uFF0C\u9664\u975E\u5DE5\u4F5C\u533A\u5DE5\u5177\u786E\u5B9E\u4E0D\u53EF\u7528\u3001\u6CA1\u6709\u7ED1\u5B9A\u6587\u4EF6\u5939\uFF0C\u6216\u8BBF\u95EE/\u547D\u4EE4\u5931\u8D25\u2014\u2014\u5148\u62AB\u9732\u5931\u8D25\u518D\u9000\u56DE\u7C98\u8D34\u3002",
12920
+ "- \u53EA\u8BFB\uFF1AlistFiles\u3001readFile\u3001globFiles\u3001searchFiles\u3002\u6CA1\u6709\u6210\u529F\u7ED3\u679C\u65F6\uFF0C\u7981\u6B62\u58F0\u79F0\u300C\u5DF2\u68C0\u67E5\u4ED3\u5E93/\u5DE5\u4F5C\u533A/\u6587\u4EF6\u300D\u3002",
12921
+ "- editFile\uFF1A\u5C0F\u8303\u56F4\u7CBE\u786E\u66FF\u6362\u3002edit \u524D\u5148 readFile \u62FF exact oldText\uFF1B\u9ED8\u8BA4 expectedReplacements=1\uFF0C\u5339\u914D\u6570\u4E0D\u7B26\u65F6\u505C\u5E76\u62A5\u544A blocker\u3002\u6CA1\u6709 writeFile\u2014\u2014\u9700\u8981\u65B0\u5EFA\u6587\u4EF6\u6216\u6574\u6587\u4EF6\u91CD\u5199\u65F6 startAgentRun \u6D3E\u53D1\u3002",
12922
+ "- execShell\uFF1A\u4F18\u5148\u53EA\u8BFB/\u8BCA\u65AD\u3002git \u72B6\u6001\u7528 shell\uFF08\u5982 git status -sb\uFF09\uFF0C\u7981\u6B62\u7528 readFile \u6316 .git \u4EE3\u66FF\u3002\u7834\u574F\u6027\u547D\u4EE4\u4E0E\u672A\u6279\u51C6\u7684 push/\u5408\u5E76\u7981\u6B62\u3002",
12923
+ "- \u5DE5\u4F5C\u533A\u5DE5\u5177\u4E0D\u53EF\u7528\uFF08\u975E Desktop\u3001\u672A\u7ED1\u5B9A boundFolder\u3001\u5DE5\u5177\u5931\u8D25\uFF09\u65F6\u5FC5\u987B\u62AB\u9732\uFF0C\u5E76\u53EA\u57FA\u4E8E\u7528\u6237\u7C98\u8D34\u5185\u5BB9\u4E0E\u4ECD\u53EF\u7528\u6E20\u9053\u7EE7\u7EED\u3002"
12924
+ ].join("\n")
12925
+ },
12926
+ {
12927
+ slug: "web-research-lite",
12928
+ title: "web-research-lite",
12929
+ description: "Lite web verification protocol for dependency/docs/issue lookups.",
12930
+ body: [
12931
+ "# web-research-lite",
12932
+ "",
12933
+ "Declares external search/scrape tools for verification after local search."
12934
+ ].join("\n"),
12935
+ triggerMode: "required",
12936
+ // 刻意不声明 toolNames:联网能力是系统层能力包(web-search / web-scrape),
12937
+ // 不编码的对话同样需要,不该由 Code Planner 私藏一份。这里只留协议,工具由
12938
+ // 宿主按能力包挂载,用户在设置页的全局开关才能真正管住它们。
12939
+ promptPatch: [
12940
+ "\u5916\u90E8\u68C0\u7D22\u534F\u8BAE\uFF1A",
12941
+ "- \u8054\u7F51\u5DE5\u5177\u7531\u5E73\u53F0\u80FD\u529B\u5305\u63D0\u4F9B\uFF08\u8054\u7F51\u641C\u7D22 / \u6DF1\u5EA6\u7F51\u9875\u6293\u53D6\uFF09\uFF0C\u7528\u6237\u53EF\u80FD\u5DF2\u5168\u5C40\u5173\u95ED\u3002",
12942
+ "- \u53EA\u4F7F\u7528\u672C\u8F6E\u5B9E\u9645\u62FF\u5230\u7684\u5DE5\u5177\uFF1B\u5DE5\u5177\u4E0D\u5728\u624B\u4E0A\u65F6\u5982\u5B9E\u8BF4\u660E\u300C\u8054\u7F51\u80FD\u529B\u672A\u5F00\u542F\u300D\uFF0C\u4E0D\u8981\u81C6\u9020\u8C03\u7528\u3002",
12943
+ "- \u6CA1\u6709\u6210\u529F\u7ED3\u679C\u65F6\uFF0C\u7981\u6B62\u58F0\u79F0\u300C\u5DF2\u641C\u7D22\u4F9D\u8D56/\u5B98\u65B9\u6587\u6863/GitHub/Web\u300D\u3002",
12944
+ "- \u6E20\u9053\u5931\u8D25\u6216\u4E0D\u53EF\u7528\u65F6\u5FC5\u987B\u62AB\u9732\u7F3A\u53E3\uFF0C\u6539\u7528\u4ECD\u53EF\u7528\u5DE5\u5177\uFF1B\u4E0D\u8981\u5047\u88C5\u5DF2\u6838\u5B9E\u3002"
12945
+ ].join("\n")
12946
+ },
12947
+ {
12948
+ slug: "dispatch-executors",
12949
+ title: "dispatch-executors",
12950
+ description: "startAgentRun dispatch protocol for Code Planner executor candidates.",
12951
+ body: [
12952
+ "# dispatch-executors",
12953
+ "",
12954
+ "Only startAgentRun is granted. Default candidate keys are platform public agents;",
12955
+ "hard allowlisting is enforced by runtimeContext.allowedChildAgentKeys when wired."
12956
+ ].join("\n"),
12957
+ triggerMode: "required",
12958
+ toolNames: ["startAgentRun"],
12959
+ // Keys come from core/builtinAgents — do not hard-code a separate list here.
12960
+ promptPatch: buildDispatchExecutorsPromptPatch(
12961
+ DEFAULT_CODE_PLANNER_EXECUTOR_CANDIDATE_KEYS
12962
+ )
12963
+ },
12964
+ {
12965
+ slug: "code-planning",
12966
+ title: "code-planning",
12967
+ description: "Root Code Planner skill: composes search-first, workspace, web, and dispatch skills.",
12968
+ body: [
12969
+ "# code-planning",
12970
+ "",
12971
+ "Composition-only root skill for Code Planner.",
12972
+ "Attach this skill on the Agent; children load via requiredSkills.",
12973
+ "Until runtimes expand skill pages, Agent seed also carries a compiled snapshot."
12974
+ ].join("\n"),
12975
+ triggerMode: "required",
12976
+ requiredSkillSlugs: [
12977
+ "search-first",
12978
+ "workspace-code",
12979
+ "web-research-lite",
12980
+ "dispatch-executors"
12981
+ ]
12982
+ }
12983
+ ];
12984
+ function seedBySlug2(slug) {
12985
+ const seed = CODE_PLANNER_SKILL_SEEDS.find((item) => item.slug === slug);
12986
+ if (!seed) {
12987
+ throw new Error(`Unknown Code Planner skill slug: ${slug}`);
12988
+ }
12989
+ return seed;
12990
+ }
12991
+ function collectCodePlannerReachableSkillSlugs(rootSlug = CODE_PLANNER_ROOT_SKILL_SLUG) {
12992
+ const ordered = [];
12993
+ const seen = /* @__PURE__ */ new Set();
12994
+ const visit = (slug) => {
12995
+ if (seen.has(slug)) return;
12996
+ seen.add(slug);
12997
+ ordered.push(slug);
12998
+ for (const child of seedBySlug2(slug).requiredSkillSlugs ?? []) {
12999
+ visit(child);
13000
+ }
13001
+ };
13002
+ visit(rootSlug);
13003
+ return ordered;
13004
+ }
13005
+ function compileCodePlannerEffectiveTools() {
13006
+ const tools = [];
13007
+ const seen = /* @__PURE__ */ new Set();
13008
+ for (const slug of collectCodePlannerReachableSkillSlugs()) {
13009
+ for (const toolName of seedBySlug2(slug).toolNames ?? []) {
13010
+ if (seen.has(toolName)) continue;
13011
+ seen.add(toolName);
13012
+ tools.push(toolName);
13013
+ }
13014
+ }
13015
+ return tools;
13016
+ }
13017
+ var CODE_PLANNER_COMPILED_EFFECTIVE_TOOLS = compileCodePlannerEffectiveTools();
13018
+ function buildCodePlannerSkillConfig(slug, options) {
13019
+ const seed = seedBySlug2(slug);
13020
+ const requiredSkills = options?.requiredSkills ?? seed.requiredSkillSlugs?.map((childSlug) => buildCodePlannerSkillId(childSlug));
13105
13021
  return {
13106
- rawData: {
13107
- success: true,
13108
- name: requestedName,
13109
- dbKey: matched.dbKey,
13110
- body
13111
- },
13112
- displayData: `Skill "${requestedName}" loaded inline. Follow its instructions.
13113
-
13114
- ${body}`
13022
+ version: "0.1",
13023
+ kind: "skill",
13024
+ id: buildCodePlannerSkillId(slug),
13025
+ name: seed.title,
13026
+ description: seed.description,
13027
+ ...seed.triggerMode ? { triggerMode: seed.triggerMode } : {},
13028
+ ...seed.toolNames?.length ? { toolNames: [...seed.toolNames] } : {},
13029
+ ...requiredSkills?.length ? { requiredSkills: [...requiredSkills] } : {},
13030
+ ...seed.promptPatch ? { promptPatch: seed.promptPatch } : {}
13115
13031
  };
13116
13032
  }
13117
- async function persistLoadedSkillReference(thunkApi, dbKey, name) {
13118
- try {
13119
- const state = thunkApi?.getState?.();
13120
- const currentDialogKey = getActiveDialogKey();
13121
- if (!state || !currentDialogKey) return;
13122
- const dialogConfig = selectById(
13123
- state,
13124
- currentDialogKey
13033
+ function buildCodePlannerSkillPageRecords(userId) {
13034
+ const trimmedUserId = userId.trim();
13035
+ if (!trimmedUserId) {
13036
+ throw new Error("buildCodePlannerSkillPageRecords requires userId");
13037
+ }
13038
+ return CODE_PLANNER_SKILL_SEEDS.map((seed) => {
13039
+ const skillId = buildCodePlannerSkillId(seed.slug);
13040
+ const dbKey = buildCodePlannerSkillPageKey(trimmedUserId, seed.slug);
13041
+ const requiredSkills = seed.requiredSkillSlugs?.map(
13042
+ (childSlug) => buildCodePlannerSkillPageKey(trimmedUserId, childSlug)
13125
13043
  );
13126
- const existing = dialogConfig?.extraReferences ?? [];
13127
- const alreadyMounted = existing.some((ref) => ref.dbKey === dbKey);
13128
- if (alreadyMounted) return;
13129
- const newRef = {
13044
+ const skillConfig = buildCodePlannerSkillConfig(seed.slug, {
13045
+ requiredSkills
13046
+ });
13047
+ return {
13048
+ slug: seed.slug,
13049
+ skillId,
13130
13050
  dbKey,
13131
- title: name,
13132
- type: "instruction"
13051
+ title: seed.title,
13052
+ content: buildSkillDocMarkdown({
13053
+ body: seed.body,
13054
+ skillConfig
13055
+ }),
13056
+ meta: {
13057
+ kind: "skill",
13058
+ skillConfig
13059
+ },
13060
+ ...skillConfig.toolNames?.length ? { tools: [...skillConfig.toolNames] } : {}
13133
13061
  };
13134
- await setDialogExtraReferencesAction([...existing, newRef], thunkApi);
13135
- } catch {
13062
+ });
13063
+ }
13064
+
13065
+ // packages/ai/skills/searchDialogSkill.ts
13066
+ var SEARCH_DIALOG_SKILL_SLUGS = [
13067
+ "search-dialog-messages"
13068
+ ];
13069
+ function deterministicId3(prefix, seed) {
13070
+ let h = 2166136261;
13071
+ for (let i = 0; i < seed.length; i++) {
13072
+ h ^= seed.charCodeAt(i);
13073
+ h = h * 16777619 >>> 0;
13074
+ }
13075
+ const suffix = h.toString(36).toUpperCase().padStart(14, "0");
13076
+ return (prefix + suffix).slice(0, 26);
13077
+ }
13078
+ function normalizeSkillSeed3(input) {
13079
+ return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
13080
+ }
13081
+ function buildSearchDialogSkillId(slug) {
13082
+ return deterministicId3("01SK", normalizeSkillSeed3(slug) || slug);
13083
+ }
13084
+ function buildSearchDialogSkillPageKey(userId, slug) {
13085
+ return `page-${userId}-${buildSearchDialogSkillId(slug)}`;
13086
+ }
13087
+ var SEARCH_DIALOG_SKILL_SEEDS = [
13088
+ {
13089
+ slug: "search-dialog-messages",
13090
+ title: "\u5BF9\u8BDD\u68C0\u7D22",
13091
+ description: "\u5BF9\u8BDD\u68C0\u7D22\uFF1AlistDialogs \u5217\u51FA\u5F53\u524D\u7528\u6237\u7684\u5BF9\u8BDD\uFF08\u9ED8\u8BA4 100 \u6761\u3001\u4E0A\u9650 500\uFF09\uFF0C\u7528\u4E8E\u5728\u76EE\u6807\u5BF9\u8BDD\u4E0D\u660E\u786E\u65F6\u5148\u5B9A\u4F4D\uFF1BreadDialog \u8BFB\u53D6\u6307\u5B9A\u5BF9\u8BDD\u7684\u5143\u6570\u636E\u4E0E\u6700\u8FD1\u6D88\u606F\uFF08dialog \u4F18\u5148\u4F20\u5B8C\u6574 dbKey dialog-<userId>-<id> \u6216\u5BF9\u8BDD URL\uFF0C\u88F8 ID \u4EC5\u5BF9\u5F53\u524D\u767B\u5F55\u7528\u6237\u6709\u6548\uFF09\uFF1BsearchDialogMessages \u5728\u6307\u5B9A\u5BF9\u8BDD\u7684\u539F\u59CB\u6D88\u606F\u4E2D\u6309\u7CBE\u786E\u6216\u6A21\u7CCA\u6587\u672C\u641C\u7D22\uFF0C\u8FD4\u56DE\u5339\u914D\u7684 messageId\u3001\u89D2\u8272\u3001\u88C1\u526A\u540E\u7684\u539F\u6587\u7247\u6BB5\u4E0E\u90BB\u8FD1\u4E0A\u4E0B\u6587\uFF0C\u4E0D\u628A\u6574\u6BB5\u5BF9\u8BDD\u704C\u8FDB\u6A21\u578B\u4E0A\u4E0B\u6587\u3002",
13092
+ body: [
13093
+ "\u4F60\u662F\u300C\u5BF9\u8BDD\u68C0\u7D22\u300D\u80FD\u529B\u7684\u4F7F\u7528\u8005\uFF1A\u9700\u8981\u8BFB\u53D6\u6216\u53D6\u8BC1\u67D0\u6BB5\u5BF9\u8BDD\u65F6\uFF0C\u5728\u672C skill \u7684 listDialogs\u3001readDialog \u4E0E searchDialogMessages \u4E09\u4E2A\u5DE5\u5177\u4E2D\u9009\u62E9\u5408\u9002\u7684\u90A3\u4E2A\u3002",
13094
+ "",
13095
+ "## \u4EC0\u4E48\u65F6\u5019\u7528",
13096
+ "- \u7528\u6237\u8981\u7CBE\u786E\u7684\u65E7\u6D88\u606F\u3001\u539F\u6587\u63AA\u8F9E\u3001\u8C01\u8BF4\u4E86\u4EC0\u4E48\u3001\u67D0\u4E2A\u51B3\u7B56\u4E3A\u4EC0\u4E48\u505A\u51FA\u3001\u65E9\u671F\u5386\u53F2\u7EC6\u8282\u3002",
13097
+ "- \u9700\u8981\u6587\u4EF6/\u5DE5\u5177\u8BC1\u636E\u3001\u5931\u8D25\u5C1D\u8BD5\u3001\u6216\u4E0E\u4E4B\u524D\u5DE5\u4F5C\u7684\u5BF9\u6BD4\uFF08\u6765\u81EA\u88AB\u5F15\u7528\u5BF9\u8BDD\uFF09\u3002",
13098
+ "- \u76EE\u6807\u5BF9\u8BDD\u4E0D\u660E\u786E\u3001\u9700\u8981\u5148\u5217\u51FA\u5019\u9009\u5BF9\u8BDD\uFF08\u5F53\u524D\u7528\u6237\u7684\u5BF9\u8BDD\u5217\u8868\uFF09\u65F6\uFF0C\u7528 listDialogs\u3002",
13099
+ "- \u5F53\u524D\u4E0A\u4E0B\u6587\u53EA\u6709\u6709\u635F\u7684\u5BF9\u8BDD\u6458\u8981\uFF0C\u800C\u7528\u6237\u9700\u8981\u8BC1\u636E\u3001\u51FA\u5904\u6216\u5177\u4F53\u5386\u53F2\u7EC6\u8282\u65F6\u2014\u2014\u4F18\u5148\u7528\u672C skill\uFF0C\u4E0D\u8981\u51ED\u6458\u8981\u731C\u3002",
13100
+ "",
13101
+ "## listDialogs\uFF1A\u5B9A\u4F4D\u5BF9\u8BDD",
13102
+ "\u5217\u51FA\u5F53\u524D\u7528\u6237\u7684\u5BF9\u8BDD\uFF1A`listDialogs({ limit?, space?, includeScheduled? })`\u3002",
13103
+ "- \u8FD4\u56DE `{ total, dialogs: [{ id, dbKey, title, status, updatedAt, createdAt, spaceId, triggerType, primaryAgentKey }] }`\uFF0C\u6309\u6700\u8FD1\u66F4\u65B0\u6392\u5E8F\u3002",
13104
+ "- limit \u63A7\u5236\u8FD4\u56DE\u6761\u6570\uFF08\u9ED8\u8BA4 100\uFF0C\u4E0A\u9650 500\uFF09\uFF1Bspace \u53EF\u4F20 space id \u6216 URL \u6536\u7A84\u8303\u56F4\uFF1BincludeScheduled \u63A7\u5236\u662F\u5426\u5305\u542B\u5B9A\u65F6/\u540E\u53F0\u8FD0\u884C\u5BF9\u8BDD\uFF08\u9ED8\u8BA4\u4E0D\u542B\uFF09\u3002",
13105
+ "- \u76EE\u6807\u5BF9\u8BDD\u4E0D\u660E\u786E\u65F6\u5148\u7528\u5B83\u5B9A\u4F4D\uFF1A\u4ECE\u7ED3\u679C\u91CC\u53D6 dbKey \u6216 URL \u4EA4\u7ED9 readDialog / searchDialogMessages\uFF0C\u4E0D\u8981\u7528\u88F8 ID\u3002",
13106
+ "",
13107
+ "## readDialog\uFF1A\u8BFB\u53D6\u5BF9\u8BDD",
13108
+ '\u8BFB\u53D6\u6307\u5B9A\u5BF9\u8BDD\u7684\u5143\u6570\u636E\u4E0E\u6700\u8FD1\u6D88\u606F\uFF1A`readDialog({ dialog: "<dialog \u7684 dbKey>" })`\u3002',
13109
+ "- dialog \u4F18\u5148\u4F20\u5B8C\u6574 dbKey\uFF08dialog-<userId>-<id>\uFF09\u6216\u5BF9\u8BDD URL\uFF1B\u88F8 ID \u53EA\u5BF9\u5F53\u524D\u767B\u5F55\u7528\u6237\u6709\u6548\uFF0C\u4E0D\u80FD\u53EF\u9760\u8BFB\u53D6\u5176\u4ED6\u7528\u6237\u6216\u8DE8\u670D\u52A1\u5668\u7684\u5BF9\u8BDD\u3002",
13110
+ "- \u76EE\u6807\u5BF9\u8BDD\u4E0D\u660E\u786E\u65F6\uFF0C\u5148 listDialogs \u5B9A\u4F4D\u518D\u8BFB\u53D6\u3002",
13111
+ "- limit \u63A7\u5236\u8FD4\u56DE\u6D88\u606F\u6761\u6570\uFF08\u9ED8\u8BA4 120\uFF0C\u4E0A\u9650 1000\uFF09\u3002",
13112
+ "",
13113
+ "## searchDialogMessages\uFF1A\u539F\u6587\u641C\u7D22",
13114
+ '\u57FA\u672C\u5F62\u5F0F\uFF1A`searchDialogMessages({ dialogKey: "<dialog \u7684 dbKey>", query: "<\u8981\u641C\u7684\u6587\u672C>" })`',
13115
+ "",
13116
+ "\u53C2\u6570\uFF1A",
13117
+ "- dialogKey\uFF1A\u76EE\u6807\u5BF9\u8BDD\u7684 dbKey\uFF08\u5F62\u5982 dialog-<userId>-01ABC...\uFF09\u3002",
13118
+ "- query\uFF1A\u8981\u5728\u539F\u59CB\u6D88\u606F\u5185\u5BB9\u91CC\u641C\u7D22\u7684\u6587\u672C\u3002",
13119
+ "- limit\uFF1A\u6700\u591A\u8FD4\u56DE\u591A\u5C11\u6761\u5339\u914D\uFF08\u4E0A\u9650 10\uFF09\u3002",
13120
+ "- scanLimit\uFF1A\u4ECE server \u62C9\u53D6\u65F6\u6700\u591A\u626B\u63CF\u591A\u5C11\u6761\u6D88\u606F\uFF08\u4E0A\u9650 500\uFF09\u3002",
13121
+ "- contextMessages\uFF1A\u6BCF\u6761\u5339\u914D\u524D\u540E\u9644\u5E26\u591A\u5C11\u6761\u90BB\u8FD1\u6D88\u606F\uFF08\u4E0A\u9650 3\uFF09\u3002",
13122
+ "- role\uFF1A\u53EF\u9009\uFF0C\u53EA\u641C\u6307\u5B9A\u89D2\u8272\uFF08user / assistant / tool / system\uFF09\u3002",
13123
+ "- includeTools\uFF1A\u53EF\u9009\uFF0C\u662F\u5426\u5305\u542B tool \u6D88\u606F\u3002",
13124
+ "",
13125
+ "## \u8FD4\u56DE",
13126
+ "searchDialogMessages \u8FD4\u56DE\u5339\u914D\u7684 messageId\u3001\u89D2\u8272\u3001\u88C1\u526A\u540E\u7684\u539F\u6587\u5185\u5BB9\u7247\u6BB5\u4EE5\u53CA\u90BB\u8FD1\u4E0A\u4E0B\u6587\u3002",
13127
+ "\u57FA\u4E8E\u8FD4\u56DE\u7684\u539F\u6587\u7247\u6BB5\u56DE\u7B54\u7528\u6237\uFF0C\u5F15\u7528\u65F6\u4FDD\u6301\u539F\u6587\uFF1B\u7247\u6BB5\u88AB\u88C1\u526A\u65F6\uFF0C\u5982\u9700\u66F4\u5B8C\u6574\u5185\u5BB9\u518D\u9488\u5BF9\u6027\u7F29\u5C0F\u67E5\u8BE2\u6216\u6362\u5173\u952E\u8BCD\u3002",
13128
+ "",
13129
+ "## \u8FB9\u754C",
13130
+ "- searchDialogMessages \u53EA\u641C**\u4E00\u4E2A**\u6307\u5B9A\u5BF9\u8BDD\u7684\u539F\u59CB\u6D88\u606F\uFF1B\u8DE8\u5BF9\u8BDD\u6216\u6309\u4E3B\u9898\u805A\u5408\u8BF7\u7528 queryDialogsBySubjectRef\u3002",
13131
+ "- listDialogs \u53EA\u5217**\u5F53\u524D\u767B\u5F55\u7528\u6237**\u7684\u5BF9\u8BDD\uFF08\u9ED8\u8BA4\u4E0D\u542B\u5B9A\u65F6/\u540E\u53F0\u8FD0\u884C\u5BF9\u8BDD\uFF0C\u9664\u975E includeScheduled\uFF09\uFF1B\u8DE8\u7528\u6237/\u8DE8\u670D\u52A1\u5668\u68C0\u7D22\u4E0D\u53D7\u652F\u6301\u3002",
13132
+ "- \u4E0D\u8981\u4E3A\u4E86\u300C\u591A\u62FF\u70B9\u4E0A\u4E0B\u6587\u300D\u800C\u7528\u5927 scanLimit/limit \u4EE3\u66FF readDialog \u7684\u5B8C\u6574\u8BFB\u53D6\u8BED\u4E49\uFF1B\u672C skill \u91CC readDialog \u8D1F\u8D23\u5B8C\u6574\u8BFB\u53D6\uFF0CsearchDialogMessages \u7684\u4EF7\u503C\u662F\u5B9A\u70B9\u53D6\u8BC1\u3002",
13133
+ "- \u641C\u4E0D\u5230\u65F6\u5982\u5B9E\u8BF4\u660E\uFF0C\u4E0D\u8981\u7528\u6458\u8981\u6216\u8BB0\u5FC6\u7F16\u9020\u539F\u6587\u3002"
13134
+ ].join("\n"),
13135
+ toolNames: ["listDialogs", "readDialog", "searchDialogMessages"]
13136
13136
  }
13137
+ ];
13138
+ function seedBySlug3(slug) {
13139
+ const seed = SEARCH_DIALOG_SKILL_SEEDS.find((item) => item.slug === slug);
13140
+ if (!seed) {
13141
+ throw new Error(`Unknown search-dialog skill slug: ${slug}`);
13142
+ }
13143
+ return seed;
13144
+ }
13145
+ function buildSearchDialogSkillConfig(slug) {
13146
+ const seed = seedBySlug3(slug);
13147
+ return {
13148
+ version: "0.1",
13149
+ kind: "skill",
13150
+ id: buildSearchDialogSkillId(slug),
13151
+ name: seed.title,
13152
+ description: seed.description,
13153
+ ...seed.toolNames?.length ? { toolNames: [...seed.toolNames] } : {}
13154
+ };
13155
+ }
13156
+ function buildSearchDialogSkillContentBySlug(slug) {
13157
+ const seed = seedBySlug3(slug);
13158
+ const skillConfig = buildSearchDialogSkillConfig(slug);
13159
+ return buildSkillDocMarkdown({
13160
+ body: seed.body,
13161
+ skillConfig
13162
+ });
13137
13163
  }
13138
13164
 
13139
- // packages/ai/tools/category/createCategoryTool.ts
13140
- var createCategoryFunctionSchema = {
13141
- // 已从 'create_category' 更新为 'createCategory'
13142
- name: "createCategory",
13143
- description: "\u5728\u5F53\u524D\u7A7A\u95F4\u4E2D\u521B\u5EFA\u65B0\u5206\u7C7B\u3002",
13144
- parameters: {
13145
- type: "object",
13146
- properties: {
13147
- name: {
13148
- type: "string",
13149
- description: "\u5206\u7C7B\u540D\u79F0"
13150
- }
13151
- },
13152
- required: ["name"]
13165
+ // packages/ai/skills/searchSpaceSkill.ts
13166
+ var SEARCH_SPACE_SKILL_SLUGS = [
13167
+ "search-all-spaces"
13168
+ ];
13169
+ function deterministicId4(prefix, seed) {
13170
+ let h = 2166136261;
13171
+ for (let i = 0; i < seed.length; i++) {
13172
+ h ^= seed.charCodeAt(i);
13173
+ h = h * 16777619 >>> 0;
13153
13174
  }
13154
- };
13155
- async function createCategoryFunc(args, thunkApi) {
13156
- const { getState } = thunkApi;
13157
- const dispatch = thunkApi.dispatch.bind(thunkApi);
13158
- const state = getState();
13159
- const spaceId = selectCurrentSpaceId(state);
13160
- if (!spaceId) {
13161
- throw new Error("\u65E0\u6CD5\u521B\u5EFA\u5206\u7C7B\uFF0C\u56E0\u4E3A\u5F53\u524D\u7A7A\u95F4\u672A\u8BBE\u5B9A\u3002");
13175
+ const suffix = h.toString(36).toUpperCase().padStart(14, "0");
13176
+ return (prefix + suffix).slice(0, 26);
13177
+ }
13178
+ function normalizeSkillSeed4(input) {
13179
+ return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
13180
+ }
13181
+ function buildSearchSpaceSkillId(slug) {
13182
+ return deterministicId4("01SK", normalizeSkillSeed4(slug) || slug);
13183
+ }
13184
+ function buildSearchSpaceSkillPageKey(userId, slug) {
13185
+ return `page-${userId}-${buildSearchSpaceSkillId(slug)}`;
13186
+ }
13187
+ var SEARCH_SPACE_SKILL_SEEDS = [
13188
+ {
13189
+ slug: "search-all-spaces",
13190
+ title: "\u5168\u7A7A\u95F4\u641C\u7D22",
13191
+ description: "\u5168\u7A7A\u95F4\u641C\u7D22\uFF1A\u4F7F\u7528 search_all_spaces \u5728\u5F53\u524D\u8BBE\u5907\u5DF2\u540C\u6B65\u7684\u5168\u90E8\u5185\u5BB9\u4E2D\u641C\u7D22\u5F53\u524D\u7528\u6237\u7684\u6570\u636E\uFF08\u7B49\u540C\u4E8E\u5168\u90E8\u89C6\u56FE Recent \u7684\u5185\u5BB9\u8BED\u4E49\uFF09\uFF0C\u5E76\u8FD4\u56DE\u6240\u5C5E\u7A7A\u95F4\uFF08\u5982\u6709\uFF09\u3002\u9002\u5408\u5728\u5168\u90E8\u89C6\u56FE\uFF08All View\uFF09\u6216\u9700\u8981\u8DE8\u7A7A\u95F4\u68C0\u7D22\u65F6\u4F7F\u7528\u3002",
13192
+ body: [
13193
+ "\u4F60\u662F\u300C\u5168\u7A7A\u95F4\u641C\u7D22\u300D\u80FD\u529B\u7684\u4F7F\u7528\u8005\uFF1A\u9700\u8981\u8DE8\u7A7A\u95F4\u3001\u6216\u5728\u6CA1\u6709\u300C\u5F53\u524D\u7A7A\u95F4\u300D\u8BED\u4E49\u7684\u4E0A\u4E0B\u6587\u4E2D\u68C0\u7D22\u7528\u6237\u5185\u5BB9\u65F6\uFF0C\u4F7F\u7528\u672C skill \u7684 search_all_spaces \u5DE5\u5177\u3002",
13194
+ "",
13195
+ "## \u4EC0\u4E48\u65F6\u5019\u7528",
13196
+ "- \u7528\u6237\u8981\u8DE8\u7A7A\u95F4\u67E5\u627E\u5185\u5BB9\uFF08\u9875\u9762\u3001\u8868\u683C\u3001\u5BF9\u8BDD\u7B49\uFF09\uFF0C\u4E14\u4E0D\u9650\u5B9A\u5728\u67D0\u4E2A\u5177\u4F53\u7A7A\u95F4\u3002",
13197
+ "- \u5F53\u524D\u89C6\u56FE\u662F\u5168\u90E8\u89C6\u56FE\uFF08All View\uFF09\uFF1A\u6CA1\u6709\u5F53\u524D\u7A7A\u95F4\uFF0Csearch_workspace \u4E0D\u9002\u7528\uFF0C\u4F18\u5148\u7528\u672C skill\u3002",
13198
+ "- \u9700\u8981\u786E\u8BA4\u67D0\u6761\u5185\u5BB9\u5C5E\u4E8E\u54EA\u4E2A\u7A7A\u95F4\uFF08\u8FD4\u56DE\u7ED3\u679C\u5E26 spaceId / spaceName\uFF09\u65F6\u3002",
13199
+ "",
13200
+ "## \u8C03\u7528\u65B9\u5F0F",
13201
+ '`search_all_spaces({ query: "<\u5173\u952E\u8BCD>" })`',
13202
+ "- query\uFF1A\u641C\u7D22\u5173\u952E\u8BCD\uFF0C\u5339\u914D\u6807\u9898\u4E0E\u6587\u4EF6\u540D\uFF08contentKey\uFF09\u3002",
13203
+ "- \u8FD4\u56DE rawData.contents\uFF1A\u6BCF\u9879\u5305\u542B title\u3001type\u3001contentKey\u3001spaceId\u3001spaceName\uFF08\u5982\u6709\uFF09\u3001createdAt / updatedAt\u3001serverOrigin\uFF08\u5982\u6709\uFF09\u3002",
13204
+ "",
13205
+ "## \u8BED\u4E49\u4E0E\u8FB9\u754C",
13206
+ "- \u641C\u7D22\u8303\u56F4 = \u5F53\u524D\u8BBE\u5907\u5DF2\u540C\u6B65\u7684 user-data \u5185\u5BB9\uFF08\u4E0E\u300C\u5168\u90E8\u89C6\u56FE Recent\u300D\u540C\u4E00\u5957\u8BED\u4E49\uFF09\uFF0C\u4E0D\u662F\u8FDC\u7A0B\u6570\u636E\u5E93\u7684\u5168\u91CF\u68C0\u7D22\u3002",
13207
+ "- \u7ED3\u679C\u53EF\u80FD\u8DE8\u591A\u4E2A\u7A7A\u95F4\uFF0C\u6309\u5185\u5BB9\u9010\u6761\u8FD4\u56DE\uFF0C\u4E0D\u9700\u8981\u5728\u8FD4\u56DE\u540E\u4E8C\u6B21\u641C\u7D22\u3002",
13208
+ "- \u6CA1\u6709\u547D\u4E2D\u65F6\u5982\u5B9E\u8BF4\u660E\uFF0C\u4E0D\u8981\u7F16\u9020\u5185\u5BB9\u6216\u7A7A\u95F4\u5F52\u5C5E\u3002",
13209
+ "- \u5206\u7C7B\u89C6\u56FE\uFF08categories\uFF09\u4E0B\u7528\u6237\u53EA\u95EE\u5F53\u524D\u7A7A\u95F4\u5185\u5BB9\u65F6\uFF0C\u4F18\u5148\u7528\u5E38\u9A7B\u7684 search_workspace\uFF1B\u9700\u8981\u8DE8\u7A7A\u95F4\u624D loadSkill \u672C skill\u3002"
13210
+ ].join("\n"),
13211
+ toolNames: ["search_all_spaces"]
13162
13212
  }
13163
- const name = args.name.trim() || "\u65B0\u5206\u7C7B";
13164
- try {
13165
- const { updatedSpaceData } = await dispatch(
13166
- addCategory({ spaceId, name })
13167
- ).unwrap();
13168
- const newCategoryId = Object.keys(updatedSpaceData.categories).find(
13169
- (id) => updatedSpaceData.categories[id]?.name === name
13170
- ) || "";
13171
- const rawData = { success: true, id: newCategoryId, name };
13172
- const displayData = `\u5206\u7C7B\u300C${name}\u300D\u5DF2\u6210\u529F\u521B\u5EFA\u3002`;
13173
- return { rawData, displayData };
13174
- } catch (error) {
13175
- const msg = error?.message || JSON.stringify(error) || "\u672A\u77E5\u9519\u8BEF";
13176
- throw new Error(`\u521B\u5EFA\u5206\u7C7B\u65F6\u51FA\u9519: ${msg}`);
13213
+ ];
13214
+ function seedBySlug4(slug) {
13215
+ const seed = SEARCH_SPACE_SKILL_SEEDS.find((item) => item.slug === slug);
13216
+ if (!seed) {
13217
+ throw new Error(`Unknown search-space skill slug: ${slug}`);
13177
13218
  }
13219
+ return seed;
13220
+ }
13221
+ function buildSearchSpaceSkillConfig(slug) {
13222
+ const seed = seedBySlug4(slug);
13223
+ return {
13224
+ version: "0.1",
13225
+ kind: "skill",
13226
+ id: buildSearchSpaceSkillId(slug),
13227
+ name: seed.title,
13228
+ description: seed.description,
13229
+ ...seed.toolNames?.length ? { toolNames: [...seed.toolNames] } : {}
13230
+ };
13231
+ }
13232
+ function buildSearchSpaceSkillContentBySlug(slug) {
13233
+ const seed = seedBySlug4(slug);
13234
+ const skillConfig = buildSearchSpaceSkillConfig(slug);
13235
+ return buildSkillDocMarkdown({
13236
+ body: seed.body,
13237
+ skillConfig
13238
+ });
13178
13239
  }
13179
13240
 
13180
- // packages/ai/tools/category/updateContentCategoryTool.ts
13181
- var updateContentCategoryFunctionSchema = {
13182
- name: "updateContentCategory",
13183
- description: "\u66F4\u65B0\u5F53\u524D\u7A7A\u95F4\u4E2D\u67D0\u4E2A\u5185\u5BB9\u7684\u5206\u7C7B\u3002",
13184
- parameters: {
13185
- type: "object",
13186
- properties: {
13187
- contentId: {
13188
- type: "string",
13189
- description: "\u8981\u66F4\u65B0\u7684\u5185\u5BB9ID"
13190
- },
13191
- categoryId: {
13192
- type: "string",
13193
- description: "\u65B0\u7684\u5206\u7C7BID\uFF0C\u53EF\u9009\uFF0C\u4E0D\u63D0\u4F9B\u5219\u8BBE\u4E3A\u672A\u5206\u7C7B"
13241
+ // packages/ai/skills/builtinSkillRegistry.ts
13242
+ var codePlannerContentBySlug = /* @__PURE__ */ (() => {
13243
+ const cache = /* @__PURE__ */ new Map();
13244
+ return (slug) => {
13245
+ if (cache.size === 0) {
13246
+ for (const page of buildCodePlannerSkillPageRecords("platform-skill-owner")) {
13247
+ cache.set(page.slug, page.content);
13194
13248
  }
13195
- },
13196
- required: ["contentId"]
13197
- }
13198
- };
13199
- async function updateContentCategoryFunc(args, thunkApi) {
13200
- const { getState } = thunkApi;
13201
- const dispatch = thunkApi.dispatch.bind(thunkApi);
13202
- const state = getState();
13203
- const spaceId = selectCurrentSpaceId(state);
13204
- if (!spaceId) {
13205
- throw new Error("\u65E0\u6CD5\u66F4\u65B0\u5206\u7C7B\uFF0C\u56E0\u4E3A\u5F53\u524D\u7A7A\u95F4\u672A\u8BBE\u5B9A\u3002");
13249
+ }
13250
+ return cache.get(slug) ?? "";
13251
+ };
13252
+ })();
13253
+ var OBJECT_SKILL_KINDS = Object.keys(
13254
+ BUILTIN_OBJECT_SKILL_IDS
13255
+ );
13256
+ var SOURCES = [
13257
+ {
13258
+ slugs: OBJECT_SKILL_KINDS,
13259
+ buildSkillId: (kind) => BUILTIN_OBJECT_SKILL_IDS[kind],
13260
+ buildPageKey: (userId, kind) => buildBuiltinObjectSkillDbKey(kind, userId),
13261
+ buildConfig: buildBuiltinObjectSkillConfig,
13262
+ buildContent: buildBuiltinObjectSkillPageContent
13263
+ },
13264
+ {
13265
+ slugs: CODING_SKILL_SLUGS,
13266
+ buildSkillId: buildCodingSkillId,
13267
+ buildPageKey: buildCodingSkillPageKey,
13268
+ buildConfig: buildCodingSkillConfig,
13269
+ buildContent: buildCodingSkillContentBySlug
13270
+ },
13271
+ {
13272
+ slugs: SPECIALIST_SKILL_SLUGS,
13273
+ buildSkillId: buildSpecialistSkillId,
13274
+ buildPageKey: buildSpecialistSkillPageKey,
13275
+ buildConfig: buildSpecialistSkillConfig,
13276
+ buildContent: buildSpecialistSkillContentBySlug
13277
+ },
13278
+ {
13279
+ slugs: CODE_PLANNER_SKILL_SLUGS,
13280
+ buildSkillId: buildCodePlannerSkillId,
13281
+ buildPageKey: buildCodePlannerSkillPageKey,
13282
+ buildConfig: buildCodePlannerSkillConfig,
13283
+ buildContent: codePlannerContentBySlug
13284
+ },
13285
+ {
13286
+ slugs: SEARCH_DIALOG_SKILL_SLUGS,
13287
+ buildSkillId: buildSearchDialogSkillId,
13288
+ buildPageKey: buildSearchDialogSkillPageKey,
13289
+ buildConfig: buildSearchDialogSkillConfig,
13290
+ buildContent: buildSearchDialogSkillContentBySlug
13291
+ },
13292
+ {
13293
+ slugs: SEARCH_SPACE_SKILL_SLUGS,
13294
+ buildSkillId: buildSearchSpaceSkillId,
13295
+ buildPageKey: buildSearchSpaceSkillPageKey,
13296
+ buildConfig: buildSearchSpaceSkillConfig,
13297
+ buildContent: buildSearchSpaceSkillContentBySlug
13206
13298
  }
13207
- if (!args.contentId.trim()) {
13208
- throw new Error("\u65E0\u6CD5\u66F4\u65B0\u5206\u7C7B\uFF0C\u56E0\u4E3A\u5185\u5BB9ID\u672A\u63D0\u4F9B\u3002");
13299
+ ];
13300
+ var buildRegistry = () => {
13301
+ const entries = [];
13302
+ const seenSlugs = /* @__PURE__ */ new Set();
13303
+ for (const source of SOURCES) {
13304
+ for (const slug of source.slugs) {
13305
+ if (seenSlugs.has(slug)) {
13306
+ throw new Error(`Duplicate builtin skill slug across sources: ${slug}`);
13307
+ }
13308
+ seenSlugs.add(slug);
13309
+ const config = source.buildConfig(slug);
13310
+ entries.push({
13311
+ slug,
13312
+ skillId: source.buildSkillId(slug),
13313
+ title: config.name || slug,
13314
+ config,
13315
+ content: source.buildContent(slug),
13316
+ buildPageKey: (userId) => source.buildPageKey(userId, slug)
13317
+ });
13318
+ }
13209
13319
  }
13210
- try {
13211
- const updatedId = await dispatch(
13212
- updateContentCategory({
13213
- spaceId,
13214
- contentId: args.contentId,
13215
- categoryId: args.categoryId || void 0
13216
- })
13217
- ).unwrap();
13218
- const rawData = { success: true, id: updatedId, categoryId: args.categoryId || void 0 };
13219
- const displayData = `\u5185\u5BB9 ${updatedId} \u7684\u5206\u7C7B\u5DF2\u66F4\u65B0\u4E3A\u300C${args.categoryId ?? "\u672A\u5206\u7C7B"}\u300D\u3002`;
13220
- return { rawData, displayData };
13221
- } catch (err) {
13222
- const msg = err?.message ?? JSON.stringify(err) ?? "\u672A\u77E5\u9519\u8BEF";
13223
- throw new Error(`\u66F4\u65B0\u5206\u7C7B\u65F6\u51FA\u9519: ${msg}`);
13320
+ return entries;
13321
+ };
13322
+ var REGISTRY = buildRegistry();
13323
+ var BY_SLUG = new Map(REGISTRY.map((entry) => [entry.slug, entry]));
13324
+ var BY_SKILL_ID = new Map(REGISTRY.map((entry) => [entry.skillId, entry]));
13325
+ var BY_LOWER_NAME = new Map(
13326
+ REGISTRY.map((entry) => [entry.title.trim().toLowerCase(), entry])
13327
+ );
13328
+ var listBuiltinSkills = () => REGISTRY;
13329
+ var resolveBuiltinSkillEntry = (identifier) => {
13330
+ const raw = typeof identifier === "string" ? identifier.trim() : "";
13331
+ if (!raw) return null;
13332
+ const bySlug = BY_SLUG.get(raw);
13333
+ if (bySlug) return bySlug;
13334
+ const byId = BY_SKILL_ID.get(raw);
13335
+ if (byId) return byId;
13336
+ if (raw.startsWith("page-")) {
13337
+ for (const entry of REGISTRY) {
13338
+ if (raw.endsWith(`-${entry.skillId}`)) return entry;
13339
+ }
13224
13340
  }
13225
- }
13341
+ return null;
13342
+ };
13343
+ var resolveBuiltinSkillByName = (identifier) => {
13344
+ const raw = typeof identifier === "string" ? identifier.trim() : "";
13345
+ if (!raw) return null;
13346
+ return resolveBuiltinSkillEntry(raw) ?? BY_LOWER_NAME.get(raw.toLowerCase()) ?? null;
13347
+ };
13348
+ var resolveBuiltinSkillPage = (identifier) => {
13349
+ const entry = resolveBuiltinSkillEntry(identifier);
13350
+ if (!entry) return null;
13351
+ const raw = typeof identifier === "string" ? identifier.trim() : entry.slug;
13352
+ return {
13353
+ dbKey: raw || entry.slug,
13354
+ title: entry.title,
13355
+ content: entry.content,
13356
+ meta: { kind: "skill", skillConfig: entry.config },
13357
+ ...entry.config.toolNames?.length ? { tools: [...entry.config.toolNames] } : {}
13358
+ };
13359
+ };
13360
+ var CAPABILITIES = CAPABILITY_PACKS.map(
13361
+ (pack) => ({
13362
+ kind: "capability",
13363
+ slug: pack.id,
13364
+ title: pack.label,
13365
+ description: pack.description,
13366
+ toolNames: pack.tools,
13367
+ ...pack.promptPatch ? { promptPatch: pack.promptPatch } : {},
13368
+ icon: pack.icon,
13369
+ defaultEnabled: pack.defaultEnabled
13370
+ })
13371
+ );
13372
+ var CAPABILITY_BY_SLUG = new Map(CAPABILITIES.map((c) => [c.slug, c]));
13373
+ var resolveBuiltinCapability = (slug) => {
13374
+ const raw = typeof slug === "string" ? slug.trim() : "";
13375
+ return raw ? CAPABILITY_BY_SLUG.get(raw) ?? null : null;
13376
+ };
13226
13377
 
13227
- // packages/ai/tools/category/queryContentsByCategoryTool.ts
13228
- var queryContentsByCategoryFunctionSchema = {
13229
- name: "queryContentsByCategory",
13230
- description: "\u67E5\u8BE2\u5F53\u524D\u7A7A\u95F4\u4E2D\u67D0\u4E2A\u5206\u7C7B\u4E0B\u7684\u6240\u6709\u5185\u5BB9\u3002",
13378
+ // packages/ai/tools/agentSkillConfig.ts
13379
+ var MODES = [
13380
+ "required",
13381
+ "recommended",
13382
+ "disabled"
13383
+ ];
13384
+ var asMode = (value) => typeof value === "string" && MODES.includes(value) ? value : null;
13385
+ var resolveAgentSkillConfig = (source) => {
13386
+ const out = {};
13387
+ const skills = source?.skills;
13388
+ if (skills && typeof skills === "object" && !Array.isArray(skills)) {
13389
+ for (const [rawSlug, rawMode] of Object.entries(skills)) {
13390
+ const slug = typeof rawSlug === "string" ? rawSlug.trim() : "";
13391
+ const mode = asMode(rawMode);
13392
+ if (slug && mode) out[slug] = mode;
13393
+ }
13394
+ return out;
13395
+ }
13396
+ for (const slug of asTrimmedNonEmptyStringArray(source?.enabledPacks) ?? []) {
13397
+ out[slug] = "required";
13398
+ }
13399
+ return out;
13400
+ };
13401
+ var resolveAgentRequiredPackIds = (source) => {
13402
+ const config = resolveAgentSkillConfig(source);
13403
+ return Object.keys(config).filter((slug) => config[slug] === "required");
13404
+ };
13405
+ var resolveAgentRecommendedSkillNames = (source, lookup) => {
13406
+ const config = resolveAgentSkillConfig(source);
13407
+ const resolve = lookup ?? defaultSkillTitleLookup;
13408
+ const out = [];
13409
+ for (const slug of Object.keys(config)) {
13410
+ if (config[slug] !== "recommended") continue;
13411
+ const title = resolve(slug)?.title;
13412
+ out.push(title || slug);
13413
+ }
13414
+ return out;
13415
+ };
13416
+ var defaultSkillTitleLookup = (slug) => {
13417
+ const cap = resolveBuiltinCapability(slug);
13418
+ if (cap) return { title: cap.title };
13419
+ const skill = resolveBuiltinSkillEntry(slug);
13420
+ return skill ? { title: skill.title } : null;
13421
+ };
13422
+ var isAgentSkillDisabled = (source, slug) => resolveAgentSkillConfig(source)[slug] === "disabled";
13423
+
13424
+ // packages/ai/tools/loadSkillTool.ts
13425
+ var loadSkillFunctionSchema = {
13426
+ name: "loadSkill",
13427
+ description: [
13428
+ "\u6309\u540D\u79F0\u52A0\u8F7D\u4E00\u4E2A\u5DF2\u4FDD\u5B58\u7684 skill \u6587\u6863\uFF0C\u8FD4\u56DE\u5176\u5B8C\u6574\u6307\u4EE4\u6B63\u6587\u3002",
13429
+ "name \u4F7F\u7528 skill \u4FDD\u5B58\u65F6\u5199\u5165 skill-config \u7684 name\uFF08\u4E5F\u63A5\u53D7 skillId\uFF09\u3002",
13430
+ "\u627E\u4E0D\u5230\u5BF9\u5E94 skill \u65F6\u8FD4\u56DE\u5F53\u524D\u53EF\u7528\u7684 skill \u540D\u79F0\u5217\u8868\uFF08\u4E0D\u62A5\u9519\uFF09\u3002",
13431
+ '\u7CFB\u7EDF\u5185\u7F6E\u5199\u4EE3\u7801\u6280\u80FD\uFF1A\u5BF9\u8BDD\u8F6C\u5411\u5199\u4EE3\u7801\u65F6\u7528 loadSkill("coding") \u8F7D\u5165\u5199\u4EE3\u7801\u80FD\u529B\u4E0E\u4EE3\u7801\u5BA1\u67E5\u7EAA\u5F8B\uFF08\u542B review \u89D2\u8272\u5207\u5272\uFF09\u3002',
13432
+ "\u7CFB\u7EDF\u5185\u7F6E\u4E13\u804C\u6280\u80FD\uFF1Afeedback\uFF08\u53CD\u9988\u6536\u96C6\uFF09/ agent-creator\uFF08\u521B\u5EFA Agent\uFF09/ app-builder\uFF08\u5E94\u7528\u6784\u5EFA\uFF09\uFF0C\u540C\u6837\u53EF\u76F4\u63A5 loadSkill \u8F7D\u5165\u3002"
13433
+ ].join("\n"),
13231
13434
  parameters: {
13232
13435
  type: "object",
13233
13436
  properties: {
13234
- categoryId: {
13235
- type: "string",
13236
- description: "\u5206\u7C7BID\uFF0C\u53EF\u9009\uFF0C\u4E0D\u63D0\u4F9B\u5219\u67E5\u8BE2\u672A\u5206\u7C7B\u5185\u5BB9"
13237
- },
13238
- filter: {
13437
+ name: {
13239
13438
  type: "string",
13240
- description: "\u6807\u9898\u5173\u952E\u5B57\u8FC7\u6EE4\uFF0C\u53EF\u9009"
13439
+ description: "\u8981\u52A0\u8F7D\u7684 skill \u540D\u79F0\u3002"
13241
13440
  }
13242
13441
  },
13243
- required: []
13442
+ required: ["name"]
13244
13443
  }
13245
13444
  };
13246
- async function queryContentsByCategoryFunc(args, thunkApi) {
13247
- const { getState } = thunkApi;
13248
- const state = getState();
13249
- const spaceId = selectCurrentSpaceId(state);
13250
- if (!spaceId) {
13251
- throw new Error("\u65E0\u6CD5\u67E5\u8BE2\u5185\u5BB9\uFF0C\u56E0\u4E3A\u5F53\u524D\u7A7A\u95F4\u672A\u8BBE\u5B9A\u3002");
13445
+ var getRuntime = (thunkApi) => {
13446
+ const state = thunkApi?.getState?.();
13447
+ return state ? selectRuntimeSnapshot(state) : null;
13448
+ };
13449
+ var authHeaders = (token) => token ? { Authorization: `Bearer ${token}` } : {};
13450
+ async function readRemoteRecord(args) {
13451
+ const serverBase = normalizeServerOrigin(args.serverBase);
13452
+ if (!serverBase || !args.token) return null;
13453
+ const response = await fetch(
13454
+ `${serverBase}/api/v1/db/read/${encodeURIComponent(args.dbKey)}?includeDeleted=true`,
13455
+ { headers: authHeaders(args.token) }
13456
+ );
13457
+ if (!response.ok) return null;
13458
+ const payload = await response.json().catch(() => null);
13459
+ return payload?.data ?? payload;
13460
+ }
13461
+ function resolveWebSkill(candidates, requestedName) {
13462
+ const candidate = matchSkillCandidate(candidates, requestedName);
13463
+ if (candidate) return { kind: "space", candidate };
13464
+ const entry = resolveBuiltinSkillByName(requestedName);
13465
+ return entry ? { kind: "builtin", entry } : null;
13466
+ }
13467
+ function listWebSkillNames(candidates) {
13468
+ return Array.from(
13469
+ /* @__PURE__ */ new Set([
13470
+ ...candidates.map((candidate) => candidate.name),
13471
+ ...listBuiltinSkills().flatMap((skill) => [skill.slug, skill.title])
13472
+ ])
13473
+ );
13474
+ }
13475
+ function matchSkillCandidate(candidates, requestedName) {
13476
+ return candidates.find(
13477
+ (candidate) => candidate.name === requestedName || candidate.skillId === requestedName
13478
+ );
13479
+ }
13480
+ function collectSkillCandidatesFromSpace(space) {
13481
+ if (!space?.contents || typeof space.contents !== "object") return [];
13482
+ const candidates = [];
13483
+ for (const [entryKey, value] of Object.entries(space.contents)) {
13484
+ if (!isRecord(value)) continue;
13485
+ const skillSummary = value.skillSummary;
13486
+ if (!isSkillSummaryMarker(skillSummary)) continue;
13487
+ const name = asTrimmedString(skillSummary.name);
13488
+ if (!name) continue;
13489
+ candidates.push({
13490
+ dbKey: entryKey,
13491
+ name,
13492
+ skillId: asOptionalTrimmedString(skillSummary.skillId) ?? void 0
13493
+ });
13252
13494
  }
13253
- const currentSpace = state.space.currentSpace;
13254
- if (!currentSpace) {
13255
- throw new Error("\u5F53\u524D\u7A7A\u95F4\u6570\u636E\u672A\u627E\u5230\u3002");
13495
+ return candidates;
13496
+ }
13497
+ function extractSkillBody(page) {
13498
+ return parseSkillDocProtocol(page?.content ?? "").content;
13499
+ }
13500
+ async function listSkillCandidates(thunkApi) {
13501
+ const runtime = getRuntime(thunkApi);
13502
+ const serverBase = runtime?.currentServer;
13503
+ const token = runtime?.currentToken;
13504
+ const userId = runtime?.currentUserId;
13505
+ if (!serverBase || !token || !userId) return [];
13506
+ const membershipsResponse = await fetch(
13507
+ `${normalizeServerOrigin(serverBase)}/rpc/getUserSpaceMemberships`,
13508
+ {
13509
+ method: "POST",
13510
+ headers: {
13511
+ "Content-Type": "application/json",
13512
+ ...authHeaders(token)
13513
+ },
13514
+ body: JSON.stringify({ userId })
13515
+ }
13516
+ ).catch(() => null);
13517
+ if (!membershipsResponse?.ok) return [];
13518
+ const memberships = await membershipsResponse.json().catch(() => []);
13519
+ if (!Array.isArray(memberships)) return [];
13520
+ const candidates = [];
13521
+ for (const membership of memberships) {
13522
+ const spaceId = asTrimmedString(membership?.spaceId);
13523
+ if (!spaceId) continue;
13524
+ const space = await readRemoteRecord({
13525
+ serverBase,
13526
+ token,
13527
+ dbKey: createSpaceKey.space(spaceId)
13528
+ });
13529
+ if (!space) continue;
13530
+ candidates.push(...collectSkillCandidatesFromSpace(space));
13256
13531
  }
13257
- let list = Object.values(currentSpace.contents || {});
13258
- if (args.categoryId != null) {
13259
- list = list.filter((c) => c.categoryId === args.categoryId);
13260
- } else {
13261
- list = list.filter((c) => !c.categoryId);
13532
+ return candidates;
13533
+ }
13534
+ var resolveCurrentAgentKeyForSkillGate = (thunkApi) => {
13535
+ try {
13536
+ const state = thunkApi?.getState?.();
13537
+ if (!state) return null;
13538
+ const currentDialogKey = getActiveDialogKey();
13539
+ if (!currentDialogKey) return null;
13540
+ const dialogConfig = selectById(
13541
+ state,
13542
+ currentDialogKey
13543
+ );
13544
+ return asTrimmedNonEmptyStringArray(dialogConfig?.cybots)[0] ?? null;
13545
+ } catch {
13546
+ return null;
13262
13547
  }
13263
- if (args.filter) {
13264
- const kw = args.filter.toLowerCase();
13265
- list = list.filter((c) => (c.title ?? "").toLowerCase().includes(kw));
13548
+ };
13549
+ var readCurrentAgentSkillSource = async (thunkApi) => {
13550
+ const agentKey = resolveCurrentAgentKeyForSkillGate(thunkApi);
13551
+ if (!agentKey) return null;
13552
+ const db = thunkApi?.extra?.db;
13553
+ if (!db) return null;
13554
+ try {
13555
+ const agent = await db.get(agentKey);
13556
+ if (!agent || typeof agent !== "object") return null;
13557
+ return agent;
13558
+ } catch {
13559
+ return null;
13560
+ }
13561
+ };
13562
+ async function loadSkillFunc(args, thunkApi) {
13563
+ const requestedName = asTrimmedString(args?.name);
13564
+ if (!requestedName) throw new Error("loadSkill \u9700\u8981\u63D0\u4F9B name\u3002");
13565
+ const candidates = await listSkillCandidates(thunkApi);
13566
+ const resolution = resolveWebSkill(candidates, requestedName);
13567
+ const matched = resolution?.kind === "space" ? resolution.candidate : void 0;
13568
+ const builtinEntry = resolution?.kind === "builtin" ? resolution.entry : null;
13569
+ const resolvedSlug = builtinEntry?.slug ?? matched?.skillId ?? null;
13570
+ if (resolvedSlug) {
13571
+ const agentSkillSource = await readCurrentAgentSkillSource(thunkApi);
13572
+ if (agentSkillSource && isAgentSkillDisabled(agentSkillSource, resolvedSlug)) {
13573
+ return {
13574
+ rawData: {
13575
+ success: false,
13576
+ name: requestedName,
13577
+ slug: resolvedSlug,
13578
+ disabled: true
13579
+ },
13580
+ displayData: `Skill "${requestedName}" \u5DF2\u88AB\u7981\u7528\uFF1A\u8BE5\u80FD\u529B\u5728\u6B64 agent \u4E0A\u4E0D\u53EF\u7528\uFF0C\u65E0\u6CD5\u52A0\u8F7D\u3002`
13581
+ };
13582
+ }
13583
+ }
13584
+ if (builtinEntry) {
13585
+ const body2 = builtinEntry.content;
13586
+ const dbKey = builtinEntry.slug;
13587
+ await persistLoadedSkillReference(thunkApi, dbKey, requestedName);
13588
+ return {
13589
+ rawData: {
13590
+ success: true,
13591
+ name: requestedName,
13592
+ dbKey,
13593
+ body: body2
13594
+ },
13595
+ displayData: `Skill "${requestedName}" loaded inline. Follow its instructions.
13596
+
13597
+ ${body2}`
13598
+ };
13599
+ }
13600
+ if (!matched) {
13601
+ const availableNames = listWebSkillNames(candidates);
13602
+ const availableText = availableNames.length ? availableNames.join(", ") : "(none)";
13603
+ return {
13604
+ rawData: {
13605
+ success: false,
13606
+ name: requestedName,
13607
+ availableSkills: availableNames
13608
+ },
13609
+ displayData: `Skill "${requestedName}" not found. Available skills: ${availableText}`
13610
+ };
13611
+ }
13612
+ const runtime = getRuntime(thunkApi);
13613
+ const page = await readRemoteRecord({
13614
+ serverBase: runtime?.currentServer,
13615
+ token: runtime?.currentToken,
13616
+ dbKey: matched.dbKey
13617
+ });
13618
+ const body = extractSkillBody(page);
13619
+ await persistLoadedSkillReference(thunkApi, matched.dbKey, requestedName);
13620
+ return {
13621
+ rawData: {
13622
+ success: true,
13623
+ name: requestedName,
13624
+ dbKey: matched.dbKey,
13625
+ body
13626
+ },
13627
+ displayData: `Skill "${requestedName}" loaded inline. Follow its instructions.
13628
+
13629
+ ${body}`
13630
+ };
13631
+ }
13632
+ async function persistLoadedSkillReference(thunkApi, dbKey, name) {
13633
+ try {
13634
+ const state = thunkApi?.getState?.();
13635
+ const currentDialogKey = getActiveDialogKey();
13636
+ if (!state || !currentDialogKey) return;
13637
+ const dialogConfig = selectById(
13638
+ state,
13639
+ currentDialogKey
13640
+ );
13641
+ const existing = dialogConfig?.extraReferences ?? [];
13642
+ const alreadyMounted = existing.some((ref) => ref.dbKey === dbKey);
13643
+ if (alreadyMounted) return;
13644
+ const newRef = {
13645
+ dbKey,
13646
+ title: name,
13647
+ type: "instruction"
13648
+ };
13649
+ await setDialogExtraReferencesAction([...existing, newRef], thunkApi);
13650
+ } catch {
13266
13651
  }
13267
- const rawData = { success: true, contents: list };
13268
- const displayData = `\u5171\u67E5\u8BE2\u5230 ${list.length} \u6761\u5185\u5BB9\u3002`;
13269
- return { rawData, displayData };
13270
13652
  }
13271
13653
 
13272
- // packages/ai/tools/executeSqlTool.ts
13273
- var executeSqlFunctionSchema = {
13274
- name: "executeSql",
13275
- description: "\u76F4\u63A5\u5728 SQLite \u6570\u636E\u5E93\u4E2D\u6267\u884C\u4EFB\u610F SQL \u8BED\u53E5\uFF0C\u5305\u62EC\u67E5\u8BE2\u3001\u63D2\u5165\u3001\u66F4\u65B0\u3001\u5220\u9664\u548C\u8868\u7ED3\u6784\u64CD\u4F5C\u3002\u5185\u90E8\u652F\u6301\u53C2\u6570\u5316\u67E5\u8BE2\u4EE5\u9632\u6B62SQL\u6CE8\u5165\u3002",
13654
+ // packages/ai/tools/category/createCategoryTool.ts
13655
+ var createCategoryFunctionSchema = {
13656
+ // 已从 'create_category' 更新为 'createCategory'
13657
+ name: "createCategory",
13658
+ description: "\u5728\u5F53\u524D\u7A7A\u95F4\u4E2D\u521B\u5EFA\u65B0\u5206\u7C7B\u3002",
13276
13659
  parameters: {
13277
13660
  type: "object",
13278
13661
  properties: {
13279
- sqlQuery: {
13662
+ name: {
13280
13663
  type: "string",
13281
- description: "\u8981\u6267\u884C\u7684\u5B8C\u6574 SQL \u8BED\u53E5\u3002\u4F8B\u5982\uFF1ASELECT * FROM users; INSERT INTO products (name, price) VALUES ('Milk', 2.5);"
13664
+ description: "\u5206\u7C7B\u540D\u79F0"
13282
13665
  }
13283
- // 注意:params 字段不向 LLM 暴露,这是内部实现细节
13284
13666
  },
13285
- required: ["sqlQuery"]
13667
+ required: ["name"]
13286
13668
  }
13287
13669
  };
13288
- var buildRequestHeaders = (token) => {
13289
- const headers = { "Content-Type": "application/json" };
13290
- if (token) headers["Authorization"] = `Bearer ${token}`;
13291
- return headers;
13292
- };
13293
- var handleApiResponse = async (response) => {
13294
- if (!response.ok) {
13295
- let errorMessage = `API \u9519\u8BEF\uFF01\u72B6\u6001\u7801: ${response.status}`;
13296
- try {
13297
- const errorData = await response.json();
13298
- if (errorData?.error) {
13299
- errorMessage += `: ${errorData.error.message || JSON.stringify(errorData.error)}`;
13300
- }
13301
- } catch (e) {
13302
- }
13303
- throw new Error(errorMessage);
13670
+ async function createCategoryFunc(args, thunkApi) {
13671
+ const { getState } = thunkApi;
13672
+ const dispatch = thunkApi.dispatch.bind(thunkApi);
13673
+ const state = getState();
13674
+ const spaceId = selectCurrentSpaceId(state);
13675
+ if (!spaceId) {
13676
+ throw new Error("\u65E0\u6CD5\u521B\u5EFA\u5206\u7C7B\uFF0C\u56E0\u4E3A\u5F53\u524D\u7A7A\u95F4\u672A\u8BBE\u5B9A\u3002");
13304
13677
  }
13305
- return response.json();
13306
- };
13307
- var formatSqlResultText = (data, sqlQuery, params) => {
13308
- if (!data.success) return `SQL \u6267\u884C\u5931\u8D25\uFF1A${data.error || "\u672A\u77E5\u9519\u8BEF"}`;
13309
- const result = data.result;
13310
- if (params && params.length > 0 && asTrimmedLowercaseString(sqlQuery).startsWith("insert")) {
13311
- const changes = result?.changes ?? 0;
13312
- const match = sqlQuery.match(/insert\s+into\s+['"]?(\w+)['"]?/i);
13313
- const tableName = match ? ` "${match[1]}"` : "";
13314
- if (changes > 0) {
13315
- return `\u2705 \u6210\u529F\u5411\u8868${tableName}\u4E2D\u6279\u91CF\u63D2\u5165\u4E86 ${changes} \u6761\u8BB0\u5F55\u3002`;
13316
- }
13678
+ const name = args.name.trim() || "\u65B0\u5206\u7C7B";
13679
+ try {
13680
+ const { updatedSpaceData } = await dispatch(
13681
+ addCategory({ spaceId, name })
13682
+ ).unwrap();
13683
+ const newCategoryId = Object.keys(updatedSpaceData.categories).find(
13684
+ (id) => updatedSpaceData.categories[id]?.name === name
13685
+ ) || "";
13686
+ const rawData = { success: true, id: newCategoryId, name };
13687
+ const displayData = `\u5206\u7C7B\u300C${name}\u300D\u5DF2\u6210\u529F\u521B\u5EFA\u3002`;
13688
+ return { rawData, displayData };
13689
+ } catch (error) {
13690
+ const msg = error?.message || JSON.stringify(error) || "\u672A\u77E5\u9519\u8BEF";
13691
+ throw new Error(`\u521B\u5EFA\u5206\u7C7B\u65F6\u51FA\u9519: ${msg}`);
13317
13692
  }
13318
- const lowerCaseQuery = asTrimmedLowercaseString(sqlQuery);
13319
- if (lowerCaseQuery.startsWith("create table")) {
13320
- const match = sqlQuery.match(
13321
- /create\s+table\s+(?:if\s+not\s+exists\s+)?['"]?(\w+)['"]?/i
13322
- );
13323
- const tableName = match ? match[1] : "\u65B0";
13324
- return `\u2705 \u8868 "${tableName}" \u5DF2\u6210\u529F\u521B\u5EFA\u3002`;
13693
+ }
13694
+
13695
+ // packages/ai/tools/category/updateContentCategoryTool.ts
13696
+ var updateContentCategoryFunctionSchema = {
13697
+ name: "updateContentCategory",
13698
+ description: "\u66F4\u65B0\u5F53\u524D\u7A7A\u95F4\u4E2D\u67D0\u4E2A\u5185\u5BB9\u7684\u5206\u7C7B\u3002",
13699
+ parameters: {
13700
+ type: "object",
13701
+ properties: {
13702
+ contentId: {
13703
+ type: "string",
13704
+ description: "\u8981\u66F4\u65B0\u7684\u5185\u5BB9ID"
13705
+ },
13706
+ categoryId: {
13707
+ type: "string",
13708
+ description: "\u65B0\u7684\u5206\u7C7BID\uFF0C\u53EF\u9009\uFF0C\u4E0D\u63D0\u4F9B\u5219\u8BBE\u4E3A\u672A\u5206\u7C7B"
13709
+ }
13710
+ },
13711
+ required: ["contentId"]
13712
+ }
13713
+ };
13714
+ async function updateContentCategoryFunc(args, thunkApi) {
13715
+ const { getState } = thunkApi;
13716
+ const dispatch = thunkApi.dispatch.bind(thunkApi);
13717
+ const state = getState();
13718
+ const spaceId = selectCurrentSpaceId(state);
13719
+ if (!spaceId) {
13720
+ throw new Error("\u65E0\u6CD5\u66F4\u65B0\u5206\u7C7B\uFF0C\u56E0\u4E3A\u5F53\u524D\u7A7A\u95F4\u672A\u8BBE\u5B9A\u3002");
13721
+ }
13722
+ if (!args.contentId.trim()) {
13723
+ throw new Error("\u65E0\u6CD5\u66F4\u65B0\u5206\u7C7B\uFF0C\u56E0\u4E3A\u5185\u5BB9ID\u672A\u63D0\u4F9B\u3002");
13724
+ }
13725
+ try {
13726
+ const updatedId = await dispatch(
13727
+ updateContentCategory({
13728
+ spaceId,
13729
+ contentId: args.contentId,
13730
+ categoryId: args.categoryId || void 0
13731
+ })
13732
+ ).unwrap();
13733
+ const rawData = { success: true, id: updatedId, categoryId: args.categoryId || void 0 };
13734
+ const displayData = `\u5185\u5BB9 ${updatedId} \u7684\u5206\u7C7B\u5DF2\u66F4\u65B0\u4E3A\u300C${args.categoryId ?? "\u672A\u5206\u7C7B"}\u300D\u3002`;
13735
+ return { rawData, displayData };
13736
+ } catch (err) {
13737
+ const msg = err?.message ?? JSON.stringify(err) ?? "\u672A\u77E5\u9519\u8BEF";
13738
+ throw new Error(`\u66F4\u65B0\u5206\u7C7B\u65F6\u51FA\u9519: ${msg}`);
13739
+ }
13740
+ }
13741
+
13742
+ // packages/ai/tools/category/queryContentsByCategoryTool.ts
13743
+ var queryContentsByCategoryFunctionSchema = {
13744
+ name: "queryContentsByCategory",
13745
+ description: "\u67E5\u8BE2\u5F53\u524D\u7A7A\u95F4\u4E2D\u67D0\u4E2A\u5206\u7C7B\u4E0B\u7684\u6240\u6709\u5185\u5BB9\u3002",
13746
+ parameters: {
13747
+ type: "object",
13748
+ properties: {
13749
+ categoryId: {
13750
+ type: "string",
13751
+ description: "\u5206\u7C7BID\uFF0C\u53EF\u9009\uFF0C\u4E0D\u63D0\u4F9B\u5219\u67E5\u8BE2\u672A\u5206\u7C7B\u5185\u5BB9"
13752
+ },
13753
+ filter: {
13754
+ type: "string",
13755
+ description: "\u6807\u9898\u5173\u952E\u5B57\u8FC7\u6EE4\uFF0C\u53EF\u9009"
13756
+ }
13757
+ },
13758
+ required: []
13759
+ }
13760
+ };
13761
+ async function queryContentsByCategoryFunc(args, thunkApi) {
13762
+ const { getState } = thunkApi;
13763
+ const state = getState();
13764
+ const spaceId = selectCurrentSpaceId(state);
13765
+ if (!spaceId) {
13766
+ throw new Error("\u65E0\u6CD5\u67E5\u8BE2\u5185\u5BB9\uFF0C\u56E0\u4E3A\u5F53\u524D\u7A7A\u95F4\u672A\u8BBE\u5B9A\u3002");
13767
+ }
13768
+ const currentSpace = state.space.currentSpace;
13769
+ if (!currentSpace) {
13770
+ throw new Error("\u5F53\u524D\u7A7A\u95F4\u6570\u636E\u672A\u627E\u5230\u3002");
13771
+ }
13772
+ let list = Object.values(currentSpace.contents || {});
13773
+ if (args.categoryId != null) {
13774
+ list = list.filter((c) => c.categoryId === args.categoryId);
13775
+ } else {
13776
+ list = list.filter((c) => !c.categoryId);
13777
+ }
13778
+ if (args.filter) {
13779
+ const kw = args.filter.toLowerCase();
13780
+ list = list.filter((c) => (c.title ?? "").toLowerCase().includes(kw));
13781
+ }
13782
+ const rawData = { success: true, contents: list };
13783
+ const displayData = `\u5171\u67E5\u8BE2\u5230 ${list.length} \u6761\u5185\u5BB9\u3002`;
13784
+ return { rawData, displayData };
13785
+ }
13786
+
13787
+ // packages/ai/tools/executeSqlTool.ts
13788
+ var executeSqlFunctionSchema = {
13789
+ name: "executeSql",
13790
+ description: "\u76F4\u63A5\u5728 SQLite \u6570\u636E\u5E93\u4E2D\u6267\u884C\u4EFB\u610F SQL \u8BED\u53E5\uFF0C\u5305\u62EC\u67E5\u8BE2\u3001\u63D2\u5165\u3001\u66F4\u65B0\u3001\u5220\u9664\u548C\u8868\u7ED3\u6784\u64CD\u4F5C\u3002\u5185\u90E8\u652F\u6301\u53C2\u6570\u5316\u67E5\u8BE2\u4EE5\u9632\u6B62SQL\u6CE8\u5165\u3002",
13791
+ parameters: {
13792
+ type: "object",
13793
+ properties: {
13794
+ sqlQuery: {
13795
+ type: "string",
13796
+ description: "\u8981\u6267\u884C\u7684\u5B8C\u6574 SQL \u8BED\u53E5\u3002\u4F8B\u5982\uFF1ASELECT * FROM users; INSERT INTO products (name, price) VALUES ('Milk', 2.5);"
13797
+ }
13798
+ // 注意:params 字段不向 LLM 暴露,这是内部实现细节
13799
+ },
13800
+ required: ["sqlQuery"]
13801
+ }
13802
+ };
13803
+ var buildRequestHeaders = (token) => {
13804
+ const headers = { "Content-Type": "application/json" };
13805
+ if (token) headers["Authorization"] = `Bearer ${token}`;
13806
+ return headers;
13807
+ };
13808
+ var handleApiResponse = async (response) => {
13809
+ if (!response.ok) {
13810
+ let errorMessage = `API \u9519\u8BEF\uFF01\u72B6\u6001\u7801: ${response.status}`;
13811
+ try {
13812
+ const errorData = await response.json();
13813
+ if (errorData?.error) {
13814
+ errorMessage += `: ${errorData.error.message || JSON.stringify(errorData.error)}`;
13815
+ }
13816
+ } catch (e) {
13817
+ }
13818
+ throw new Error(errorMessage);
13819
+ }
13820
+ return response.json();
13821
+ };
13822
+ var formatSqlResultText = (data, sqlQuery, params) => {
13823
+ if (!data.success) return `SQL \u6267\u884C\u5931\u8D25\uFF1A${data.error || "\u672A\u77E5\u9519\u8BEF"}`;
13824
+ const result = data.result;
13825
+ if (params && params.length > 0 && asTrimmedLowercaseString(sqlQuery).startsWith("insert")) {
13826
+ const changes = result?.changes ?? 0;
13827
+ const match = sqlQuery.match(/insert\s+into\s+['"]?(\w+)['"]?/i);
13828
+ const tableName = match ? ` "${match[1]}"` : "";
13829
+ if (changes > 0) {
13830
+ return `\u2705 \u6210\u529F\u5411\u8868${tableName}\u4E2D\u6279\u91CF\u63D2\u5165\u4E86 ${changes} \u6761\u8BB0\u5F55\u3002`;
13831
+ }
13832
+ }
13833
+ const lowerCaseQuery = asTrimmedLowercaseString(sqlQuery);
13834
+ if (lowerCaseQuery.startsWith("create table")) {
13835
+ const match = sqlQuery.match(
13836
+ /create\s+table\s+(?:if\s+not\s+exists\s+)?['"]?(\w+)['"]?/i
13837
+ );
13838
+ const tableName = match ? match[1] : "\u65B0";
13839
+ return `\u2705 \u8868 "${tableName}" \u5DF2\u6210\u529F\u521B\u5EFA\u3002`;
13325
13840
  }
13326
13841
  if (Array.isArray(result)) {
13327
13842
  const isListTablesQuery = lowerCaseQuery.includes("select") && lowerCaseQuery.includes("name") && lowerCaseQuery.includes("sqlite_master") && lowerCaseQuery.includes("type") && lowerCaseQuery.includes("'table'");
@@ -14037,11 +14552,17 @@ async function listDialogsFunc(args, thunkApi) {
14037
14552
  }
14038
14553
  var readDialogFunctionSchema = {
14039
14554
  name: "readDialog",
14040
- description: "Read one persisted Nolo dialog, including metadata and recent messages.",
14555
+ description: [
14556
+ "Read one persisted Nolo dialog, including metadata and recent messages.",
14557
+ "Prefer the full dialog dbKey (dialog-<userId>-<id>) or a dialog URL; a bare id only resolves for the currently logged-in user and cannot reliably read other users' or cross-server dialogs. Use listDialogs first when the target dialog is unclear."
14558
+ ].join("\n"),
14041
14559
  parameters: {
14042
14560
  type: "object",
14043
14561
  properties: {
14044
- dialog: { type: "string", description: "Dialog id, dialog dbKey, or dialog URL." },
14562
+ dialog: {
14563
+ type: "string",
14564
+ description: "Dialog dbKey (dialog-<userId>-<id>), dialog URL, or bare id (current user only)."
14565
+ },
14045
14566
  limit: { type: "integer", description: "Message limit. Default 120, max 1000." }
14046
14567
  },
14047
14568
  required: ["dialog"]
@@ -14252,7 +14773,7 @@ async function deleteDialogsFunc(args, thunkApi) {
14252
14773
  const deletedDialogIds = [];
14253
14774
  const deletedDialogKeys = [];
14254
14775
  const failures = [];
14255
- const { deleteDialog } = await import("./dialogSlice-UQAXF23P.js");
14776
+ const { deleteDialog } = await import("./dialogSlice-KLLVH4WI.js");
14256
14777
  for (const target of targets) {
14257
14778
  try {
14258
14779
  await thunkApi.dispatch(deleteDialog(target.dbKey)).unwrap();
@@ -14312,7 +14833,7 @@ async function fetchUserFavoriteAgentMap(thunkApi) {
14312
14833
  return {};
14313
14834
  }
14314
14835
  }
14315
- function formatAgentListCard(agents, maxDisplay = 20) {
14836
+ function formatAgentListCard(agents, maxDisplay = 8) {
14316
14837
  const total = agents.length;
14317
14838
  const lines = [`Agents (${total})`];
14318
14839
  const visible = agents.slice(0, maxDisplay);
@@ -14331,7 +14852,7 @@ function formatAgentListCard(agents, maxDisplay = 20) {
14331
14852
  }
14332
14853
  var listAgentsFunctionSchema = {
14333
14854
  name: "listAgents",
14334
- description: "List the current user's Nolo agents as safe summaries. The `agents` array in the JSON result carries each agent's runnable `agentKey` (agent-<userId>-<id> for owned, agent-pub-<id> for public) plus model, apiSource, tools, prices, isOwned, isFavorite. Copy `agentKey` verbatim into startAgentRun/callAgent. Prefer isOwned agents (use your own quota, no platform credits).",
14855
+ description: "List the current user's Nolo agents as safe summaries. The `agents` array in the JSON result carries each agent's runnable `agentKey` (agent-<userId>-<id> for owned, agent-pub-<id> for public) plus model, apiSource, tools, prices, isOwned, isOAuth, nextAvailableAt (epoch ms when temporarily unavailable), isFavorite. Copy `agentKey` verbatim into startAgentRun. Results prioritize favorites; within that, user OAuth/custom agents first, then other owned agents, then public agents.",
14335
14856
  parameters: {
14336
14857
  type: "object",
14337
14858
  properties: {
@@ -14380,7 +14901,7 @@ async function listAgentsFunc(args, thunkApi) {
14380
14901
  }
14381
14902
  var readAgentFunctionSchema = {
14382
14903
  name: "readAgent",
14383
- description: "Read one agent's full config from the Nolo workspace. Accepts an agent dbKey (agent-xxx), plain id, alias, or agent URL; resolves it (including public agents via agent-pub-<id>; the server runtime also falls back to handle lookup) and returns the runnable agentKey plus a redacted record with fields such as model, provider, apiSource, tools, prompt, inputPrice, outputPrice, and isPublic. Use it to inspect an agent's full capabilities/credential status before delegation. Note: startAgentRun/callAgent take the exact agentKey from listAgents/readAgent; readAgent is not required before every dispatch when listAgents already gave you the key.",
14904
+ description: "Read one agent's full config from the Nolo workspace. Accepts an agent dbKey (agent-xxx), plain id, alias, or agent URL; resolves it (including public agents via agent-pub-<id>; the server runtime also falls back to handle lookup) and returns the runnable agentKey plus a redacted record with fields such as model, provider, apiSource, tools, prompt, inputPrice, outputPrice, and isPublic. Use it to inspect an agent's full capabilities/credential status before delegation. Note: startAgentRun takes the exact agentKey from listAgents/readAgent; readAgent is not required before every dispatch when listAgents already gave you the key.",
14384
14905
  parameters: {
14385
14906
  type: "object",
14386
14907
  properties: {
@@ -14520,7 +15041,7 @@ var readSkillDocFunctionSchema = {
14520
15041
  }
14521
15042
  };
14522
15043
  async function readSkillDocFunc(args, thunkApi) {
14523
- const { buildReadDocResult } = await import("./readDocTool-VSYHKK3V.js");
15044
+ const { buildReadDocResult } = await import("./readDocTool-FOHWVA4R.js");
14524
15045
  const id = args?.id ?? args?.doc ?? args?.docKey ?? args?.pageKey;
14525
15046
  if (typeof id !== "string" || !id.trim()) {
14526
15047
  throw new Error("readSkillDoc requires id or doc.");
@@ -19195,7 +19716,7 @@ var cloudflareCrawlStatusFunctionSchema = {
19195
19716
  async function cloudflareCrawlStatusFunc(args, thunkApi) {
19196
19717
  const { jobId, limit, status, cursor } = args;
19197
19718
  if (!jobId) throw new Error("\u5FC5\u987B\u63D0\u4F9B jobId");
19198
- const { getToolRequestContext: getToolRequestContext2 } = await import("./toolApiClient-QI3YBNWB.js");
19719
+ const { getToolRequestContext: getToolRequestContext2 } = await import("./toolApiClient-ISM4ZQX4.js");
19199
19720
  const { baseUrl, token } = getToolRequestContext2(thunkApi);
19200
19721
  const params = new URLSearchParams();
19201
19722
  if (limit !== void 0) params.set("limit", String(limit));
@@ -19970,7 +20491,7 @@ var selectUserIdFromState = (state) => typeof state?.auth?.currentUser?.userId =
19970
20491
  var selectCurrentServerFromState = (state) => typeof state?.settings?.currentServer === "string" ? state.settings.currentServer : null;
19971
20492
  async function addImageContentToSpace(input) {
19972
20493
  const injectedAddContentAction = input.thunkApi?.extra?.addContentAction;
19973
- const addContentAction2 = typeof injectedAddContentAction === "function" ? injectedAddContentAction : (await import("./addContentAction-PL3KKBDH.js")).addContentAction;
20494
+ const addContentAction2 = typeof injectedAddContentAction === "function" ? injectedAddContentAction : (await import("./addContentAction-UNSYTVTB.js")).addContentAction;
19974
20495
  await addContentAction2(
19975
20496
  {
19976
20497
  spaceId: input.spaceId,
@@ -21105,480 +21626,77 @@ ${displayParts.join("\n")}`
21105
21626
  };
21106
21627
  }
21107
21628
 
21108
- // packages/app/utils/retryAfter.ts
21109
- var resolveRetryAfterMs = (headers, fallbackMs, bodyRetryAfterMs) => {
21110
- const headerDelayMs = parseRetryAfterHeaderMs(headers?.get("Retry-After"));
21111
- if (headerDelayMs !== null) return headerDelayMs;
21112
- return normalizeNonNegativeMs(bodyRetryAfterMs, fallbackMs);
21629
+ // packages/ai/agent/guidedCreation/capabilities.ts
21630
+ var GUIDED_AGENT_CAPABILITIES = {
21631
+ webSearch: {
21632
+ id: "webSearch",
21633
+ label: { zhCN: "\u8054\u7F51\u641C\u7D22", en: "Search the web" },
21634
+ description: {
21635
+ zhCN: "\u9700\u8981\u83B7\u53D6\u5916\u90E8\u7F51\u9875\u3001\u8D44\u6599\u6216\u6700\u65B0\u4FE1\u606F\u65F6\u4F7F\u7528\u3002",
21636
+ en: "Use when the agent needs external webpages, research, or current information."
21637
+ },
21638
+ toolIds: ["exa_search", "firecrawl_search", "firecrawl_scrape", "fetchWebpage"]
21639
+ },
21640
+ docs: {
21641
+ id: "docs",
21642
+ label: { zhCN: "\u8BFB\u5199\u6587\u6863", en: "Read and write docs" },
21643
+ description: {
21644
+ zhCN: "\u9700\u8981\u8BFB\u53D6\u3001\u521B\u5EFA\u6216\u66F4\u65B0\u77E5\u8BC6\u9875\u548C\u6587\u6863\u65F6\u4F7F\u7528\u3002",
21645
+ en: "Use when the agent should read, create, or update docs."
21646
+ },
21647
+ toolIds: ["createDoc", "updateDoc", "read"]
21648
+ },
21649
+ tables: {
21650
+ id: "tables",
21651
+ label: { zhCN: "\u5904\u7406\u8868\u683C", en: "Work with tables" },
21652
+ description: {
21653
+ zhCN: "\u9700\u8981\u521B\u5EFA\u8868\u3001\u8FFD\u52A0\u8BB0\u5F55\u6216\u6574\u7406\u7ED3\u6784\u5316\u6570\u636E\u65F6\u4F7F\u7528\u3002",
21654
+ en: "Use when the agent should create tables or manage structured rows."
21655
+ },
21656
+ toolIds: ["createTable", "addTableRow", "addTableRows", "read"]
21657
+ },
21658
+ agents: {
21659
+ id: "agents",
21660
+ label: { zhCN: "\u8C03\u7528\u5176\u4ED6 AI", en: "Call other AI agents" },
21661
+ description: {
21662
+ zhCN: "\u9700\u8981\u591A Agent \u534F\u4F5C\u3001\u8BC4\u5BA1\u6216\u5206\u5DE5\u65F6\u4F7F\u7528\u3002",
21663
+ en: "Use when the agent should collaborate with other agents."
21664
+ },
21665
+ toolIds: ["startAgentRun"]
21666
+ },
21667
+ apps: {
21668
+ id: "apps",
21669
+ label: { zhCN: "\u521B\u5EFA\u5E94\u7528\u6216\u4EE3\u7801", en: "Create apps or code" },
21670
+ description: {
21671
+ zhCN: "\u9700\u8981\u751F\u6210\u5E94\u7528\u3001\u4EE3\u7801\u6216\u4F7F\u7528 App Builder \u80FD\u529B\u65F6\u4F7F\u7528\u3002",
21672
+ en: "Use when the agent should build apps, code, or App Builder outputs."
21673
+ },
21674
+ toolIds: ["appDeploy", "appList", "appRead", "appFileList", "appFileSearch", "appFileRead", "appFileReplace", "appFileWrite"]
21675
+ },
21676
+ imageProcessing: {
21677
+ id: "imageProcessing",
21678
+ label: { zhCN: "\u56FE\u7247\u5904\u7406", en: "Image processing" },
21679
+ description: {
21680
+ zhCN: "\u9700\u8981\u538B\u7F29\u56FE\u7247\u3001\u8C03\u6574\u56FE\u7247\u5927\u5C0F\u6216\u7528\u53EF\u6267\u884C\u811A\u672C\u5904\u7406\u56FE\u7247\u6587\u4EF6\u65F6\u4F7F\u7528\u3002",
21681
+ en: "Use when the agent should compress images, resize images, or process image files with executable scripts."
21682
+ },
21683
+ toolIds: ["execShell"]
21684
+ }
21113
21685
  };
21114
-
21115
- // packages/core/abortableDelay.ts
21116
- function waitForAbortableDelay(ms, signal) {
21117
- const delayMs = Number.isFinite(ms) && ms >= 0 ? Math.round(ms) : 0;
21118
- if (signal?.aborted) {
21119
- return Promise.reject(new DOMException("Aborted", "AbortError"));
21686
+ var mapCapabilityIdsToToolIds = (capabilityIds2) => {
21687
+ const seen = /* @__PURE__ */ new Set();
21688
+ const result = [];
21689
+ for (const id of capabilityIds2) {
21690
+ const definition = GUIDED_AGENT_CAPABILITIES[id];
21691
+ if (!definition) continue;
21692
+ for (const toolId of definition.toolIds) {
21693
+ if (seen.has(toolId)) continue;
21694
+ seen.add(toolId);
21695
+ result.push(toolId);
21696
+ }
21120
21697
  }
21121
- return new Promise((resolve, reject) => {
21122
- const onAbort = () => {
21123
- clearTimeout(timeoutId);
21124
- signal?.removeEventListener("abort", onAbort);
21125
- reject(new DOMException("Aborted", "AbortError"));
21126
- };
21127
- const timeoutId = setTimeout(() => {
21128
- signal?.removeEventListener("abort", onAbort);
21129
- resolve();
21130
- }, delayMs);
21131
- signal?.addEventListener("abort", onAbort, { once: true });
21132
- });
21133
- }
21134
-
21135
- // packages/core/deployWindowRetrySignal.ts
21136
- function isDeployWindowRetrySignal(e) {
21137
- if (e.reason === CORE_DRAIN_REASON) return true;
21138
- if (typeof e.status === "number") return isGatewayHttpStatus(e.status);
21139
- return e.retryable === true;
21140
- }
21141
-
21142
- // packages/ai/chat/parseMultilineSSE.ts
21143
- function createSSEParser() {
21144
- let buffer = "";
21145
- return function parseSSE(chunk) {
21146
- const results = [];
21147
- if (!chunk) return results;
21148
- buffer += chunk;
21149
- const events = buffer.split(/\r?\n\r?\n/);
21150
- buffer = events.pop() ?? "";
21151
- for (const ev of events) {
21152
- if (!ev.trim()) continue;
21153
- const lines = ev.split(/\r?\n/);
21154
- let accumulator = "";
21155
- for (const line of lines) {
21156
- const t = line.trim();
21157
- if (t === "data: [DONE]") {
21158
- if (accumulator.trim()) {
21159
- try {
21160
- results.push(JSON.parse(accumulator));
21161
- } catch (e) {
21162
- }
21163
- accumulator = "";
21164
- }
21165
- results.push("[DONE]");
21166
- continue;
21167
- }
21168
- let content = "";
21169
- let isDataLine = false;
21170
- if (t.startsWith("data:")) {
21171
- content = line.substring(line.indexOf("data:") + 5).trim();
21172
- isDataLine = true;
21173
- } else if (accumulator && t && !t.startsWith("event:") && !t.startsWith("id:") && !t.startsWith("retry:")) {
21174
- content = line;
21175
- } else {
21176
- continue;
21177
- }
21178
- if (isDataLine && !accumulator) {
21179
- try {
21180
- const obj = JSON.parse(content);
21181
- results.push(obj);
21182
- continue;
21183
- } catch (e) {
21184
- }
21185
- }
21186
- accumulator += content;
21187
- }
21188
- if (accumulator.trim()) {
21189
- try {
21190
- const obj = JSON.parse(accumulator);
21191
- results.push(obj);
21192
- } catch (e) {
21193
- }
21194
- }
21195
- }
21196
- return results;
21197
- };
21198
- }
21199
- var parseMultilineSSE = createSSEParser();
21200
-
21201
- // packages/ai/agent/runAgentBackground.ts
21202
- var MAX_SSE_RETRIES = 3;
21203
- var MAX_SSE_CORE_DRAINING_RETRIES = 30;
21204
- var SSE_RETRY_DELAY_MS = 1500;
21205
- var MAX_RUN_START_RETRIES = 1;
21206
- var MAX_RUN_START_CORE_DRAINING_RETRIES = 30;
21207
- function createRetryableError(message, retryAfterMs) {
21208
- return Object.assign(new Error(message), {
21209
- retryable: true,
21210
- retryAfterMs
21211
- });
21212
- }
21213
- function createSubscriptionError(status, hasBody, retryAfterMs, reason) {
21214
- const message = !hasBody ? `\u4E8B\u4EF6\u6D41\u54CD\u5E94\u7F3A\u5C11 body (${status})` : `\u65E0\u6CD5\u8BA2\u9605\u4E8B\u4EF6\u6D41 (${status})`;
21215
- if (status === 401 || status === 403) {
21216
- return new Error(message);
21217
- }
21218
- const err = createRetryableError(message, retryAfterMs);
21219
- err.status = status;
21220
- if (reason) err.reason = reason;
21221
- return err;
21222
- }
21223
- async function waitForRetryDelay(retryAfterMs, signal) {
21224
- await waitForAbortableDelay(retryAfterMs, signal);
21225
- }
21226
- function parseRetryableJson(text) {
21227
- try {
21228
- return JSON.parse(text);
21229
- } catch {
21230
- return null;
21231
- }
21232
- }
21233
- async function listenToDialogEvents(dialogId, currentServer, authHeader, signal, onStatusChange, onDone, onFailed) {
21234
- let eventsRes;
21235
- try {
21236
- eventsRes = await fetch(
21237
- `${currentServer}/api/events/dialog-${dialogId}`,
21238
- {
21239
- method: "GET",
21240
- headers: {
21241
- Accept: "text/event-stream",
21242
- ...authHeader && { Authorization: authHeader }
21243
- },
21244
- signal
21245
- }
21246
- );
21247
- } catch (e) {
21248
- if (isAbortError(e)) throw e;
21249
- throw createRetryableError("\u4E8B\u4EF6\u6D41\u8FDE\u63A5\u5931\u8D25");
21250
- }
21251
- if (!eventsRes.ok || !eventsRes.body) {
21252
- const errText = await eventsRes.text().catch(() => "");
21253
- const payload = parseRetryableJson(errText);
21254
- throw createSubscriptionError(
21255
- eventsRes.status,
21256
- !!eventsRes.body,
21257
- resolveRetryAfterMs(eventsRes.headers, SSE_RETRY_DELAY_MS, payload?.retryAfterMs),
21258
- payload?.reason
21259
- );
21260
- }
21261
- const reader = eventsRes.body.getReader();
21262
- const decoder = new TextDecoder();
21263
- const parseSSE = createSSEParser();
21264
- return new Promise((resolve, reject) => {
21265
- const processStream = async () => {
21266
- try {
21267
- while (true) {
21268
- const { done, value } = await reader.read();
21269
- if (done) break;
21270
- const chunk = decoder.decode(value, { stream: true });
21271
- const events = parseSSE(chunk);
21272
- for (const event of events) {
21273
- const type = event.type;
21274
- if (type === "status") {
21275
- onStatusChange?.(event.status);
21276
- } else if (type === "done") {
21277
- const result = {
21278
- dialogId,
21279
- content: event.content,
21280
- usage: event.usage
21281
- };
21282
- onStatusChange?.("done");
21283
- onDone?.(result);
21284
- reader.cancel().catch(() => {
21285
- });
21286
- resolve(result);
21287
- return;
21288
- } else if (type === "failed") {
21289
- const errMsg = event.error ?? "\u672A\u77E5\u9519\u8BEF";
21290
- onStatusChange?.("failed");
21291
- onFailed?.(errMsg);
21292
- reader.cancel().catch(() => {
21293
- });
21294
- reject(new Error(errMsg));
21295
- return;
21296
- }
21297
- }
21298
- }
21299
- const err = createRetryableError("\u4E8B\u4EF6\u6D41\u610F\u5916\u5173\u95ED");
21300
- reject(err);
21301
- } catch (e) {
21302
- if (isAbortError(e)) {
21303
- resolve({ dialogId });
21304
- } else {
21305
- reject(e);
21306
- }
21307
- }
21308
- };
21309
- processStream();
21310
- });
21311
- }
21312
- var runAgentBackground = createAsyncThunk("agent/runBackground", async (args, { getState, signal: thunkSignal }) => {
21313
- const { agentKey, userInput, serverBase, spaceId, parentDialogId, ephemeral, onStatusChange, onDone, onFailed } = args;
21314
- const state = getState();
21315
- const currentServer = normalizeServerOrigin(serverBase) || selectCurrentServer(state);
21316
- const token = selectIdentityToken(state);
21317
- if (!currentServer) throw new Error("\u672A\u914D\u7F6E\u670D\u52A1\u5668\u5730\u5740");
21318
- const authHeader = token ? `Bearer ${token}` : "";
21319
- const effectiveSignal = args.signal ?? thunkSignal;
21320
- let runResponse = null;
21321
- let maxRunStartRetries = MAX_RUN_START_RETRIES;
21322
- for (let attempt = 0; attempt <= maxRunStartRetries; attempt++) {
21323
- const runRes = await fetch(`${currentServer}/api/agent/run`, {
21324
- method: "POST",
21325
- headers: {
21326
- "Content-Type": "application/json",
21327
- ...authHeader && { Authorization: authHeader }
21328
- },
21329
- body: JSON.stringify({
21330
- agentKey,
21331
- userInput,
21332
- spaceId,
21333
- background: true,
21334
- ...parentDialogId ? { parentDialogId } : {},
21335
- ...ephemeral ? { ephemeral: true } : {},
21336
- runtimeContext: {
21337
- surface: "web",
21338
- host: "browser",
21339
- runtime: "react",
21340
- entrypoint: "background-agent-run",
21341
- capabilities: ["background", "sse-events"],
21342
- ...parentDialogId ? { parentThreadId: parentDialogId } : {}
21343
- }
21344
- }),
21345
- signal: effectiveSignal
21346
- });
21347
- if (runRes.ok) {
21348
- runResponse = await runRes.json();
21349
- break;
21350
- }
21351
- const errText = await runRes.text();
21352
- const payload = parseRetryableJson(errText);
21353
- const retryAfterMs = resolveRetryAfterMs(
21354
- runRes.headers,
21355
- SSE_RETRY_DELAY_MS,
21356
- payload?.retryAfterMs
21357
- );
21358
- const isCoreDraining = payload?.reason === CORE_DRAIN_REASON;
21359
- const retryable = payload?.retryable === true || isCoreDraining || isGatewayHttpStatus(runRes.status);
21360
- if (isCoreDraining) {
21361
- maxRunStartRetries = MAX_RUN_START_CORE_DRAINING_RETRIES;
21362
- }
21363
- if (retryable && attempt < maxRunStartRetries) {
21364
- await waitForRetryDelay(retryAfterMs, effectiveSignal);
21365
- continue;
21366
- }
21367
- if (isCoreDraining) {
21368
- throw new Error(DRAIN_EXHAUSTED_USER_MESSAGE);
21369
- }
21370
- throw new Error(`\u542F\u52A8\u540E\u53F0\u4EFB\u52A1\u5931\u8D25 (${runRes.status}): ${errText}`);
21371
- }
21372
- if (!runResponse) {
21373
- throw new Error("\u542F\u52A8\u540E\u53F0\u4EFB\u52A1\u5931\u8D25\uFF1A\u672A\u6536\u5230\u53EF\u7528\u7684\u540E\u53F0\u8FD0\u884C\u54CD\u5E94");
21374
- }
21375
- const {
21376
- dialogId,
21377
- serverBase: routedServerBase
21378
- } = runResponse;
21379
- onStatusChange?.("pending");
21380
- if (args.waitForCompletion === false) {
21381
- return { dialogId, status: runResponse.status };
21382
- }
21383
- let lastError;
21384
- let maxSseRetries = MAX_SSE_RETRIES;
21385
- const eventServer = normalizeServerOrigin(routedServerBase) || currentServer;
21386
- for (let attempt = 0; attempt <= maxSseRetries; attempt++) {
21387
- try {
21388
- return await listenToDialogEvents(
21389
- dialogId,
21390
- eventServer,
21391
- authHeader,
21392
- effectiveSignal,
21393
- onStatusChange,
21394
- onDone,
21395
- onFailed
21396
- );
21397
- } catch (e) {
21398
- if (isAbortError(e)) throw e;
21399
- if (!e?.retryable || attempt >= maxSseRetries) throw e;
21400
- if (isDeployWindowRetrySignal(e)) {
21401
- maxSseRetries = MAX_SSE_CORE_DRAINING_RETRIES;
21402
- }
21403
- lastError = e;
21404
- onStatusChange?.("reconnecting");
21405
- await waitForRetryDelay(e?.retryAfterMs ?? SSE_RETRY_DELAY_MS, effectiveSignal);
21406
- }
21407
- }
21408
- throw lastError ?? new Error("\u4E8B\u4EF6\u6D41\u91CD\u8FDE\u5931\u8D25");
21409
- });
21410
-
21411
- // packages/ai/tools/agent/callAgentTool.ts
21412
- function buildDelegatedTaskContent(task, input) {
21413
- if (input === void 0 || input === null) {
21414
- return task;
21415
- }
21416
- if (typeof input === "string") {
21417
- return `${task}
21418
-
21419
- --- INPUT (text) ---
21420
- ${input}`;
21421
- }
21422
- const jsonStr = JSON.stringify(input, null, 2);
21423
- return `${task}
21424
-
21425
- --- INPUT (json) ---
21426
- ${jsonStr}`;
21427
- }
21428
- var callAgentFunctionSchema = {
21429
- name: "callAgent",
21430
- description: "\u8C03\u7528\u4E00\u4E2A\u6307\u5B9A\u7684 Agent \u6267\u884C\u4E00\u6B21\u5B50\u4EFB\u52A1\u5E76\u8FD4\u56DE\u7ED3\u679C\u3002\u901A\u5E38\u7528\u4E8E\uFF1A\u5C06\u590D\u6742\u5B50\u95EE\u9898\u59D4\u6258\u7ED9\u5176\u4ED6 Agent\uFF0C\u4F8B\u5982\u81EA\u52A8\u8BC4\u6D4B\u3001\u591A Agent \u5BF9\u6BD4\u3001\u6293\u53D6\u7ED3\u679C\u7684\u7ED3\u6784\u5316\u5904\u7406\u7B49\u3002",
21431
- parameters: {
21432
- type: "object",
21433
- properties: {
21434
- agentKey: {
21435
- type: "string",
21436
- description: "\u8981\u8C03\u7528\u7684 Agent \u7684\u53EF\u8FD0\u884C dbKey\uFF0C\u5FC5\u987B\u662F listAgents \u8FD4\u56DE\u7684 agentKey \u5B57\u6BB5\uFF08owned: agent-<userId>-<id>\uFF1Bpublic: agent-pub-<id>\uFF09\u6216 readAgent \u8FD4\u56DE\u7684 agentKey\u3002\u53EA\u63A5\u53D7\u7CBE\u786E dbKey\uFF0C\u4E0D\u63A5\u53D7 name/handle/bare id\u3002"
21437
- },
21438
- task: {
21439
- type: "string",
21440
- description: "\u59D4\u6258\u7ED9\u8BE5 Agent \u7684\u5B50\u4EFB\u52A1\u63CF\u8FF0\uFF08\u81EA\u7136\u8BED\u8A00\uFF09\u3002\u5EFA\u8BAE\u5728\u6B64\u5305\u542B\u5FC5\u8981\u7684\u4E0A\u4E0B\u6587\u8BF4\u660E\uFF08\u4F8B\u5982\u5F53\u524D\u8868\u7ED3\u6784\u3001\u9898\u5E93\u8BF4\u660E\u7B49\uFF09\u3002\u5728 task \u91CC\u8981\u6C42\u5B50 agent '\u6700\u540E\u7528 1-3 \u53E5\u8BDD\u603B\u7ED3\u7ED3\u8BBA + \u5217\u51FA\u5173\u952E\u4EA7\u51FA'\uFF0C\u7236 agent \u7528 resultMode:summary \u65F6\u5C31\u53EA\u9700\u8BFB\u8FD9\u6BB5\u603B\u7ED3\uFF0C\u4E0D\u5FC5\u6D88\u5316\u5B8C\u6574\u8F93\u51FA\u3002"
21441
- },
21442
- input: {
21443
- description: "\u53EF\u9009\u3002JSON \u6216\u5B57\u7B26\u4E32\uFF0C\u5C06\u4F5C\u4E3A\u672C\u6B21\u5B50\u4EFB\u52A1\u7684\u9644\u52A0\u8F93\u5165\u3002\u901A\u5E38\u7528\u4E8E\u4F20\u9012\u6293\u53D6\u5230\u7684\u539F\u59CB\u6570\u636E\u3001\u9898\u5E93\u3001\u4E0A\u4E0B\u6587\u7247\u6BB5\u7B49\u3002"
21444
- },
21445
- background: {
21446
- type: "boolean",
21447
- description: "\u53EF\u9009\u3002\u5F53\u4E3A true \u65F6\u7ACB\u5373\u521B\u5EFA\u540E\u53F0\u5B50\u5BF9\u8BDD\u5E76\u8FD4\u56DE childDialogId\uFF0C\u7531\u8C03\u7528\u65B9\u7A0D\u540E\u67E5\u8BE2\u7ED3\u679C\uFF1B\u9002\u5408\u53EF\u80FD\u8D85\u8FC7 HTTP \u7F51\u5173\u7B49\u5F85\u7A97\u53E3\uFF08\u7EA6 100 \u79D2\uFF09\u7684\u957F\u4EFB\u52A1\uFF0C\u907F\u514D Cloudflare 524 \u5BFC\u81F4\u7ED3\u679C\u4E22\u5931\u3002\u9ED8\u8BA4 false\uFF0C\u5373\u7EE7\u7EED\u7B49\u5F85\u5B50\u4EFB\u52A1\u5B8C\u6210\u5E76\u8FD4\u56DE content\u3002",
21448
- default: false
21449
- },
21450
- resultMode: {
21451
- type: "string",
21452
- enum: ["summary", "full"],
21453
- description: "\u53EF\u9009\u3002\u63A7\u5236\u8FD4\u56DE\u7ED9\u7236 agent \u7684\u5185\u5BB9\u91CF\uFF0C\u51CF\u5C11\u7236 agent \u4E0A\u4E0B\u6587\u6210\u672C\u3002summary\uFF08\u9ED8\u8BA4\uFF09\uFF1A\u53EA\u8FD4\u56DE\u5B50 agent \u8F93\u51FA\u7684\u524D 2000 \u5B57 + \u672B\u5C3E\u603B\u7ED3\u6BB5\uFF0C\u9002\u5408\u7236 agent \u53EA\u9700\u7ED3\u8BBA\u800C\u975E\u5B8C\u6574\u8FC7\u7A0B\u3002full\uFF1A\u8FD4\u56DE\u5B50 agent \u5B8C\u6574\u8F93\u51FA\uFF0C\u9002\u5408\u9700\u8981\u5B8C\u6574 diff/\u65E5\u5FD7\u505A\u540E\u7EED\u5904\u7406\u3002\u7236 agent \u6BCF\u591A\u4E00\u4E2A turn \u5904\u7406\u5B50\u8F93\u51FA = \u5168\u524D\u7F00\u91CD\u65B0\u8BA1\u4EF7\uFF0C\u6240\u4EE5\u975E\u5FC5\u8981\u65F6\u7528 summary\u3002\u4EC5\u5728 foreground \u6A21\u5F0F\uFF08background \u672A\u8BBE\u6216 false\uFF09\u751F\u6548\uFF1Bbackground \u6A21\u5F0F\u65E0 content \u53EF\u622A\uFF0C\u6B64\u53C2\u6570\u88AB\u5FFD\u7565\u3002",
21454
- default: "summary"
21455
- }
21456
- },
21457
- required: ["agentKey", "task"]
21458
- }
21459
- };
21460
- async function callAgentFunc(args, thunkApi, context) {
21461
- const { agentKey, task, input, background, resultMode } = args;
21462
- const { dispatch } = thunkApi;
21463
- if (!agentKey) {
21464
- throw new Error("callAgent: \u7F3A\u5C11 agentKey \u53C2\u6570\u3002");
21465
- }
21466
- if (!task || typeof task !== "string") {
21467
- throw new Error("callAgent: \u7F3A\u5C11\u6709\u6548\u7684 task \u6587\u672C\u63CF\u8FF0\u3002");
21468
- }
21469
- const content = buildDelegatedTaskContent(task, input);
21470
- const activeDialogKey = getActiveDialogKey();
21471
- const parentDialogId = activeDialogKey ? extractCustomId(activeDialogKey) : void 0;
21472
- try {
21473
- const bgResult = await dispatch(
21474
- runAgentBackground({
21475
- agentKey,
21476
- userInput: content,
21477
- ...background === true ? { waitForCompletion: false } : {},
21478
- ...parentDialogId ? { parentDialogId } : {}
21479
- })
21480
- ).unwrap();
21481
- if (background === true) {
21482
- return {
21483
- rawData: { dialogId: bgResult.dialogId, status: bgResult.status ?? "pending" },
21484
- displayData: `\u23F3 callAgent \u540E\u53F0\u5DF2\u542F\u52A8\uFF0CdialogId: ${bgResult.dialogId}\uFF0C\u8BF7\u7A0D\u540E\u67E5\u8BE2\u7ED3\u679C\u3002`
21485
- };
21486
- }
21487
- const fullContent = bgResult.content ?? bgResult;
21488
- const wantSummary = resultMode !== "full";
21489
- const returnedContent = wantSummary ? summarizeChildContent(typeof fullContent === "string" ? fullContent : JSON.stringify(fullContent)) : fullContent;
21490
- return {
21491
- rawData: returnedContent,
21492
- displayData: `\u2705 callAgent \u6267\u884C\u5B8C\u6210\uFF0CdialogId: ${bgResult.dialogId}${wantSummary ? "\uFF08summary\uFF09" : ""}`
21493
- };
21494
- } catch (e) {
21495
- const msg = toErrorMessage(e);
21496
- throw new Error(`callAgent \u8C03\u7528 Agent [${agentKey}] \u65F6\u51FA\u9519: ${msg}`);
21497
- }
21498
- }
21499
- var SUMMARY_HEAD_CHARS = 1500;
21500
- var SUMMARY_TAIL_CHARS = 500;
21501
- var SUMMARY_MIN_LENGTH_THRESHOLD = SUMMARY_HEAD_CHARS + SUMMARY_TAIL_CHARS + 50;
21502
- function summarizeChildContent(text) {
21503
- if (text.length <= SUMMARY_MIN_LENGTH_THRESHOLD) return text;
21504
- return `${text.slice(0, SUMMARY_HEAD_CHARS)}
21505
-
21506
- \u2026\uFF08\u4E2D\u95F4\u90E8\u5206\u5DF2\u7701\u7565\uFF0CresultMode=full \u53EF\u770B\u5B8C\u6574\u8F93\u51FA\uFF09\u2026
21507
-
21508
- ${text.slice(-SUMMARY_TAIL_CHARS)}`;
21509
- }
21510
-
21511
- // packages/ai/agent/guidedCreation/capabilities.ts
21512
- var GUIDED_AGENT_CAPABILITIES = {
21513
- webSearch: {
21514
- id: "webSearch",
21515
- label: { zhCN: "\u8054\u7F51\u641C\u7D22", en: "Search the web" },
21516
- description: {
21517
- zhCN: "\u9700\u8981\u83B7\u53D6\u5916\u90E8\u7F51\u9875\u3001\u8D44\u6599\u6216\u6700\u65B0\u4FE1\u606F\u65F6\u4F7F\u7528\u3002",
21518
- en: "Use when the agent needs external webpages, research, or current information."
21519
- },
21520
- toolIds: ["exa_search", "firecrawl_search", "firecrawl_scrape", "fetchWebpage"]
21521
- },
21522
- docs: {
21523
- id: "docs",
21524
- label: { zhCN: "\u8BFB\u5199\u6587\u6863", en: "Read and write docs" },
21525
- description: {
21526
- zhCN: "\u9700\u8981\u8BFB\u53D6\u3001\u521B\u5EFA\u6216\u66F4\u65B0\u77E5\u8BC6\u9875\u548C\u6587\u6863\u65F6\u4F7F\u7528\u3002",
21527
- en: "Use when the agent should read, create, or update docs."
21528
- },
21529
- toolIds: ["createDoc", "updateDoc", "read"]
21530
- },
21531
- tables: {
21532
- id: "tables",
21533
- label: { zhCN: "\u5904\u7406\u8868\u683C", en: "Work with tables" },
21534
- description: {
21535
- zhCN: "\u9700\u8981\u521B\u5EFA\u8868\u3001\u8FFD\u52A0\u8BB0\u5F55\u6216\u6574\u7406\u7ED3\u6784\u5316\u6570\u636E\u65F6\u4F7F\u7528\u3002",
21536
- en: "Use when the agent should create tables or manage structured rows."
21537
- },
21538
- toolIds: ["createTable", "addTableRow", "addTableRows", "read"]
21539
- },
21540
- agents: {
21541
- id: "agents",
21542
- label: { zhCN: "\u8C03\u7528\u5176\u4ED6 AI", en: "Call other AI agents" },
21543
- description: {
21544
- zhCN: "\u9700\u8981\u591A Agent \u534F\u4F5C\u3001\u8BC4\u5BA1\u6216\u5206\u5DE5\u65F6\u4F7F\u7528\u3002",
21545
- en: "Use when the agent should collaborate with other agents."
21546
- },
21547
- toolIds: ["callAgent"]
21548
- },
21549
- apps: {
21550
- id: "apps",
21551
- label: { zhCN: "\u521B\u5EFA\u5E94\u7528\u6216\u4EE3\u7801", en: "Create apps or code" },
21552
- description: {
21553
- zhCN: "\u9700\u8981\u751F\u6210\u5E94\u7528\u3001\u4EE3\u7801\u6216\u4F7F\u7528 App Builder \u80FD\u529B\u65F6\u4F7F\u7528\u3002",
21554
- en: "Use when the agent should build apps, code, or App Builder outputs."
21555
- },
21556
- toolIds: ["appDeploy", "appList", "appRead", "appFileList", "appFileSearch", "appFileRead", "appFileReplace", "appFileWrite"]
21557
- },
21558
- imageProcessing: {
21559
- id: "imageProcessing",
21560
- label: { zhCN: "\u56FE\u7247\u5904\u7406", en: "Image processing" },
21561
- description: {
21562
- zhCN: "\u9700\u8981\u538B\u7F29\u56FE\u7247\u3001\u8C03\u6574\u56FE\u7247\u5927\u5C0F\u6216\u7528\u53EF\u6267\u884C\u811A\u672C\u5904\u7406\u56FE\u7247\u6587\u4EF6\u65F6\u4F7F\u7528\u3002",
21563
- en: "Use when the agent should compress images, resize images, or process image files with executable scripts."
21564
- },
21565
- toolIds: ["execShell"]
21566
- }
21567
- };
21568
- var mapCapabilityIdsToToolIds = (capabilityIds2) => {
21569
- const seen = /* @__PURE__ */ new Set();
21570
- const result = [];
21571
- for (const id of capabilityIds2) {
21572
- const definition = GUIDED_AGENT_CAPABILITIES[id];
21573
- if (!definition) continue;
21574
- for (const toolId of definition.toolIds) {
21575
- if (seen.has(toolId)) continue;
21576
- seen.add(toolId);
21577
- result.push(toolId);
21578
- }
21579
- }
21580
- return result;
21581
- };
21698
+ return result;
21699
+ };
21582
21700
 
21583
21701
  // packages/ai/tools/agent/prepareAgentDraftTool.ts
21584
21702
  var capabilityIds = new Set(Object.keys(GUIDED_AGENT_CAPABILITIES));
@@ -21748,331 +21866,650 @@ var buildPreset = (mode) => {
21748
21866
  - \u5BF9\u5916\u90E8\u6280\u80FD\u5BFC\u5165\uFF0C\u4F18\u5148\u4FDD\u7559\u6587\u672C\u6D41\u7A0B\uFF0C\u518D\u8C28\u614E\u6620\u5C04\u5DE5\u5177`
21749
21867
  };
21750
21868
  }
21751
- if (mode === "evaluator") {
21752
- return {
21753
- defaultName: "Skill Evaluator",
21754
- tools: [...commonTools, "runLlm"],
21755
- introduction: "\u5E2E\u4F60\u8BCA\u65AD skill \u6587\u6863\u8D28\u91CF\u3001\u534F\u8BAE\u5B8C\u6574\u6027\u4E0E\u8BC4\u4F30\u7ED3\u679C\u7684\u52A9\u624B\u3002",
21756
- greeting: "\u4F60\u597D\uFF0C\u6211\u662F Skill Evaluator\u3002\n\n\u628A\u4E00\u4E2A skill \u6587\u6863\u7ED9\u6211\uFF0C\u6211\u4F1A\u68C0\u67E5\u534F\u8BAE\u3001\u5DE5\u5177\u7ED1\u5B9A\u3001\u8BC4\u4F30\u7528\u4F8B\u548C\u6F5C\u5728\u98CE\u9669\u3002",
21757
- prompt: `\u4F60\u662F\u4E00\u4E2A skill evaluator\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u5BA1\u67E5 skill \u662F\u5426\u771F\u7684\u53EF\u7528\uFF0C\u800C\u4E0D\u662F\u66FF\u7528\u6237\u5199\u65B0\u529F\u80FD\u3002
21758
-
21759
- \u5DE5\u4F5C\u987A\u5E8F\uFF1A
21760
- 1. \u5148 doctorSkill \u770B\u534F\u8BAE\u548C\u660E\u663E\u95EE\u9898
21761
- 2. \u518D evalSkill \u770B eval-config \u662F\u5426\u901A\u8FC7
21762
- 3. \u5982\u53D1\u73B0\u95EE\u9898\uFF0C\u6307\u51FA\u6700\u5C0F\u4FEE\u590D\u70B9
21763
- 4. \u9664\u975E\u7528\u6237\u8981\u6C42\uFF0C\u4E0D\u4E3B\u52A8\u5927\u6539 skill
21764
-
21765
- \u5BA1\u67E5\u91CD\u70B9\uFF1A
21766
- - \u5DE5\u5177\u540D\u662F\u5426\u6709\u6548\u3001\u662F\u5426\u9700\u8981 canonicalize
21767
- - requiredSkills / recommendedSkills \u662F\u5426\u8868\u8FBE\u51C6\u786E
21768
- - eval-config \u662F\u5426\u8986\u76D6\u5173\u952E\u6210\u529F\u8DEF\u5F84
21769
- - \u662F\u5426\u5B58\u5728\u8FC7\u671F\u547D\u4EE4\u3001\u73AF\u5883\u524D\u63D0\u3001\u767B\u5F55\u6001\u4F9D\u8D56\u7B49\u9690\u60A3`
21770
- };
21869
+ if (mode === "evaluator") {
21870
+ return {
21871
+ defaultName: "Skill Evaluator",
21872
+ tools: [...commonTools, "runLlm"],
21873
+ introduction: "\u5E2E\u4F60\u8BCA\u65AD skill \u6587\u6863\u8D28\u91CF\u3001\u534F\u8BAE\u5B8C\u6574\u6027\u4E0E\u8BC4\u4F30\u7ED3\u679C\u7684\u52A9\u624B\u3002",
21874
+ greeting: "\u4F60\u597D\uFF0C\u6211\u662F Skill Evaluator\u3002\n\n\u628A\u4E00\u4E2A skill \u6587\u6863\u7ED9\u6211\uFF0C\u6211\u4F1A\u68C0\u67E5\u534F\u8BAE\u3001\u5DE5\u5177\u7ED1\u5B9A\u3001\u8BC4\u4F30\u7528\u4F8B\u548C\u6F5C\u5728\u98CE\u9669\u3002",
21875
+ prompt: `\u4F60\u662F\u4E00\u4E2A skill evaluator\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u5BA1\u67E5 skill \u662F\u5426\u771F\u7684\u53EF\u7528\uFF0C\u800C\u4E0D\u662F\u66FF\u7528\u6237\u5199\u65B0\u529F\u80FD\u3002
21876
+
21877
+ \u5DE5\u4F5C\u987A\u5E8F\uFF1A
21878
+ 1. \u5148 doctorSkill \u770B\u534F\u8BAE\u548C\u660E\u663E\u95EE\u9898
21879
+ 2. \u518D evalSkill \u770B eval-config \u662F\u5426\u901A\u8FC7
21880
+ 3. \u5982\u53D1\u73B0\u95EE\u9898\uFF0C\u6307\u51FA\u6700\u5C0F\u4FEE\u590D\u70B9
21881
+ 4. \u9664\u975E\u7528\u6237\u8981\u6C42\uFF0C\u4E0D\u4E3B\u52A8\u5927\u6539 skill
21882
+
21883
+ \u5BA1\u67E5\u91CD\u70B9\uFF1A
21884
+ - \u5DE5\u5177\u540D\u662F\u5426\u6709\u6548\u3001\u662F\u5426\u9700\u8981 canonicalize
21885
+ - requiredSkills / recommendedSkills \u662F\u5426\u8868\u8FBE\u51C6\u786E
21886
+ - eval-config \u662F\u5426\u8986\u76D6\u5173\u952E\u6210\u529F\u8DEF\u5F84
21887
+ - \u662F\u5426\u5B58\u5728\u8FC7\u671F\u547D\u4EE4\u3001\u73AF\u5883\u524D\u63D0\u3001\u767B\u5F55\u6001\u4F9D\u8D56\u7B49\u9690\u60A3`
21888
+ };
21889
+ }
21890
+ return {
21891
+ defaultName: "Skill Builder",
21892
+ tools: [...commonTools, "runLlm", "createAgent", "updateAgent"],
21893
+ introduction: "\u65E2\u80FD\u521B\u5EFA\u4E5F\u80FD\u8BC4\u4F30 skill \u6587\u6863\u534F\u8BAE\uFF0C\u8FD8\u80FD\u5E2E\u52A9\u4F60\u6C89\u6DC0 skill \u5DE5\u4F5C\u6D41\u52A9\u624B\u3002",
21894
+ greeting: "\u4F60\u597D\uFF0C\u6211\u662F Skill Builder\u3002\n\n\u6211\u53EF\u4EE5\u5E2E\u4F60\u628A\u80FD\u529B\u505A\u6210 skill\u3001\u5BFC\u5165\u5916\u90E8 skill\u3001\u8BCA\u65AD\u8D28\u91CF\u3001\u8865\u8BC4\u4F30\uFF0C\u5E76\u7EE7\u7EED\u8FED\u4EE3\u76F8\u5173 agent\u3002",
21895
+ prompt: `\u4F60\u662F\u4E00\u4E2A skill creator + evaluator\u3002
21896
+
21897
+ \u539F\u5219\uFF1A
21898
+ - \u5148\u5224\u65AD\u8BE5\u95EE\u9898\u662F\u5426\u66F4\u9002\u5408\u6362 Agent\uFF1B\u53EA\u6709\u6CA1\u5FC5\u8981\u5207 Agent \u6216\u5207 Agent \u6210\u672C\u66F4\u9AD8\u65F6\uFF0C\u624D\u8865 skill
21899
+ - skill \u8D1F\u8D23\u52A8\u6001\u80FD\u529B\u7F16\u6392\uFF1Bknowledge \u8D1F\u8D23\u5185\u5BB9\uFF1Bdispatch \u8D1F\u8D23\u4EFB\u52A1\u5206\u6D3E
21900
+ - \u521B\u5EFA\u6216\u66F4\u65B0 skill \u540E\uFF0C\u5FC5\u987B\u81F3\u5C11\u505A\u4E00\u6B21 doctorSkill\uFF1B\u5982\u679C\u6709 eval-config\uFF0C\u518D\u8DD1 evalSkill
21901
+ - \u4E0D\u628A recommendedSkills \u5F53\u786C\u52A0\u8F7D\uFF1BrequiredSkills \u624D\u662F\u786C\u4F9D\u8D56
21902
+ - \u5C3D\u91CF\u5E2E\u52A9\u7528\u6237\u5F62\u6210\u201C\u521B\u5EFA -> \u8BCA\u65AD -> \u8BC4\u4F30 -> \u8FED\u4EE3\u201D\u7684\u95ED\u73AF`
21903
+ };
21904
+ };
21905
+ var buildCreateSkillAgentArgs = (args) => {
21906
+ const mode = args.mode ?? "creator_evaluator";
21907
+ const preset = buildPreset(mode);
21908
+ return {
21909
+ name: (args.name ?? "").trim() || preset.defaultName,
21910
+ model: (args.model ?? "").trim() || DEFAULT_MODEL2,
21911
+ provider: (args.provider ?? "").trim() || DEFAULT_PROVIDER,
21912
+ introduction: preset.introduction,
21913
+ greeting: preset.greeting,
21914
+ prompt: preset.prompt,
21915
+ isPublic: args.isPublic ?? false,
21916
+ tools: preset.tools,
21917
+ references: args.references ?? [],
21918
+ linkedSpaces: args.linkedSpaces ?? [],
21919
+ temperature: 0.3,
21920
+ reasoning_effort: "medium"
21921
+ };
21922
+ };
21923
+
21924
+ // packages/ai/tools/agent/createSkillAgentTool.ts
21925
+ var createSkillAgentToolFunctionSchema = {
21926
+ name: "createSkillAgent",
21927
+ description: "\u521B\u5EFA\u4E00\u4E2A\u4E13\u95E8\u7528\u4E8E\u521B\u5EFA/\u8BC4\u4F30 skill \u6587\u6863\u534F\u8BAE\u7684 Agent\uFF0C\u652F\u6301 creator\u3001evaluator \u6216\u4E8C\u5408\u4E00\u6A21\u5F0F\u3002",
21928
+ parameters: {
21929
+ type: "object",
21930
+ properties: {
21931
+ mode: {
21932
+ type: "string",
21933
+ enum: ["creator", "evaluator", "creator_evaluator"],
21934
+ description: "\u8981\u521B\u5EFA\u7684 skill agent \u7C7B\u578B\u3002"
21935
+ },
21936
+ name: {
21937
+ type: "string",
21938
+ description: "\u53EF\u9009\uFF1AAgent \u540D\u79F0\u3002"
21939
+ },
21940
+ model: {
21941
+ type: "string",
21942
+ description: "\u53EF\u9009\uFF1A\u8986\u76D6\u9ED8\u8BA4\u6A21\u578B\u3002"
21943
+ },
21944
+ provider: {
21945
+ type: "string",
21946
+ description: "\u53EF\u9009\uFF1A\u8986\u76D6\u9ED8\u8BA4 provider\u3002"
21947
+ },
21948
+ isPublic: {
21949
+ type: "boolean",
21950
+ description: "\u53EF\u9009\uFF1A\u662F\u5426\u516C\u5F00\u3002"
21951
+ },
21952
+ references: {
21953
+ type: "array",
21954
+ description: "\u53EF\u9009\uFF1A\u521B\u5EFA\u540E\u9ED8\u8BA4\u6302\u8F7D\u7684 references\u3002",
21955
+ items: {
21956
+ type: "object",
21957
+ properties: {
21958
+ dbKey: { type: "string" },
21959
+ title: { type: "string" },
21960
+ type: { type: "string", enum: ["knowledge", "instruction", "page"] }
21961
+ },
21962
+ required: ["dbKey"]
21963
+ }
21964
+ },
21965
+ linkedSpaces: {
21966
+ type: "array",
21967
+ items: { type: "string" },
21968
+ description: "\u53EF\u9009\uFF1A\u989D\u5916\u6302\u8F7D\u7684 linked spaces\u3002"
21969
+ }
21970
+ }
21971
+ }
21972
+ };
21973
+ async function createSkillAgentToolFunc(args, thunkApi) {
21974
+ return createAgentToolFunc(buildCreateSkillAgentArgs(args), thunkApi);
21975
+ }
21976
+
21977
+ // packages/chat/messages/messageAgent.ts
21978
+ function resolveMessageAgentKey(message) {
21979
+ if (!message) return void 0;
21980
+ return message.agentKey || message.cybotKey;
21981
+ }
21982
+
21983
+ // packages/ai/tools/agent/updateSelfTool.ts
21984
+ var updateSelfToolFunctionSchema = {
21985
+ name: "updateSelf",
21986
+ description: "\u66F4\u65B0\u5F53\u524D\u6B63\u5728\u8FD0\u884C\u7684 Agent \u81EA\u5DF1\u3002\u4F4E\u98CE\u9669\u5B57\u6BB5\u53EF\u76F4\u63A5\u66F4\u65B0\uFF0C\u5176\u4ED6\u5B57\u6BB5\u4F1A\u5148\u5411\u7528\u6237\u786E\u8BA4\u3002",
21987
+ parameters: {
21988
+ type: "object",
21989
+ properties: agentUpdateFieldSchemaProperties
21990
+ }
21991
+ };
21992
+ var resolveCurrentAgentKey = (state, parentMessageId) => {
21993
+ const parentMessage = parentMessageId ? selectMsgById(state, parentMessageId) : void 0;
21994
+ const parentAgentKey = resolveMessageAgentKey(parentMessage);
21995
+ if (parentAgentKey) {
21996
+ return parentAgentKey;
21997
+ }
21998
+ const currentDialog = selectCurrentDialogConfig(state);
21999
+ return asTrimmedNonEmptyStringArray(currentDialog?.cybots)[0];
22000
+ };
22001
+ async function updateSelfToolFunc(args, thunkApi, runtime) {
22002
+ const state = thunkApi.getState();
22003
+ const userId = selectIdentityUserId(state);
22004
+ const db = thunkApi.extra?.db;
22005
+ validateUpdateArgs(userId);
22006
+ const currentAgentKey = resolveCurrentAgentKey(state, runtime?.parentMessageId);
22007
+ if (!currentAgentKey) {
22008
+ throw new Error("updateSelf \u5931\u8D25\uFF1A\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D\u6B63\u5728\u8FD0\u884C\u7684 Agent\u3002");
22009
+ }
22010
+ const previousAgent = await fetchAgentByDbKey(currentAgentKey, db);
22011
+ if (!previousAgent) {
22012
+ throw new Error(`updateSelf \u5931\u8D25\uFF1A\u672A\u627E\u5230\u5F53\u524D Agent\uFF08${currentAgentKey}\uFF09\u3002`);
22013
+ }
22014
+ const requestedFields = listRequestedFields(args);
22015
+ const autoApprovedFields = selectAutoApproveSelfUpdateFields(state);
22016
+ assertAgentUpdateConfirmation({
22017
+ scope: "self",
22018
+ requestedFields,
22019
+ confirmed: args.__confirmedSelfEvolution === true,
22020
+ autoApprovedFields
22021
+ });
22022
+ const previousAgentForUpdate = buildUpdateThunkPreviousAgent(previousAgent, userId);
22023
+ const agent = await thunkApi.dispatch(
22024
+ updateAgent({
22025
+ userId,
22026
+ agentId: extractAgentId(currentAgentKey),
22027
+ formData: buildPatch(args),
22028
+ previousAgent: previousAgentForUpdate
22029
+ })
22030
+ ).unwrap().catch((e) => {
22031
+ throw new Error(`updateSelf \u5931\u8D25\uFF1A${e?.message ?? "\u672A\u77E5\u9519\u8BEF"}`);
22032
+ });
22033
+ return {
22034
+ rawData: buildRawDataWithUpdateInfo(
22035
+ agent,
22036
+ previousAgentForUpdate,
22037
+ requestedFields
22038
+ ),
22039
+ displayData: formatUpdatedAgentOutput(agent)
22040
+ };
22041
+ }
22042
+
22043
+ // packages/ai/tools/agent/runStreamingAgentTool.ts
22044
+ var runStreamingAgentFunctionSchema = {
22045
+ name: "runStreamingAgent",
22046
+ description: "\u51C6\u5907\u8C03\u7528\u4E00\u4E2A\u6307\u5B9A\u7684 Agent (\u667A\u80FD\u4EE3\u7406)\uFF0C\u5E76\u4EE5\u6D41\u5F0F\u65B9\u5F0F\u5904\u7406\u7528\u6237\u8F93\u5165\u3002\u8BE5\u5DE5\u5177\u672C\u8EAB\u53EA\u8FD4\u56DE\u8981\u8C03\u7528\u7684 Agent \u4FE1\u606F\uFF0C\u5B9E\u9645\u6D41\u5F0F\u8C03\u7528\u7531\u7CFB\u7EDF\u5728\u5DE5\u5177\u6267\u884C\u540E\u53D1\u8D77\u3002",
22047
+ parameters: {
22048
+ type: "object",
22049
+ properties: {
22050
+ agentKey: {
22051
+ type: "string",
22052
+ description: "\u8981\u8FD0\u884C\u7684 Agent \u7684\u552F\u4E00\u6807\u8BC6\u7B26 (Key)\u3002"
22053
+ },
22054
+ userInput: {
22055
+ type: "string",
22056
+ description: "\u8981\u53D1\u9001\u7ED9\u8BE5 Agent \u7684\u7528\u6237\u8F93\u5165\u6216\u95EE\u9898\u3002"
22057
+ },
22058
+ serverBase: {
22059
+ type: "string",
22060
+ description: "\u53EF\u9009\u3002\u76EE\u6807 Agent \u6240\u5728\u7684 nolo server origin\uFF0C\u4F8B\u5982 Windows \u673A\u5668\u901A\u8FC7 Cloudflare \u66B4\u9732\u7684 https://win.example.com\u3002\u8DE8\u57DF\u76EE\u6807\u5FC5\u987B\u7531\u670D\u52A1\u7AEF AGENT_TOOL_ALLOWED_SERVER_BASES \u660E\u786E\u653E\u884C\u3002\u5982\u679C\u76EE\u6807 Agent \u8BB0\u5F55\u58F0\u660E\u4E86 delegation.serverBase / runtimeServerBase\uFF0C\u670D\u52A1\u7AEF\u4F1A\u5728\u672A\u663E\u5F0F\u4F20\u5165\u65F6\u81EA\u52A8\u8DEF\u7531\u3002"
22061
+ }
22062
+ },
22063
+ required: ["agentKey", "userInput"]
22064
+ }
22065
+ };
22066
+ async function runStreamingAgentFunc(args, _thunkApi, _context) {
22067
+ const { agentKey, userInput, serverBase } = args;
22068
+ if (!agentKey) {
22069
+ throw new Error("\u8C03\u7528 'runStreamingAgent' \u5931\u8D25\uFF1A\u7F3A\u5C11 'agentKey' \u53C2\u6570\u3002");
21771
22070
  }
21772
- return {
21773
- defaultName: "Skill Builder",
21774
- tools: [...commonTools, "runLlm", "createAgent", "updateAgent"],
21775
- introduction: "\u65E2\u80FD\u521B\u5EFA\u4E5F\u80FD\u8BC4\u4F30 skill \u6587\u6863\u534F\u8BAE\uFF0C\u8FD8\u80FD\u5E2E\u52A9\u4F60\u6C89\u6DC0 skill \u5DE5\u4F5C\u6D41\u52A9\u624B\u3002",
21776
- greeting: "\u4F60\u597D\uFF0C\u6211\u662F Skill Builder\u3002\n\n\u6211\u53EF\u4EE5\u5E2E\u4F60\u628A\u80FD\u529B\u505A\u6210 skill\u3001\u5BFC\u5165\u5916\u90E8 skill\u3001\u8BCA\u65AD\u8D28\u91CF\u3001\u8865\u8BC4\u4F30\uFF0C\u5E76\u7EE7\u7EED\u8FED\u4EE3\u76F8\u5173 agent\u3002",
21777
- prompt: `\u4F60\u662F\u4E00\u4E2A skill creator + evaluator\u3002
21778
-
21779
- \u539F\u5219\uFF1A
21780
- - \u5148\u5224\u65AD\u8BE5\u95EE\u9898\u662F\u5426\u66F4\u9002\u5408\u6362 Agent\uFF1B\u53EA\u6709\u6CA1\u5FC5\u8981\u5207 Agent \u6216\u5207 Agent \u6210\u672C\u66F4\u9AD8\u65F6\uFF0C\u624D\u8865 skill
21781
- - skill \u8D1F\u8D23\u52A8\u6001\u80FD\u529B\u7F16\u6392\uFF1Bknowledge \u8D1F\u8D23\u5185\u5BB9\uFF1Bdispatch \u8D1F\u8D23\u4EFB\u52A1\u5206\u6D3E
21782
- - \u521B\u5EFA\u6216\u66F4\u65B0 skill \u540E\uFF0C\u5FC5\u987B\u81F3\u5C11\u505A\u4E00\u6B21 doctorSkill\uFF1B\u5982\u679C\u6709 eval-config\uFF0C\u518D\u8DD1 evalSkill
21783
- - \u4E0D\u628A recommendedSkills \u5F53\u786C\u52A0\u8F7D\uFF1BrequiredSkills \u624D\u662F\u786C\u4F9D\u8D56
21784
- - \u5C3D\u91CF\u5E2E\u52A9\u7528\u6237\u5F62\u6210\u201C\u521B\u5EFA -> \u8BCA\u65AD -> \u8BC4\u4F30 -> \u8FED\u4EE3\u201D\u7684\u95ED\u73AF`
22071
+ if (!userInput) {
22072
+ throw new Error("\u8C03\u7528 'runStreamingAgent' \u5931\u8D25\uFF1A\u7F3A\u5C11 'userInput' \u53C2\u6570\u3002");
22073
+ }
22074
+ const rawData = {
22075
+ agentKey,
22076
+ userInput,
22077
+ ...serverBase ? { serverBase } : {}
21785
22078
  };
22079
+ const displayData = `\u5C06\u8C03\u7528 Agent(${agentKey}) \u6267\u884C\u4E00\u8F6E\u6D41\u5F0F\u5BF9\u8BDD`;
22080
+ return { rawData, displayData };
22081
+ }
22082
+
22083
+ // packages/ai/tools/agent/createDialogTool.ts
22084
+ var createDialogFunctionSchema = {
22085
+ name: "createDialog",
22086
+ description: "\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u5BF9\u8BDD\uFF08Dialog\uFF09\uFF0C\u53EF\u4EE5\u6307\u5B9A\u7531\u54EA\u4E2A Agent \u6765\u54CD\u5E94\uFF0C\u5E76\u53EF\u9009\u5730\u53D1\u9001\u7B2C\u4E00\u6761\u6D88\u606F\u89E6\u53D1 Agent \u7ACB\u5373\u6267\u884C\u3002\u5E38\u7528\u4E8E\uFF1A\u6D3E\u751F\u5B50\u4EFB\u52A1\u5BF9\u8BDD\u3001\u8BA9\u67D0\u4E2A\u4E13\u7528 Agent \u5728\u540E\u53F0\u5904\u7406\u95EE\u9898\u3001\u7761\u524D\u5E03\u7F6E\u4EFB\u52A1\u7B49\u573A\u666F\u3002\u8FD4\u56DE dialogId\uFF0C\u53EF\u901A\u8FC7 read({ dbKey: dialogId }) \u968F\u65F6\u67E5\u770B\u5BF9\u8BDD\u7ED3\u679C\u3002",
22087
+ parameters: {
22088
+ type: "object",
22089
+ properties: {
22090
+ agentKey: {
22091
+ type: "string",
22092
+ description: "\u8D1F\u8D23\u54CD\u5E94\u8FD9\u4E2A\u5BF9\u8BDD\u7684 Agent ID\uFF08dbKey\uFF0C\u683C\u5F0F\u5982 agent-xxx\uFF09\u3002"
22093
+ },
22094
+ firstMessage: {
22095
+ type: "string",
22096
+ description: "\u53EF\u9009\u3002\u521B\u5EFA\u5BF9\u8BDD\u540E\u7ACB\u5373\u53D1\u9001\u7684\u7B2C\u4E00\u6761\u6D88\u606F\uFF0CAgent \u4F1A\u81EA\u52A8\u5F00\u59CB\u6267\u884C\u3002\u5982\u679C\u4E0D\u4F20\u5219\u53EA\u521B\u5EFA\u7A7A\u5BF9\u8BDD\u3002"
22097
+ },
22098
+ title: {
22099
+ type: "string",
22100
+ description: "\u53EF\u9009\u3002\u5BF9\u8BDD\u6807\u9898\uFF0C\u65B9\u4FBF\u540E\u7EED\u8BC6\u522B\u3002"
22101
+ }
22102
+ },
22103
+ required: ["agentKey"]
22104
+ }
21786
22105
  };
21787
- var buildCreateSkillAgentArgs = (args) => {
21788
- const mode = args.mode ?? "creator_evaluator";
21789
- const preset = buildPreset(mode);
22106
+ var createDialogFunc = async (args, context) => {
22107
+ const { agentKey, firstMessage, title } = args;
22108
+ const { getState, dispatch } = context;
22109
+ const dialogConfig = await createDialogAction(
22110
+ {
22111
+ // TODO: 后续改为 [agentKey, ...subAgents] 组合,支持多 Agent 协作
22112
+ // 目前仅使用主 agentKey 作为 cybots[0]
22113
+ cybots: [agentKey],
22114
+ title: title ?? `Dialog with ${agentKey}`
22115
+ },
22116
+ { getState, dispatch }
22117
+ );
22118
+ const dialogId = dialogConfig.id;
22119
+ if (firstMessage) {
22120
+ void dispatch(
22121
+ streamAgentChatTurn({
22122
+ agentKey,
22123
+ userInput: firstMessage,
22124
+ dialogKey: dialogConfig.dbKey
22125
+ })
22126
+ );
22127
+ }
21790
22128
  return {
21791
- name: (args.name ?? "").trim() || preset.defaultName,
21792
- model: (args.model ?? "").trim() || DEFAULT_MODEL2,
21793
- provider: (args.provider ?? "").trim() || DEFAULT_PROVIDER,
21794
- introduction: preset.introduction,
21795
- greeting: preset.greeting,
21796
- prompt: preset.prompt,
21797
- isPublic: args.isPublic ?? false,
21798
- tools: preset.tools,
21799
- references: args.references ?? [],
21800
- linkedSpaces: args.linkedSpaces ?? [],
21801
- temperature: 0.3,
21802
- reasoning_effort: "medium"
22129
+ dialogId,
22130
+ dialogKey: dialogConfig.dbKey,
22131
+ message: firstMessage ? `\u5DF2\u521B\u5EFA\u5BF9\u8BDD\u5E76\u53D1\u9001\u4EFB\u52A1\uFF0CAgent \u6B63\u5728\u540E\u53F0\u6267\u884C\u3002\u53EF\u901A\u8FC7 read({ dbKey: "${dialogConfig.dbKey}" }) \u67E5\u770B\u8FDB\u5EA6\u3002` : `\u5DF2\u521B\u5EFA\u7A7A\u5BF9\u8BDD\u3002\u53EF\u901A\u8FC7 read({ dbKey: "${dialogConfig.dbKey}" }) \u67E5\u770B\u3002`
21803
22132
  };
21804
22133
  };
21805
22134
 
21806
- // packages/ai/tools/agent/createSkillAgentTool.ts
21807
- var createSkillAgentToolFunctionSchema = {
21808
- name: "createSkillAgent",
21809
- description: "\u521B\u5EFA\u4E00\u4E2A\u4E13\u95E8\u7528\u4E8E\u521B\u5EFA/\u8BC4\u4F30 skill \u6587\u6863\u534F\u8BAE\u7684 Agent\uFF0C\u652F\u6301 creator\u3001evaluator \u6216\u4E8C\u5408\u4E00\u6A21\u5F0F\u3002",
22135
+ // packages/ai/tools/agent/runLlmTool.ts
22136
+ var runLlmFunctionSchema = {
22137
+ name: "runLlm",
22138
+ description: "\u5BF9\u6307\u5B9A\u6A21\u578B\u53D1\u8D77\u4E00\u6B21\u5355\u8F6E LLM \u8C03\u7528\u5E76\u8FD4\u56DE\u7ED3\u679C\u3002\u4E0D\u52A0\u8F7D Agent \u77E5\u8BC6\u5E93\uFF08references\uFF09\uFF0C\u9002\u5408\u6458\u8981\u3001\u5206\u7C7B\u3001\u683C\u5F0F\u5316\u3001\u7FFB\u8BD1\u7B49\u7EAF\u6587\u672C\u5904\u7406\u4EFB\u52A1\u3002\u53EF\u9009\u62E9\u6CE8\u5165\u4E34\u65F6\u7CFB\u7EDF\u63D0\u793A\u6216\u8986\u76D6\u5DE5\u5177\u5217\u8868\u3002",
21810
22139
  parameters: {
21811
22140
  type: "object",
21812
22141
  properties: {
21813
- mode: {
21814
- type: "string",
21815
- enum: ["creator", "evaluator", "creator_evaluator"],
21816
- description: "\u8981\u521B\u5EFA\u7684 skill agent \u7C7B\u578B\u3002"
21817
- },
21818
- name: {
22142
+ agentKey: {
21819
22143
  type: "string",
21820
- description: "\u53EF\u9009\uFF1AAgent \u540D\u79F0\u3002"
22144
+ description: "\u8981\u4F7F\u7528\u7684\u6A21\u578B\u914D\u7F6E ID\u3002\u82E5\u4E0D\u586B\uFF0C\u4F7F\u7528\u5F53\u524D\u5BF9\u8BDD\u7ED1\u5B9A\u7684\u9ED8\u8BA4\u6A21\u578B\u3002"
21821
22145
  },
21822
- model: {
22146
+ userInput: {
21823
22147
  type: "string",
21824
- description: "\u53EF\u9009\uFF1A\u8986\u76D6\u9ED8\u8BA4\u6A21\u578B\u3002"
22148
+ description: "\u53D1\u9001\u7ED9\u6A21\u578B\u7684\u63D0\u793A\u8BCD\u6216\u95EE\u9898\u3002"
21825
22149
  },
21826
- provider: {
22150
+ systemPrompt: {
21827
22151
  type: "string",
21828
- description: "\u53EF\u9009\uFF1A\u8986\u76D6\u9ED8\u8BA4 provider\u3002"
21829
- },
21830
- isPublic: {
21831
- type: "boolean",
21832
- description: "\u53EF\u9009\uFF1A\u662F\u5426\u516C\u5F00\u3002"
22152
+ description: "\u53EF\u9009\u3002\u4E34\u65F6\u7CFB\u7EDF\u63D0\u793A\uFF0C\u4F1A\u8986\u76D6 Agent \u539F\u6709\u914D\u7F6E\u4E2D\u7684 prompt\u3002\u9002\u5408\u4E34\u65F6\u8C03\u6574\u6A21\u578B\u884C\u4E3A\u6216\u89D2\u8272\u3002"
21833
22153
  },
21834
- references: {
22154
+ tools: {
21835
22155
  type: "array",
21836
- description: "\u53EF\u9009\uFF1A\u521B\u5EFA\u540E\u9ED8\u8BA4\u6302\u8F7D\u7684 references\u3002",
21837
- items: {
21838
- type: "object",
21839
- properties: {
21840
- dbKey: { type: "string" },
21841
- title: { type: "string" },
21842
- type: { type: "string", enum: ["knowledge", "instruction", "page"] }
21843
- },
21844
- required: ["dbKey"]
22156
+ items: { type: "string" },
22157
+ description: "\u53EF\u9009\u3002\u5DE5\u5177 ID \u5217\u8868\uFF0C\u8986\u76D6 Agent \u9ED8\u8BA4\u914D\u7F6E\u7684\u5DE5\u5177\u96C6\u3002\u4F20\u7A7A\u6570\u7EC4\u5219\u7981\u7528\u6240\u6709\u5DE5\u5177\u3002"
22158
+ }
22159
+ },
22160
+ required: ["userInput"]
22161
+ }
22162
+ };
22163
+ async function runLlmToolFunc(args, thunkApi, _context) {
22164
+ const { agentKey, userInput, systemPrompt, tools } = args;
22165
+ if (!userInput?.trim()) {
22166
+ throw new Error("runLlm: \u7F3A\u5C11 userInput \u53C2\u6570\u3002");
22167
+ }
22168
+ const { dispatch } = thunkApi;
22169
+ try {
22170
+ const result = await dispatch(
22171
+ runLlm({
22172
+ agentKey,
22173
+ content: userInput,
22174
+ isStreaming: false,
22175
+ ...systemPrompt !== void 0 && { systemPromptOverride: systemPrompt },
22176
+ ...tools !== void 0 && { toolsOverride: tools }
22177
+ })
22178
+ ).unwrap();
22179
+ const preview = typeof result === "string" ? result.slice(0, 60) + (result.length > 60 ? "\u2026" : "") : "";
22180
+ return {
22181
+ rawData: { result, userInput },
22182
+ displayData: preview || "\u2705 runLlm \u5B8C\u6210"
22183
+ };
22184
+ } catch (e) {
22185
+ const msg = toErrorMessage(e);
22186
+ throw new Error(`runLlm \u8C03\u7528\u5931\u8D25: ${msg}`);
22187
+ }
22188
+ }
22189
+
22190
+ // packages/app/utils/retryAfter.ts
22191
+ var resolveRetryAfterMs = (headers, fallbackMs, bodyRetryAfterMs) => {
22192
+ const headerDelayMs = parseRetryAfterHeaderMs(headers?.get("Retry-After"));
22193
+ if (headerDelayMs !== null) return headerDelayMs;
22194
+ return normalizeNonNegativeMs(bodyRetryAfterMs, fallbackMs);
22195
+ };
22196
+
22197
+ // packages/core/abortableDelay.ts
22198
+ function waitForAbortableDelay(ms, signal) {
22199
+ const delayMs = Number.isFinite(ms) && ms >= 0 ? Math.round(ms) : 0;
22200
+ if (signal?.aborted) {
22201
+ return Promise.reject(new DOMException("Aborted", "AbortError"));
22202
+ }
22203
+ return new Promise((resolve, reject) => {
22204
+ const onAbort = () => {
22205
+ clearTimeout(timeoutId);
22206
+ signal?.removeEventListener("abort", onAbort);
22207
+ reject(new DOMException("Aborted", "AbortError"));
22208
+ };
22209
+ const timeoutId = setTimeout(() => {
22210
+ signal?.removeEventListener("abort", onAbort);
22211
+ resolve();
22212
+ }, delayMs);
22213
+ signal?.addEventListener("abort", onAbort, { once: true });
22214
+ });
22215
+ }
22216
+
22217
+ // packages/core/deployWindowRetrySignal.ts
22218
+ function isDeployWindowRetrySignal(e) {
22219
+ if (e.reason === CORE_DRAIN_REASON) return true;
22220
+ if (typeof e.status === "number") return isGatewayHttpStatus(e.status);
22221
+ return e.retryable === true;
22222
+ }
22223
+
22224
+ // packages/ai/chat/parseMultilineSSE.ts
22225
+ function createSSEParser() {
22226
+ let buffer = "";
22227
+ return function parseSSE(chunk) {
22228
+ const results = [];
22229
+ if (!chunk) return results;
22230
+ buffer += chunk;
22231
+ const events = buffer.split(/\r?\n\r?\n/);
22232
+ buffer = events.pop() ?? "";
22233
+ for (const ev of events) {
22234
+ if (!ev.trim()) continue;
22235
+ const lines = ev.split(/\r?\n/);
22236
+ let accumulator = "";
22237
+ for (const line of lines) {
22238
+ const t = line.trim();
22239
+ if (t === "data: [DONE]") {
22240
+ if (accumulator.trim()) {
22241
+ try {
22242
+ results.push(JSON.parse(accumulator));
22243
+ } catch (e) {
22244
+ }
22245
+ accumulator = "";
22246
+ }
22247
+ results.push("[DONE]");
22248
+ continue;
22249
+ }
22250
+ let content = "";
22251
+ let isDataLine = false;
22252
+ if (t.startsWith("data:")) {
22253
+ content = line.substring(line.indexOf("data:") + 5).trim();
22254
+ isDataLine = true;
22255
+ } else if (accumulator && t && !t.startsWith("event:") && !t.startsWith("id:") && !t.startsWith("retry:")) {
22256
+ content = line;
22257
+ } else {
22258
+ continue;
22259
+ }
22260
+ if (isDataLine && !accumulator) {
22261
+ try {
22262
+ const obj = JSON.parse(content);
22263
+ results.push(obj);
22264
+ continue;
22265
+ } catch (e) {
22266
+ }
22267
+ }
22268
+ accumulator += content;
22269
+ }
22270
+ if (accumulator.trim()) {
22271
+ try {
22272
+ const obj = JSON.parse(accumulator);
22273
+ results.push(obj);
22274
+ } catch (e) {
21845
22275
  }
21846
- },
21847
- linkedSpaces: {
21848
- type: "array",
21849
- items: { type: "string" },
21850
- description: "\u53EF\u9009\uFF1A\u989D\u5916\u6302\u8F7D\u7684 linked spaces\u3002"
21851
22276
  }
21852
22277
  }
21853
- }
21854
- };
21855
- async function createSkillAgentToolFunc(args, thunkApi) {
21856
- return createAgentToolFunc(buildCreateSkillAgentArgs(args), thunkApi);
22278
+ return results;
22279
+ };
21857
22280
  }
22281
+ var parseMultilineSSE = createSSEParser();
21858
22282
 
21859
- // packages/chat/messages/messageAgent.ts
21860
- function resolveMessageAgentKey(message) {
21861
- if (!message) return void 0;
21862
- return message.agentKey || message.cybotKey;
22283
+ // packages/ai/agent/runAgentBackground.ts
22284
+ var MAX_SSE_RETRIES = 3;
22285
+ var MAX_SSE_CORE_DRAINING_RETRIES = 30;
22286
+ var SSE_RETRY_DELAY_MS = 1500;
22287
+ var MAX_RUN_START_RETRIES = 1;
22288
+ var MAX_RUN_START_CORE_DRAINING_RETRIES = 30;
22289
+ function createRetryableError(message, retryAfterMs) {
22290
+ return Object.assign(new Error(message), {
22291
+ retryable: true,
22292
+ retryAfterMs
22293
+ });
21863
22294
  }
21864
-
21865
- // packages/ai/tools/agent/updateSelfTool.ts
21866
- var updateSelfToolFunctionSchema = {
21867
- name: "updateSelf",
21868
- description: "\u66F4\u65B0\u5F53\u524D\u6B63\u5728\u8FD0\u884C\u7684 Agent \u81EA\u5DF1\u3002\u4F4E\u98CE\u9669\u5B57\u6BB5\u53EF\u76F4\u63A5\u66F4\u65B0\uFF0C\u5176\u4ED6\u5B57\u6BB5\u4F1A\u5148\u5411\u7528\u6237\u786E\u8BA4\u3002",
21869
- parameters: {
21870
- type: "object",
21871
- properties: agentUpdateFieldSchemaProperties
21872
- }
21873
- };
21874
- var resolveCurrentAgentKey = (state, parentMessageId) => {
21875
- const parentMessage = parentMessageId ? selectMsgById(state, parentMessageId) : void 0;
21876
- const parentAgentKey = resolveMessageAgentKey(parentMessage);
21877
- if (parentAgentKey) {
21878
- return parentAgentKey;
21879
- }
21880
- const currentDialog = selectCurrentDialogConfig(state);
21881
- return asTrimmedNonEmptyStringArray(currentDialog?.cybots)[0];
21882
- };
21883
- async function updateSelfToolFunc(args, thunkApi, runtime) {
21884
- const state = thunkApi.getState();
21885
- const userId = selectIdentityUserId(state);
21886
- const db = thunkApi.extra?.db;
21887
- validateUpdateArgs(userId);
21888
- const currentAgentKey = resolveCurrentAgentKey(state, runtime?.parentMessageId);
21889
- if (!currentAgentKey) {
21890
- throw new Error("updateSelf \u5931\u8D25\uFF1A\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D\u6B63\u5728\u8FD0\u884C\u7684 Agent\u3002");
22295
+ var createAgentRunIdempotencyKey = () => `run_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
22296
+ function createSubscriptionError(status, hasBody, retryAfterMs, reason) {
22297
+ const message = !hasBody ? `\u4E8B\u4EF6\u6D41\u54CD\u5E94\u7F3A\u5C11 body (${status})` : `\u65E0\u6CD5\u8BA2\u9605\u4E8B\u4EF6\u6D41 (${status})`;
22298
+ if (status === 401 || status === 403) {
22299
+ return new Error(message);
21891
22300
  }
21892
- const previousAgent = await fetchAgentByDbKey(currentAgentKey, db);
21893
- if (!previousAgent) {
21894
- throw new Error(`updateSelf \u5931\u8D25\uFF1A\u672A\u627E\u5230\u5F53\u524D Agent\uFF08${currentAgentKey}\uFF09\u3002`);
22301
+ const err = createRetryableError(message, retryAfterMs);
22302
+ err.status = status;
22303
+ if (reason) err.reason = reason;
22304
+ return err;
22305
+ }
22306
+ async function waitForRetryDelay(retryAfterMs, signal) {
22307
+ await waitForAbortableDelay(retryAfterMs, signal);
22308
+ }
22309
+ function parseRetryableJson(text) {
22310
+ try {
22311
+ return JSON.parse(text);
22312
+ } catch {
22313
+ return null;
21895
22314
  }
21896
- const requestedFields = listRequestedFields(args);
21897
- const autoApprovedFields = selectAutoApproveSelfUpdateFields(state);
21898
- assertAgentUpdateConfirmation({
21899
- scope: "self",
21900
- requestedFields,
21901
- confirmed: args.__confirmedSelfEvolution === true,
21902
- autoApprovedFields
21903
- });
21904
- const previousAgentForUpdate = buildUpdateThunkPreviousAgent(previousAgent, userId);
21905
- const agent = await thunkApi.dispatch(
21906
- updateAgent({
21907
- userId,
21908
- agentId: extractAgentId(currentAgentKey),
21909
- formData: buildPatch(args),
21910
- previousAgent: previousAgentForUpdate
21911
- })
21912
- ).unwrap().catch((e) => {
21913
- throw new Error(`updateSelf \u5931\u8D25\uFF1A${e?.message ?? "\u672A\u77E5\u9519\u8BEF"}`);
21914
- });
21915
- return {
21916
- rawData: buildRawDataWithUpdateInfo(
21917
- agent,
21918
- previousAgentForUpdate,
21919
- requestedFields
21920
- ),
21921
- displayData: formatUpdatedAgentOutput(agent)
21922
- };
21923
22315
  }
21924
-
21925
- // packages/ai/tools/agent/runStreamingAgentTool.ts
21926
- var runStreamingAgentFunctionSchema = {
21927
- name: "runStreamingAgent",
21928
- description: "\u51C6\u5907\u8C03\u7528\u4E00\u4E2A\u6307\u5B9A\u7684 Agent (\u667A\u80FD\u4EE3\u7406)\uFF0C\u5E76\u4EE5\u6D41\u5F0F\u65B9\u5F0F\u5904\u7406\u7528\u6237\u8F93\u5165\u3002\u8BE5\u5DE5\u5177\u672C\u8EAB\u53EA\u8FD4\u56DE\u8981\u8C03\u7528\u7684 Agent \u4FE1\u606F\uFF0C\u5B9E\u9645\u6D41\u5F0F\u8C03\u7528\u7531\u7CFB\u7EDF\u5728\u5DE5\u5177\u6267\u884C\u540E\u53D1\u8D77\u3002",
21929
- parameters: {
21930
- type: "object",
21931
- properties: {
21932
- agentKey: {
21933
- type: "string",
21934
- description: "\u8981\u8FD0\u884C\u7684 Agent \u7684\u552F\u4E00\u6807\u8BC6\u7B26 (Key)\u3002"
21935
- },
21936
- userInput: {
21937
- type: "string",
21938
- description: "\u8981\u53D1\u9001\u7ED9\u8BE5 Agent \u7684\u7528\u6237\u8F93\u5165\u6216\u95EE\u9898\u3002"
21939
- },
21940
- serverBase: {
21941
- type: "string",
21942
- description: "\u53EF\u9009\u3002\u76EE\u6807 Agent \u6240\u5728\u7684 nolo server origin\uFF0C\u4F8B\u5982 Windows \u673A\u5668\u901A\u8FC7 Cloudflare \u66B4\u9732\u7684 https://win.example.com\u3002\u8DE8\u57DF\u76EE\u6807\u5FC5\u987B\u7531\u670D\u52A1\u7AEF AGENT_TOOL_ALLOWED_SERVER_BASES \u660E\u786E\u653E\u884C\u3002\u5982\u679C\u76EE\u6807 Agent \u8BB0\u5F55\u58F0\u660E\u4E86 delegation.serverBase / runtimeServerBase\uFF0C\u670D\u52A1\u7AEF\u4F1A\u5728\u672A\u663E\u5F0F\u4F20\u5165\u65F6\u81EA\u52A8\u8DEF\u7531\u3002"
22316
+ async function listenToDialogEvents(dialogId, currentServer, authHeader, signal, onStatusChange, onDone, onFailed) {
22317
+ let eventsRes;
22318
+ try {
22319
+ eventsRes = await fetch(
22320
+ `${currentServer}/api/events/dialog-${dialogId}`,
22321
+ {
22322
+ method: "GET",
22323
+ headers: {
22324
+ Accept: "text/event-stream",
22325
+ ...authHeader && { Authorization: authHeader }
22326
+ },
22327
+ signal
21943
22328
  }
21944
- },
21945
- required: ["agentKey", "userInput"]
21946
- }
21947
- };
21948
- async function runStreamingAgentFunc(args, _thunkApi, _context) {
21949
- const { agentKey, userInput, serverBase } = args;
21950
- if (!agentKey) {
21951
- throw new Error("\u8C03\u7528 'runStreamingAgent' \u5931\u8D25\uFF1A\u7F3A\u5C11 'agentKey' \u53C2\u6570\u3002");
22329
+ );
22330
+ } catch (e) {
22331
+ if (isAbortError(e)) throw e;
22332
+ throw createRetryableError("\u4E8B\u4EF6\u6D41\u8FDE\u63A5\u5931\u8D25");
21952
22333
  }
21953
- if (!userInput) {
21954
- throw new Error("\u8C03\u7528 'runStreamingAgent' \u5931\u8D25\uFF1A\u7F3A\u5C11 'userInput' \u53C2\u6570\u3002");
22334
+ if (!eventsRes.ok || !eventsRes.body) {
22335
+ const errText = await eventsRes.text().catch(() => "");
22336
+ const payload = parseRetryableJson(errText);
22337
+ throw createSubscriptionError(
22338
+ eventsRes.status,
22339
+ !!eventsRes.body,
22340
+ resolveRetryAfterMs(eventsRes.headers, SSE_RETRY_DELAY_MS, payload?.retryAfterMs),
22341
+ payload?.reason
22342
+ );
21955
22343
  }
21956
- const rawData = {
21957
- agentKey,
21958
- userInput,
21959
- ...serverBase ? { serverBase } : {}
21960
- };
21961
- const displayData = `\u5C06\u8C03\u7528 Agent(${agentKey}) \u6267\u884C\u4E00\u8F6E\u6D41\u5F0F\u5BF9\u8BDD`;
21962
- return { rawData, displayData };
22344
+ const reader = eventsRes.body.getReader();
22345
+ const decoder = new TextDecoder();
22346
+ const parseSSE = createSSEParser();
22347
+ return new Promise((resolve, reject) => {
22348
+ const processStream = async () => {
22349
+ try {
22350
+ while (true) {
22351
+ const { done, value } = await reader.read();
22352
+ if (done) break;
22353
+ const chunk = decoder.decode(value, { stream: true });
22354
+ const events = parseSSE(chunk);
22355
+ for (const event of events) {
22356
+ const type = event.type;
22357
+ if (type === "status") {
22358
+ onStatusChange?.(event.status);
22359
+ } else if (type === "done") {
22360
+ const result = {
22361
+ dialogId,
22362
+ content: event.content,
22363
+ usage: event.usage
22364
+ };
22365
+ onStatusChange?.("done");
22366
+ onDone?.(result);
22367
+ reader.cancel().catch(() => {
22368
+ });
22369
+ resolve(result);
22370
+ return;
22371
+ } else if (type === "failed") {
22372
+ const errMsg = event.error ?? "\u672A\u77E5\u9519\u8BEF";
22373
+ onStatusChange?.("failed");
22374
+ onFailed?.(errMsg);
22375
+ reader.cancel().catch(() => {
22376
+ });
22377
+ reject(new Error(errMsg));
22378
+ return;
22379
+ }
22380
+ }
22381
+ }
22382
+ const err = createRetryableError("\u4E8B\u4EF6\u6D41\u610F\u5916\u5173\u95ED");
22383
+ reject(err);
22384
+ } catch (e) {
22385
+ reject(e);
22386
+ }
22387
+ };
22388
+ processStream();
22389
+ });
21963
22390
  }
21964
-
21965
- // packages/ai/tools/agent/createDialogTool.ts
21966
- var createDialogFunctionSchema = {
21967
- name: "createDialog",
21968
- description: "\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u5BF9\u8BDD\uFF08Dialog\uFF09\uFF0C\u53EF\u4EE5\u6307\u5B9A\u7531\u54EA\u4E2A Agent \u6765\u54CD\u5E94\uFF0C\u5E76\u53EF\u9009\u5730\u53D1\u9001\u7B2C\u4E00\u6761\u6D88\u606F\u89E6\u53D1 Agent \u7ACB\u5373\u6267\u884C\u3002\u5E38\u7528\u4E8E\uFF1A\u6D3E\u751F\u5B50\u4EFB\u52A1\u5BF9\u8BDD\u3001\u8BA9\u67D0\u4E2A\u4E13\u7528 Agent \u5728\u540E\u53F0\u5904\u7406\u95EE\u9898\u3001\u7761\u524D\u5E03\u7F6E\u4EFB\u52A1\u7B49\u573A\u666F\u3002\u8FD4\u56DE dialogId\uFF0C\u53EF\u901A\u8FC7 read({ dbKey: dialogId }) \u968F\u65F6\u67E5\u770B\u5BF9\u8BDD\u7ED3\u679C\u3002",
21969
- parameters: {
21970
- type: "object",
21971
- properties: {
21972
- agentKey: {
21973
- type: "string",
21974
- description: "\u8D1F\u8D23\u54CD\u5E94\u8FD9\u4E2A\u5BF9\u8BDD\u7684 Agent ID\uFF08dbKey\uFF0C\u683C\u5F0F\u5982 agent-xxx\uFF09\u3002"
21975
- },
21976
- firstMessage: {
21977
- type: "string",
21978
- description: "\u53EF\u9009\u3002\u521B\u5EFA\u5BF9\u8BDD\u540E\u7ACB\u5373\u53D1\u9001\u7684\u7B2C\u4E00\u6761\u6D88\u606F\uFF0CAgent \u4F1A\u81EA\u52A8\u5F00\u59CB\u6267\u884C\u3002\u5982\u679C\u4E0D\u4F20\u5219\u53EA\u521B\u5EFA\u7A7A\u5BF9\u8BDD\u3002"
21979
- },
21980
- title: {
21981
- type: "string",
21982
- description: "\u53EF\u9009\u3002\u5BF9\u8BDD\u6807\u9898\uFF0C\u65B9\u4FBF\u540E\u7EED\u8BC6\u522B\u3002"
22391
+ var runAgentBackground = createAsyncThunk("agent/runBackground", async (args, { getState, signal: thunkSignal }) => {
22392
+ const { agentKey, userInput, serverBase, spaceId, parentDialogId, ephemeral, runKind, onStatusChange, onDone, onFailed } = args;
22393
+ const state = getState();
22394
+ const currentServer = normalizeServerOrigin(serverBase) || selectCurrentServer(state);
22395
+ const token = selectIdentityToken(state);
22396
+ if (!currentServer) throw new Error("\u672A\u914D\u7F6E\u670D\u52A1\u5668\u5730\u5740");
22397
+ const authHeader = token ? `Bearer ${token}` : "";
22398
+ const effectiveSignal = args.signal ?? thunkSignal;
22399
+ let runResponse = null;
22400
+ let maxRunStartRetries = MAX_RUN_START_RETRIES;
22401
+ const idempotencyKey = args.idempotencyKey?.trim() || createAgentRunIdempotencyKey();
22402
+ for (let attempt = 0; attempt <= maxRunStartRetries; attempt++) {
22403
+ let runRes;
22404
+ try {
22405
+ runRes = await fetch(`${currentServer}/api/agent/run`, {
22406
+ method: "POST",
22407
+ headers: {
22408
+ "Content-Type": "application/json",
22409
+ ...authHeader && { Authorization: authHeader }
22410
+ },
22411
+ body: JSON.stringify({
22412
+ agentKey,
22413
+ userInput,
22414
+ spaceId,
22415
+ background: true,
22416
+ idempotencyKey,
22417
+ ...parentDialogId ? { parentDialogId } : {},
22418
+ ...ephemeral ? { ephemeral: true } : {},
22419
+ ...runKind ? { runKind } : {},
22420
+ runtimeContext: {
22421
+ surface: "web",
22422
+ host: "browser",
22423
+ runtime: "react",
22424
+ entrypoint: "background-agent-run",
22425
+ capabilities: ["background", "sse-events"],
22426
+ ...parentDialogId ? {
22427
+ parentThreadId: parentDialogId,
22428
+ // 标记为 background_handoff:子 run 到达终态时,
22429
+ // 服务端会向父对话注入 terminal wake 消息,父 agent
22430
+ // 下一 turn 自然看到结果并继续——无需轮询。
22431
+ presentationIntent: "background_handoff"
22432
+ } : {}
22433
+ }
22434
+ }),
22435
+ signal: effectiveSignal
22436
+ });
22437
+ } catch (e) {
22438
+ if (isAbortError(e)) throw e;
22439
+ if (attempt < maxRunStartRetries) {
22440
+ await waitForRetryDelay(SSE_RETRY_DELAY_MS, effectiveSignal);
22441
+ continue;
21983
22442
  }
21984
- },
21985
- required: ["agentKey"]
21986
- }
21987
- };
21988
- var createDialogFunc = async (args, context) => {
21989
- const { agentKey, firstMessage, title } = args;
21990
- const { getState, dispatch } = context;
21991
- const dialogConfig = await createDialogAction(
21992
- {
21993
- // TODO: 后续改为 [agentKey, ...subAgents] 组合,支持多 Agent 协作
21994
- // 目前仅使用主 agentKey 作为 cybots[0]
21995
- cybots: [agentKey],
21996
- title: title ?? `Dialog with ${agentKey}`
21997
- },
21998
- { getState, dispatch }
21999
- );
22000
- const dialogId = dialogConfig.id;
22001
- if (firstMessage) {
22002
- void dispatch(
22003
- streamAgentChatTurn({
22004
- agentKey,
22005
- userInput: firstMessage,
22006
- dialogKey: dialogConfig.dbKey
22007
- })
22443
+ throw new Error(`\u542F\u52A8\u540E\u53F0\u4EFB\u52A1\u5931\u8D25: ${e?.message ?? String(e)}`);
22444
+ }
22445
+ if (runRes.ok) {
22446
+ runResponse = await runRes.json();
22447
+ break;
22448
+ }
22449
+ const errText = await runRes.text();
22450
+ const payload = parseRetryableJson(errText);
22451
+ const retryAfterMs = resolveRetryAfterMs(
22452
+ runRes.headers,
22453
+ SSE_RETRY_DELAY_MS,
22454
+ payload?.retryAfterMs
22008
22455
  );
22456
+ const isCoreDraining = payload?.reason === CORE_DRAIN_REASON;
22457
+ const retryable = payload?.retryable === true || isCoreDraining || isGatewayHttpStatus(runRes.status);
22458
+ if (isCoreDraining) {
22459
+ maxRunStartRetries = MAX_RUN_START_CORE_DRAINING_RETRIES;
22460
+ }
22461
+ if (retryable && attempt < maxRunStartRetries) {
22462
+ await waitForRetryDelay(retryAfterMs, effectiveSignal);
22463
+ continue;
22464
+ }
22465
+ if (isCoreDraining) {
22466
+ throw new Error(DRAIN_EXHAUSTED_USER_MESSAGE);
22467
+ }
22468
+ throw new Error(`\u542F\u52A8\u540E\u53F0\u4EFB\u52A1\u5931\u8D25 (${runRes.status}): ${errText}`);
22009
22469
  }
22010
- return {
22011
- dialogId,
22012
- dialogKey: dialogConfig.dbKey,
22013
- message: firstMessage ? `\u5DF2\u521B\u5EFA\u5BF9\u8BDD\u5E76\u53D1\u9001\u4EFB\u52A1\uFF0CAgent \u6B63\u5728\u540E\u53F0\u6267\u884C\u3002\u53EF\u901A\u8FC7 read({ dbKey: "${dialogConfig.dbKey}" }) \u67E5\u770B\u8FDB\u5EA6\u3002` : `\u5DF2\u521B\u5EFA\u7A7A\u5BF9\u8BDD\u3002\u53EF\u901A\u8FC7 read({ dbKey: "${dialogConfig.dbKey}" }) \u67E5\u770B\u3002`
22014
- };
22015
- };
22016
-
22017
- // packages/ai/tools/agent/runLlmTool.ts
22018
- var runLlmFunctionSchema = {
22019
- name: "runLlm",
22020
- description: "\u5BF9\u6307\u5B9A\u6A21\u578B\u53D1\u8D77\u4E00\u6B21\u5355\u8F6E LLM \u8C03\u7528\u5E76\u8FD4\u56DE\u7ED3\u679C\u3002\u4E0D\u52A0\u8F7D Agent \u77E5\u8BC6\u5E93\uFF08references\uFF09\uFF0C\u9002\u5408\u6458\u8981\u3001\u5206\u7C7B\u3001\u683C\u5F0F\u5316\u3001\u7FFB\u8BD1\u7B49\u7EAF\u6587\u672C\u5904\u7406\u4EFB\u52A1\u3002\u53EF\u9009\u62E9\u6CE8\u5165\u4E34\u65F6\u7CFB\u7EDF\u63D0\u793A\u6216\u8986\u76D6\u5DE5\u5177\u5217\u8868\u3002",
22021
- parameters: {
22022
- type: "object",
22023
- properties: {
22024
- agentKey: {
22025
- type: "string",
22026
- description: "\u8981\u4F7F\u7528\u7684\u6A21\u578B\u914D\u7F6E ID\u3002\u82E5\u4E0D\u586B\uFF0C\u4F7F\u7528\u5F53\u524D\u5BF9\u8BDD\u7ED1\u5B9A\u7684\u9ED8\u8BA4\u6A21\u578B\u3002"
22027
- },
22028
- userInput: {
22029
- type: "string",
22030
- description: "\u53D1\u9001\u7ED9\u6A21\u578B\u7684\u63D0\u793A\u8BCD\u6216\u95EE\u9898\u3002"
22031
- },
22032
- systemPrompt: {
22033
- type: "string",
22034
- description: "\u53EF\u9009\u3002\u4E34\u65F6\u7CFB\u7EDF\u63D0\u793A\uFF0C\u4F1A\u8986\u76D6 Agent \u539F\u6709\u914D\u7F6E\u4E2D\u7684 prompt\u3002\u9002\u5408\u4E34\u65F6\u8C03\u6574\u6A21\u578B\u884C\u4E3A\u6216\u89D2\u8272\u3002"
22035
- },
22036
- tools: {
22037
- type: "array",
22038
- items: { type: "string" },
22039
- description: "\u53EF\u9009\u3002\u5DE5\u5177 ID \u5217\u8868\uFF0C\u8986\u76D6 Agent \u9ED8\u8BA4\u914D\u7F6E\u7684\u5DE5\u5177\u96C6\u3002\u4F20\u7A7A\u6570\u7EC4\u5219\u7981\u7528\u6240\u6709\u5DE5\u5177\u3002"
22040
- }
22041
- },
22042
- required: ["userInput"]
22470
+ if (!runResponse) {
22471
+ throw new Error("\u542F\u52A8\u540E\u53F0\u4EFB\u52A1\u5931\u8D25\uFF1A\u672A\u6536\u5230\u53EF\u7528\u7684\u540E\u53F0\u8FD0\u884C\u54CD\u5E94");
22043
22472
  }
22044
- };
22045
- async function runLlmToolFunc(args, thunkApi, _context) {
22046
- const { agentKey, userInput, systemPrompt, tools } = args;
22047
- if (!userInput?.trim()) {
22048
- throw new Error("runLlm: \u7F3A\u5C11 userInput \u53C2\u6570\u3002");
22473
+ const {
22474
+ dialogId,
22475
+ serverBase: routedServerBase
22476
+ } = runResponse;
22477
+ onStatusChange?.("pending");
22478
+ if (args.waitForCompletion === false) {
22479
+ return { dialogId, status: runResponse.status };
22049
22480
  }
22050
- const { dispatch } = thunkApi;
22051
- try {
22052
- const result = await dispatch(
22053
- runLlm({
22054
- agentKey,
22055
- content: userInput,
22056
- isStreaming: false,
22057
- ...systemPrompt !== void 0 && { systemPromptOverride: systemPrompt },
22058
- ...tools !== void 0 && { toolsOverride: tools }
22059
- })
22060
- ).unwrap();
22061
- const preview = typeof result === "string" ? result.slice(0, 60) + (result.length > 60 ? "\u2026" : "") : "";
22062
- return {
22063
- rawData: { result, userInput },
22064
- displayData: preview || "\u2705 runLlm \u5B8C\u6210"
22065
- };
22066
- } catch (e) {
22067
- const msg = toErrorMessage(e);
22068
- throw new Error(`runLlm \u8C03\u7528\u5931\u8D25: ${msg}`);
22481
+ let lastError;
22482
+ let maxSseRetries = MAX_SSE_RETRIES;
22483
+ const eventServer = normalizeServerOrigin(routedServerBase) || currentServer;
22484
+ for (let attempt = 0; attempt <= maxSseRetries; attempt++) {
22485
+ try {
22486
+ return await listenToDialogEvents(
22487
+ dialogId,
22488
+ eventServer,
22489
+ authHeader,
22490
+ effectiveSignal,
22491
+ onStatusChange,
22492
+ onDone,
22493
+ onFailed
22494
+ );
22495
+ } catch (e) {
22496
+ if (isAbortError(e)) throw e;
22497
+ if (!e?.retryable || attempt >= maxSseRetries) throw e;
22498
+ if (isDeployWindowRetrySignal(e)) {
22499
+ maxSseRetries = MAX_SSE_CORE_DRAINING_RETRIES;
22500
+ }
22501
+ lastError = e;
22502
+ onStatusChange?.("reconnecting");
22503
+ await waitForRetryDelay(e?.retryAfterMs ?? SSE_RETRY_DELAY_MS, effectiveSignal);
22504
+ }
22069
22505
  }
22070
- }
22506
+ throw lastError ?? new Error("\u4E8B\u4EF6\u6D41\u91CD\u8FDE\u5931\u8D25");
22507
+ });
22071
22508
 
22072
22509
  // packages/ai/tools/agent/startAgentRunTool.ts
22073
22510
  var startAgentRunFunctionSchema = {
22074
22511
  name: "startAgentRun",
22075
- description: "\u540E\u53F0\u542F\u52A8\u4E00\u4E2A Agent \u6267\u884C\u5B50\u4EFB\u52A1\uFF0C\u7ACB\u5373\u8FD4\u56DE runId\uFF0C\u4E0D\u963B\u585E\u5F53\u524D\u5BF9\u8BDD\u3002\u76F8\u5F53\u4E8E Unix \u7684 fork+exec\uFF1A\u62FF\u5230 runId \u540E\u7528 controlAgentRun \u89C2\u5BDF/\u505C\u6B62\u3002\u9002\u5408\u957F\u4EFB\u52A1\u3001\u5E76\u884C\u5B50\u4EFB\u52A1\u3001\u9700\u8981\u4E2D\u9014\u89C2\u5BDF\u6216\u53EB\u505C\u7684\u573A\u666F\u3002\u5982\u679C\u5B50\u4EFB\u52A1 < 100s \u4E14\u9700\u8981\u7ACB\u5373\u62FF\u7ED3\u679C\uFF0C\u7528 callAgent\uFF08\u540C\u6B65\uFF09\u66F4\u5408\u9002\u3002",
22512
+ description: "\u542F\u52A8\u4E00\u4E2A Agent \u6267\u884C\u5B50\u4EFB\u52A1\u3002\u9ED8\u8BA4\u5F02\u6B65\uFF08Unix fork+exec\uFF09\uFF1A\u7ACB\u5373\u8FD4\u56DE runId\uFF0C\u4E0D\u963B\u585E\u5F53\u524D\u5BF9\u8BDD\uFF0C\u4E4B\u540E\u7528 controlAgentRun \u89C2\u5BDF/\u505C\u6B62\uFF1B\u5F02\u6B65\u6D3E\u53D1\u540E\u7981\u6B62\u8F6E\u8BE2\u67E5\u8BE2\u2014\u2014\u4E0D\u8981\u53CD\u590D\u8C03 status \u7B49\u7ED3\u679C\uFF0C\u7528\u6237\u754C\u9762\u5DF2\u5728\u5B9E\u65F6\u663E\u793A\u6BCF\u6761 run \u7684\u72B6\u6001\u3002\u8981\u540C\u6B65\u7ED3\u679C\u76F4\u63A5\u4F20 wait:true\uFF1A\u8BA2\u9605 SSE \u7B49 done/failed \u5E76\u76F4\u63A5\u8FD4\u56DE\u5B50\u4EFB\u52A1\u7ED3\u679C\uFF08\u9002\u5408 <100s \u7684\u5B50\u4EFB\u52A1\uFF09\u3002wait:true \u65F6\u53EF\u7528 resultMode \u63A7\u5236\u8FD4\u56DE\u5185\u5BB9\uFF1Afull=\u8FD4\u56DE\u5B8C\u6574\u8F93\u51FA\uFF1Bsummary=\u53EA\u8FD4\u56DE\u5934\u5C3E\u603B\u7ED3\uFF08\u622A\u65AD\u4E2D\u95F4\uFF0C\u9632\u957F\u8F93\u51FA\u6491\u7206\u4E0A\u4E0B\u6587\uFF09\u3002\u9002\u5408\u957F\u4EFB\u52A1\u3001\u5E76\u884C\u5B50\u4EFB\u52A1\u3001\u9700\u8981\u4E2D\u9014\u89C2\u5BDF\u6216\u53EB\u505C\u7684\u573A\u666F\u3002",
22076
22513
  parameters: {
22077
22514
  type: "object",
22078
22515
  properties: {
@@ -22102,13 +22539,25 @@ var startAgentRunFunctionSchema = {
22102
22539
  trackTodo: {
22103
22540
  type: "boolean",
22104
22541
  description: '\u53EF\u9009\u3002\u4E3A true \u65F6\u672C\u6B21 run \u4F1A\u88AB\u8BB0\u5F55\u8FDB runtime todo\uFF08~/.nolo/todos.json\uFF09\u3002\u4F20\u4E86 batchId \u65F6\u9ED8\u8BA4\u5373\u8BB0\u5F55\uFF08\u6BCF\u6279\u5BF9\u5E94\u4E00\u9879 todo\uFF09\u3002todo \u72B6\u6001\u7531\u5173\u8054 run \u72B6\u6001 + review \u7ED3\u8BBA\u63A8\u5BFC\uFF0C\u7528 controlAgentRun(action:"todo") \u67E5\u8BE2\u3002'
22542
+ },
22543
+ wait: {
22544
+ type: "boolean",
22545
+ description: "\u53EF\u9009\u3002\u4E3A true \u65F6\u540C\u6B65\u7B49\u5F85\u5B50\u4EFB\u52A1\u5B8C\u6210\u5E76\u76F4\u63A5\u8FD4\u56DE\u7ED3\u679C\uFF08\u8BA2\u9605 SSE \u7B49 done/failed\uFF09\uFF0C\u4E0D\u8FD4\u56DE runId \u8BA9\u8C03\u7528\u65B9\u8F6E\u8BE2\uFF1B\u9002\u5408 <100s \u4E14\u9700\u8981\u7ACB\u5373\u62FF\u7ED3\u679C\u7684\u5B50\u4EFB\u52A1\u3002\u9ED8\u8BA4 false\uFF08\u5F02\u6B65 fork+exec\uFF0C\u8FD4\u56DE runId \u540E\u7528 controlAgentRun \u89C2\u5BDF\uFF09\u3002",
22546
+ default: false
22547
+ },
22548
+ resultMode: {
22549
+ type: "string",
22550
+ enum: ["full", "summary"],
22551
+ default: "full",
22552
+ description: "\u53EF\u9009\u3002full=\u8FD4\u56DE\u5B8C\u6574\u8F93\u51FA\uFF1Bsummary=\u53EA\u8FD4\u56DE\u5B50\u4EFB\u52A1\u603B\u7ED3\uFF08\u622A\u65AD\u4E2D\u95F4\u90E8\u5206\uFF09\u3002\u9ED8\u8BA4 full\u3002"
22105
22553
  }
22106
22554
  },
22107
22555
  required: ["agentKey", "task"]
22108
22556
  }
22109
22557
  };
22110
22558
  async function startAgentRunFunc(args, thunkApi, _context) {
22111
- const { agentKey, task, input, agentName, ephemeral, batchId } = args;
22559
+ const { agentKey, task, input, agentName, ephemeral, batchId, wait } = args;
22560
+ const resultMode = args.resultMode ?? "full";
22112
22561
  const { dispatch } = thunkApi;
22113
22562
  const effectiveBatchId = typeof batchId === "string" && batchId.trim() ? batchId.trim() : `batch-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}-${Math.random().toString(36).slice(2, 8)}`;
22114
22563
  if (!agentKey) {
@@ -22125,11 +22574,22 @@ async function startAgentRunFunc(args, thunkApi, _context) {
22125
22574
  runAgentBackground({
22126
22575
  agentKey,
22127
22576
  userInput: content,
22128
- waitForCompletion: false,
22577
+ // wait 缺省必须归一为 false:runAgentBackground 只对
22578
+ // waitForCompletion === false 走「拿到 dialogId 立即返回」快路径,
22579
+ // undefined 会误入同步等待分支。
22580
+ waitForCompletion: wait === true,
22581
+ runKind: "subtask",
22129
22582
  ...parentDialogId ? { parentDialogId } : {},
22130
22583
  ...ephemeral ? { ephemeral: true } : {}
22131
22584
  })
22132
22585
  ).unwrap();
22586
+ if (wait === true) {
22587
+ const fullContent = bgResult.content ?? "";
22588
+ return {
22589
+ rawData: resultMode === "summary" ? summarizeChildContent(fullContent) : fullContent,
22590
+ displayData: `\u2705 startAgentRun \u540C\u6B65\u5B8C\u6210\uFF0CdialogId: ${bgResult.dialogId}${resultMode === "summary" ? "\uFF08summary\uFF09" : ""}`
22591
+ };
22592
+ }
22133
22593
  const runId = bgResult.dialogId;
22134
22594
  const status = bgResult.status ?? "pending";
22135
22595
  const resolvedName = agentName?.trim() || bgResult.agentName || bgResult.name;
@@ -22157,23 +22617,39 @@ async function startAgentRunFunc(args, thunkApi, _context) {
22157
22617
  throw new Error(`startAgentRun \u542F\u52A8 Agent [${agentKey}] \u5931\u8D25: ${toErrorMessage(e)}`);
22158
22618
  }
22159
22619
  }
22620
+ var SUMMARY_HEAD_CHARS = 1500;
22621
+ var SUMMARY_TAIL_CHARS = 500;
22622
+ var SUMMARY_MIN_LENGTH_THRESHOLD = SUMMARY_HEAD_CHARS + SUMMARY_TAIL_CHARS + 50;
22623
+ function summarizeChildContent(text) {
22624
+ if (text.length <= SUMMARY_MIN_LENGTH_THRESHOLD) return text;
22625
+ return `${text.slice(0, SUMMARY_HEAD_CHARS)}
22626
+
22627
+ \u2026\uFF08\u4E2D\u95F4\u90E8\u5206\u5DF2\u7701\u7565\uFF0CresultMode=full \u53EF\u770B\u5B8C\u6574\u8F93\u51FA\uFF09\u2026
22628
+
22629
+ ${text.slice(-SUMMARY_TAIL_CHARS)}`;
22630
+ }
22160
22631
 
22161
22632
  // packages/ai/tools/agent/controlAgentRunTool.ts
22162
22633
  var controlAgentRunFunctionSchema = {
22163
22634
  name: "controlAgentRun",
22164
- description: "\u89C2\u5BDF\u548C\u63A7\u5236\u540E\u53F0 agent run\u3002\u4E00\u4E2A\u5DE5\u5177\u4E09\u4E2A action\uFF1Alist\uFF08\u5217\u51FA run\uFF0C\u652F\u6301\u6309\u6279\u6B21/\u72B6\u6001\u8FC7\u6EE4\u4E0E\u5206\u9875\uFF09\u3001status\uFF08\u67E5\u5355\u6761 + \u53EF\u9009\u65E5\u5FD7\uFF09\u3001stop\uFF08\u53D6\u6D88 run\uFF09\u3002\u76F8\u5F53\u4E8E Unix \u7684 wait + signal + /proc\u3002\u7528 startAgentRun \u62FF\u5230 runId \u540E\uFF0C\u7528\u672C\u5DE5\u5177\u8DDF\u8FDB\u5EA6\u6216\u53EB\u505C\u3002list \u9ED8\u8BA4\u53EA\u8FD4\u56DE\u6700\u8FD1 20 \u6761\uFF0C\u907F\u514D\u5168\u91CF\u51B2\u7206\u4E0A\u4E0B\u6587\uFF1B\u7528 status/batchId/limit/offset \u53D6\u6240\u9700\u5206\u9875\u3002\u6CE8\u610F\uFF1A\u7528\u6237\u754C\u9762\u5DF2\u7ECF\u5728\u72EC\u7ACB\u5B9E\u65F6\u663E\u793A\u6BCF\u6761 run \u7684\u72B6\u6001\uFF0C\u672C\u5DE5\u5177\u662F\u7ED9\u4F60\u81EA\u5DF1\u505A\u51B3\u7B56\u7528\u7684\uFF0C\u4E0D\u662F\u7528\u6765\u7ED9\u7528\u6237\u6C47\u62A5\u8FDB\u5EA6\u7684\u2014\u2014\u4E0D\u5FC5\u4E3A\u4E86\u300C\u8BA9\u7528\u6237\u770B\u5230\u72B6\u6001\u300D\u800C\u8F6E\u8BE2\uFF0C\u4E5F\u4E0D\u8981\u628A\u8FD4\u56DE\u503C\u590D\u8FF0\u7ED9\u7528\u6237\u3002",
22635
+ description: "\u89C2\u5BDF\u548C\u63A7\u5236\u540E\u53F0 agent run\u3002\u4E00\u4E2A\u5DE5\u5177\u56DB\u4E2A\u6838\u5FC3 action\uFF1Alist\uFF08\u5217\u51FA run\uFF0C\u652F\u6301\u6309\u6279\u6B21/\u72B6\u6001\u8FC7\u6EE4\u4E0E\u5206\u9875\uFF09\u3001status\uFF08\u67E5\u5355\u6761 + \u53EF\u9009\u65E5\u5FD7\uFF09\u3001stop\uFF08\u53D6\u6D88 run\uFF09\u3001wait\uFF08\u540C\u6B65\u7B49\u5F85 run \u5230\u8FBE\u7EC8\u6001\u5E76\u8FD4\u56DE\u7ED3\u679C\uFF0CUnix wait \u8BED\u4E49\uFF1B\u53E6\u6709 todo \u67E5\u8BE2 runtime todo\uFF09\u3002\u76F8\u5F53\u4E8E Unix \u7684 wait + signal + /proc\u3002\u7528 startAgentRun \u62FF\u5230 runId \u540E\uFF0C\u7528\u672C\u5DE5\u5177\u8DDF\u8FDB\u5EA6\u3001\u7B49\u7ED3\u679C\u6216\u53EB\u505C\u3002\u5F02\u6B65\u6D3E\u53D1\u540E\u7981\u6B62\u8F6E\u8BE2\u67E5\u8BE2\u2014\u2014\u4E0D\u8981\u53CD\u590D\u8C03 status \u7B49\u7ED3\u679C\uFF0C\u7528\u6237\u754C\u9762\u5DF2\u5728\u5B9E\u65F6\u663E\u793A\u6BCF\u6761 run \u7684\u72B6\u6001\uFF1B\u8981\u540C\u6B65\u7ED3\u679C\u76F4\u63A5\u7528 startAgentRun(wait:true) \u6216\u672C\u5DE5\u5177 wait action\u3002list \u9ED8\u8BA4\u53EA\u8FD4\u56DE\u6700\u8FD1 20 \u6761\uFF0C\u907F\u514D\u5168\u91CF\u51B2\u7206\u4E0A\u4E0B\u6587\uFF1B\u7528 status/batchId/limit/offset \u53D6\u6240\u9700\u5206\u9875\u3002\u6CE8\u610F\uFF1A\u7528\u6237\u754C\u9762\u5DF2\u7ECF\u5728\u72EC\u7ACB\u5B9E\u65F6\u663E\u793A\u6BCF\u6761 run \u7684\u72B6\u6001\uFF0C\u672C\u5DE5\u5177\u662F\u7ED9\u4F60\u81EA\u5DF1\u505A\u51B3\u7B56\u7528\u7684\uFF0C\u4E0D\u662F\u7528\u6765\u7ED9\u7528\u6237\u6C47\u62A5\u8FDB\u5EA6\u7684\u2014\u2014\u4E0D\u5FC5\u4E3A\u4E86\u300C\u8BA9\u7528\u6237\u770B\u5230\u72B6\u6001\u300D\u800C\u8F6E\u8BE2\uFF0C\u4E5F\u4E0D\u8981\u628A\u8FD4\u56DE\u503C\u590D\u8FF0\u7ED9\u7528\u6237\u3002",
22165
22636
  parameters: {
22166
22637
  type: "object",
22167
22638
  properties: {
22168
22639
  action: {
22169
22640
  type: "string",
22170
- enum: ["list", "status", "stop", "todo"],
22171
- description: "\u8981\u6267\u884C\u7684\u64CD\u4F5C\uFF1Alist=\u5217\u51FA run\uFF08\u7701\u7565 runId\uFF09\uFF1Bstatus=\u67E5\u5355\u6761 run \u72B6\u6001 + \u53EF\u9009\u65E5\u5FD7\uFF1Bstop=\u53D6\u6D88 run\uFF1Btodo=\u5217\u51FA runtime todo\uFF08\u7531 startAgentRun \u7684 batchId/trackTodo \u4EA7\u751F\uFF0C\u72B6\u6001\u7531\u5173\u8054 run \u63A8\u5BFC\uFF09\u3002"
22641
+ enum: ["list", "status", "stop", "todo", "wait"],
22642
+ description: "\u8981\u6267\u884C\u7684\u64CD\u4F5C\uFF1Alist=\u5217\u51FA run\uFF08\u7701\u7565 runId\uFF09\uFF1Bstatus=\u67E5\u5355\u6761 run \u72B6\u6001 + \u53EF\u9009\u65E5\u5FD7\uFF1Bstop=\u53D6\u6D88 run\uFF1Bwait=\u540C\u6B65\u7B49\u5F85 run \u5230\u8FBE\u7EC8\u6001\u5E76\u8FD4\u56DE\u7ED3\u679C\uFF08Unix wait \u8BED\u4E49\uFF1B\u5BA2\u6237\u7AEF\u8BA2\u9605\u8BE5 dialog \u7684 SSE \u4E8B\u4EF6\u6D41\u7B49 done/failed\uFF0C\u5DF2\u7EC8\u6001\u7ACB\u5373\u8FD4\u56DE\uFF09\uFF1Btodo=\u5217\u51FA runtime todo\uFF08\u7531 startAgentRun \u7684 batchId/trackTodo \u4EA7\u751F\uFF0C\u72B6\u6001\u7531\u5173\u8054 run \u63A8\u5BFC\uFF09\u3002"
22172
22643
  },
22173
22644
  runId: {
22174
22645
  type: "string",
22175
22646
  description: "\u76EE\u6807 run \u7684 ID\uFF08startAgentRun \u8FD4\u56DE\u7684 runId\uFF09\u3002action=list \u65F6\u7701\u7565\u3002"
22176
22647
  },
22648
+ timeoutMs: {
22649
+ type: "number",
22650
+ description: '\u53EF\u9009\u3002action=wait \u7684\u7B49\u5F85\u4E0A\u9650\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 100000\uFF08100s\uFF09\u3002\u8D85\u8FC7\u4E0A\u9650\u4ECD\u672A\u5230\u8FBE\u7EC8\u6001\u65F6\u8FD4\u56DE status="timeout"\uFF08\u4E0D\u662F\u5931\u8D25\uFF09\uFF0C\u53EF\u7A0D\u540E\u518D wait \u6216\u6539\u7528 status/stop\u3002',
22651
+ default: 1e5
22652
+ },
22177
22653
  tailLines: {
22178
22654
  type: "number",
22179
22655
  description: "\u53EF\u9009\u3002action=status \u65F6\uFF1A0=\u53EA\u8FD4\u56DE\u72B6\u6001\u6458\u8981\uFF0C>0=\u540C\u65F6\u8FD4\u56DE\u6700\u8FD1 N \u884C\u65E5\u5FD7\uFF08\u9ED8\u8BA4 0\uFF09\u3002\u672C\u5730 run \u7684\u72B6\u6001\u6458\u8981\u91CC\u5E26 progress\uFF08toolCalls/llmCalls/fileEdits\u3001inFlight=\u6B64\u523B\u5728\u6267\u884C\u4EC0\u4E48\u3001idleMs=\u8DDD\u4E0A\u6B21\u4E8B\u4EF6\u591A\u4E45\uFF09\uFF0C\u8DB3\u4EE5\u5224\u65AD\u300C\u5728\u5E72\u6D3B\u300D\u8FD8\u662F\u300C\u5361\u4F4F\u4E86\u300D\u2014\u2014\u5148\u770B\u5B83\uFF0C\u53EA\u6709\u786E\u5B9E\u53EF\u7591\u6216\u5DF2\u5931\u8D25\u65F6\u624D tailLines>0 \u62C9\u65E5\u5FD7\u3002",
@@ -22205,7 +22681,7 @@ var controlAgentRunFunctionSchema = {
22205
22681
  }
22206
22682
  };
22207
22683
  async function controlAgentRunFunc(args, thunkApi, _context) {
22208
- const { action, runId, tailLines, batchId, status, statusFilter, limit, offset } = args;
22684
+ const { action, runId, tailLines, timeoutMs, batchId, status, statusFilter, limit, offset } = args;
22209
22685
  if (action === "list") {
22210
22686
  return handleList(thunkApi, { batchId, status, statusFilter, limit, offset });
22211
22687
  }
@@ -22220,6 +22696,10 @@ async function controlAgentRunFunc(args, thunkApi, _context) {
22220
22696
  if (!runId) throw new Error('controlAgentRun(action:"stop"): \u7F3A\u5C11 runId\u3002');
22221
22697
  return handleStop(thunkApi, { runId });
22222
22698
  }
22699
+ if (action === "wait") {
22700
+ if (!runId) throw new Error('controlAgentRun(action:"wait"): \u7F3A\u5C11 runId\u3002');
22701
+ return handleWait(thunkApi, { runId, timeoutMs, signal: _context?.signal });
22702
+ }
22223
22703
  throw new Error(`controlAgentRun: \u672A\u77E5 action "${action}"\u3002`);
22224
22704
  }
22225
22705
  async function handleList(thunkApi, opts) {
@@ -22301,6 +22781,112 @@ async function handleStop(thunkApi, opts) {
22301
22781
  throw new Error(`controlAgentRun(stop) \u5931\u8D25: ${toErrorMessage(e)}`);
22302
22782
  }
22303
22783
  }
22784
+ var WAIT_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["done", "failed", "cancelled", "orphaned"]);
22785
+ var DEFAULT_WAIT_TIMEOUT_MS = 1e5;
22786
+ var WAIT_INTERRUPTED_ERROR_NAME = "AgentWaitInterruptedError";
22787
+ function createWaitInterruptedError() {
22788
+ const err = new Error(
22789
+ "\u7B49\u5F85\u88AB\u4E2D\u6B62\uFF1ASSE \u8BA2\u9605\u5DF2\u4E2D\u65AD\uFF08\u5916\u90E8\u53D6\u6D88\u6216\u8FDE\u63A5\u6E05\u7406\uFF09\uFF0C\u672A\u6536\u5230 done/failed \u4E8B\u4EF6\uFF0C\u4E0D\u662F\u6210\u529F\u5B8C\u6210"
22790
+ );
22791
+ err.name = WAIT_INTERRUPTED_ERROR_NAME;
22792
+ return err;
22793
+ }
22794
+ async function handleWait(thunkApi, opts) {
22795
+ const timeoutMs = opts.timeoutMs && opts.timeoutMs > 0 ? opts.timeoutMs : DEFAULT_WAIT_TIMEOUT_MS;
22796
+ const { currentServer, token } = getToolRequestContext(thunkApi);
22797
+ const authHeader = token ? `Bearer ${token}` : "";
22798
+ const abortController = new AbortController();
22799
+ const externalSignal = opts.signal;
22800
+ const onExternalAbort = () => abortController.abort();
22801
+ if (externalSignal) {
22802
+ if (externalSignal.aborted) {
22803
+ abortController.abort();
22804
+ } else {
22805
+ externalSignal.addEventListener("abort", onExternalAbort, { once: true });
22806
+ }
22807
+ }
22808
+ const sseSignal = abortController.signal;
22809
+ let timer;
22810
+ try {
22811
+ if (sseSignal.aborted) throw createWaitInterruptedError();
22812
+ const data = await callToolApi(
22813
+ thunkApi,
22814
+ "/api/agent/runs/control",
22815
+ { action: "status", runId: opts.runId },
22816
+ { withAuth: true }
22817
+ );
22818
+ const resData = data?.data ?? data;
22819
+ if (!resData || resData.found === false || !resData.run) {
22820
+ throw new Error(`run ${opts.runId} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u89C1`);
22821
+ }
22822
+ const run = resData.run;
22823
+ if (WAIT_TERMINAL_STATUSES.has(run.status)) {
22824
+ return {
22825
+ rawData: { runId: opts.runId, status: run.status, content: run.lastAssistantText ?? "" },
22826
+ displayData: `\u2705 controlAgentRun(wait) \u5B8C\u6210\uFF0Crun ${opts.runId} \u5DF2\u5904\u4E8E\u7EC8\u6001 ${run.status}`
22827
+ };
22828
+ }
22829
+ if (sseSignal.aborted) throw createWaitInterruptedError();
22830
+ const outcome = await new Promise((resolve, reject) => {
22831
+ let settled = false;
22832
+ const settle = (fn) => {
22833
+ if (settled) return;
22834
+ settled = true;
22835
+ fn();
22836
+ };
22837
+ listenToDialogEvents(
22838
+ opts.runId,
22839
+ currentServer,
22840
+ authHeader,
22841
+ sseSignal,
22842
+ void 0,
22843
+ (result) => settle(() => resolve({ kind: "done", dialogId: result.dialogId, content: result.content })),
22844
+ (errMsg) => settle(() => reject(new Error(errMsg)))
22845
+ ).then(
22846
+ (r) => {
22847
+ if (settled) return;
22848
+ if (sseSignal.aborted) {
22849
+ settle(() => reject(createWaitInterruptedError()));
22850
+ } else if (r && ("content" in r || "usage" in r)) {
22851
+ settle(() => resolve({ kind: "done", dialogId: r.dialogId, content: r.content }));
22852
+ } else {
22853
+ settle(() => reject(new Error("\u4E8B\u4EF6\u6D41\u610F\u5916\u5173\u95ED\uFF0C\u672A\u6536\u5230 done/failed \u4E8B\u4EF6")));
22854
+ }
22855
+ },
22856
+ (e) => {
22857
+ if (settled) return;
22858
+ if (isAbortError(e)) {
22859
+ settle(() => reject(e));
22860
+ } else if (sseSignal.aborted) {
22861
+ settle(() => reject(createWaitInterruptedError()));
22862
+ } else {
22863
+ settle(() => reject(e));
22864
+ }
22865
+ }
22866
+ );
22867
+ timer = setTimeout(() => {
22868
+ abortController.abort();
22869
+ settle(() => resolve({ kind: "timeout", waitedMs: timeoutMs }));
22870
+ }, timeoutMs);
22871
+ });
22872
+ if (outcome.kind === "timeout") {
22873
+ return {
22874
+ rawData: { runId: opts.runId, status: "timeout", waitedMs: outcome.waitedMs },
22875
+ displayData: `\u23F3 controlAgentRun(wait) \u5DF2\u7B49\u5F85 ${Math.round(outcome.waitedMs / 1e3)}s \u4ECD\u672A\u5B8C\u6210\uFF0C\u672A\u8FBE\u7EC8\u6001\uFF1B\u53EF\u7A0D\u540E\u518D wait\uFF0C\u6216\u6539\u7528 status/stop\u3002`
22876
+ };
22877
+ }
22878
+ return {
22879
+ rawData: { runId: opts.runId, status: "done", content: outcome.content ?? "" },
22880
+ displayData: `\u2705 controlAgentRun(wait) \u5B8C\u6210\uFF0CdialogId: ${outcome.dialogId}`
22881
+ };
22882
+ } catch (e) {
22883
+ if (isAbortError(e) || e?.name === WAIT_INTERRUPTED_ERROR_NAME) throw e;
22884
+ throw new Error(`controlAgentRun(wait) \u5931\u8D25: ${toErrorMessage(e)}`);
22885
+ } finally {
22886
+ if (timer) clearTimeout(timer);
22887
+ if (externalSignal) externalSignal.removeEventListener("abort", onExternalAbort);
22888
+ }
22889
+ }
22304
22890
  async function handleTodo(thunkApi, opts) {
22305
22891
  try {
22306
22892
  const body = { action: "todo" };
@@ -22324,6 +22910,75 @@ async function handleTodo(thunkApi, opts) {
22324
22910
  }
22325
22911
  }
22326
22912
 
22913
+ // packages/ai/tools/agent/setTodoListTool.ts
22914
+ var setTodoListFunctionSchema = {
22915
+ name: "setTodoList",
22916
+ description: "\u8BBE\u7F6E/\u6574\u4F53\u66F4\u65B0\u5F53\u524D\u5BF9\u8BDD\u7684\u4EFB\u52A1\u5217\u8868\uFF08Kimi \u5F0F Todo \u5217\u8868\uFF09\u3002\u7528\u4E8E\u591A\u6B65\u9AA4\u4EFB\u52A1\u8FDB\u5EA6\u8FFD\u8E2A\u4E0E\u5C55\u793A\u3002",
22917
+ parameters: {
22918
+ type: "object",
22919
+ properties: {
22920
+ todos: {
22921
+ type: "array",
22922
+ description: "\u5B8C\u6574\u7684 Todo \u4EFB\u52A1\u5217\u8868\uFF08\u6574\u4F53\u66FF\u6362\uFF09",
22923
+ items: {
22924
+ type: "object",
22925
+ properties: {
22926
+ title: {
22927
+ type: "string",
22928
+ description: "\u4EFB\u52A1\u63CF\u8FF0/\u6807\u9898"
22929
+ },
22930
+ status: {
22931
+ type: "string",
22932
+ enum: ["pending", "in_progress", "done"],
22933
+ description: "\u4EFB\u52A1\u72B6\u6001\uFF1Apending(\u5F85\u5904\u7406), in_progress(\u8FDB\u884C\u4E2D), done(\u5DF2\u5B8C\u6210)"
22934
+ }
22935
+ },
22936
+ required: ["title", "status"]
22937
+ }
22938
+ }
22939
+ },
22940
+ required: ["todos"]
22941
+ }
22942
+ };
22943
+ function formatTodoListDisplayData(todos) {
22944
+ if (!todos || todos.length === 0) {
22945
+ return "\u{1F4CB} Todo \u5217\u8868\u5DF2\u6E05\u7A7A";
22946
+ }
22947
+ const statusIcons = {
22948
+ pending: "\u23F3",
22949
+ in_progress: "\u{1F504}",
22950
+ done: "\u2705"
22951
+ };
22952
+ const statusLabels = {
22953
+ pending: "\u5F85\u5904\u7406",
22954
+ in_progress: "\u8FDB\u884C\u4E2D",
22955
+ done: "\u5DF2\u5B8C\u6210"
22956
+ };
22957
+ const doneCount = todos.filter((t) => t.status === "done").length;
22958
+ const lines = [
22959
+ `\u{1F4CB} Todo \u5217\u8868 (${doneCount}/${todos.length})`,
22960
+ ...todos.map(
22961
+ (t) => `\u2022 ${statusIcons[t.status] ?? "\u2022"} [${statusLabels[t.status] ?? t.status}] ${t.title}`
22962
+ )
22963
+ ];
22964
+ return lines.join("\n");
22965
+ }
22966
+ async function setTodoListFunc(args) {
22967
+ const todos = Array.isArray(args?.todos) ? args.todos : [];
22968
+ const sanitizedTodos = todos.map((item) => {
22969
+ const title = typeof item?.title === "string" ? item.title.trim() : "Untitled Task";
22970
+ let status = "pending";
22971
+ if (item?.status === "in_progress") status = "in_progress";
22972
+ else if (item?.status === "done") status = "done";
22973
+ return { title, status };
22974
+ });
22975
+ const displayData = formatTodoListDisplayData(sanitizedTodos);
22976
+ return {
22977
+ rawData: { todos: sanitizedTodos },
22978
+ displayData
22979
+ };
22980
+ }
22981
+
22327
22982
  // packages/ai/tools/agent/agentTools.ts
22328
22983
  var agentToolDefinitions = [
22329
22984
  {
@@ -22406,18 +23061,6 @@ var agentToolDefinitions = [
22406
23061
  costLevel: "low",
22407
23062
  defaultConsent: "ask"
22408
23063
  },
22409
- {
22410
- id: "callAgent",
22411
- schema: callAgentFunctionSchema,
22412
- executor: callAgentFunc,
22413
- description: {
22414
- name: "callAgent",
22415
- description: "\u8C03\u7528\u4E00\u4E2A\u6307\u5B9A\u7684 Agent \u6267\u884C\u4E00\u6B21\u5B50\u4EFB\u52A1\uFF0C\u53EF\u7528\u4E8E\u591A Agent \u7F16\u6392\u3001\u81EA\u52A8\u8BC4\u6D4B\u3001\u81EA\u52A8\u5BF9\u6BD4\u7B49\u573A\u666F\u3002",
22416
- category: "\u8BA1\u5212\u4E0E\u7F16\u6392"
22417
- },
22418
- behavior: "orchestrator",
22419
- uiGroup: "agent"
22420
- },
22421
23064
  {
22422
23065
  id: "runStreamingAgent",
22423
23066
  schema: runStreamingAgentFunctionSchema,
@@ -22483,6 +23126,21 @@ var agentToolDefinitions = [
22483
23126
  riskLevel: "medium",
22484
23127
  costLevel: "low",
22485
23128
  defaultConsent: "auto"
23129
+ },
23130
+ {
23131
+ id: "setTodoList",
23132
+ schema: setTodoListFunctionSchema,
23133
+ executor: setTodoListFunc,
23134
+ description: {
23135
+ name: "setTodoList",
23136
+ description: "\u8BBE\u7F6E/\u6574\u4F53\u66F4\u65B0\u5F53\u524D\u5BF9\u8BDD\u7684\u4EFB\u52A1\u5217\u8868\uFF08Kimi \u5F0F Todo \u5217\u8868\uFF09\u3002\u7528\u4E8E\u591A\u6B65\u9AA4\u4EFB\u52A1\u8FDB\u5EA6\u8FFD\u8E2A\u4E0E\u5C55\u793A\u3002",
23137
+ category: "\u8BA1\u5212\u4E0E\u7F16\u6392"
23138
+ },
23139
+ behavior: "data",
23140
+ uiGroup: "agent",
23141
+ riskLevel: "low",
23142
+ costLevel: "low",
23143
+ defaultConsent: "auto"
22486
23144
  }
22487
23145
  ];
22488
23146
 
@@ -23516,7 +24174,7 @@ var executeToolRun = createAsyncThunk(
23516
24174
  if (!executionInput) {
23517
24175
  throw new Error(`ToolRun ${id} has no input to execute with.`);
23518
24176
  }
23519
- const { findToolExecutor: findToolExecutor2 } = await import("./tools-ECGXR5QF.js");
24177
+ const { findToolExecutor: findToolExecutor2 } = await import("./tools-L7RCHAPT.js");
23520
24178
  const { executor } = findToolExecutor2(run.toolName);
23521
24179
  toolRunStarted({
23522
24180
  id: run.id,
@@ -23540,7 +24198,7 @@ var executeToolRun = createAsyncThunk(
23540
24198
  const latestState = thunkApi.getState();
23541
24199
  const userId = latestState.auth?.currentUser?.userId;
23542
24200
  if (userId) {
23543
- const { fetchUserSpaceMemberships } = await import("./spaceSlice-ZXLLG3CR.js");
24201
+ const { fetchUserSpaceMemberships } = await import("./spaceSlice-47Z6XLFQ.js");
23544
24202
  await thunkApi.dispatch(fetchUserSpaceMemberships(userId));
23545
24203
  }
23546
24204
  }
@@ -26023,7 +26681,7 @@ async function updateDocFunc(args, thunkApi) {
26023
26681
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
26024
26682
  };
26025
26683
  await dispatch(write({ data: updatedPageData, customKey: id })).unwrap();
26026
- const { getDocState, applyExternalDocUpdate } = await import("./docStore-5HOJ4D7D.js");
26684
+ const { getDocState, applyExternalDocUpdate } = await import("./docStore-SPH3D6BT.js");
26027
26685
  if (getDocState().pageKey === id) {
26028
26686
  applyExternalDocUpdate({
26029
26687
  slateData: finalSlateData,
@@ -26048,7 +26706,7 @@ async function updateDocFunc(args, thunkApi) {
26048
26706
  // packages/ai/tools/updateUserPreferenceProfileTool.ts
26049
26707
  async function dispatchSetSettings(thunkApi, changes) {
26050
26708
  const injectedSetSettings = thunkApi?.extra?.setSettings;
26051
- const setSettings = typeof injectedSetSettings === "function" ? injectedSetSettings : (await import("./settingSlice-7MNKHZ6R.js")).setSettings;
26709
+ const setSettings = typeof injectedSetSettings === "function" ? injectedSetSettings : (await import("./settingSlice-XNM5AFPU.js")).setSettings;
26052
26710
  await thunkApi.dispatch(setSettings(changes)).unwrap();
26053
26711
  }
26054
26712
  var updateUserPreferenceProfileFunctionSchema = {
@@ -27413,7 +28071,7 @@ var baseToolDefinitions = [
27413
28071
  executor: readDialogFunc,
27414
28072
  description: {
27415
28073
  name: "readDialog",
27416
- description: "Read a Nolo dialog and recent messages.",
28074
+ description: "Read a Nolo dialog (prefer dialog dbKey or URL; bare id is current-user only).",
27417
28075
  category: "Nolo workspace"
27418
28076
  },
27419
28077
  behavior: "data",
@@ -28300,17 +28958,10 @@ export {
28300
28958
  readXPostFunc,
28301
28959
  readXhsProfileFunctionSchema,
28302
28960
  readXhsProfileFunc,
28303
- TOOL_PACKS,
28304
- resolveEffectiveEnabledPacks,
28305
- addDefaultSystemCapabilityTools,
28306
- applySystemBuiltinSkillFilter,
28307
- expandEnabledPacks,
28308
- expandEnabledPackPromptPatches,
28309
- appendEnabledPackPromptPatches,
28310
- FORCED_TOOLS,
28311
- applyDisabledTools,
28312
- addDefaultLightWebToolsForConfiguredAgents,
28313
- applyDefaultWebToolPacks,
28961
+ setTodoListFunc,
28962
+ resolveBuiltinSkillPage,
28963
+ resolveAgentRequiredPackIds,
28964
+ resolveAgentRecommendedSkillNames,
28314
28965
  shouldBlockForGptPro,
28315
28966
  i18n_default,
28316
28967
  clipMultilineText,