@xcanwin/manyoyo 5.8.9 → 5.8.10

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.
@@ -1,603 +0,0 @@
1
- 'use strict';
2
-
3
- function createStructuredTraceHelpers(deps) {
4
- const {
5
- pickFirstString,
6
- toPlainObject,
7
- collectStructuredText,
8
- clipText: rawClipText,
9
- stripAnsi: rawStripAnsi
10
- } = deps;
11
- const clipText = typeof rawClipText === 'function' ? rawClipText : (text => String(text || ''));
12
- const stripAnsi = typeof rawStripAnsi === 'function' ? rawStripAnsi : (text => String(text || ''));
13
-
14
- function shortenTraceText(value, maxChars = 140) {
15
- const raw = clipText(stripAnsi(String(value || '')).replace(/\s+/g, ' ').trim(), maxChars);
16
- return raw.trim();
17
- }
18
-
19
- function summarizeTraceArguments(args) {
20
- if (!args || typeof args !== 'object' || Array.isArray(args)) {
21
- return '';
22
- }
23
- const parts = [];
24
- for (const [key, value] of Object.entries(args)) {
25
- if (value === undefined || value === null) continue;
26
- if (typeof value === 'string') {
27
- const textValue = value.trim();
28
- if (!textValue) continue;
29
- parts.push(`${key}=${shortenTraceText(textValue, 80)}`);
30
- continue;
31
- }
32
- if (typeof value === 'number' || typeof value === 'boolean') {
33
- parts.push(`${key}=${String(value)}`);
34
- }
35
- }
36
- return parts.slice(0, 3).join(', ');
37
- }
38
-
39
- function createStructuredTraceEvent(provider, kind, eventType, textValue, extra = {}) {
40
- const normalizedText = String(textValue || '').trim();
41
- if (!normalizedText) {
42
- return null;
43
- }
44
- return {
45
- provider,
46
- kind,
47
- eventType,
48
- text: normalizedText,
49
- ...extra
50
- };
51
- }
52
-
53
- return {
54
- pickFirstString,
55
- toPlainObject,
56
- collectStructuredText,
57
- clipText,
58
- stripAnsi,
59
- shortenTraceText,
60
- summarizeTraceArguments,
61
- createStructuredTraceEvent
62
- };
63
- }
64
-
65
- function prepareClaudeTraceEvents(payload, state, helpers) {
66
- const { pickFirstString, toPlainObject, collectStructuredText, summarizeTraceArguments, createStructuredTraceEvent } = helpers;
67
- const eventType = pickFirstString(payload.type);
68
- const subtype = pickFirstString(payload.subtype);
69
- const message = toPlainObject(payload.message);
70
- const content = Array.isArray(message.content) ? message.content : [];
71
- const toolNamesById = state.toolNamesById;
72
- const events = [];
73
-
74
- if (eventType === 'system' && subtype === 'init') {
75
- events.push(createStructuredTraceEvent('claude', 'thread', eventType, '[会话] Claude 已开始处理', {
76
- phase: 'started',
77
- status: 'started',
78
- subtype
79
- }));
80
- return events.filter(Boolean);
81
- }
82
- if (eventType === 'assistant') {
83
- content.forEach(item => {
84
- if (!item || typeof item !== 'object') {
85
- return;
86
- }
87
- if (item.type === 'text') {
88
- const detail = collectStructuredText(item);
89
- if (detail) {
90
- events.push(createStructuredTraceEvent('claude', 'agent_message', eventType, `[说明] ${detail}`, {
91
- phase: 'completed',
92
- status: 'completed',
93
- detail
94
- }));
95
- }
96
- return;
97
- }
98
- if (item.type === 'tool_use') {
99
- const toolName = pickFirstString(item.name, item.id, 'tool');
100
- const toolId = pickFirstString(item.id);
101
- if (toolId) {
102
- toolNamesById.set(toolId, toolName);
103
- }
104
- const summary = summarizeTraceArguments(toPlainObject(item.input));
105
- events.push(createStructuredTraceEvent(
106
- 'claude',
107
- 'tool',
108
- eventType,
109
- summary ? `[工具开始] ${toolName} (${summary})` : `[工具开始] ${toolName}`,
110
- {
111
- phase: 'started',
112
- status: 'in_progress',
113
- toolName,
114
- toolId,
115
- arguments: toPlainObject(item.input),
116
- argumentSummary: summary
117
- }
118
- ));
119
- }
120
- });
121
- return events.filter(Boolean);
122
- }
123
- if (eventType === 'user') {
124
- content.forEach(item => {
125
- if (!item || typeof item !== 'object' || item.type !== 'tool_result') {
126
- return;
127
- }
128
- const toolId = pickFirstString(item.tool_use_id);
129
- const toolName = pickFirstString(toolNamesById.get(toolId), toolId, 'tool');
130
- const status = item.is_error === true ? 'error' : 'success';
131
- events.push(createStructuredTraceEvent('claude', 'tool', eventType, `[工具完成] ${toolName} (${status})`, {
132
- phase: 'completed',
133
- status,
134
- toolName,
135
- toolId,
136
- result: collectStructuredText(item.content),
137
- error: item.is_error === true ? collectStructuredText(item.content) : ''
138
- }));
139
- });
140
- return events.filter(Boolean);
141
- }
142
- if (eventType === 'result') {
143
- events.push(createStructuredTraceEvent('claude', 'turn', eventType, '[回合] 响应完成', {
144
- phase: 'completed',
145
- status: pickFirstString(subtype, 'completed'),
146
- subtype
147
- }));
148
- return events.filter(Boolean);
149
- }
150
- if (eventType === 'error') {
151
- const detail = pickFirstString(payload.message, payload.error);
152
- events.push(createStructuredTraceEvent('claude', 'error', eventType, detail ? `[错误] ${detail}` : '[错误] Claude 返回了错误事件', {
153
- status: 'error',
154
- detail
155
- }));
156
- return events.filter(Boolean);
157
- }
158
- return [];
159
- }
160
-
161
- function prepareGeminiTraceEvents(payload, state, helpers) {
162
- const { pickFirstString, toPlainObject, collectStructuredText, summarizeTraceArguments, createStructuredTraceEvent } = helpers;
163
- const eventType = pickFirstString(payload.type);
164
- const toolNamesById = state.toolNamesById;
165
- const events = [];
166
-
167
- if (eventType === 'init') {
168
- events.push(createStructuredTraceEvent('gemini', 'thread', eventType, '[会话] Gemini 已开始处理', {
169
- phase: 'started',
170
- status: 'started',
171
- sessionId: pickFirstString(payload.session_id),
172
- model: pickFirstString(payload.model)
173
- }));
174
- return events.filter(Boolean);
175
- }
176
- if (eventType === 'message' && payload.role === 'assistant') {
177
- if (payload.delta === true) {
178
- return [];
179
- }
180
- const detail = collectStructuredText(payload.content);
181
- if (!detail) {
182
- return [];
183
- }
184
- events.push(createStructuredTraceEvent('gemini', 'agent_message', eventType, `[说明] ${detail}`, {
185
- phase: 'completed',
186
- status: 'completed',
187
- detail
188
- }));
189
- return events.filter(Boolean);
190
- }
191
- if (eventType === 'tool_use') {
192
- const toolName = pickFirstString(payload.tool_name, payload.tool_id, 'tool');
193
- const toolId = pickFirstString(payload.tool_id);
194
- if (toolId) {
195
- toolNamesById.set(toolId, toolName);
196
- }
197
- const summary = summarizeTraceArguments(toPlainObject(payload.parameters));
198
- events.push(createStructuredTraceEvent(
199
- 'gemini',
200
- 'tool',
201
- eventType,
202
- summary ? `[工具开始] ${toolName} (${summary})` : `[工具开始] ${toolName}`,
203
- {
204
- phase: 'started',
205
- status: 'in_progress',
206
- toolName,
207
- toolId,
208
- arguments: toPlainObject(payload.parameters),
209
- argumentSummary: summary
210
- }
211
- ));
212
- return events.filter(Boolean);
213
- }
214
- if (eventType === 'tool_result') {
215
- const toolId = pickFirstString(payload.tool_id);
216
- const toolName = pickFirstString(toolNamesById.get(toolId), toolId, 'tool');
217
- const status = pickFirstString(payload.status, 'completed');
218
- events.push(createStructuredTraceEvent('gemini', 'tool', eventType, `[工具完成] ${toolName} (${status})`, {
219
- phase: 'completed',
220
- status,
221
- toolName,
222
- toolId,
223
- result: collectStructuredText(payload.output),
224
- error: toPlainObject(payload.error)
225
- }));
226
- return events.filter(Boolean);
227
- }
228
- if (eventType === 'result') {
229
- events.push(createStructuredTraceEvent('gemini', 'turn', eventType, '[回合] 响应完成', {
230
- phase: 'completed',
231
- status: pickFirstString(payload.status, 'completed')
232
- }));
233
- return events.filter(Boolean);
234
- }
235
- if (eventType === 'error') {
236
- const detail = pickFirstString(payload.message);
237
- events.push(createStructuredTraceEvent('gemini', 'error', eventType, detail ? `[错误] ${detail}` : '[错误] Gemini 返回了错误事件', {
238
- status: pickFirstString(payload.severity, 'error'),
239
- detail
240
- }));
241
- return events.filter(Boolean);
242
- }
243
- return [];
244
- }
245
-
246
- function prepareOpenCodeTraceEvents(payload, state, helpers) {
247
- const { pickFirstString, toPlainObject, collectStructuredText, summarizeTraceArguments, createStructuredTraceEvent } = helpers;
248
- const eventType = pickFirstString(payload.type);
249
- const message = toPlainObject(payload.message);
250
- const role = pickFirstString(payload.role, message.role);
251
- const toolNamesById = state.toolNamesById;
252
- const events = [];
253
-
254
- if (eventType === 'session.start' || eventType === 'init') {
255
- events.push(createStructuredTraceEvent('opencode', 'thread', eventType, '[会话] OpenCode 已开始处理', {
256
- phase: 'started',
257
- status: 'started',
258
- sessionId: pickFirstString(payload.session_id, payload.sessionID)
259
- }));
260
- return events.filter(Boolean);
261
- }
262
- if (eventType === 'message' || eventType === 'assistant' || eventType === 'assistant_message' || eventType === 'text') {
263
- if (role && role !== 'assistant') {
264
- return [];
265
- }
266
- if (payload.delta === true) {
267
- return [];
268
- }
269
- const detail = collectStructuredText(message.content || payload.content || payload.text || payload);
270
- if (!detail) {
271
- return [];
272
- }
273
- events.push(createStructuredTraceEvent('opencode', 'agent_message', eventType, `[说明] ${detail}`, {
274
- phase: 'completed',
275
- status: 'completed',
276
- detail
277
- }));
278
- return events.filter(Boolean);
279
- }
280
- if (eventType === 'tool_use' || eventType === 'step_start') {
281
- const toolName = pickFirstString(payload.tool_name, payload.name, payload.tool, payload.step, payload.tool_id, 'tool');
282
- const toolId = pickFirstString(payload.tool_id, payload.id);
283
- if (toolId) {
284
- toolNamesById.set(toolId, toolName);
285
- }
286
- const argumentsValue = toPlainObject(payload.parameters || payload.input || payload.arguments);
287
- const summary = summarizeTraceArguments(argumentsValue);
288
- events.push(createStructuredTraceEvent(
289
- 'opencode',
290
- 'tool',
291
- eventType,
292
- summary ? `[工具开始] ${toolName} (${summary})` : `[工具开始] ${toolName}`,
293
- {
294
- phase: 'started',
295
- status: pickFirstString(payload.status, 'in_progress'),
296
- toolName,
297
- toolId,
298
- arguments: argumentsValue,
299
- argumentSummary: summary
300
- }
301
- ));
302
- return events.filter(Boolean);
303
- }
304
- if (eventType === 'tool_result' || eventType === 'step_finish') {
305
- const toolId = pickFirstString(payload.tool_id, payload.id);
306
- const toolName = pickFirstString(toolNamesById.get(toolId), payload.tool_name, payload.name, payload.tool, toolId, 'tool');
307
- const status = pickFirstString(payload.status, payload.state, 'completed');
308
- events.push(createStructuredTraceEvent('opencode', 'tool', eventType, `[工具完成] ${toolName} (${status})`, {
309
- phase: 'completed',
310
- status,
311
- toolName,
312
- toolId,
313
- result: collectStructuredText(payload.output || payload.result),
314
- error: toPlainObject(payload.error)
315
- }));
316
- return events.filter(Boolean);
317
- }
318
- if (eventType === 'result') {
319
- events.push(createStructuredTraceEvent('opencode', 'turn', eventType, '[回合] 响应完成', {
320
- phase: 'completed',
321
- status: pickFirstString(payload.status, 'completed')
322
- }));
323
- return events.filter(Boolean);
324
- }
325
- if (eventType === 'error') {
326
- const detail = pickFirstString(payload.message, payload.error && payload.error.message);
327
- events.push(createStructuredTraceEvent('opencode', 'error', eventType, detail ? `[错误] ${detail}` : '[错误] OpenCode 返回了错误事件', {
328
- status: 'error',
329
- detail
330
- }));
331
- return events.filter(Boolean);
332
- }
333
- return [];
334
- }
335
-
336
- function prepareCodexTraceEvent(payload, helpers) {
337
- const { pickFirstString, shortenTraceText, summarizeTraceArguments } = helpers;
338
- if (!payload || typeof payload !== 'object') {
339
- return null;
340
- }
341
-
342
- const eventType = typeof payload.type === 'string' ? payload.type : '';
343
- const item = payload.item && typeof payload.item === 'object' && !Array.isArray(payload.item)
344
- ? payload.item
345
- : {};
346
- const itemType = typeof item.type === 'string' ? item.type : '';
347
- const text = pickFirstString(
348
- item.title,
349
- item.summary,
350
- item.text,
351
- item.name,
352
- item.command,
353
- payload.message,
354
- payload.text
355
- );
356
- const toolName = pickFirstString(
357
- item.name,
358
- item.tool_name,
359
- item.tool,
360
- item.command
361
- );
362
- const commandText = pickFirstString(item.command);
363
- const mcpServer = pickFirstString(item.server);
364
- const mcpTool = pickFirstString(item.tool);
365
- const itemStatus = pickFirstString(item.status);
366
-
367
- function pickDisplayStatus(defaultStatus) {
368
- const status = String(itemStatus || defaultStatus || '').trim();
369
- return status || '';
370
- }
371
-
372
- function createTraceEvent(kind, textValue, extra = {}) {
373
- const normalizedText = String(textValue || '').trim();
374
- if (!normalizedText) {
375
- return null;
376
- }
377
- return {
378
- provider: 'codex',
379
- kind,
380
- eventType,
381
- itemType: itemType || '',
382
- text: normalizedText,
383
- ...extra
384
- };
385
- }
386
-
387
- if (eventType === 'thread.started') {
388
- return createTraceEvent('thread', '[会话] Codex 已开始处理', {
389
- phase: 'started',
390
- status: 'started'
391
- });
392
- }
393
- if (eventType === 'thread.completed') {
394
- return createTraceEvent('thread', '[会话] Codex 已完成当前任务', {
395
- phase: 'completed',
396
- status: 'completed'
397
- });
398
- }
399
- if (eventType === 'turn.started') {
400
- return createTraceEvent('turn', '[回合] 开始生成响应', {
401
- phase: 'started',
402
- status: 'started'
403
- });
404
- }
405
- if (eventType === 'turn.completed') {
406
- return createTraceEvent('turn', '[回合] 响应完成', {
407
- phase: 'completed',
408
- status: 'completed'
409
- });
410
- }
411
- if (eventType === 'item.started') {
412
- if (itemType === 'tool_call') {
413
- return createTraceEvent('tool', `[工具开始] ${toolName || 'tool_call'}`, {
414
- phase: 'started',
415
- status: pickDisplayStatus('in_progress'),
416
- toolName: toolName || 'tool_call'
417
- });
418
- }
419
- if (itemType === 'command_execution') {
420
- return createTraceEvent('command', `[命令开始] ${commandText || 'command_execution'}`, {
421
- phase: 'started',
422
- status: pickDisplayStatus('in_progress'),
423
- command: commandText || 'command_execution'
424
- });
425
- }
426
- if (itemType === 'mcp_tool_call') {
427
- const summary = summarizeTraceArguments(item.arguments);
428
- return createTraceEvent(
429
- 'mcp',
430
- summary
431
- ? `[MCP开始] ${mcpServer || 'mcp'}.${mcpTool || 'tool'} (${summary})`
432
- : `[MCP开始] ${mcpServer || 'mcp'}.${mcpTool || 'tool'}`,
433
- {
434
- phase: 'started',
435
- status: pickDisplayStatus('in_progress'),
436
- server: mcpServer || 'mcp',
437
- tool: mcpTool || 'tool',
438
- arguments: item.arguments && typeof item.arguments === 'object' && !Array.isArray(item.arguments)
439
- ? item.arguments
440
- : null,
441
- argumentSummary: summary
442
- }
443
- );
444
- }
445
- if (itemType === 'reasoning') {
446
- return createTraceEvent('status', text ? `[状态] ${shortenTraceText(text)}` : '[状态] Codex 正在分析', {
447
- phase: 'started',
448
- status: pickDisplayStatus('in_progress'),
449
- detail: text || 'Codex 正在分析'
450
- });
451
- }
452
- if (itemType === 'agent_message') {
453
- return createTraceEvent('agent_message', text ? `[说明] ${shortenTraceText(text)}` : '[回复] 正在生成最终答复', {
454
- phase: 'started',
455
- status: pickDisplayStatus('in_progress'),
456
- detail: text || '正在生成最终答复'
457
- });
458
- }
459
- return createTraceEvent('event', text ? `[事件开始] ${text}` : `[事件开始] ${itemType || eventType}`, {
460
- phase: 'started',
461
- status: pickDisplayStatus('in_progress'),
462
- detail: text || itemType || eventType
463
- });
464
- }
465
- if (eventType === 'item.completed') {
466
- if (itemType === 'tool_call') {
467
- return createTraceEvent('tool', `[工具完成] ${toolName || 'tool_call'}`, {
468
- phase: 'completed',
469
- status: pickDisplayStatus('completed'),
470
- toolName: toolName || 'tool_call'
471
- });
472
- }
473
- if (itemType === 'command_execution') {
474
- const suffix = itemStatus || (typeof item.exit_code === 'number' ? `exit=${item.exit_code}` : 'completed');
475
- return createTraceEvent('command', `[命令完成] ${commandText || 'command_execution'} (${suffix})`, {
476
- phase: 'completed',
477
- status: pickDisplayStatus(suffix),
478
- command: commandText || 'command_execution',
479
- exitCode: typeof item.exit_code === 'number' ? item.exit_code : null
480
- });
481
- }
482
- if (itemType === 'mcp_tool_call') {
483
- const summary = summarizeTraceArguments(item.arguments);
484
- return createTraceEvent(
485
- 'mcp',
486
- summary
487
- ? `[MCP完成] ${mcpServer || 'mcp'}.${mcpTool || 'tool'} (${summary})`
488
- : `[MCP完成] ${mcpServer || 'mcp'}.${mcpTool || 'tool'}`,
489
- {
490
- phase: 'completed',
491
- status: pickDisplayStatus('completed'),
492
- server: mcpServer || 'mcp',
493
- tool: mcpTool || 'tool',
494
- arguments: item.arguments && typeof item.arguments === 'object' && !Array.isArray(item.arguments)
495
- ? item.arguments
496
- : null,
497
- argumentSummary: summary,
498
- result: item.result !== undefined ? item.result : null,
499
- error: item.error !== undefined ? item.error : null
500
- }
501
- );
502
- }
503
- if (itemType === 'reasoning') {
504
- return createTraceEvent('status', text ? `[状态] ${shortenTraceText(text)}` : '', {
505
- phase: 'completed',
506
- status: pickDisplayStatus('completed'),
507
- detail: text || ''
508
- });
509
- }
510
- if (itemType === 'agent_message') {
511
- return createTraceEvent('agent_message', text ? `[说明] ${shortenTraceText(text)}` : '[回复] 已生成', {
512
- phase: 'completed',
513
- status: pickDisplayStatus('completed'),
514
- detail: text || '已生成'
515
- });
516
- }
517
- return createTraceEvent('event', text ? `[事件完成] ${text}` : `[事件完成] ${itemType || eventType}`, {
518
- phase: 'completed',
519
- status: pickDisplayStatus('completed'),
520
- detail: text || itemType || eventType
521
- });
522
- }
523
- if (eventType === 'error') {
524
- return createTraceEvent('error', text ? `[错误] ${text}` : '[错误] Codex 返回了错误事件', {
525
- status: 'error',
526
- detail: text || 'Codex 返回了错误事件'
527
- });
528
- }
529
-
530
- return createTraceEvent('event', `[事件] ${eventType}`, {
531
- status: itemStatus || '',
532
- detail: eventType
533
- });
534
- }
535
-
536
- function prepareStructuredTraceEvents(agentProgram, payload, state, deps) {
537
- if (!payload || typeof payload !== 'object') {
538
- return [];
539
- }
540
- const helpers = createStructuredTraceHelpers(deps);
541
- if (agentProgram === 'codex') {
542
- const traceEvent = prepareCodexTraceEvent(payload, helpers);
543
- return traceEvent ? [traceEvent] : [];
544
- }
545
- if (agentProgram === 'claude') {
546
- return prepareClaudeTraceEvents(payload, state, helpers);
547
- }
548
- if (agentProgram === 'gemini') {
549
- return prepareGeminiTraceEvents(payload, state, helpers);
550
- }
551
- if (agentProgram === 'opencode') {
552
- return prepareOpenCodeTraceEvents(payload, state, helpers);
553
- }
554
- return [];
555
- }
556
-
557
- function extractContentDeltaFromPayload(agentProgram, payload, deps) {
558
- if (!payload || typeof payload !== 'object') {
559
- return null;
560
- }
561
- const { pickFirstString, toPlainObject, collectStructuredText } = deps;
562
- if (agentProgram === 'claude') {
563
- if (pickFirstString(payload.type) !== 'assistant') {
564
- return null;
565
- }
566
- const message = toPlainObject(payload.message);
567
- const content = Array.isArray(message.content) ? message.content : [];
568
- const text = content
569
- .filter(item => item && typeof item === 'object' && item.type === 'text')
570
- .map(item => collectStructuredText(item))
571
- .filter(Boolean)
572
- .join('\n')
573
- .trim();
574
- if (!text) {
575
- return null;
576
- }
577
- return { text, reset: true };
578
- }
579
- if (agentProgram === 'gemini' || agentProgram === 'opencode') {
580
- const eventType = pickFirstString(payload.type);
581
- if (eventType !== 'message') {
582
- return null;
583
- }
584
- const role = pickFirstString(payload.role);
585
- if (role !== 'assistant') {
586
- return null;
587
- }
588
- const text = collectStructuredText(payload.content);
589
- if (!text) {
590
- return null;
591
- }
592
- if (payload.delta === true) {
593
- return { text, reset: false };
594
- }
595
- return { text, reset: true };
596
- }
597
- return null;
598
- }
599
-
600
- module.exports = {
601
- prepareStructuredTraceEvents,
602
- extractContentDeltaFromPayload
603
- };