runModelStepStreaming 流式执行模型步骤 返回: (done, error)
(ctx context.Context, writer *stream.Writer[*session.Event])
| 304 | // runModelStepStreaming 流式执行模型步骤 |
| 305 | // 返回: (done, error) |
| 306 | func (a *Agent) runModelStepStreaming(ctx context.Context, writer *stream.Writer[*session.Event]) (bool, error) { |
| 307 | // 1. 准备消息 |
| 308 | a.mu.RLock() |
| 309 | messages := make([]types.Message, len(a.messages)) |
| 310 | copy(messages, a.messages) |
| 311 | a.mu.RUnlock() |
| 312 | |
| 313 | // 2. 通过 Middleware 调用 LLM |
| 314 | var resp *middleware.ModelResponse |
| 315 | var err error |
| 316 | |
| 317 | streamLog.Debug(ctx, "using middleware stack", map[string]any{"has_stack": a.middlewareStack != nil}) |
| 318 | |
| 319 | if a.middlewareStack != nil { |
| 320 | // 使用 Middleware Stack |
| 321 | streamLog.Debug(ctx, "using middleware stack for streaming", nil) |
| 322 | // 转换工具列表 |
| 323 | toolList := make([]tools.Tool, 0, len(a.toolMap)) |
| 324 | for _, tool := range a.toolMap { |
| 325 | toolList = append(toolList, tool) |
| 326 | } |
| 327 | |
| 328 | req := &middleware.ModelRequest{ |
| 329 | Messages: messages, |
| 330 | SystemPrompt: a.template.SystemPrompt, |
| 331 | Tools: toolList, |
| 332 | Metadata: make(map[string]any), |
| 333 | } |
| 334 | |
| 335 | // 创建适配器处理provider调用 |
| 336 | finalHandler := func(ctx context.Context, req *middleware.ModelRequest) (*middleware.ModelResponse, error) { |
| 337 | // 转换工具定义 |
| 338 | toolSchemas := make([]provider.ToolSchema, len(req.Tools)) |
| 339 | for i, tool := range req.Tools { |
| 340 | toolSchemas[i] = provider.ToolSchema{ |
| 341 | Name: tool.Name(), |
| 342 | Description: tool.Description(), |
| 343 | InputSchema: tool.InputSchema(), |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | // 创建Provider选项 |
| 348 | streamOpts := &provider.StreamOptions{ |
| 349 | Tools: toolSchemas, |
| 350 | System: req.SystemPrompt, |
| 351 | Temperature: 0.7, |
| 352 | } |
| 353 | |
| 354 | // 调用Provider - 使用Stream方法支持流式响应 |
| 355 | streamLog.Debug(ctx, "calling provider.Stream() for middleware", nil) |
| 356 | chunkCh, err := a.provider.Stream(ctx, req.Messages, streamOpts) |
| 357 | if err != nil { |
| 358 | return nil, err |
| 359 | } |
| 360 | |
| 361 | // 直接将流式响应发送到WebSocket,但这里先收集用于兼容旧逻辑 |
| 362 | streamLog.Debug(ctx, "starting to collect chunks from provider", nil) |
| 363 | var assistantMessage types.Message |
no test coverage detected