fix: clean up iMessage adapter type compatibility

Replace `as never` cast with proper polyfill for channelIdFromThreadId.
Narrow GatewayAdapter cast to only the gateway code path in bridge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-04-09 11:42:49 +03:00
parent 9486d56b01
commit 2b64fec0e6
2 changed files with 11 additions and 6 deletions

View File

@@ -31,7 +31,7 @@ interface GatewayAdapter extends Adapter {
}
export interface ChatSdkBridgeConfig {
adapter: GatewayAdapter;
adapter: Adapter;
concurrency?: ConcurrencyStrategy;
/** Bot token for authenticating forwarded Gateway events (required for interaction handling). */
botToken?: string;
@@ -114,17 +114,18 @@ export function createChatSdkBridge(config: ChatSdkBridgeConfig): ChannelAdapter
await chat.initialize();
// Start Gateway listener for adapters that support it (e.g., Discord)
if (adapter.startGatewayListener) {
const gatewayAdapter = adapter as GatewayAdapter;
if (gatewayAdapter.startGatewayListener) {
gatewayAbort = new AbortController();
// Start local HTTP server to receive forwarded Gateway events (including interactions)
const webhookUrl = await startLocalWebhookServer(adapter, setupConfig, config.botToken);
const webhookUrl = await startLocalWebhookServer(gatewayAdapter, setupConfig, config.botToken);
const startGateway = () => {
if (gatewayAbort?.signal.aborted) return;
// Capture the long-running listener promise via waitUntil
let listenerPromise: Promise<unknown> | undefined;
adapter.startGatewayListener!(
gatewayAdapter.startGatewayListener!(
{
waitUntil: (p: Promise<unknown>) => {
listenerPromise = p;

View File

@@ -15,11 +15,15 @@ registerChannelAdapter('imessage', {
const isLocal = env.IMESSAGE_LOCAL !== 'false';
if (isLocal && !env.IMESSAGE_ENABLED) return null;
if (!isLocal && !env.IMESSAGE_SERVER_URL) return null;
const imessageAdapter = createiMessageAdapter({
const rawAdapter = createiMessageAdapter({
local: isLocal,
serverUrl: env.IMESSAGE_SERVER_URL,
apiKey: env.IMESSAGE_API_KEY,
});
return createChatSdkBridge({ adapter: imessageAdapter as never, concurrency: 'concurrent' });
// Polyfill channelIdFromThreadId (community adapter doesn't implement it)
const imessageAdapter = Object.assign(rawAdapter, {
channelIdFromThreadId: (threadId: string) => threadId,
});
return createChatSdkBridge({ adapter: imessageAdapter, concurrency: 'concurrent' });
},
});