@muyichengshayu/promptx 0.1.31 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/apps/runner/src/engines/claudeCodeRunner.js +258 -2
- package/apps/runner/src/engines/openCodeRunner.js +106 -0
- package/apps/server/src/agents/claudeCodeRunner.js +234 -1
- package/apps/server/src/agents/openCodeRunner.js +106 -0
- package/apps/server/src/assetRoutes.js +20 -6
- package/apps/web/dist/assets/CodexSessionManagerDialog-DY9w5JSD.js +1 -0
- package/apps/web/dist/assets/{TaskDiffReviewDialog-Dzj4GDaj.js → TaskDiffReviewDialog-BDZvXvKm.js} +2 -12
- package/apps/web/dist/assets/WorkbenchSettingsDialog-DBJyJtvD.js +1 -0
- package/apps/web/dist/assets/WorkbenchView-CMjjT7fc.js +29 -0
- package/apps/web/dist/assets/index-BSpefDgA.css +1 -0
- package/apps/web/dist/assets/index-CGOI_HcK.js +2 -0
- package/apps/web/dist/assets/vendor-markdown-CNlC48LI.js +15 -0
- package/apps/web/dist/assets/vendor-misc-CWjGI0ex.js +31 -0
- package/apps/web/dist/assets/vendor-router-Bcjfmow0.js +9 -0
- package/apps/web/dist/assets/vendor-tiptap-BCwG_IWj.js +129 -0
- package/apps/web/dist/assets/vendor-ui-D4mCpibF.js +271 -0
- package/apps/web/dist/index.html +4 -2
- package/package.json +1 -2
- package/apps/web/dist/assets/CodexSessionManagerDialog-jzGuqsOt.js +0 -16
- package/apps/web/dist/assets/WorkbenchSettingsDialog-BA9EYzIQ.js +0 -16
- package/apps/web/dist/assets/WorkbenchView-WoVxKFEW.js +0 -423
- package/apps/web/dist/assets/index-BhMEdZoM.css +0 -1
- package/apps/web/dist/assets/index-DVWGdkCl.js +0 -26
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.34
|
|
4
|
+
|
|
5
|
+
- 统一图片预览层遮罩,直接复用和工作台弹窗一致的 `theme-modal-backdrop`,不再单独维护一套 overlay 背景,避免预览层与其它弹窗视觉割裂。
|
|
6
|
+
- 修复放大图片时顶部工具按钮对比度不足的问题:为缩放、翻页和关闭按钮补上稳定的底色、边框和阴影,在亮图背景上也能清楚辨认。
|
|
7
|
+
|
|
8
|
+
## 0.1.33
|
|
9
|
+
|
|
10
|
+
- 修复安装包在 Node.js 22 下启动失败的问题:移除 `jimp` 及其 `@jimp/plugin-print -> simple-xml-to-json` 这条有问题的 ESM 依赖链,避免 `promptx start` 在加载阶段直接抛出 `does not provide an export named 'default'`。
|
|
11
|
+
- 上传图片改为使用现有的 `@napi-rs/canvas` 完成读取、缩放和 JPEG 导出,不再依赖 `jimp`,同时保持上传后图片会统一缩放到 `1600x1600` 以内的现有语义。
|
|
12
|
+
- 补充图片上传回归测试,并更新锁文件与打包产物校验,确保新安装包不再带入这条启动时会炸掉的依赖链。
|
|
13
|
+
|
|
14
|
+
## 0.1.32
|
|
15
|
+
|
|
16
|
+
- 继续收敛执行过程面板:统一过程事件卡片为白底轻边框,过程区与输入区统一等宽字体,移动端优先折行显示,减少横向滚动与样式不一致带来的阅读负担。
|
|
17
|
+
- 精简子代理展示:`Codex / Claude Code / OpenCode` 的子代理事件统一为更轻量的一行摘要,移动端最多显示两行、桌面端单行;同时去掉多余的“更新”标签、局部展开/收起和重色块背景。
|
|
18
|
+
- 下线执行过程中的代码类自动识别兼容:移除 `code_text / code_snippet / numbered_lines / build_error / search_results` 等旧分支,统一回退为稳定的文本或少量明确结构块,减少误判和错误代码块渲染。
|
|
19
|
+
- 优化前端打包输出:为 `tiptap`、图标与 markdown 等依赖拆分 vendor chunk,消除 Vite 的大包告警,降低工作台主包体积。
|
|
20
|
+
|
|
3
21
|
## 0.1.31
|
|
4
22
|
|
|
5
23
|
- 继续打磨执行过程展示:统一 `Codex / Claude Code / OpenCode` 的终端输出、搜索命中、构建报错与 diff 渲染,补齐移动端横向滚动、代码字体统一和多余元信息收敛,整体阅读更稳定。
|
|
@@ -132,6 +132,45 @@ function flushBufferedText(buffer = '') {
|
|
|
132
132
|
return tail ? [...lines, tail] : lines
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function extractAgentTargetFromTexts(...values) {
|
|
136
|
+
const matcher = /(?:^|[\s`'"])([A-Za-z]:[\\/][^\s`'"]+\.[A-Za-z0-9]+|\/[^\s`'"]+\.[A-Za-z0-9]+|(?:[A-Za-z0-9._-]+\/)*[A-Za-z0-9._-]+\.[A-Za-z0-9]+)(?=$|[\s`'"])/i
|
|
137
|
+
for (const value of values) {
|
|
138
|
+
const text = String(value || '').trim()
|
|
139
|
+
if (!text) {
|
|
140
|
+
continue
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const matched = text.match(matcher)
|
|
144
|
+
if (!matched?.[1]) {
|
|
145
|
+
continue
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const normalized = matched[1].replace(/\\/g, '/')
|
|
149
|
+
const parts = normalized.split('/').filter(Boolean)
|
|
150
|
+
return parts[parts.length - 1] || normalized
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return ''
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function normalizeCollabAgentStatus(status = '') {
|
|
157
|
+
const normalized = String(status || '').trim().toLowerCase()
|
|
158
|
+
if (['completed', 'complete', 'succeeded', 'success', 'done'].includes(normalized)) {
|
|
159
|
+
return 'completed'
|
|
160
|
+
}
|
|
161
|
+
if (['failed', 'error', 'errored', 'cancelled', 'canceled', 'stopped'].includes(normalized)) {
|
|
162
|
+
return 'failed'
|
|
163
|
+
}
|
|
164
|
+
if (['running', 'in_progress', 'in-progress', 'pending_init', 'pending'].includes(normalized)) {
|
|
165
|
+
return normalized === 'pending_init' ? 'pending_init' : 'running'
|
|
166
|
+
}
|
|
167
|
+
return normalized || 'pending_init'
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function isClaudeCollabToolName(name = '') {
|
|
171
|
+
return ['agent', 'task'].includes(String(name || '').trim().toLowerCase())
|
|
172
|
+
}
|
|
173
|
+
|
|
135
174
|
function collectTextParts(value, parts = []) {
|
|
136
175
|
if (!value) {
|
|
137
176
|
return parts
|
|
@@ -180,6 +219,29 @@ export function extractClaudeAssistantText(event = {}) {
|
|
|
180
219
|
return parts.join('\n').trim()
|
|
181
220
|
}
|
|
182
221
|
|
|
222
|
+
function stringifyClaudeToolResultContent(value) {
|
|
223
|
+
const parts = []
|
|
224
|
+
collectTextParts(value, parts)
|
|
225
|
+
if (parts.length) {
|
|
226
|
+
return parts.join('\n').trim()
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (typeof value === 'string') {
|
|
230
|
+
return value.trim()
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (value == null) {
|
|
234
|
+
return ''
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const compact = JSON.stringify(value)
|
|
239
|
+
return compact.length <= 12000 ? compact : `${compact.slice(0, 11997)}...`
|
|
240
|
+
} catch {
|
|
241
|
+
return String(value || '').trim()
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
183
245
|
export function extractClaudeResultText(event = {}) {
|
|
184
246
|
const parts = []
|
|
185
247
|
if (event?.result) {
|
|
@@ -206,6 +268,8 @@ export function extractClaudeSessionId(event = {}) {
|
|
|
206
268
|
export function createClaudeNormalizationState() {
|
|
207
269
|
return {
|
|
208
270
|
toolUses: new Map(),
|
|
271
|
+
taskIdToToolUseId: new Map(),
|
|
272
|
+
completedCollabToolUseIds: new Set(),
|
|
209
273
|
}
|
|
210
274
|
}
|
|
211
275
|
|
|
@@ -246,19 +310,61 @@ function buildClaudeToolCommand(name = '', input = {}) {
|
|
|
246
310
|
return inputSummary ? `${toolName}: ${inputSummary}` : toolName
|
|
247
311
|
}
|
|
248
312
|
|
|
313
|
+
function buildClaudeCollabState(toolUse = {}, overrides = {}) {
|
|
314
|
+
const taskId = String(overrides.taskId || '').trim()
|
|
315
|
+
const message = stringifyClaudeToolResultContent(overrides.message)
|
|
316
|
+
const baseStatus = overrides.status ?? (message ? 'completed' : 'running')
|
|
317
|
+
const status = normalizeCollabAgentStatus(baseStatus)
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
status,
|
|
321
|
+
message,
|
|
322
|
+
title: String(overrides.title || toolUse.description || '').trim(),
|
|
323
|
+
role: String(overrides.role || toolUse.role || '').trim(),
|
|
324
|
+
target: String(overrides.target || toolUse.target || '').trim(),
|
|
325
|
+
model: String(overrides.model || toolUse.model || '').trim(),
|
|
326
|
+
...(taskId ? { task_id: taskId } : {}),
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
249
330
|
function createClaudeToolUseEvent(block = {}, state = createClaudeNormalizationState()) {
|
|
250
331
|
const toolUseId = String(block?.id || '').trim()
|
|
251
332
|
const name = String(block?.name || block?.tool_name || 'Claude Code tool').trim() || 'Claude Code tool'
|
|
252
333
|
const input = block?.input && typeof block.input === 'object' ? block.input : {}
|
|
253
334
|
const command = buildClaudeToolCommand(name, input)
|
|
335
|
+
const isCollabTool = isClaudeCollabToolName(name)
|
|
336
|
+
const collabPrompt = String(input.prompt || '').trim()
|
|
337
|
+
const collabDescription = String(input.description || '').trim()
|
|
338
|
+
const collabRole = String(input.subagent_type || input.agent || '').trim()
|
|
339
|
+
const collabModel = String(input.model || '').trim()
|
|
340
|
+
const collabTarget = extractAgentTargetFromTexts(collabDescription, collabPrompt)
|
|
254
341
|
|
|
255
342
|
if (toolUseId) {
|
|
256
343
|
state.toolUses.set(toolUseId, {
|
|
257
344
|
name,
|
|
258
345
|
command,
|
|
346
|
+
kind: isCollabTool ? 'collab' : 'command',
|
|
347
|
+
prompt: collabPrompt || collabDescription,
|
|
348
|
+
description: collabDescription,
|
|
349
|
+
role: collabRole,
|
|
350
|
+
model: collabModel,
|
|
351
|
+
target: collabTarget,
|
|
352
|
+
taskIds: [],
|
|
259
353
|
})
|
|
260
354
|
}
|
|
261
355
|
|
|
356
|
+
if (isCollabTool) {
|
|
357
|
+
return {
|
|
358
|
+
...createItemStartedEvent({
|
|
359
|
+
type: AGENT_RUN_ITEM_TYPES.COLLAB_TOOL_CALL,
|
|
360
|
+
tool: 'spawn_agent',
|
|
361
|
+
receiver_thread_ids: [],
|
|
362
|
+
prompt: collabPrompt || collabDescription,
|
|
363
|
+
agents_states: {},
|
|
364
|
+
}),
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
262
368
|
return {
|
|
263
369
|
...createItemStartedEvent({
|
|
264
370
|
type: AGENT_RUN_ITEM_TYPES.COMMAND_EXECUTION,
|
|
@@ -271,12 +377,47 @@ function createClaudeToolUseEvent(block = {}, state = createClaudeNormalizationS
|
|
|
271
377
|
function createClaudeToolResultEvent(block = {}, state = createClaudeNormalizationState()) {
|
|
272
378
|
const toolUseId = String(block?.tool_use_id || block?.toolUseId || '').trim()
|
|
273
379
|
const remembered = toolUseId ? state.toolUses.get(toolUseId) : null
|
|
274
|
-
const output =
|
|
380
|
+
const output = stringifyClaudeToolResultContent(block?.content ?? block?.result)
|
|
275
381
|
const isError = Boolean(block?.is_error)
|
|
382
|
+
const taskIds = Array.isArray(remembered?.taskIds) ? remembered.taskIds.filter(Boolean) : []
|
|
383
|
+
const collabTool = remembered?.kind === 'collab'
|
|
384
|
+
|
|
385
|
+
if (toolUseId && state.completedCollabToolUseIds.has(toolUseId)) {
|
|
386
|
+
return null
|
|
387
|
+
}
|
|
276
388
|
|
|
277
389
|
if (toolUseId) {
|
|
278
390
|
state.toolUses.delete(toolUseId)
|
|
279
391
|
}
|
|
392
|
+
taskIds.forEach((taskId) => {
|
|
393
|
+
state.taskIdToToolUseId.delete(taskId)
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
if (collabTool) {
|
|
397
|
+
if (toolUseId) {
|
|
398
|
+
state.completedCollabToolUseIds.add(toolUseId)
|
|
399
|
+
}
|
|
400
|
+
const receiverThreadIds = taskIds.length
|
|
401
|
+
? taskIds
|
|
402
|
+
: (toolUseId ? [`claude-agent-${toolUseId}`] : [])
|
|
403
|
+
const agentsStates = Object.fromEntries(
|
|
404
|
+
receiverThreadIds.map((taskId) => [taskId, buildClaudeCollabState(remembered, {
|
|
405
|
+
taskId,
|
|
406
|
+
status: isError ? 'failed' : 'completed',
|
|
407
|
+
message: output,
|
|
408
|
+
})])
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
return {
|
|
412
|
+
...createItemCompletedEvent({
|
|
413
|
+
type: AGENT_RUN_ITEM_TYPES.COLLAB_TOOL_CALL,
|
|
414
|
+
tool: 'wait',
|
|
415
|
+
receiver_thread_ids: receiverThreadIds,
|
|
416
|
+
prompt: remembered?.prompt || remembered?.description || '',
|
|
417
|
+
agents_states: agentsStates,
|
|
418
|
+
}),
|
|
419
|
+
}
|
|
420
|
+
}
|
|
280
421
|
|
|
281
422
|
return {
|
|
282
423
|
...createItemCompletedEvent({
|
|
@@ -289,6 +430,105 @@ function createClaudeToolResultEvent(block = {}, state = createClaudeNormalizati
|
|
|
289
430
|
}
|
|
290
431
|
}
|
|
291
432
|
|
|
433
|
+
function resolveClaudeTaskToolUseId(event = {}, state = createClaudeNormalizationState()) {
|
|
434
|
+
const explicitToolUseId = String(event?.tool_use_id || event?.toolUseId || '').trim()
|
|
435
|
+
if (explicitToolUseId) {
|
|
436
|
+
return explicitToolUseId
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const taskId = String(event?.task_id || event?.taskId || '').trim()
|
|
440
|
+
if (!taskId) {
|
|
441
|
+
return ''
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return String(state.taskIdToToolUseId.get(taskId) || '').trim()
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function createClaudeTaskStartedEvent(event = {}, state = createClaudeNormalizationState()) {
|
|
448
|
+
const toolUseId = resolveClaudeTaskToolUseId(event, state)
|
|
449
|
+
const taskId = String(event?.task_id || event?.taskId || '').trim()
|
|
450
|
+
const remembered = toolUseId ? state.toolUses.get(toolUseId) : null
|
|
451
|
+
|
|
452
|
+
if (!remembered || remembered.kind !== 'collab' || !taskId) {
|
|
453
|
+
return null
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (!Array.isArray(remembered.taskIds)) {
|
|
457
|
+
remembered.taskIds = []
|
|
458
|
+
}
|
|
459
|
+
if (!remembered.taskIds.includes(taskId)) {
|
|
460
|
+
remembered.taskIds.push(taskId)
|
|
461
|
+
}
|
|
462
|
+
state.taskIdToToolUseId.set(taskId, toolUseId)
|
|
463
|
+
|
|
464
|
+
return {
|
|
465
|
+
...createItemCompletedEvent({
|
|
466
|
+
type: AGENT_RUN_ITEM_TYPES.COLLAB_TOOL_CALL,
|
|
467
|
+
tool: 'spawn_agent',
|
|
468
|
+
receiver_thread_ids: [taskId],
|
|
469
|
+
prompt: remembered.prompt || String(event?.prompt || event?.description || '').trim(),
|
|
470
|
+
agents_states: {
|
|
471
|
+
[taskId]: buildClaudeCollabState(remembered, {
|
|
472
|
+
taskId,
|
|
473
|
+
status: 'running',
|
|
474
|
+
title: String(event?.description || remembered.description || '').trim(),
|
|
475
|
+
target: extractAgentTargetFromTexts(event?.description, event?.prompt, remembered.target),
|
|
476
|
+
}),
|
|
477
|
+
},
|
|
478
|
+
}),
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function createClaudeTaskFinishedEvent(event = {}, state = createClaudeNormalizationState()) {
|
|
483
|
+
const subtype = String(event?.subtype || '').trim().toLowerCase()
|
|
484
|
+
const toolUseId = resolveClaudeTaskToolUseId(event, state)
|
|
485
|
+
const taskId = String(event?.task_id || event?.taskId || '').trim()
|
|
486
|
+
const remembered = toolUseId ? state.toolUses.get(toolUseId) : null
|
|
487
|
+
|
|
488
|
+
if (!remembered || remembered.kind !== 'collab') {
|
|
489
|
+
return null
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (toolUseId && state.completedCollabToolUseIds.has(toolUseId)) {
|
|
493
|
+
return null
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const failed = subtype === 'task_failed'
|
|
497
|
+
const output = stringifyClaudeToolResultContent(
|
|
498
|
+
event?.result
|
|
499
|
+
?? event?.message
|
|
500
|
+
?? event?.content
|
|
501
|
+
?? event?.error
|
|
502
|
+
?? event?.task_result
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
if (toolUseId) {
|
|
506
|
+
state.toolUses.delete(toolUseId)
|
|
507
|
+
state.completedCollabToolUseIds.add(toolUseId)
|
|
508
|
+
}
|
|
509
|
+
if (taskId) {
|
|
510
|
+
state.taskIdToToolUseId.delete(taskId)
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
return {
|
|
514
|
+
...createItemCompletedEvent({
|
|
515
|
+
type: AGENT_RUN_ITEM_TYPES.COLLAB_TOOL_CALL,
|
|
516
|
+
tool: 'wait',
|
|
517
|
+
receiver_thread_ids: taskId ? [taskId] : (Array.isArray(remembered.taskIds) ? remembered.taskIds.filter(Boolean) : []),
|
|
518
|
+
prompt: remembered.prompt || remembered.description || '',
|
|
519
|
+
agents_states: {
|
|
520
|
+
[(taskId || `claude-agent-${toolUseId}`)]: buildClaudeCollabState(remembered, {
|
|
521
|
+
taskId,
|
|
522
|
+
status: failed ? 'failed' : 'completed',
|
|
523
|
+
message: output,
|
|
524
|
+
title: String(event?.description || remembered.description || '').trim(),
|
|
525
|
+
target: extractAgentTargetFromTexts(event?.description, event?.prompt, remembered.target),
|
|
526
|
+
}),
|
|
527
|
+
},
|
|
528
|
+
}),
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
292
532
|
function buildClaudeApiRetryReason(event = {}) {
|
|
293
533
|
const status = Number(event?.error_status) || 0
|
|
294
534
|
const code = String(event?.error || '').trim()
|
|
@@ -323,6 +563,19 @@ export function normalizeClaudeEvents(event = {}, state = createClaudeNormalizat
|
|
|
323
563
|
return [createThreadStartedEvent(extractClaudeSessionId(event))]
|
|
324
564
|
}
|
|
325
565
|
|
|
566
|
+
if (eventType === 'system' && String(event?.subtype || '').trim().toLowerCase() === 'task_started') {
|
|
567
|
+
const collabEvent = createClaudeTaskStartedEvent(event, state)
|
|
568
|
+
return collabEvent ? [collabEvent] : []
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (
|
|
572
|
+
eventType === 'system'
|
|
573
|
+
&& ['task_result', 'task_completed', 'task_failed'].includes(String(event?.subtype || '').trim().toLowerCase())
|
|
574
|
+
) {
|
|
575
|
+
const collabEvent = createClaudeTaskFinishedEvent(event, state)
|
|
576
|
+
return collabEvent ? [collabEvent] : []
|
|
577
|
+
}
|
|
578
|
+
|
|
326
579
|
if (eventType === 'system' && String(event?.subtype || '').trim().toLowerCase() === 'api_retry') {
|
|
327
580
|
if (isClaudeFatalAuthRetry(event)) {
|
|
328
581
|
return [createErrorEvent(formatClaudeFatalAuthMessage(event))]
|
|
@@ -378,7 +631,10 @@ export function normalizeClaudeEvents(event = {}, state = createClaudeNormalizat
|
|
|
378
631
|
blocks.forEach((block) => {
|
|
379
632
|
const blockType = String(block?.type || '').trim().toLowerCase()
|
|
380
633
|
if (blockType === 'tool_result') {
|
|
381
|
-
|
|
634
|
+
const toolResultEvent = createClaudeToolResultEvent(block, state)
|
|
635
|
+
if (toolResultEvent) {
|
|
636
|
+
normalizedEvents.push(toolResultEvent)
|
|
637
|
+
}
|
|
382
638
|
}
|
|
383
639
|
})
|
|
384
640
|
return normalizedEvents
|
|
@@ -133,6 +133,41 @@ function flushBufferedText(buffer = '') {
|
|
|
133
133
|
return tail ? [...lines, tail] : lines
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
function extractAgentTargetFromTexts(...values) {
|
|
137
|
+
const matcher = /(?:^|[\s`'"])([A-Za-z]:[\\/][^\s`'"]+\.[A-Za-z0-9]+|\/[^\s`'"]+\.[A-Za-z0-9]+|(?:[A-Za-z0-9._-]+\/)*[A-Za-z0-9._-]+\.[A-Za-z0-9]+)(?=$|[\s`'"])/i
|
|
138
|
+
for (const value of values) {
|
|
139
|
+
const text = String(value || '').trim()
|
|
140
|
+
if (!text) {
|
|
141
|
+
continue
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const matched = text.match(matcher)
|
|
145
|
+
if (!matched?.[1]) {
|
|
146
|
+
continue
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const normalized = matched[1].replace(/\\/g, '/')
|
|
150
|
+
const parts = normalized.split('/').filter(Boolean)
|
|
151
|
+
return parts[parts.length - 1] || normalized
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return ''
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function normalizeCollabAgentStatus(status = '') {
|
|
158
|
+
const normalized = String(status || '').trim().toLowerCase()
|
|
159
|
+
if (['completed', 'complete', 'succeeded', 'success', 'done'].includes(normalized)) {
|
|
160
|
+
return 'completed'
|
|
161
|
+
}
|
|
162
|
+
if (['failed', 'error', 'errored', 'cancelled', 'canceled', 'stopped'].includes(normalized)) {
|
|
163
|
+
return 'failed'
|
|
164
|
+
}
|
|
165
|
+
if (['running', 'in_progress', 'in-progress', 'pending_init', 'pending'].includes(normalized)) {
|
|
166
|
+
return normalized === 'pending_init' ? 'pending_init' : 'running'
|
|
167
|
+
}
|
|
168
|
+
return normalized || 'pending_init'
|
|
169
|
+
}
|
|
170
|
+
|
|
136
171
|
function summarizeOpenCodeInput(input = {}) {
|
|
137
172
|
if (!input || typeof input !== 'object') {
|
|
138
173
|
return ''
|
|
@@ -295,6 +330,73 @@ export function createOpenCodeNormalizationState() {
|
|
|
295
330
|
}
|
|
296
331
|
}
|
|
297
332
|
|
|
333
|
+
function isOpenCodeSubAgentTask(event = {}) {
|
|
334
|
+
const part = event?.part && typeof event.part === 'object' ? event.part : {}
|
|
335
|
+
const tool = String(part?.tool || '').trim().toLowerCase()
|
|
336
|
+
const input = part?.state?.input && typeof part.state.input === 'object'
|
|
337
|
+
? part.state.input
|
|
338
|
+
: {}
|
|
339
|
+
return tool === 'task' && Boolean(String(input.subagent_type || '').trim())
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function extractOpenCodeSubAgentSessionId(event = {}, output = '') {
|
|
343
|
+
const metadataSessionId = String(event?.part?.state?.metadata?.sessionId || '').trim()
|
|
344
|
+
if (metadataSessionId) {
|
|
345
|
+
return metadataSessionId
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const matched = String(output || '').match(/task_id:\s*([^\s)]+)/i)
|
|
349
|
+
return matched?.[1] ? String(matched[1]).trim() : ''
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function createOpenCodeSubAgentEvents(event = {}) {
|
|
353
|
+
const part = event?.part && typeof event.part === 'object' ? event.part : {}
|
|
354
|
+
const state = part?.state && typeof part.state === 'object' ? part.state : {}
|
|
355
|
+
const input = state?.input && typeof state.input === 'object' ? state.input : {}
|
|
356
|
+
const output = stringifyOpenCodeOutput(state?.output)
|
|
357
|
+
const sessionId = extractOpenCodeSubAgentSessionId(event, output)
|
|
358
|
+
const receiverThreadIds = sessionId ? [sessionId] : []
|
|
359
|
+
const collabPrompt = String(input.prompt || input.description || '').trim()
|
|
360
|
+
const collabStatus = normalizeCollabAgentStatus(state?.status)
|
|
361
|
+
const target = extractAgentTargetFromTexts(input.description, input.prompt, output)
|
|
362
|
+
const modelId = String(state?.metadata?.model?.modelID || '').trim()
|
|
363
|
+
const providerId = String(state?.metadata?.model?.providerID || '').trim()
|
|
364
|
+
const model = modelId
|
|
365
|
+
? `${providerId ? `${providerId}/` : ''}${modelId}`
|
|
366
|
+
: ''
|
|
367
|
+
const agentsStates = sessionId
|
|
368
|
+
? {
|
|
369
|
+
[sessionId]: {
|
|
370
|
+
status: collabStatus,
|
|
371
|
+
message: output,
|
|
372
|
+
title: String(input.description || part?.title || '').trim(),
|
|
373
|
+
role: String(input.subagent_type || '').trim(),
|
|
374
|
+
target,
|
|
375
|
+
model,
|
|
376
|
+
},
|
|
377
|
+
}
|
|
378
|
+
: {}
|
|
379
|
+
const spawnPayload = {
|
|
380
|
+
type: AGENT_RUN_ITEM_TYPES.COLLAB_TOOL_CALL,
|
|
381
|
+
tool: 'spawn_agent',
|
|
382
|
+
receiver_thread_ids: receiverThreadIds,
|
|
383
|
+
prompt: collabPrompt,
|
|
384
|
+
agents_states: agentsStates,
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (['completed', 'failed'].includes(collabStatus)) {
|
|
388
|
+
return [
|
|
389
|
+
createItemCompletedEvent(spawnPayload),
|
|
390
|
+
createItemCompletedEvent({
|
|
391
|
+
...spawnPayload,
|
|
392
|
+
tool: 'wait',
|
|
393
|
+
}),
|
|
394
|
+
]
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return [createItemStartedEvent(spawnPayload)]
|
|
398
|
+
}
|
|
399
|
+
|
|
298
400
|
export function normalizeOpenCodeEvents(event = {}, state = createOpenCodeNormalizationState()) {
|
|
299
401
|
const eventType = String(event?.type || '').trim().toLowerCase()
|
|
300
402
|
const normalizedEvents = []
|
|
@@ -308,6 +410,10 @@ export function normalizeOpenCodeEvents(event = {}, state = createOpenCodeNormal
|
|
|
308
410
|
}
|
|
309
411
|
|
|
310
412
|
if (eventType === 'tool_use') {
|
|
413
|
+
if (isOpenCodeSubAgentTask(event)) {
|
|
414
|
+
return createOpenCodeSubAgentEvents(event)
|
|
415
|
+
}
|
|
416
|
+
|
|
311
417
|
const command = buildOpenCodeToolCommand(event)
|
|
312
418
|
const status = String(event?.part?.state?.status || '').trim().toLowerCase()
|
|
313
419
|
const output = stringifyOpenCodeOutput(event?.part?.state?.output)
|