diff --git a/CHANGELOG.md b/CHANGELOG.md index c775398c5..fd039894a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ - Control UI: show/patch per-session reasoning level and render extracted reasoning in chat. - Control UI: queue outgoing chat messages, add Enter-to-send, and show queued items. (#527) — thanks @YuriNachos - Control UI: drop explicit `ui:install` step; `ui:build` now auto-installs UI deps (docs + update flow). +- Control UI: default control UI asset base to relative paths for subpath hosting. (#569) — thanks @bjesuiter - Telegram: retry long-polling conflicts with backoff to avoid fatal exits. - Telegram: fix grammY fetch type mismatch when injecting `fetch`. (#512) — thanks @YuriNachos - WhatsApp: resolve @lid JIDs via Baileys mapping to unblock inbound messages. (#415) diff --git a/src/agents/sandbox-agent-config.test.ts b/src/agents/sandbox-agent-config.test.ts index d233b451c..c9ae71b4f 100644 --- a/src/agents/sandbox-agent-config.test.ts +++ b/src/agents/sandbox-agent-config.test.ts @@ -80,7 +80,7 @@ describe("Agent-specific sandbox config", () => { expect(context).toBeDefined(); expect(context?.enabled).toBe(true); - }); + }, 20000); it("should allow agent-specific docker setupCommand overrides", async () => { const { resolveSandboxContext } = await import("./sandbox.js"); diff --git a/src/cli/gateway-cli.ts b/src/cli/gateway-cli.ts index 86776d28d..6ec9e8ec3 100644 --- a/src/cli/gateway-cli.ts +++ b/src/cli/gateway-cli.ts @@ -179,14 +179,22 @@ async function ensureDevGatewayConfig(opts: { reset?: boolean }) { mode: "local", bind: "loopback", }, - agent: { - workspace, - skipBootstrap: true, - }, - identity: { - name: DEV_IDENTITY_NAME, - theme: DEV_IDENTITY_THEME, - emoji: DEV_IDENTITY_EMOJI, + agents: { + defaults: { + workspace, + skipBootstrap: true, + }, + list: [ + { + id: "main", + default: true, + identity: { + name: DEV_IDENTITY_NAME, + theme: DEV_IDENTITY_THEME, + emoji: DEV_IDENTITY_EMOJI, + }, + }, + ], }, }); await ensureDevWorkspace(workspace); diff --git a/src/commands/doctor.test.ts b/src/commands/doctor.test.ts index 468548e55..a8e47bc29 100644 --- a/src/commands/doctor.test.ts +++ b/src/commands/doctor.test.ts @@ -289,7 +289,7 @@ describe("doctor", () => { "+15555550123", ]); expect(written.routing).toBeUndefined(); - }); + }, 20000); it("migrates legacy Clawdis services", async () => { readConfigFileSnapshot.mockResolvedValue({ diff --git a/src/commands/onboard-auth.ts b/src/commands/onboard-auth.ts index 14325ff20..1a006f307 100644 --- a/src/commands/onboard-auth.ts +++ b/src/commands/onboard-auth.ts @@ -10,12 +10,6 @@ const DEFAULT_MINIMAX_CONTEXT_WINDOW = 200000; const DEFAULT_MINIMAX_MAX_TOKENS = 8192; export const MINIMAX_HOSTED_MODEL_REF = `minimax/${MINIMAX_HOSTED_MODEL_ID}`; -const DEFAULT_MINIMAX_BASE_URL = "https://api.minimax.io/v1"; -export const MINIMAX_HOSTED_MODEL_ID = "MiniMax-M2.1"; -const DEFAULT_MINIMAX_CONTEXT_WINDOW = 200000; -const DEFAULT_MINIMAX_MAX_TOKENS = 8192; -export const MINIMAX_HOSTED_MODEL_REF = `minimax/${MINIMAX_HOSTED_MODEL_ID}`; - export async function writeOAuthCredentials( provider: OAuthProvider, creds: OAuthCredentials, @@ -176,7 +170,7 @@ export function applyMinimaxHostedProviderConfig( cfg: ClawdbotConfig, params?: { baseUrl?: string }, ): ClawdbotConfig { - const models = { ...cfg.agent?.models }; + const models = { ...cfg.agents?.defaults?.models }; models[MINIMAX_HOSTED_MODEL_REF] = { ...models[MINIMAX_HOSTED_MODEL_REF], alias: models[MINIMAX_HOSTED_MODEL_REF]?.alias ?? "Minimax", @@ -212,9 +206,12 @@ export function applyMinimaxHostedProviderConfig( return { ...cfg, - agent: { - ...cfg.agent, - models, + agents: { + ...cfg.agents, + defaults: { + ...cfg.agents?.defaults, + models, + }, }, models: { mode: cfg.models?.mode ?? "merge", @@ -254,17 +251,21 @@ export function applyMinimaxHostedConfig( const next = applyMinimaxHostedProviderConfig(cfg, params); return { ...next, - agent: { - ...next.agent, - model: { - ...(next.agent?.model && - "fallbacks" in (next.agent.model as Record) - ? { - fallbacks: (next.agent.model as { fallbacks?: string[] }) - .fallbacks, - } - : undefined), - primary: MINIMAX_HOSTED_MODEL_REF, + agents: { + ...next.agents, + defaults: { + ...next.agents?.defaults, + model: { + ...(next.agents?.defaults?.model && + "fallbacks" in (next.agents.defaults.model as Record) + ? { + fallbacks: ( + next.agents.defaults.model as { fallbacks?: string[] } + ).fallbacks, + } + : undefined), + primary: MINIMAX_HOSTED_MODEL_REF, + }, }, }, }; diff --git a/src/commands/onboard-providers.ts b/src/commands/onboard-providers.ts index 23dc60e22..dd08e30cf 100644 --- a/src/commands/onboard-providers.ts +++ b/src/commands/onboard-providers.ts @@ -546,7 +546,8 @@ async function promptWhatsAppAllowFrom( "WhatsApp number", ); const entry = await prompter.text({ - message: "Your personal WhatsApp number (the phone you will message from)", + message: + "Your personal WhatsApp number (the phone you will message from)", placeholder: "+15555550123", initialValue: existingAllowFrom[0], validate: (value) => { @@ -613,7 +614,8 @@ async function promptWhatsAppAllowFrom( "WhatsApp number", ); const entry = await prompter.text({ - message: "Your personal WhatsApp number (the phone you will message from)", + message: + "Your personal WhatsApp number (the phone you will message from)", placeholder: "+15555550123", initialValue: existingAllowFrom[0], validate: (value) => { diff --git a/src/config/types.ts b/src/config/types.ts index e09d1af69..6ef516b8a 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -1202,7 +1202,7 @@ export type AgentDefaultsConfig = { every?: string; /** Heartbeat model override (provider/model). */ model?: string; - /** Delivery target (last|whatsapp|telegram|discord|signal|imessage|none). */ + /** Delivery target (last|whatsapp|telegram|discord|slack|signal|imessage|msteams|none). */ target?: | "last" | "whatsapp" @@ -1211,6 +1211,7 @@ export type AgentDefaultsConfig = { | "slack" | "signal" | "imessage" + | "msteams" | "none"; /** Optional delivery override (E.164 for WhatsApp, chat id for Telegram). */ to?: string; diff --git a/src/config/zod-schema.ts b/src/config/zod-schema.ts index b29c19e3b..5ec335f54 100644 --- a/src/config/zod-schema.ts +++ b/src/config/zod-schema.ts @@ -603,6 +603,7 @@ const HeartbeatSchema = z z.literal("slack"), z.literal("signal"), z.literal("imessage"), + z.literal("msteams"), z.literal("none"), ]) .optional(), diff --git a/src/msteams/monitor.ts b/src/msteams/monitor.ts index a137cd190..c9bf23bf2 100644 --- a/src/msteams/monitor.ts +++ b/src/msteams/monitor.ts @@ -56,8 +56,9 @@ export async function monitorMSTeamsProvider( const textLimit = resolveTextChunkLimit(cfg, "msteams"); const MB = 1024 * 1024; const mediaMaxBytes = - typeof cfg.agent?.mediaMaxMb === "number" && cfg.agent.mediaMaxMb > 0 - ? Math.floor(cfg.agent.mediaMaxMb * MB) + typeof cfg.agents?.defaults?.mediaMaxMb === "number" && + cfg.agents.defaults.mediaMaxMb > 0 + ? Math.floor(cfg.agents.defaults.mediaMaxMb * MB) : 8 * MB; const conversationStore = opts.conversationStore ?? createMSTeamsConversationStoreFs(); diff --git a/src/telegram/send.ts b/src/telegram/send.ts index 2464d5b5e..5309a5f89 100644 --- a/src/telegram/send.ts +++ b/src/telegram/send.ts @@ -122,9 +122,7 @@ export async function sendMessageTelegram( const client: ApiClientOptions | undefined = fetchImpl ? { fetch: fetchImpl as unknown as ApiClientOptions["fetch"] } : undefined; - const api = - opts.api ?? - new Bot(token, client ? { client } : undefined).api; + const api = opts.api ?? new Bot(token, client ? { client } : undefined).api; const mediaUrl = opts.mediaUrl?.trim(); // Build optional params for forum topics and reply threading. @@ -296,9 +294,7 @@ export async function reactMessageTelegram( const client: ApiClientOptions | undefined = fetchImpl ? { fetch: fetchImpl as unknown as ApiClientOptions["fetch"] } : undefined; - const api = - opts.api ?? - new Bot(token, client ? { client } : undefined).api; + const api = opts.api ?? new Bot(token, client ? { client } : undefined).api; const request = createTelegramRetryRunner({ retry: opts.retry, configRetry: account.config.retry, diff --git a/src/telegram/webhook-set.ts b/src/telegram/webhook-set.ts index 69609bcd6..eced660e6 100644 --- a/src/telegram/webhook-set.ts +++ b/src/telegram/webhook-set.ts @@ -11,10 +11,7 @@ export async function setTelegramWebhook(opts: { const client: ApiClientOptions | undefined = fetchImpl ? { fetch: fetchImpl as unknown as ApiClientOptions["fetch"] } : undefined; - const bot = new Bot( - opts.token, - client ? { client } : undefined, - ); + const bot = new Bot(opts.token, client ? { client } : undefined); await bot.api.setWebhook(opts.url, { secret_token: opts.secret, drop_pending_updates: opts.dropPendingUpdates ?? false, @@ -26,9 +23,6 @@ export async function deleteTelegramWebhook(opts: { token: string }) { const client: ApiClientOptions | undefined = fetchImpl ? { fetch: fetchImpl as unknown as ApiClientOptions["fetch"] } : undefined; - const bot = new Bot( - opts.token, - client ? { client } : undefined, - ); + const bot = new Bot(opts.token, client ? { client } : undefined); await bot.api.deleteWebhook(); }