docs: 修正全部文档使其与源码实现一致

主仓库:
- 修复 4 份英文文档语言切换链接指向错误 (../zh/ → ../en/)
- ARCHITECTURE.md 标题 "三种加载方式" → "四种加载方式" (实际表格4行)
- PLUGIN_DEV.md 示例表: 添加 webfetch, 移除不存在的 luaplugintest/testlua
- PLUGIN_DEV.md 代码示例: InjectInput/InjectInterrupt → InjectText/InjectInterruptText
- PLUGIN_DEV.md 代码示例: Memory/Knowledge/LLM/Events 接口签名修正
- PLUGIN_DEV.md .hmap 内容统一, plugindev 编译去除 .exe 后缀

SDK 仓库:
- Plugin.Start(sdk *PluginSDK) 接口签名改为指针
- 方法表重写: 移除 CallLLM/QueryKnowledge/SetMemory 等不存在方法
- IOInjector 参数顺序修正为 (source, channel, text)
- 删除虚构 SDKConfig, 替换为实际 New() 构造函数签名
- .hmap 内容描述一致化

修正前一次会话中的 QQ/Bili 插件问题:
- qq napcat() 超时, fetchBotInfo 竞态, handleWebhook 同步阻塞
- bili CDN 直连失败, 添加 HTTP_PROXY 代理
This commit is contained in:
root
2026-07-18 20:46:58 +08:00
parent 2cc600121c
commit c9e67d3d55
14 changed files with 125 additions and 145 deletions

View File

@ -380,6 +380,27 @@ func (a *Agent) processMediaInput(evt *agentIO.InputEvent) {
blocks, fallback := a.mediaToBlocks(evt.Payload, evt.Type, evt.Source)
// stage 上下文携带 blocksprocess() 会将其附着到 user message 上
stageCtx := a.stageCtxFromInput(fallback, evt.Source, "")
stageCtx.Extra = map[string]interface{}{
"media_blocks": blocks,
"media_type": evt.Type,
"input_source": evt.Source,
"output_channel": evt.OutputChannel,
}
a.injectSourceContext(stageCtx, evt)
// === Stage: on_input — 插件可拦截/改写/短路(在 Append 之前) ===
if a.runStage(sdk.StageOnInput, stageCtx) {
a.emitResponse(evt, *stageCtx.Response)
return
}
a.publishEvent(events.EventRawInput, map[string]interface{}{
"content": evt.Payload,
"source": evt.Source,
})
// 先遗忘再输入
archived := a.context.Prune(fallback, a.maxContextSize-1, a.docStore)
if archived > 0 {
@ -392,26 +413,6 @@ func (a *Agent) processMediaInput(evt *agentIO.InputEvent) {
Input: fallback,
})
// stage 上下文携带 blocksprocess() 会将其附着到 user message 上
stageCtx := a.stageCtxFromInput(fallback, evt.Source, "")
stageCtx.Extra = map[string]interface{}{
"media_blocks": blocks,
"media_type": evt.Type,
"input_source": evt.Source,
"output_channel": evt.OutputChannel,
}
a.injectSourceContext(stageCtx, evt)
a.publishEvent(events.EventRawInput, map[string]interface{}{
"content": evt.Payload,
"source": evt.Source,
})
if a.runStage(sdk.StageOnInput, stageCtx) {
a.emitResponse(evt, *stageCtx.Response)
return
}
response, toolsUsed, err := a.process(fallback, stageCtx)
if err != nil {
log.Printf("[agent] process media error: %v", err)
@ -433,6 +434,10 @@ func (a *Agent) processMediaInput(evt *agentIO.InputEvent) {
})
a.emitResponse(evt, response)
if !stageCtx.NoMemory {
a.emitMemoryCandidate(evt.Source, fallback, response, toolsUsed)
}
}
// mediaToBlocks 将媒体 payload 转为多模态 ContentBlock 数组和纯文本 fallback。
@ -502,7 +507,7 @@ func (a *Agent) processTextInput(evt *agentIO.InputEvent, input string) {
// 记忆整理任务:不路由到外部输出通道
if evt.OutputChannel == "_consolidation_" {
a.processConsolidation(input)
a.processConsolidation(evt, input)
return
}
@ -520,8 +525,18 @@ func (a *Agent) processTextInput(evt *agentIO.InputEvent, input string) {
}
a.injectSourceContext(stageCtx, evt)
if a.runStage(sdk.StageOnInput, stageCtx) {
a.emitResponse(evt, *stageCtx.Response)
return
}
input = stageCtx.RawMessage
a.publishEvent(events.EventRawInput, map[string]interface{}{
"content": input,
"source": evt.Source,
})
// 先"遗忘"再输入用当前输入决定淘汰哪些不相关旧事件LSTM forget gate 模式)
archived := a.context.Prune(input, a.maxContextSize-1, a.docStore)
if archived > 0 {
@ -2549,10 +2564,14 @@ func (a *Agent) emitMemoryCandidate(source, input, response string, toolsUsed []
// executeOutputChannelTool — AI 切换当前请求的输出通道
// 在 process() 内调用mutex 保护,只有一个请求在执行
// processConsolidation 处理后台记忆整理任务(不发外部输出)
func (a *Agent) processConsolidation(input string) {
func (a *Agent) processConsolidation(evt *agentIO.InputEvent, input string) {
start := time.Now()
a.currentOutputChannel = "_consolidation_"
stageCtx := a.stageCtxFromInput(input, evt.Source, "")
stageCtx.Extra["output_channel"] = evt.OutputChannel
a.injectSourceContext(stageCtx, evt)
// 遗忘不相关的旧事件
archived := a.context.Prune(input, a.maxContextSize-1, a.docStore)
if archived > 0 {
@ -2564,7 +2583,7 @@ func (a *Agent) processConsolidation(input string) {
Source: "system",
Input: input,
})
response, toolsUsed, err := a.process(input, &sdk.StageContext{RawMessage: input})
response, toolsUsed, err := a.process(input, stageCtx)
if err != nil {
log.Printf("[agent] consolidation error: %v", err)
return