@p-dsh-market/conversation-knowledge-map 0.1.3 → 0.1.4
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/README.md +1 -1
- package/lib/generation-orchestrator.js +65 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ DSH 的“知识视图”插件,把同一工作路径下用户明确选择的
|
|
|
15
15
|
|
|
16
16
|
## 生成失败诊断
|
|
17
17
|
|
|
18
|
-
Host 和生成编排器会输出带 `[conversation-knowledge-map]` 前缀的诊断日志。日志包含路由、Provider / Model、Agent Session、实时事件类型、surface/session 读取次数、提取文本长度、输出形状和错误原因,不记录 Prompt、对话正文或模型返回正文。优先查看 DSH Web Runtime 的终端日志;若 Runtime 提供 logger 服务,则同时写入该 logger。重点关注 `agent event`、`agent idle`、`agent surface read`、`agent session read` 和 `agent output parse failed`。
|
|
18
|
+
Host 和生成编排器会输出带 `[conversation-knowledge-map]` 前缀的诊断日志。日志包含路由、Provider / Model、Agent Session、实时事件类型、surface/session 读取次数、提取文本长度、输出形状和错误原因,不记录 Prompt、对话正文或模型返回正文。优先查看 DSH Web Runtime 的终端日志;若 Runtime 提供 logger 服务,则同时写入该 logger。重点关注 `agent event`、`agent idle`、`agent turn failure`、`agent surface read`、`agent session read` 和 `agent output parse failed`。Runtime 在 `turn/end.reason.kind = error` 时会优先显示其 `code/message`;只有未发现 turn 错误且确实没有助手输出时,才会报告“模型没有返回 JSON 对象”。
|
|
19
19
|
|
|
20
20
|
## 本地验证
|
|
21
21
|
|
|
@@ -235,6 +235,38 @@ function extractAgentText(surface) {
|
|
|
235
235
|
return chunks.join('')
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
function agentTurnError(event) {
|
|
239
|
+
if (String(event?.type || '') !== 'turn/end') return null
|
|
240
|
+
const data = event?.data && typeof event.data === 'object' ? event.data : {}
|
|
241
|
+
const reason = data.reason && typeof data.reason === 'object' ? data.reason : null
|
|
242
|
+
if (reason?.kind !== 'error') return null
|
|
243
|
+
const nestedError = reason.error && typeof reason.error === 'object' ? reason.error : null
|
|
244
|
+
const code = String(nestedError?.code || reason.code || '').trim()
|
|
245
|
+
const message = String(nestedError?.message || reason.message || (typeof reason.error === 'string' ? reason.error : '')).trim()
|
|
246
|
+
const detail = shortText(message || 'Agent turn 执行失败。', 1200)
|
|
247
|
+
const error = new Error(`Agent Runtime 生成失败${code ? `(${code})` : ''}:${detail}`)
|
|
248
|
+
error.code = code
|
|
249
|
+
error.agentTurn = true
|
|
250
|
+
error.cause = nestedError || reason
|
|
251
|
+
return error
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function findAgentTurnError(surface) {
|
|
255
|
+
const events = Array.isArray(surface?.events) ? surface.events : []
|
|
256
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
257
|
+
const error = agentTurnError(events[index])
|
|
258
|
+
if (error) return error
|
|
259
|
+
}
|
|
260
|
+
return null
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function wrapAgentRuntimeError(error) {
|
|
264
|
+
if (error?.agentTurn || /^Agent Runtime 生成失败/.test(errorMessage(error))) return error
|
|
265
|
+
const wrapped = new Error(`Agent Runtime 生成失败:${errorMessage(error)}`)
|
|
266
|
+
wrapped.cause = error
|
|
267
|
+
return wrapped
|
|
268
|
+
}
|
|
269
|
+
|
|
238
270
|
async function readAgentText(sessionQuery, sessionId, signal, { logger, diagnostics } = {}) {
|
|
239
271
|
const stats = diagnostics || { surfaceReads: 0, sessionReads: 0 }
|
|
240
272
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
@@ -247,6 +279,13 @@ async function readAgentText(sessionQuery, sessionId, signal, { logger, diagnost
|
|
|
247
279
|
stats.lastSurfaceShape = diagnosticSummary(surface)
|
|
248
280
|
stats.lastSurfaceTextLength = text.length
|
|
249
281
|
logMessage(logger, 'info', 'agent surface read session=%s attempt=%d events=%d extractedTextLength=%d shape=%s', logId(sessionId), attempt + 1, eventCount, text.length, stats.lastSurfaceShape)
|
|
282
|
+
const surfaceError = findAgentTurnError(surface)
|
|
283
|
+
if (surfaceError) {
|
|
284
|
+
stats.agentFailureSource = 'surface'
|
|
285
|
+
stats.agentFailureCode = surfaceError.code || ''
|
|
286
|
+
logMessage(logger, 'error', 'agent turn failure session=%s source=surface code=%s error=%s', logId(sessionId), surfaceError.code || '', errorMessage(surfaceError))
|
|
287
|
+
throw surfaceError
|
|
288
|
+
}
|
|
250
289
|
if (text.trim()) return text
|
|
251
290
|
if (attempt < 5) await new Promise((resolve) => setTimeout(resolve, 40 * (attempt + 1)))
|
|
252
291
|
}
|
|
@@ -259,6 +298,13 @@ async function readAgentText(sessionQuery, sessionId, signal, { logger, diagnost
|
|
|
259
298
|
stats.lastSessionShape = diagnosticSummary(log)
|
|
260
299
|
stats.lastSessionTextLength = text.length
|
|
261
300
|
logMessage(logger, 'info', 'agent session read session=%s events=%d extractedTextLength=%d shape=%s', logId(sessionId), eventCount, text.length, stats.lastSessionShape)
|
|
301
|
+
const sessionError = findAgentTurnError(log)
|
|
302
|
+
if (sessionError) {
|
|
303
|
+
stats.agentFailureSource = 'session'
|
|
304
|
+
stats.agentFailureCode = sessionError.code || ''
|
|
305
|
+
logMessage(logger, 'error', 'agent turn failure session=%s source=session code=%s error=%s', logId(sessionId), sessionError.code || '', errorMessage(sessionError))
|
|
306
|
+
throw sessionError
|
|
307
|
+
}
|
|
262
308
|
if (text.trim()) return text
|
|
263
309
|
}
|
|
264
310
|
return ''
|
|
@@ -513,7 +559,10 @@ export class KnowledgeGenerationOrchestrator {
|
|
|
513
559
|
surfaceReads: 0,
|
|
514
560
|
sessionReads: 0,
|
|
515
561
|
lastSurfaceEventCount: 0,
|
|
516
|
-
lastSessionEventCount: 0
|
|
562
|
+
lastSessionEventCount: 0,
|
|
563
|
+
agentFailureSource: '',
|
|
564
|
+
agentFailureCode: '',
|
|
565
|
+
agentFailure: null
|
|
517
566
|
}
|
|
518
567
|
logMessage(this.logger, 'info', 'agent call start kind=%s session=%s provider=%s model=%s promptLength=%d', input.kind, logId(sessionId), provider, model, String(input.prompt || '').length)
|
|
519
568
|
let unsubscribe
|
|
@@ -528,6 +577,13 @@ export class KnowledgeGenerationOrchestrator {
|
|
|
528
577
|
else if (event.type === 'assistant/chunk') diagnostics.liveAssistantChunks += 1
|
|
529
578
|
else diagnostics.liveOtherEvents += 1
|
|
530
579
|
logMessage(this.logger, 'info', 'agent event session=%s type=%s data=%s', logId(sessionId), String(event.type || 'unknown'), diagnosticSummary(event.data))
|
|
580
|
+
const failure = agentTurnError(event)
|
|
581
|
+
if (failure && !diagnostics.agentFailure) {
|
|
582
|
+
diagnostics.agentFailure = failure
|
|
583
|
+
diagnostics.agentFailureSource = 'live-event'
|
|
584
|
+
diagnostics.agentFailureCode = failure.code || ''
|
|
585
|
+
logMessage(this.logger, 'error', 'agent turn failure session=%s source=live-event code=%s error=%s', logId(sessionId), failure.code || '', errorMessage(failure))
|
|
586
|
+
}
|
|
531
587
|
})
|
|
532
588
|
logMessage(this.logger, 'info', 'agent event subscription ready session=%s', logId(sessionId))
|
|
533
589
|
} catch (error) {
|
|
@@ -535,6 +591,7 @@ export class KnowledgeGenerationOrchestrator {
|
|
|
535
591
|
}
|
|
536
592
|
}
|
|
537
593
|
let handle
|
|
594
|
+
let stage = 'create'
|
|
538
595
|
try {
|
|
539
596
|
handle = await this.agents.create({
|
|
540
597
|
sessionId,
|
|
@@ -552,8 +609,12 @@ export class KnowledgeGenerationOrchestrator {
|
|
|
552
609
|
} catch { /* older runtimes may not expose tool restriction */ }
|
|
553
610
|
}
|
|
554
611
|
})
|
|
612
|
+
stage = 'followup'
|
|
555
613
|
handle.agent.followup(makeUserMessage(input.prompt, `${sessionId}-${input.kind}`))
|
|
614
|
+
stage = 'idle'
|
|
556
615
|
await handle.agent.whenIdle()
|
|
616
|
+
if (diagnostics.agentFailure) throw diagnostics.agentFailure
|
|
617
|
+
stage = 'read-output'
|
|
557
618
|
const liveText = extractAgentText({ events: liveEvents })
|
|
558
619
|
logMessage(this.logger, 'info', 'agent idle session=%s liveEvents=%d assistantMessages=%d assistantChunks=%d otherEvents=%d liveTextLength=%d', logId(sessionId), diagnostics.liveEvents, diagnostics.liveAssistantMessages, diagnostics.liveAssistantChunks, diagnostics.liveOtherEvents, liveText.length)
|
|
559
620
|
if (liveText.trim()) return parseModelOutput(liveText, 'live-events', diagnostics)
|
|
@@ -561,8 +622,9 @@ export class KnowledgeGenerationOrchestrator {
|
|
|
561
622
|
logMessage(this.logger, 'info', 'agent persisted output session=%s textLength=%d surfaceReads=%d sessionReads=%d', logId(sessionId), persistedText.length, diagnostics.surfaceReads, diagnostics.sessionReads)
|
|
562
623
|
return parseModelOutput(persistedText, 'persisted-session', diagnostics)
|
|
563
624
|
} catch (error) {
|
|
564
|
-
|
|
565
|
-
|
|
625
|
+
const surfacedError = diagnostics.agentFailure || (stage === 'read-output' ? error : wrapAgentRuntimeError(error))
|
|
626
|
+
logMessage(this.logger, 'error', 'agent call failed kind=%s session=%s liveEvents=%d surfaceReads=%d sessionReads=%d error=%s', input.kind, logId(sessionId), diagnostics.liveEvents, diagnostics.surfaceReads, diagnostics.sessionReads, errorMessage(surfacedError))
|
|
627
|
+
throw surfacedError
|
|
566
628
|
} finally {
|
|
567
629
|
if (typeof unsubscribe === 'function') await unsubscribe()
|
|
568
630
|
await handle?.dispose?.()
|