






















@@ -1,8 +1,17 @@
1-import { normalizeOptionalString } from "../shared/string-coerce.js";
1+import {
2+normalizeOptionalLowercaseString,
3+normalizeOptionalString,
4+} from "../shared/string-coerce.js";
25import type { RealtimeVoiceTool } from "./provider-types.js";
3647export const REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME = "openclaw_agent_consult";
5-export type RealtimeVoiceAgentConsultToolPolicy = "safe-read-only" | "owner" | "none";
8+export const REALTIME_VOICE_AGENT_CONSULT_TOOL_POLICIES = [
9+"safe-read-only",
10+"owner",
11+"none",
12+] as const;
13+export type RealtimeVoiceAgentConsultToolPolicy =
14+(typeof REALTIME_VOICE_AGENT_CONSULT_TOOL_POLICIES)[number];
615export type RealtimeVoiceAgentConsultArgs = {
716question: string;
817context?: string;
@@ -38,6 +47,62 @@ export const REALTIME_VOICE_AGENT_CONSULT_TOOL: RealtimeVoiceTool = {
3847},
3948};
404950+const SAFE_READ_ONLY_TOOLS = [
51+"read",
52+"web_search",
53+"web_fetch",
54+"x_search",
55+"memory_search",
56+"memory_get",
57+] as const;
58+59+export function isRealtimeVoiceAgentConsultToolPolicy(
60+value: unknown,
61+): value is RealtimeVoiceAgentConsultToolPolicy {
62+return (
63+typeof value === "string" &&
64+REALTIME_VOICE_AGENT_CONSULT_TOOL_POLICIES.includes(
65+value as RealtimeVoiceAgentConsultToolPolicy,
66+)
67+);
68+}
69+70+export function resolveRealtimeVoiceAgentConsultToolPolicy(
71+value: unknown,
72+fallback: RealtimeVoiceAgentConsultToolPolicy,
73+): RealtimeVoiceAgentConsultToolPolicy {
74+const normalized = normalizeOptionalLowercaseString(value);
75+return isRealtimeVoiceAgentConsultToolPolicy(normalized) ? normalized : fallback;
76+}
77+78+export function resolveRealtimeVoiceAgentConsultTools(
79+policy: RealtimeVoiceAgentConsultToolPolicy,
80+customTools: RealtimeVoiceTool[] = [],
81+): RealtimeVoiceTool[] {
82+const tools = new Map<string, RealtimeVoiceTool>();
83+if (policy !== "none") {
84+tools.set(REALTIME_VOICE_AGENT_CONSULT_TOOL.name, REALTIME_VOICE_AGENT_CONSULT_TOOL);
85+}
86+for (const tool of customTools) {
87+if (!tools.has(tool.name)) {
88+tools.set(tool.name, tool);
89+}
90+}
91+return [...tools.values()];
92+}
93+94+export function resolveRealtimeVoiceAgentConsultToolsAllow(
95+policy: RealtimeVoiceAgentConsultToolPolicy,
96+): string[] | undefined {
97+if (policy === "owner") {
98+return undefined;
99+}
100+if (policy === "safe-read-only") {
101+return [...SAFE_READ_ONLY_TOOLS];
102+}
103+return [];
104+}
105+41106export function parseRealtimeVoiceAgentConsultArgs(args: unknown): RealtimeVoiceAgentConsultArgs {
42107const question = readConsultStringArg(args, "question");
43108if (!question) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。