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
+12 -9
View File
@@ -1,4 +1,5 @@
import type {
ChannelAccountSnapshot,
ChannelOutboundAdapter,
ChannelPlugin,
ChannelSetupInput,
@@ -154,7 +155,7 @@ const tlonOutbound: ChannelOutboundAdapter = {
},
sendMedia: async ({ cfg, to, text, mediaUrl, accountId, replyToId, threadId }) => {
const mergedText = buildMediaText(text, mediaUrl);
return await tlonOutbound.sendText({
return await tlonOutbound.sendText!({
cfg,
to,
text: mergedText,
@@ -224,9 +225,11 @@ export const tlonPlugin: ChannelPlugin = {
deleteAccount: ({ cfg, accountId }) => {
const useDefault = !accountId || accountId === "default";
if (useDefault) {
// @ts-expect-error
// oxlint-disable-next-line no-unused-vars
const { ship, code, url, name, ...rest } = cfg.channels?.tlon ?? {};
const { ship, code, url, name, ...rest } = (cfg.channels?.tlon ?? {}) as Record<
string,
unknown
>;
return {
...cfg,
channels: {
@@ -235,9 +238,9 @@ export const tlonPlugin: ChannelPlugin = {
},
} as OpenClawConfig;
}
// @ts-expect-error
// oxlint-disable-next-line no-unused-vars
const { [accountId]: removed, ...remainingAccounts } = cfg.channels?.tlon?.accounts ?? {};
const { [accountId]: removed, ...remainingAccounts } = (cfg.channels?.tlon?.accounts ??
{}) as Record<string, unknown>;
return {
...cfg,
channels: {
@@ -334,8 +337,8 @@ export const tlonPlugin: ChannelPlugin = {
},
buildChannelSummary: ({ snapshot }) => ({
configured: snapshot.configured ?? false,
ship: snapshot.ship ?? null,
url: snapshot.url ?? null,
ship: (snapshot as { ship?: string | null }).ship ?? null,
url: (snapshot as { url?: string | null }).url ?? null,
}),
probeAccount: async ({ account }) => {
if (!account.configured || !account.ship || !account.url || !account.code) {
@@ -356,7 +359,7 @@ export const tlonPlugin: ChannelPlugin = {
await api.delete();
}
} catch (error) {
return { ok: false, error: error?.message ?? String(error) };
return { ok: false, error: (error as { message?: string })?.message ?? String(error) };
}
},
buildAccountSnapshot: ({ account, runtime, probe }) => ({
@@ -380,7 +383,7 @@ export const tlonPlugin: ChannelPlugin = {
accountId: account.accountId,
ship: account.ship,
url: account.url,
});
} as ChannelAccountSnapshot);
ctx.log?.info(`[${account.accountId}] starting Tlon provider for ${account.ship ?? "tlon"}`);
return monitorTlonProvider({
runtime: ctx.runtime,
+4 -2
View File
@@ -17,7 +17,7 @@ export async function fetchGroupChanges(
return null;
} catch (error) {
runtime.log?.(
`[tlon] Failed to fetch changes (falling back to full init): ${error?.message ?? String(error)}`,
`[tlon] Failed to fetch changes (falling back to full init): ${(error as { message?: string })?.message ?? String(error)}`,
);
return null;
}
@@ -66,7 +66,9 @@ export async function fetchAllChannels(
return channels;
} catch (error) {
runtime.log?.(`[tlon] Auto-discovery failed: ${error?.message ?? String(error)}`);
runtime.log?.(
`[tlon] Auto-discovery failed: ${(error as { message?: string })?.message ?? String(error)}`,
);
runtime.log?.(
"[tlon] To monitor group channels, add them to config: channels.tlon.groupChannels",
);
+3 -1
View File
@@ -68,7 +68,9 @@ export async function fetchChannelHistory(
runtime?.log?.(`[tlon] Extracted ${messages.length} messages from history`);
return messages;
} catch (error) {
runtime?.log?.(`[tlon] Error fetching channel history: ${error?.message ?? String(error)}`);
runtime?.log?.(
`[tlon] Error fetching channel history: ${(error as { message?: string })?.message ?? String(error)}`,
);
return [];
}
}
+42 -23
View File
@@ -18,6 +18,11 @@ import {
isSummarizationRequest,
} from "./utils.js";
function formatError(err: unknown): string {
if (err instanceof Error) return err.message;
return String(err);
}
export type MonitorTlonOpts = {
runtime?: RuntimeEnv;
abortSignal?: AbortSignal;
@@ -35,6 +40,11 @@ type UrbitMemo = {
sent?: number;
};
type UrbitSeal = {
"parent-id"?: string;
parent?: string;
};
type UrbitUpdate = {
id?: string | number;
response?: {
@@ -42,10 +52,10 @@ type UrbitUpdate = {
post?: {
id?: string | number;
"r-post"?: {
set?: { essay?: UrbitMemo };
set?: { essay?: UrbitMemo; seal?: UrbitSeal };
reply?: {
id?: string | number;
"r-reply"?: { set?: { memo?: UrbitMemo } };
"r-reply"?: { set?: { memo?: UrbitMemo; seal?: UrbitSeal } };
};
};
};
@@ -113,7 +123,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
},
});
} catch (error) {
runtime.error?.(`[tlon] Failed to authenticate: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Failed to authenticate: ${formatError(error)}`);
throw error;
}
@@ -127,7 +137,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
groupChannels = discoveredChannels;
}
} catch (error) {
runtime.error?.(`[tlon] Auto-discovery failed: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Auto-discovery failed: ${formatError(error)}`);
}
}
@@ -179,7 +189,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
timestamp: memo.sent || Date.now(),
});
} catch (error) {
runtime.error?.(`[tlon] Error handling DM: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Error handling DM: ${formatError(error)}`);
}
};
@@ -198,6 +208,9 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
}
const content = memo || essay;
if (!content) {
return;
}
const isThreadReply = Boolean(memo);
const rawMessageId = isThreadReply ? post?.reply?.id : update?.response?.post?.id;
const messageId = rawMessageId != null ? String(rawMessageId) : undefined;
@@ -260,7 +273,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
parentId,
});
} catch (error) {
runtime.error?.(`[tlon] Error handling group message: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Error handling group message: ${formatError(error)}`);
}
};
@@ -319,7 +332,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
"3. Action items if any\n" +
"4. Notable participants";
} catch (error) {
const errorMsg = `Sorry, I encountered an error while fetching the channel history: ${error?.message ?? String(error)}`;
const errorMsg = `Sorry, I encountered an error while fetching the channel history: ${formatError(error)}`;
if (isGroup && groupChannel) {
const parsed = parseChannelNest(groupChannel);
if (parsed) {
@@ -400,10 +413,15 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
const showSignature =
account.showModelSignature ?? cfg.channels?.tlon?.showModelSignature ?? false;
if (showSignature) {
const extPayload = payload as ReplyPayload & {
metadata?: { model?: string };
model?: string;
};
const extRoute = route as typeof route & { model?: string };
const modelInfo =
payload.metadata?.model ||
payload.model ||
route.model ||
extPayload.metadata?.model ||
extPayload.model ||
extRoute.model ||
cfg.agents?.defaults?.model?.primary;
replyText = `${replyText}\n\n_[Generated by ${formatModelName(modelInfo)}]_`;
}
@@ -455,7 +473,9 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
await api!.subscribe({
app: "channels",
path: `/${channelNest}`,
event: handleIncomingGroupMessage(channelNest),
event: (data: unknown) => {
handleIncomingGroupMessage(channelNest)(data as UrbitUpdate);
},
err: (error) => {
runtime.error?.(`[tlon] Group subscription error for ${channelNest}: ${String(error)}`);
},
@@ -467,9 +487,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
subscribedChannels.add(channelNest);
runtime.log?.(`[tlon] Subscribed to group channel: ${channelNest}`);
} catch (error) {
runtime.error?.(
`[tlon] Failed to subscribe to ${channelNest}: ${error?.message ?? String(error)}`,
);
runtime.error?.(`[tlon] Failed to subscribe to ${channelNest}: ${formatError(error)}`);
}
}
@@ -481,7 +499,9 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
await api!.subscribe({
app: "chat",
path: `/dm/${dmShip}`,
event: handleIncomingDM,
event: (data: unknown) => {
handleIncomingDM(data as UrbitUpdate);
},
err: (error) => {
runtime.error?.(`[tlon] DM subscription error for ${dmShip}: ${String(error)}`);
},
@@ -493,9 +513,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
subscribedDMs.add(dmShip);
runtime.log?.(`[tlon] Subscribed to DM with ${dmShip}`);
} catch (error) {
runtime.error?.(
`[tlon] Failed to subscribe to DM with ${dmShip}: ${error?.message ?? String(error)}`,
);
runtime.error?.(`[tlon] Failed to subscribe to DM with ${dmShip}: ${formatError(error)}`);
}
}
@@ -515,7 +533,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
}
}
} catch (error) {
runtime.error?.(`[tlon] Channel refresh failed: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Channel refresh failed: ${formatError(error)}`);
}
}
@@ -530,7 +548,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
runtime.log?.(`[tlon] Found ${dmShips.length} DM conversation(s)`);
}
} catch (error) {
runtime.error?.(`[tlon] Failed to fetch DM list: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Failed to fetch DM list: ${formatError(error)}`);
}
for (const dmShip of dmShips) {
@@ -549,7 +567,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
() => {
if (!opts.abortSignal?.aborted) {
refreshChannelSubscriptions().catch((error) => {
runtime.error?.(`[tlon] Channel refresh error: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Channel refresh error: ${formatError(error)}`);
});
}
},
@@ -557,8 +575,9 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
);
if (opts.abortSignal) {
const signal = opts.abortSignal;
await new Promise((resolve) => {
opts.abortSignal.addEventListener(
signal.addEventListener(
"abort",
() => {
clearInterval(pollInterval);
@@ -574,7 +593,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
try {
await api?.close();
} catch (error) {
runtime.error?.(`[tlon] Cleanup error: ${error?.message ?? String(error)}`);
runtime.error?.(`[tlon] Cleanup error: ${formatError(error)}`);
}
}
}
+1 -1
View File
@@ -67,7 +67,7 @@ export async function sendGroupMessage({
let formattedReplyId = replyToId;
if (replyToId && /^\d+$/.test(replyToId)) {
try {
formattedReplyId = formatUd(BigInt(replyToId));
formattedReplyId = scot("ud", BigInt(replyToId));
} catch {
// Fall back to raw ID if formatting fails
}
+2 -1
View File
@@ -204,7 +204,8 @@ export class UrbitSSEClient {
if (!body) {
return;
}
const stream = body instanceof ReadableStream ? Readable.fromWeb(body) : body;
// oxlint-disable-next-line typescript/no-explicit-any
const stream = body instanceof ReadableStream ? Readable.fromWeb(body as any) : body;
let buffer = "";
try {