Files
ars-backend/app/Services/Agent/OpenAi/OpenAiEventNormalizer.php
ROOG 59d4831f00 main: 增强工具调用与消息流程
- 支持 tool.call 和 tool.result 消息类型处理
- 引入 Tool 调度与执行逻辑,支持超时与结果截断
- 增加 ToolRegistry 和 ToolExecutor 管理工具定义与执行
- 更新上下文构建与消息映射逻辑,适配工具闭环处理
- 扩展配置与环境变量,支持 Tool 调用相关选项
- 增强单元测试覆盖工具调用与执行情景
- 更新文档和 OpenAPI,新增工具相关说明与模型定义
2025-12-22 12:36:59 +08:00

70 lines
2.3 KiB
PHP

<?php
namespace App\Services\Agent\OpenAi;
use App\Services\Agent\ProviderEvent;
class OpenAiEventNormalizer
{
/**
* Normalizes a single SSE payload into ProviderEvent values.
*
* @return array<int, ProviderEvent>
*/
public function normalize(string $payload): array
{
if (trim($payload) === '[DONE]') {
return [ProviderEvent::done('done')];
}
$decoded = json_decode($payload, true);
if (! is_array($decoded)) {
return [ProviderEvent::error('INVALID_JSON', 'Agent provider returned invalid JSON', [
'raw' => $payload,
])];
}
$events = [];
$choices = $decoded['choices'] ?? [];
$firstChoice = is_array($choices) ? ($choices[0] ?? null) : null;
$delta = is_array($firstChoice) ? ($firstChoice['delta'] ?? null) : null;
if (is_array($delta)) {
$content = $delta['content'] ?? null;
if (is_string($content) && $content !== '') {
$events[] = ProviderEvent::messageDelta($content);
}
if (isset($delta['tool_calls']) && is_array($delta['tool_calls'])) {
$toolCalls = [];
foreach ($delta['tool_calls'] as $toolCall) {
if (! is_array($toolCall)) {
continue;
}
$toolCalls[] = [
'id' => $toolCall['id'] ?? null,
'name' => $toolCall['function']['name'] ?? null,
'arguments' => $toolCall['function']['arguments'] ?? '',
'index' => $toolCall['index'] ?? null,
];
}
if (! empty($toolCalls)) {
$events[] = ProviderEvent::toolDelta(['tool_calls' => $toolCalls]);
}
}
}
if (is_array($firstChoice) && array_key_exists('finish_reason', $firstChoice) && $firstChoice['finish_reason'] !== null) {
$events[] = ProviderEvent::done((string) $firstChoice['finish_reason']);
}
if (isset($decoded['usage']) && is_array($decoded['usage'])) {
$events[] = ProviderEvent::usage($decoded['usage']);
}
return $events;
}
}