diff --git a/app/Http/Controllers/ChatSessionSseController.php b/app/Http/Controllers/ChatSessionSseController.php index 106af39..520402e 100644 --- a/app/Http/Controllers/ChatSessionSseController.php +++ b/app/Http/Controllers/ChatSessionSseController.php @@ -75,6 +75,13 @@ class ChatSessionSseController extends Controller $msg = json_decode($payload, true, 512, JSON_THROW_ON_ERROR); $msg = new Message($msg); + + // message.delta 不持久化,seq=0,直接推送 + if ($msg && $msg->type === 'message.delta') { + $this->emitMessage($msg, true); + return; + } + if ($msg && $msg->seq > $lastSentSeq) { if ($msg->seq > $lastSentSeq + 1) { $this->sendBacklog($sessionId, $lastSentSeq, $limit); diff --git a/app/Services/Agent/OpenAi/ChatCompletionsRequestBuilder.php b/app/Services/Agent/OpenAi/ChatCompletionsRequestBuilder.php index c1c0d22..b33b48b 100644 --- a/app/Services/Agent/OpenAi/ChatCompletionsRequestBuilder.php +++ b/app/Services/Agent/OpenAi/ChatCompletionsRequestBuilder.php @@ -69,7 +69,10 @@ class ChatCompletionsRequestBuilder $toolsSpec = $this->toolRegistry->openAiToolsSpec(); - if (! empty($toolsSpec)) { + // 支持 disable_tools 选项,用于在达到工具调用上限后禁用工具 + $disableTools = $options['disable_tools'] ?? false; + + if (! empty($toolsSpec) && ! $disableTools) { $payload['tools'] = $toolsSpec; $payload['tool_choice'] = $options['tool_choice'] ?? $this->toolChoice ?? 'auto'; } @@ -105,6 +108,10 @@ class ChatCompletionsRequestBuilder $toolCall = $this->normalizeToolCallPayload($payload, $content); if ($toolCall) { $messages[] = $toolCall; + logger('openai adapter: added tool.call', [ + 'tool_call_id' => $payload['tool_call_id'] ?? null, + 'name' => $payload['name'] ?? null, + ]); } continue; } @@ -113,6 +120,16 @@ class ChatCompletionsRequestBuilder $toolResult = $this->normalizeToolResultPayload($payload, $content); if ($toolResult) { $messages[] = $toolResult; + logger('openai adapter: added tool.result', [ + 'tool_call_id' => $payload['tool_call_id'] ?? null, + 'name' => $payload['name'] ?? null, + 'content_length' => strlen($toolResult['content'] ?? ''), + ]); + } else { + logger('openai adapter: tool.result normalized to null', [ + 'payload' => $payload, + 'content' => $content, + ]); } continue; } @@ -125,6 +142,11 @@ class ChatCompletionsRequestBuilder } } + logger('openai adapter: built messages', [ + 'total_messages' => count($messages), + 'message_roles' => array_column($messages, 'role'), + ]); + return $messages; } @@ -134,6 +156,7 @@ class ChatCompletionsRequestBuilder Message::ROLE_USER => 'user', Message::ROLE_AGENT => 'assistant', Message::ROLE_SYSTEM => 'system', + Message::ROLE_TOOL => 'tool', default => null, }; } diff --git a/app/Services/ContextBuilder.php b/app/Services/ContextBuilder.php index 916305d..ccefc7c 100644 --- a/app/Services/ContextBuilder.php +++ b/app/Services/ContextBuilder.php @@ -16,6 +16,13 @@ class ContextBuilder { $messages = $this->loadRecentMessages($sessionId); + logger('context builder loaded messages', [ + 'session_id' => $sessionId, + 'run_id' => $runId, + 'message_count' => $messages->count(), + 'message_types' => $messages->pluck('type', 'seq')->toArray(), + ]); + return new AgentContext( $runId, $sessionId, diff --git a/app/Services/RunLoop.php b/app/Services/RunLoop.php index 26e1dc1..0f4ad6f 100644 --- a/app/Services/RunLoop.php +++ b/app/Services/RunLoop.php @@ -202,9 +202,9 @@ class RunLoop 'should_stop' => fn () => $this->isCanceled($sessionId, $runId), ]; - // 达到工具调用上限后,强制禁用工具调用,避免再次触发 TOOL_CALL_LIMIT 错误 + // 达到工具调用上限后,禁用工具列表,避免再次触发 TOOL_CALL_LIMIT 错误 if ($toolCallCount >= $this->maxToolCalls) { - $options['tool_choice'] = 'none'; + $options['disable_tools'] = true; } return $options;