TypeScript: add extensions to tsconfig and fix type errors (#12781)

* TypeScript: add extensions to tsconfig and fix type errors

- Add extensions/**/* to tsconfig.json includes
- Export ProviderAuthResult, AnyAgentTool from plugin-sdk
- Fix optional chaining for messageActions across channels
- Add missing type imports (MSTeamsConfig, GroupPolicy, etc.)
- Add type annotations for provider auth handlers
- Fix undici/fetch type compatibility in zalo proxy
- Correct ChannelAccountSnapshot property usage
- Add type casts for tool registrations
- Extract usage view styles and types to separate files

* TypeScript: fix optional debug calls and handleAction guards
This commit is contained in:
max
2026-02-09 10:05:38 -08:00
committed by GitHub
parent 2e4334c32c
commit 40b11db80e
87 changed files with 2947 additions and 2706 deletions
+146 -127
View File
@@ -1,3 +1,4 @@
import type { GatewayRequestHandlerOptions, OpenClawPluginApi } from "openclaw/plugin-sdk";
import { Type } from "@sinclair/typebox";
import type { CoreConfig } from "./src/core-bridge.js";
import { registerVoiceCallCli } from "./src/cli.js";
@@ -144,7 +145,7 @@ const voiceCallPlugin = {
name: "Voice Call",
description: "Voice-call plugin with Telnyx/Twilio/Plivo providers",
configSchema: voiceCallConfigSchema,
register(api) {
register(api: OpenClawPluginApi) {
const config = resolveVoiceCallConfig(voiceCallConfigSchema.parse(api.pluginConfig));
const validation = validateProviderConfig(config);
@@ -188,142 +189,160 @@ const voiceCallPlugin = {
respond(false, { error: err instanceof Error ? err.message : String(err) });
};
api.registerGatewayMethod("voicecall.initiate", async ({ params, respond }) => {
try {
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!message) {
respond(false, { error: "message required" });
return;
api.registerGatewayMethod(
"voicecall.initiate",
async ({ params, respond }: GatewayRequestHandlerOptions) => {
try {
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!message) {
respond(false, { error: "message required" });
return;
}
const rt = await ensureRuntime();
const to =
typeof params?.to === "string" && params.to.trim()
? params.to.trim()
: rt.config.toNumber;
if (!to) {
respond(false, { error: "to required" });
return;
}
const mode =
params?.mode === "notify" || params?.mode === "conversation" ? params.mode : undefined;
const result = await rt.manager.initiateCall(to, undefined, {
message,
mode,
});
if (!result.success) {
respond(false, { error: result.error || "initiate failed" });
return;
}
respond(true, { callId: result.callId, initiated: true });
} catch (err) {
sendError(respond, err);
}
const rt = await ensureRuntime();
const to =
typeof params?.to === "string" && params.to.trim()
? params.to.trim()
: rt.config.toNumber;
if (!to) {
respond(false, { error: "to required" });
return;
}
const mode =
params?.mode === "notify" || params?.mode === "conversation" ? params.mode : undefined;
const result = await rt.manager.initiateCall(to, undefined, {
message,
mode,
});
if (!result.success) {
respond(false, { error: result.error || "initiate failed" });
return;
}
respond(true, { callId: result.callId, initiated: true });
} catch (err) {
sendError(respond, err);
}
});
},
);
api.registerGatewayMethod("voicecall.continue", async ({ params, respond }) => {
try {
const callId = typeof params?.callId === "string" ? params.callId.trim() : "";
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!callId || !message) {
respond(false, { error: "callId and message required" });
return;
api.registerGatewayMethod(
"voicecall.continue",
async ({ params, respond }: GatewayRequestHandlerOptions) => {
try {
const callId = typeof params?.callId === "string" ? params.callId.trim() : "";
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!callId || !message) {
respond(false, { error: "callId and message required" });
return;
}
const rt = await ensureRuntime();
const result = await rt.manager.continueCall(callId, message);
if (!result.success) {
respond(false, { error: result.error || "continue failed" });
return;
}
respond(true, { success: true, transcript: result.transcript });
} catch (err) {
sendError(respond, err);
}
const rt = await ensureRuntime();
const result = await rt.manager.continueCall(callId, message);
if (!result.success) {
respond(false, { error: result.error || "continue failed" });
return;
}
respond(true, { success: true, transcript: result.transcript });
} catch (err) {
sendError(respond, err);
}
});
},
);
api.registerGatewayMethod("voicecall.speak", async ({ params, respond }) => {
try {
const callId = typeof params?.callId === "string" ? params.callId.trim() : "";
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!callId || !message) {
respond(false, { error: "callId and message required" });
return;
api.registerGatewayMethod(
"voicecall.speak",
async ({ params, respond }: GatewayRequestHandlerOptions) => {
try {
const callId = typeof params?.callId === "string" ? params.callId.trim() : "";
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!callId || !message) {
respond(false, { error: "callId and message required" });
return;
}
const rt = await ensureRuntime();
const result = await rt.manager.speak(callId, message);
if (!result.success) {
respond(false, { error: result.error || "speak failed" });
return;
}
respond(true, { success: true });
} catch (err) {
sendError(respond, err);
}
const rt = await ensureRuntime();
const result = await rt.manager.speak(callId, message);
if (!result.success) {
respond(false, { error: result.error || "speak failed" });
return;
}
respond(true, { success: true });
} catch (err) {
sendError(respond, err);
}
});
},
);
api.registerGatewayMethod("voicecall.end", async ({ params, respond }) => {
try {
const callId = typeof params?.callId === "string" ? params.callId.trim() : "";
if (!callId) {
respond(false, { error: "callId required" });
return;
api.registerGatewayMethod(
"voicecall.end",
async ({ params, respond }: GatewayRequestHandlerOptions) => {
try {
const callId = typeof params?.callId === "string" ? params.callId.trim() : "";
if (!callId) {
respond(false, { error: "callId required" });
return;
}
const rt = await ensureRuntime();
const result = await rt.manager.endCall(callId);
if (!result.success) {
respond(false, { error: result.error || "end failed" });
return;
}
respond(true, { success: true });
} catch (err) {
sendError(respond, err);
}
const rt = await ensureRuntime();
const result = await rt.manager.endCall(callId);
if (!result.success) {
respond(false, { error: result.error || "end failed" });
return;
}
respond(true, { success: true });
} catch (err) {
sendError(respond, err);
}
});
},
);
api.registerGatewayMethod("voicecall.status", async ({ params, respond }) => {
try {
const raw =
typeof params?.callId === "string"
? params.callId.trim()
: typeof params?.sid === "string"
? params.sid.trim()
: "";
if (!raw) {
respond(false, { error: "callId required" });
return;
api.registerGatewayMethod(
"voicecall.status",
async ({ params, respond }: GatewayRequestHandlerOptions) => {
try {
const raw =
typeof params?.callId === "string"
? params.callId.trim()
: typeof params?.sid === "string"
? params.sid.trim()
: "";
if (!raw) {
respond(false, { error: "callId required" });
return;
}
const rt = await ensureRuntime();
const call = rt.manager.getCall(raw) || rt.manager.getCallByProviderCallId(raw);
if (!call) {
respond(true, { found: false });
return;
}
respond(true, { found: true, call });
} catch (err) {
sendError(respond, err);
}
const rt = await ensureRuntime();
const call = rt.manager.getCall(raw) || rt.manager.getCallByProviderCallId(raw);
if (!call) {
respond(true, { found: false });
return;
}
respond(true, { found: true, call });
} catch (err) {
sendError(respond, err);
}
});
},
);
api.registerGatewayMethod("voicecall.start", async ({ params, respond }) => {
try {
const to = typeof params?.to === "string" ? params.to.trim() : "";
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!to) {
respond(false, { error: "to required" });
return;
api.registerGatewayMethod(
"voicecall.start",
async ({ params, respond }: GatewayRequestHandlerOptions) => {
try {
const to = typeof params?.to === "string" ? params.to.trim() : "";
const message = typeof params?.message === "string" ? params.message.trim() : "";
if (!to) {
respond(false, { error: "to required" });
return;
}
const rt = await ensureRuntime();
const result = await rt.manager.initiateCall(to, undefined, {
message: message || undefined,
});
if (!result.success) {
respond(false, { error: result.error || "initiate failed" });
return;
}
respond(true, { callId: result.callId, initiated: true });
} catch (err) {
sendError(respond, err);
}
const rt = await ensureRuntime();
const result = await rt.manager.initiateCall(to, undefined, {
message: message || undefined,
});
if (!result.success) {
respond(false, { error: result.error || "initiate failed" });
return;
}
respond(true, { callId: result.callId, initiated: true });
} catch (err) {
sendError(respond, err);
}
});
},
);
api.registerTool({
name: "voice_call",
@@ -332,7 +351,7 @@ const voiceCallPlugin = {
parameters: VoiceCallToolSchema,
async execute(_toolCallId, params) {
const json = (payload: unknown) => ({
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
content: [{ type: "text" as const, text: JSON.stringify(payload, null, 2) }],
details: payload,
});
@@ -146,7 +146,7 @@ export async function generateVoiceResponse(
const text = texts.join(" ") || null;
if (!text && result.meta.aborted) {
if (!text && result.meta?.aborted) {
return { text: null, error: "Response generation was aborted" };
}
+1 -1
View File
@@ -30,7 +30,7 @@ type Logger = {
info: (message: string) => void;
warn: (message: string) => void;
error: (message: string) => void;
debug: (message: string) => void;
debug?: (message: string) => void;
};
function isLoopbackBind(bind: string | undefined): boolean {