From ace5d5ca2e685ee87a9fef3d004e4ba7ef364834 Mon Sep 17 00:00:00 2001 From: siddseethepalli Date: Tue, 24 Feb 2026 15:13:16 -0500 Subject: [PATCH] fix: resolve all CI type-check and lint errors - Add missing streamThinking to ThinkingConfigSchema default and test assertions - Fix boolean | undefined return type in contradiction-checker transaction - Wrap media-processing stage handlers to return Promise - Cast Cron through unknown for Record conversion - Update AgentLoopRun type to accept CheckpointInfo parameter - Add withSurface to ToolSetupContext test stubs - Add sessionId to ToolContext test stubs - Cast input_schema to typed interface for property access in tests - Fix fetch mock casts through unknown for Bun's preconnect property - Remove unused imports/vars and fix lint violations across 14 files Co-Authored-By: Claude --- assistant/src/__tests__/config-schema.test.ts | 4 +- .../provider-error-scenarios.test.ts | 8 ++-- .../src/__tests__/session-agent-loop.test.ts | 6 +-- .../session-tool-setup-app-refresh.test.ts | 1 + .../session-tool-setup-memory-scope.test.ts | 1 + ...ession-tool-setup-side-effect-flag.test.ts | 1 + .../src/__tests__/terminal-tools.test.ts | 28 ++++++----- assistant/src/__tests__/web-search.test.ts | 46 +++++++++---------- assistant/src/amazon/client.ts | 8 ++-- .../src/browser-extension-relay/server.ts | 2 +- assistant/src/cli/amazon.ts | 3 -- .../media-processing/services/gemini-map.ts | 2 +- .../media-processing/services/preprocess.ts | 2 +- .../tools/extract-keyframes.ts | 2 +- assistant/src/config/env-registry.ts | 10 ---- assistant/src/config/env.ts | 6 --- assistant/src/config/schema.ts | 1 + assistant/src/daemon/handlers/pairing.ts | 4 +- assistant/src/memory/contradiction-checker.ts | 2 + .../memory/job-handlers/media-processing.ts | 10 ++-- assistant/src/runtime/http-server.ts | 2 +- .../runtime/routes/channel-guardian-routes.ts | 1 - .../runtime/routes/channel-inbound-routes.ts | 3 +- assistant/src/schedule/schedule-store.ts | 2 +- assistant/src/util/log-redact.ts | 2 +- 25 files changed, 72 insertions(+), 85 deletions(-) diff --git a/assistant/src/__tests__/config-schema.test.ts b/assistant/src/__tests__/config-schema.test.ts index 4fe9a05a6a1..6088bccaa9a 100644 --- a/assistant/src/__tests__/config-schema.test.ts +++ b/assistant/src/__tests__/config-schema.test.ts @@ -76,7 +76,7 @@ describe('AssistantConfigSchema', () => { expect(result.model).toBe('claude-opus-4-6'); expect(result.maxTokens).toBe(16000); expect(result.apiKeys).toEqual({}); - expect(result.thinking).toEqual({ enabled: false, budgetTokens: 10000 }); + expect(result.thinking).toEqual({ enabled: false, budgetTokens: 10000, streamThinking: false }); expect(result.contextWindow).toEqual({ enabled: true, maxInputTokens: 180000, @@ -1194,7 +1194,7 @@ describe('loadConfig with schema validation', () => { expect(config.provider).toBe('anthropic'); expect(config.model).toBe('claude-opus-4-6'); expect(config.maxTokens).toBe(16000); - expect(config.thinking).toEqual({ enabled: false, budgetTokens: 10000 }); + expect(config.thinking).toEqual({ enabled: false, budgetTokens: 10000, streamThinking: false }); expect(config.contextWindow).toEqual({ enabled: true, maxInputTokens: 180000, diff --git a/assistant/src/__tests__/provider-error-scenarios.test.ts b/assistant/src/__tests__/provider-error-scenarios.test.ts index 470aad72d50..823a456b177 100644 --- a/assistant/src/__tests__/provider-error-scenarios.test.ts +++ b/assistant/src/__tests__/provider-error-scenarios.test.ts @@ -10,8 +10,8 @@ mock.module('../util/logger.js', () => ({ })); // Only mock sleep so retries complete instantly; keep real retry logic -mock.module('../util/retry.js', () => { - const real = require(retryModulePath); +mock.module('../util/retry.js', async () => { + const real = await import(retryModulePath); return { ...real, sleep: () => Promise.resolve(), @@ -231,7 +231,7 @@ describe('RetryProvider — network error retries', () => { const inner = makeFlaky(1, err); const provider = new RetryProvider(inner); - const result = await provider.sendMessage(MESSAGES); + const _result = await provider.sendMessage(MESSAGES); expect(inner.calls).toBe(2); }); @@ -386,7 +386,7 @@ describe('FailoverProvider — model unavailability fallback', () => { const secondary = makeProvider('secondary'); const provider = new FailoverProvider([primary, secondary]); - const result = await provider.sendMessage(MESSAGES); + const _result = await provider.sendMessage(MESSAGES); expect(primary.calls).toBe(1); expect(secondary.calls).toBe(1); }); diff --git a/assistant/src/__tests__/session-agent-loop.test.ts b/assistant/src/__tests__/session-agent-loop.test.ts index cd64d9d389f..b1dc6981938 100644 --- a/assistant/src/__tests__/session-agent-loop.test.ts +++ b/assistant/src/__tests__/session-agent-loop.test.ts @@ -1,6 +1,6 @@ import { describe, expect, mock, test, beforeEach } from 'bun:test'; import type { Message, ContentBlock } from '../providers/types.js'; -import type { AgentEvent, CheckpointDecision } from '../agent/loop.js'; +import type { AgentEvent, CheckpointDecision, CheckpointInfo } from '../agent/loop.js'; import type { ServerMessage } from '../daemon/ipc-protocol.js'; // ── Module mocks (must precede imports of the module under test) ───── @@ -212,7 +212,7 @@ type AgentLoopRun = ( onEvent: (event: AgentEvent) => void, signal?: AbortSignal, requestId?: string, - onCheckpoint?: () => CheckpointDecision, + onCheckpoint?: (checkpoint: CheckpointInfo) => CheckpointDecision, ) => Promise; function makeCtx(overrides?: Partial & { agentLoopRun?: AgentLoopRun }): AgentLoopSessionContext { @@ -811,7 +811,7 @@ describe('session-agent-loop', () => { test('drains queue after completion', async () => { let drainReason: string | undefined; const ctx = makeCtx({ - agentLoopRun: async (messages, onEvent) => { + agentLoopRun: async (messages: Message[], onEvent: (event: AgentEvent) => void) => { onEvent({ type: 'message_complete', message: { role: 'assistant', content: [{ type: 'text', text: 'ok' }] }, diff --git a/assistant/src/__tests__/session-tool-setup-app-refresh.test.ts b/assistant/src/__tests__/session-tool-setup-app-refresh.test.ts index 8564ef6fbd8..614462357be 100644 --- a/assistant/src/__tests__/session-tool-setup-app-refresh.test.ts +++ b/assistant/src/__tests__/session-tool-setup-app-refresh.test.ts @@ -68,6 +68,7 @@ function makeCtx(overrides: Partial = {}): ToolSetupContext { enqueueMessage: () => ({ queued: false, requestId: 'r' }), getQueueDepth: () => 0, processMessage: async () => '', + withSurface: async (_id: string, fn: () => T | Promise) => fn(), memoryPolicy: { scopeId: 'default', strictSideEffects: false }, ...overrides, }; diff --git a/assistant/src/__tests__/session-tool-setup-memory-scope.test.ts b/assistant/src/__tests__/session-tool-setup-memory-scope.test.ts index b7453b34b9c..0571e729dad 100644 --- a/assistant/src/__tests__/session-tool-setup-memory-scope.test.ts +++ b/assistant/src/__tests__/session-tool-setup-memory-scope.test.ts @@ -55,6 +55,7 @@ function makeCtx(overrides: Partial = {}): ToolSetupContext { enqueueMessage: () => ({ queued: false, requestId: 'r' }), getQueueDepth: () => 0, processMessage: async () => '', + withSurface: async (_id: string, fn: () => T | Promise) => fn(), memoryPolicy: { scopeId: 'default', strictSideEffects: false }, ...overrides, }; diff --git a/assistant/src/__tests__/session-tool-setup-side-effect-flag.test.ts b/assistant/src/__tests__/session-tool-setup-side-effect-flag.test.ts index b71a9becdb7..c608d37ca37 100644 --- a/assistant/src/__tests__/session-tool-setup-side-effect-flag.test.ts +++ b/assistant/src/__tests__/session-tool-setup-side-effect-flag.test.ts @@ -55,6 +55,7 @@ function makeCtx(overrides: Partial = {}): ToolSetupContext { enqueueMessage: () => ({ queued: false, requestId: 'r' }), getQueueDepth: () => 0, processMessage: async () => '', + withSurface: async (_id: string, fn: () => T | Promise) => fn(), memoryPolicy: { scopeId: 'default', strictSideEffects: false }, ...overrides, }; diff --git a/assistant/src/__tests__/terminal-tools.test.ts b/assistant/src/__tests__/terminal-tools.test.ts index a0e563e87d2..93f4fb36cbb 100644 --- a/assistant/src/__tests__/terminal-tools.test.ts +++ b/assistant/src/__tests__/terminal-tools.test.ts @@ -639,6 +639,7 @@ describe('Shell tool input validation', () => { const baseContext = { workingDir: testTmpDir, + sessionId: 'test-session-1', conversationId: 'test-conv-1', onOutput: () => {}, }; @@ -702,13 +703,14 @@ describe('Shell tool input validation', () => { test('tool definition includes required schema fields', () => { const def = shellTool.getDefinition(); + const schema = def.input_schema as { required: string[]; properties: Record }; expect(def.name).toBe('bash'); - expect(def.input_schema.required).toContain('command'); - expect(def.input_schema.required).toContain('reason'); - expect(def.input_schema.properties.command).toBeDefined(); - expect(def.input_schema.properties.timeout_seconds).toBeDefined(); - expect(def.input_schema.properties.network_mode).toBeDefined(); - expect(def.input_schema.properties.credential_ids).toBeDefined(); + expect(schema.required).toContain('command'); + expect(schema.required).toContain('reason'); + expect(schema.properties.command).toBeDefined(); + expect(schema.properties.timeout_seconds).toBeDefined(); + expect(schema.properties.network_mode).toBeDefined(); + expect(schema.properties.credential_ids).toBeDefined(); }); }); @@ -786,6 +788,7 @@ describe('EvaluateTypescriptTool input validation', () => { const baseContext = { workingDir: testTmpDir, + sessionId: 'test-session-1', conversationId: 'test-conv-1', onOutput: () => {}, }; @@ -831,12 +834,13 @@ describe('EvaluateTypescriptTool input validation', () => { test('tool definition has correct name and schema', () => { const def = evalTool.getDefinition(); + const schema = def.input_schema as { required: string[]; properties: Record }; expect(def.name).toBe('evaluate_typescript_code'); - expect(def.input_schema.required).toContain('code'); - expect(def.input_schema.properties.code).toBeDefined(); - expect(def.input_schema.properties.mock_input_json).toBeDefined(); - expect(def.input_schema.properties.timeout_seconds).toBeDefined(); - expect(def.input_schema.properties.filename).toBeDefined(); - expect(def.input_schema.properties.entrypoint).toBeDefined(); + expect(schema.required).toContain('code'); + expect(schema.properties.code).toBeDefined(); + expect(schema.properties.mock_input_json).toBeDefined(); + expect(schema.properties.timeout_seconds).toBeDefined(); + expect(schema.properties.filename).toBeDefined(); + expect(schema.properties.entrypoint).toBeDefined(); }); }); diff --git a/assistant/src/__tests__/web-search.test.ts b/assistant/src/__tests__/web-search.test.ts index 278255187f8..4ed4285d216 100644 --- a/assistant/src/__tests__/web-search.test.ts +++ b/assistant/src/__tests__/web-search.test.ts @@ -44,7 +44,7 @@ describe('WebSearchTool', () => { globalThis.fetch = (async () => { fetchCalled = true; return new Response('{}', { status: 200 }); - }) as typeof fetch; + }) as unknown as typeof fetch; process.env.BRAVE_API_KEY = 'test-key'; @@ -73,7 +73,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }); - }) as typeof fetch; + }) as unknown as typeof fetch; await executeWebSearch({ query: 'test', count: 50 }, 'test-key', 'brave'); expect(capturedUrl).toContain('count=20'); @@ -90,7 +90,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }); - }) as typeof fetch; + }) as unknown as typeof fetch; await executeWebSearch({ query: 'test', offset: 20 }, 'test-key', 'brave'); expect(capturedUrl).toContain('offset=9'); @@ -104,7 +104,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }); - }) as typeof fetch; + }) as unknown as typeof fetch; await executeWebSearch({ query: 'test', freshness: 'pw' }, 'test-key', 'brave'); expect(capturedUrl).toContain('freshness=pw'); @@ -118,7 +118,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }); - }) as typeof fetch; + }) as unknown as typeof fetch; await executeWebSearch({ query: 'test', freshness: 'invalid' }, 'test-key', 'brave'); expect(capturedUrl).not.toContain('freshness'); @@ -141,7 +141,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'test-key', 'brave'); expect(result.isError).toBe(false); @@ -158,7 +158,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'noresults' }, 'test-key', 'brave'); expect(result.isError).toBe(false); @@ -171,7 +171,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'empty' }, 'test-key', 'brave'); expect(result.isError).toBe(false); @@ -181,7 +181,7 @@ describe('WebSearchTool', () => { test('handles 401 unauthorized', async () => { globalThis.fetch = (async () => new Response('Unauthorized', { status: 401 }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'bad-key', 'brave'); expect(result.isError).toBe(true); @@ -199,7 +199,7 @@ describe('WebSearchTool', () => { JSON.stringify({ web: { results: [{ title: 'Result', url: 'https://example.com', description: 'Found it' }] } }), { status: 200, headers: { 'Content-Type': 'application/json' } }, ); - }) as typeof fetch; + }) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'test-key', 'brave'); expect(result.isError).toBe(false); @@ -210,7 +210,7 @@ describe('WebSearchTool', () => { test('returns error after exhausting 429 retries', async () => { globalThis.fetch = (async () => new Response('Too Many Requests', { status: 429 }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'test-key', 'brave'); expect(result.isError).toBe(true); @@ -234,7 +234,7 @@ describe('WebSearchTool', () => { JSON.stringify({ web: { results: [] } }), { status: 200, headers: { 'Content-Type': 'application/json' } }, ); - }) as typeof fetch; + }) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'test-key', 'brave'); expect(result.isError).toBe(false); @@ -244,7 +244,7 @@ describe('WebSearchTool', () => { test('handles network errors', async () => { globalThis.fetch = (async () => { throw new Error('Network unreachable'); - }) as typeof fetch; + }) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'test-key', 'brave'); expect(result.isError).toBe(true); @@ -261,7 +261,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }); - }) as typeof fetch; + }) as unknown as typeof fetch; await executeWebSearch({ query: 'test' }, 'my-api-key', 'brave'); expect(capturedHeaders['X-Subscription-Token']).toBe('my-api-key'); @@ -287,7 +287,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'test-key', 'brave'); expect(result.isError).toBe(false); @@ -308,7 +308,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'pplx-key', 'perplexity'); expect(result.isError).toBe(false); @@ -327,7 +327,7 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'noresults' }, 'pplx-key', 'perplexity'); expect(result.isError).toBe(false); @@ -337,7 +337,7 @@ describe('WebSearchTool', () => { test('handles 401 unauthorized', async () => { globalThis.fetch = (async () => new Response('Unauthorized', { status: 401 }) - ) as typeof fetch; + ) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'bad-key', 'perplexity'); expect(result.isError).toBe(true); @@ -346,7 +346,7 @@ describe('WebSearchTool', () => { test('sends correct headers', async () => { let capturedHeaders: Record = {}; - let capturedBody: Record; + let capturedBody: Record = {}; globalThis.fetch = (async (_url: string, init: RequestInit) => { capturedHeaders = Object.fromEntries( Object.entries(init.headers as Record), @@ -356,13 +356,13 @@ describe('WebSearchTool', () => { status: 200, headers: { 'Content-Type': 'application/json' }, }); - }) as typeof fetch; + }) as unknown as typeof fetch; await executeWebSearch({ query: 'test query' }, 'pplx-my-key', 'perplexity'); expect(capturedHeaders['Authorization']).toBe('Bearer pplx-my-key'); expect(capturedHeaders['Content-Type']).toBe('application/json'); expect(capturedBody.model).toBe('sonar'); - expect(capturedBody.messages[0].content).toBe('test query'); + expect((capturedBody.messages as Array<{ content: string }>)[0].content).toBe('test query'); }); test('retries on 429 and succeeds', async () => { @@ -376,7 +376,7 @@ describe('WebSearchTool', () => { JSON.stringify({ choices: [{ message: { content: 'Found it' } }] }), { status: 200, headers: { 'Content-Type': 'application/json' } }, ); - }) as typeof fetch; + }) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'pplx-key', 'perplexity'); expect(result.isError).toBe(false); @@ -387,7 +387,7 @@ describe('WebSearchTool', () => { test('handles network errors', async () => { globalThis.fetch = (async () => { throw new Error('Network unreachable'); - }) as typeof fetch; + }) as unknown as typeof fetch; const result = await executeWebSearch({ query: 'test' }, 'pplx-key', 'perplexity'); expect(result.isError).toBe(true); diff --git a/assistant/src/amazon/client.ts b/assistant/src/amazon/client.ts index f70d3f08b8d..eb7264b51fd 100644 --- a/assistant/src/amazon/client.ts +++ b/assistant/src/amazon/client.ts @@ -54,7 +54,7 @@ import { } from './session.js'; import type { ExtractedCredential } from '../tools/browser/network-recording-types.js'; import { extensionRelayServer } from '../browser-extension-relay/server.js'; -import type { ExtensionResponse } from '../browser-extension-relay/protocol.js'; +import type { ExtensionCommand, ExtensionResponse } from '../browser-extension-relay/protocol.js'; import { readHttpToken } from '../util/platform.js'; import { getRuntimeHttpPort } from '../config/env.js'; @@ -72,7 +72,7 @@ async function sendRelayCommand(command: Record): Promise); } // Fall back to HTTP relay endpoint on the daemon @@ -163,7 +163,7 @@ async function findAmazonTab(): Promise { let lastCookieSyncTime = 0; const COOKIE_SYNC_INTERVAL = 60_000; // re-sync at most once per minute -async function syncCookiesToBrowser(cookies: ExtractedCredential[]): Promise { +async function _syncCookiesToBrowser(cookies: ExtractedCredential[]): Promise { const now = Date.now(); if (now - lastCookieSyncTime < COOKIE_SYNC_INTERVAL) return; @@ -212,7 +212,7 @@ async function cdpEval(tabId: number, script: string): Promise { } const value = resp.result; - if (value === undefined || value === null) { + if (value == null) { throw new Error('Empty browser eval response'); } diff --git a/assistant/src/browser-extension-relay/server.ts b/assistant/src/browser-extension-relay/server.ts index 58dbaa916b9..f0763f36a33 100644 --- a/assistant/src/browser-extension-relay/server.ts +++ b/assistant/src/browser-extension-relay/server.ts @@ -147,7 +147,7 @@ export class ExtensionRelayServer { getStatus(): ExtensionRelayStatus { return { - connected: this.ws !== null, + connected: !!this.ws, connectionId: this.connectionId, lastHeartbeatAt: this.lastHeartbeatAt, pendingCommandCount: this.pendingCommands.size, diff --git a/assistant/src/cli/amazon.ts b/assistant/src/cli/amazon.ts index 3a054271e9b..fda62cd9473 100644 --- a/assistant/src/cli/amazon.ts +++ b/assistant/src/cli/amazon.ts @@ -17,12 +17,9 @@ import { extractRequests, saveRequests, } from '../amazon/request-extractor.js'; -import { NetworkRecorder } from '../tools/browser/network-recorder.js'; import { - saveRecording, loadRecording, } from '../tools/browser/recording-store.js'; -import type { SessionRecording } from '../tools/browser/network-recording-types.js'; import { search, getProductDetails, diff --git a/assistant/src/config/bundled-skills/media-processing/services/gemini-map.ts b/assistant/src/config/bundled-skills/media-processing/services/gemini-map.ts index 9f8ca4c70b5..db4f7fa0b43 100644 --- a/assistant/src/config/bundled-skills/media-processing/services/gemini-map.ts +++ b/assistant/src/config/bundled-skills/media-processing/services/gemini-map.ts @@ -13,7 +13,7 @@ import { GoogleGenAI, ApiError } from '@google/genai'; import { ConcurrencyPool } from './concurrency-pool.js'; import { CostTracker, type CostSummary } from './cost-tracker.js'; import { computeRetryDelay, sleep } from '../../../../util/retry.js'; -import type { Segment, SubjectRegistry } from './preprocess.js'; +import type { Segment } from './preprocess.js'; // --------------------------------------------------------------------------- // Types diff --git a/assistant/src/config/bundled-skills/media-processing/services/preprocess.ts b/assistant/src/config/bundled-skills/media-processing/services/preprocess.ts index 4dbf67e803a..4cf7f2272b4 100644 --- a/assistant/src/config/bundled-skills/media-processing/services/preprocess.ts +++ b/assistant/src/config/bundled-skills/media-processing/services/preprocess.ts @@ -424,7 +424,7 @@ export async function preprocessForAsset( for (const seg of rawSegments) { const segDuration = seg.endSeconds - seg.startSeconds; const effectiveInterval = computeEffectiveInterval(segDuration, config.intervalSeconds); - const frameTimestamps = generateFrameTimestamps(seg.startSeconds, seg.endSeconds, config.intervalSeconds); + const _frameTimestamps = generateFrameTimestamps(seg.startSeconds, seg.endSeconds, config.intervalSeconds); const segTempDir = join(tempDir, seg.id); await mkdir(segTempDir, { recursive: true }); diff --git a/assistant/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts b/assistant/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts index f07116eecf4..d3dd35d3cea 100644 --- a/assistant/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +++ b/assistant/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts @@ -1,7 +1,7 @@ import { join, dirname } from 'node:path'; import type { ToolContext, ToolExecutionResult } from '../../../../tools/types.js'; import { getMediaAssetById, getKeyframesForAsset } from '../../../../memory/media-store.js'; -import { preprocessForAsset, type PreprocessOptions, type PreprocessManifest } from '../services/preprocess.js'; +import { preprocessForAsset, type PreprocessOptions } from '../services/preprocess.js'; export { preprocessForAsset } from '../services/preprocess.js'; diff --git a/assistant/src/config/env-registry.ts b/assistant/src/config/env-registry.ts index 8663f74d95a..936170bc9f4 100644 --- a/assistant/src/config/env-registry.ts +++ b/assistant/src/config/env-registry.ts @@ -31,16 +31,6 @@ function flagTriState(name: string): boolean | undefined { return undefined; } -function int(name: string, fallback: number): number; -function int(name: string): number | undefined; -function int(name: string, fallback?: number): number | undefined { - const raw = str(name); - if (!raw) return fallback; - const n = parseInt(raw, 10); - if (isNaN(n)) return fallback; - return n; -} - // ── Registry ───────────────────────────────────────────────────────────────── // Each entry documents the env var name, type, default, and purpose. diff --git a/assistant/src/config/env.ts b/assistant/src/config/env.ts index 40692f38c74..def2bccdb56 100644 --- a/assistant/src/config/env.ts +++ b/assistant/src/config/env.ts @@ -40,12 +40,6 @@ function int(name: string, fallback?: number): number | undefined { return n; } -/** Read an env var as a boolean flag ('true'/'1' → true, everything else → false). */ -function flag(name: string): boolean { - const raw = str(name); - return raw === 'true' || raw === '1'; -} - // ── Gateway ────────────────────────────────────────────────────────────────── const DEFAULT_GATEWAY_PORT = 7830; diff --git a/assistant/src/config/schema.ts b/assistant/src/config/schema.ts index a63391da353..04e38341b9e 100644 --- a/assistant/src/config/schema.ts +++ b/assistant/src/config/schema.ts @@ -176,6 +176,7 @@ export const AssistantConfigSchema = z.object({ thinking: ThinkingConfigSchema.default({ enabled: false, budgetTokens: 10000, + streamThinking: false, }), contextWindow: ContextWindowConfigSchema.default({ enabled: true, diff --git a/assistant/src/daemon/handlers/pairing.ts b/assistant/src/daemon/handlers/pairing.ts index 4d5dfd7c876..899b88ad1a8 100644 --- a/assistant/src/daemon/handlers/pairing.ts +++ b/assistant/src/daemon/handlers/pairing.ts @@ -5,9 +5,7 @@ import type { } from '../ipc-protocol.js'; import { log, defineHandlers, type HandlerContext } from './shared.js'; import { - isDeviceApproved, approveDevice, - refreshDevice, removeDevice, clearAllDevices, listDevices, @@ -26,7 +24,7 @@ export function initPairingHandlers(store: PairingStore, bearerToken: string | u function handlePairingApprovalResponse( msg: PairingApprovalResponse, _socket: net.Socket, - ctx: HandlerContext, + _ctx: HandlerContext, ): void { if (!pairingStoreRef) { log.warn('Pairing store not initialized'); diff --git a/assistant/src/memory/contradiction-checker.ts b/assistant/src/memory/contradiction-checker.ts index caebe876409..bc1a8e67767 100644 --- a/assistant/src/memory/contradiction-checker.ts +++ b/assistant/src/memory/contradiction-checker.ts @@ -364,6 +364,8 @@ function handleRelationship( }); return true; } + default: + return false; } }).immediate(); } diff --git a/assistant/src/memory/job-handlers/media-processing.ts b/assistant/src/memory/job-handlers/media-processing.ts index aedcff7f376..f681a84325c 100644 --- a/assistant/src/memory/job-handlers/media-processing.ts +++ b/assistant/src/memory/job-handlers/media-processing.ts @@ -36,14 +36,14 @@ export async function mediaProcessingJob(job: MemoryJob): Promise { } const handlers: Record = { - preprocess: { execute: (assetId, onProgress) => preprocessForAsset(assetId, {}, onProgress) }, - map: { execute: (assetId, onProgress) => mapSegmentsForAsset(assetId, { + preprocess: { execute: async (assetId, onProgress) => { await preprocessForAsset(assetId, {}, onProgress); } }, + map: { execute: async (assetId, onProgress) => { await mapSegmentsForAsset(assetId, { systemPrompt: 'Describe what you see in these video frames. For each frame, note: subjects present, actions occurring, scene context, and any text visible.', outputSchema: { type: 'object', properties: { frames: { type: 'array', items: { type: 'object', properties: { timestamp: { type: 'number' }, subjects: { type: 'array', items: { type: 'string' } }, actions: { type: 'array', items: { type: 'string' } }, scene: { type: 'string' }, text: { type: 'string' } } } } } } - }, onProgress) }, - reduce: { execute: (assetId, onProgress) => reduceForAsset(assetId, { + }, onProgress); } }, + reduce: { execute: async (assetId, onProgress) => { await reduceForAsset(assetId, { systemPrompt: 'Summarize the video content based on the structured observations.', - }, onProgress) }, + }, onProgress); } }, }; const result = await runPipeline(mediaAssetId, handlers, { diff --git a/assistant/src/runtime/http-server.ts b/assistant/src/runtime/http-server.ts index 1b3b4f5679b..bd9d5834f15 100644 --- a/assistant/src/runtime/http-server.ts +++ b/assistant/src/runtime/http-server.ts @@ -499,7 +499,7 @@ export class RuntimeHttpServer { if (endpoint === 'browser-relay/command' && req.method === 'POST') { try { const body = await req.json() as Record; - const resp = await extensionRelayServer.sendCommand(body as any); + const resp = await extensionRelayServer.sendCommand(body as Omit); return Response.json(resp); } catch (err) { return Response.json({ success: false, error: err instanceof Error ? err.message : String(err) }, { status: 500 }); diff --git a/assistant/src/runtime/routes/channel-guardian-routes.ts b/assistant/src/runtime/routes/channel-guardian-routes.ts index d0ac925bfb3..3547e6e9ec1 100644 --- a/assistant/src/runtime/routes/channel-guardian-routes.ts +++ b/assistant/src/runtime/routes/channel-guardian-routes.ts @@ -39,7 +39,6 @@ import { parseCallbackData, requiredDecisionKeywords, buildGuardianDenyContext, - buildPromptDeliveryFailureContext, } from './channel-route-shared.js'; import { schedulePostDecisionDelivery } from './channel-delivery-routes.js'; diff --git a/assistant/src/runtime/routes/channel-inbound-routes.ts b/assistant/src/runtime/routes/channel-inbound-routes.ts index b49801f8b58..5e8ff3dda07 100644 --- a/assistant/src/runtime/routes/channel-inbound-routes.ts +++ b/assistant/src/runtime/routes/channel-inbound-routes.ts @@ -44,7 +44,6 @@ import type { ApprovalCopyGenerator, ApprovalConversationGenerator, } from '../http-types.js'; -import type { GuardianRuntimeContext } from '../../daemon/session-runtime-assembly.js'; import { composeApprovalMessageGenerative } from '../approval-message-composer.js'; import { refreshThreadEscalation } from '../../memory/inbox-escalation-projection.js'; import { @@ -58,7 +57,7 @@ import { RUN_POLL_INTERVAL_MS, getEffectivePollMaxWait, } from './channel-route-shared.js'; -import { deliverReplyViaCallback, schedulePostDecisionDelivery } from './channel-delivery-routes.js'; +import { deliverReplyViaCallback } from './channel-delivery-routes.js'; import { handleApprovalInterception, deliverGeneratedApprovalPrompt } from './channel-guardian-routes.js'; const log = getLogger('runtime-http'); diff --git a/assistant/src/schedule/schedule-store.ts b/assistant/src/schedule/schedule-store.ts index 42e46b240f7..b977ef643df 100644 --- a/assistant/src/schedule/schedule-store.ts +++ b/assistant/src/schedule/schedule-store.ts @@ -362,7 +362,7 @@ export function describeCronExpression(expr: string): string { const cron = new Cron(expr, { maxRuns: 0 }); // Access Croner internal state to extract the parsed cron pattern. // This is fragile but necessary — Croner doesn't expose a public API for this. - const cronInternal = cron as Record; + const cronInternal = cron as unknown as Record; const states = cronInternal._states; if (!states || typeof states !== 'object') return expr; const p = (states as Record).pattern; diff --git a/assistant/src/util/log-redact.ts b/assistant/src/util/log-redact.ts index f30d8e6564e..a949fb0d2c7 100644 --- a/assistant/src/util/log-redact.ts +++ b/assistant/src/util/log-redact.ts @@ -89,7 +89,7 @@ function redactValue(value: unknown, depth: number): unknown { return value.map((item) => redactValue(item, depth + 1)); } - if (value !== null && typeof value === 'object') { + if (value != null && typeof value === 'object') { const result: Record = {}; for (const [key, val] of Object.entries(value as Record)) { const lowerKey = key.toLowerCase();