main: 增强工具调用与消息流程
- 支持 tool.call 和 tool.result 消息类型处理 - 引入 Tool 调度与执行逻辑,支持超时与结果截断 - 增加 ToolRegistry 和 ToolExecutor 管理工具定义与执行 - 更新上下文构建与消息映射逻辑,适配工具闭环处理 - 扩展配置与环境变量,支持 Tool 调用相关选项 - 增强单元测试覆盖工具调用与执行情景 - 更新文档和 OpenAPI,新增工具相关说明与模型定义
This commit is contained in:
86
app/Services/Tool/ToolExecutor.php
Normal file
86
app/Services/Tool/ToolExecutor.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Tool;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Tool 执行调度器,负责超时/结果截断等基础防护。
|
||||
*/
|
||||
class ToolExecutor
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ToolRegistry $registry,
|
||||
private ?int $timeoutSeconds = null,
|
||||
private ?int $maxResultBytes = null,
|
||||
) {
|
||||
$this->timeoutSeconds = $this->timeoutSeconds ?? (int) config('agent.tools.timeout_seconds', 15);
|
||||
$this->maxResultBytes = $this->maxResultBytes ?? (int) config('agent.tools.result_max_bytes', 4096);
|
||||
}
|
||||
|
||||
public function execute(ToolCall $call): ToolResult
|
||||
{
|
||||
$tool = $this->registry->get($call->name);
|
||||
|
||||
if (! $tool) {
|
||||
return new ToolResult(
|
||||
$call->runId,
|
||||
$call->parentRunId,
|
||||
$call->toolCallId,
|
||||
$call->name,
|
||||
'FAILED',
|
||||
'',
|
||||
'TOOL_NOT_FOUND'
|
||||
);
|
||||
}
|
||||
|
||||
$started = microtime(true);
|
||||
|
||||
try {
|
||||
$result = $tool->execute($call->arguments);
|
||||
$output = is_string($result) ? $result : json_encode($result, JSON_UNESCAPED_UNICODE);
|
||||
} catch (\Throwable $exception) {
|
||||
return new ToolResult(
|
||||
$call->runId,
|
||||
$call->parentRunId,
|
||||
$call->toolCallId,
|
||||
$call->name,
|
||||
'FAILED',
|
||||
'',
|
||||
Str::limit($exception->getMessage(), 200)
|
||||
);
|
||||
}
|
||||
|
||||
$duration = microtime(true) - $started;
|
||||
$truncated = false;
|
||||
|
||||
if ($this->maxResultBytes > 0 && strlen($output) > $this->maxResultBytes) {
|
||||
$output = substr($output, 0, $this->maxResultBytes);
|
||||
$truncated = true;
|
||||
}
|
||||
|
||||
if ($this->timeoutSeconds > 0 && $duration > $this->timeoutSeconds) {
|
||||
return new ToolResult(
|
||||
$call->runId,
|
||||
$call->parentRunId,
|
||||
$call->toolCallId,
|
||||
$call->name,
|
||||
'TIMEOUT',
|
||||
$output,
|
||||
'TOOL_TIMEOUT',
|
||||
$truncated
|
||||
);
|
||||
}
|
||||
|
||||
return new ToolResult(
|
||||
$call->runId,
|
||||
$call->parentRunId,
|
||||
$call->toolCallId,
|
||||
$call->name,
|
||||
'SUCCESS',
|
||||
$output,
|
||||
null,
|
||||
$truncated
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user