@wrongstack/runtime 0.277.1 → 0.280.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/host.ts","../src/container.ts","../src/vision.ts","../src/clipboard.ts","../src/fleet/light-subagent-factory.ts"],"names":["fs","os","path2","TOKENS"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n Agent,\n Context,\n EventBus,\n ExtensionRegistry,\n PluginAPI,\n ProviderRegistry,\n SessionWriter,\n SlashCommandRegistry,\n ToolRegistry,\n} from '@wrongstack/core';\nimport type { WrongStackPack } from './pack.js';\n\nexport interface RuntimeHost {\n agent: Agent;\n context: Context;\n events: EventBus;\n tools: ToolRegistry;\n providers: ProviderRegistry;\n slashCommands: SlashCommandRegistry;\n session: SessionWriter;\n extensions?: ExtensionRegistry | undefined;\n shutdown(): Promise<void>;\n}\n\nexport interface RuntimeHostParts {\n agent: Agent;\n context: Context;\n events: EventBus;\n tools: ToolRegistry;\n providers: ProviderRegistry;\n slashCommands: SlashCommandRegistry;\n session: SessionWriter;\n extensions?: ExtensionRegistry | undefined;\n shutdown?: (() => void | Promise<void>) | undefined;\n}\n\nexport function createRuntimeHostFromParts(parts: RuntimeHostParts): RuntimeHost {\n return {\n agent: parts.agent,\n context: parts.context,\n events: parts.events,\n tools: parts.tools,\n providers: parts.providers,\n slashCommands: parts.slashCommands,\n session: parts.session,\n extensions: parts.extensions,\n async shutdown() {\n await parts.shutdown?.();\n },\n };\n}\n\nexport interface ApplyPackOptions {\n owner?: string | undefined;\n api?: PluginAPI | undefined;\n}\n\nexport interface AppliedPack {\n pack: WrongStackPack;\n owner: string;\n teardown(): Promise<void>;\n}\n\nexport async function applyWrongStackPack(\n host: Pick<RuntimeHost, 'tools' | 'providers' | 'slashCommands'> & {\n extensions?: ExtensionRegistry | undefined;\n },\n pack: WrongStackPack,\n opts: ApplyPackOptions = {},\n): Promise<AppliedPack> {\n const owner = opts.owner ?? pack.name;\n const unregisterExtensions: Array<() => void> = [];\n\n // Track registered tool names, command names, and provider types so teardown\n // can reverse everything in registration order.\n const registeredToolNames: string[] = [];\n const registeredCommandNames: string[] = [];\n const registeredProviderTypes: string[] = [];\n\n if (pack.tools) {\n const tools = [...pack.tools];\n host.tools.registerAllOrThrow(tools, owner);\n for (const t of tools) registeredToolNames.push(t.name);\n }\n if (pack.providers) {\n const providers = [...pack.providers];\n host.providers.registerAll(providers);\n for (const p of providers) registeredProviderTypes.push(p.type);\n }\n if (pack.slashCommands) {\n const cmds = [...pack.slashCommands];\n host.slashCommands.registerAll(cmds, owner);\n for (const c of cmds) registeredCommandNames.push(c.name);\n }\n if (pack.extensions && host.extensions) {\n for (const ext of pack.extensions) {\n unregisterExtensions.push(host.extensions.register(ext));\n }\n }\n\n // If setup() throws after registration, roll back everything we registered above.\n // This makes applyWrongStackPack() transactional from the caller's perspective —\n // either the pack is fully applied or it is not.\n if (pack.setup) {\n if (!opts.api) {\n throw new Error(`Pack \"${pack.name}\" defines setup() but no PluginAPI was provided`);\n }\n try {\n await pack.setup(opts.api);\n } catch (setupErr) {\n // Roll back in reverse order: extensions first, then commands,\n // then tools, then providers. Extensions are unregistered before\n // tools/commands because extensions may depend on those capabilities;\n // tearing them down first avoids dangling refs.\n for (const unregister of unregisterExtensions.reverse()) {\n unregister();\n }\n for (const name of registeredCommandNames.reverse()) {\n host.slashCommands.unregister(name);\n }\n for (const name of registeredToolNames.reverse()) {\n host.tools.unregister(name);\n }\n for (const type of registeredProviderTypes.reverse()) {\n host.providers.unregister(type);\n }\n throw setupErr;\n }\n }\n\n return {\n pack,\n owner,\n async teardown() {\n for (const unregister of unregisterExtensions.reverse()) {\n unregister();\n }\n // Unregister commands, tools, and providers so the same pack can be\n // re-loaded cleanly without name/type conflicts.\n for (const name of registeredCommandNames.reverse()) {\n host.slashCommands.unregister(name);\n }\n for (const name of registeredToolNames.reverse()) {\n host.tools.unregister(name);\n }\n for (const type of registeredProviderTypes.reverse()) {\n host.providers.unregister(type);\n }\n if (pack.teardown) {\n if (!opts.api) {\n throw new Error(`Pack \"${pack.name}\" defines teardown() but no PluginAPI was provided`);\n }\n await pack.teardown(opts.api);\n }\n },\n };\n}\n\nexport async function applyWrongStackPacks(\n host: Pick<RuntimeHost, 'tools' | 'providers' | 'slashCommands'> & {\n extensions?: ExtensionRegistry | undefined;\n },\n packs: readonly WrongStackPack[],\n opts: ApplyPackOptions = {},\n): Promise<AppliedPack[]> {\n const applied: AppliedPack[] = [];\n try {\n for (const pack of packs) {\n applied.push(await applyWrongStackPack(host, pack, opts));\n }\n return applied;\n } catch (err) {\n // Roll back already-mounted packs. Surface teardown failures via\n // process.emitWarning so they don't mask the original error but\n // remain visible — a silent teardown failure can leave state\n // half-initialized in ways that make the next run fail mysteriously.\n for (const mounted of applied.reverse()) {\n await mounted.teardown().catch((teardownErr) => {\n const detail = teardownErr instanceof Error ? teardownErr.message : String(teardownErr);\n process.emitWarning(\n `Pack teardown during error rollback failed: ${detail}`,\n 'PackRollbackWarning',\n );\n });\n }\n throw err;\n }\n}\n","import {\n type Config,\n Container,\n DefaultConfigStore,\n DefaultErrorHandler,\n DefaultMemoryStore,\n DefaultModeStore,\n DefaultPermissionPolicy,\n DefaultRetryPolicy,\n DefaultPromptLoader,\n DefaultSecretScrubber,\n DefaultSessionStore,\n DefaultSkillLoader,\n DefaultSystemPromptBuilder,\n DefaultTokenCounter,\n type EventBus,\n createStrategyCompactor,\n buildRecoveryStrategies,\n type Logger,\n type ModelsRegistry,\n TOKENS,\n type Tool,\n type WstackPaths,\n} from '@wrongstack/core';\nimport type { DefaultSystemPromptBuilderOptions } from '@wrongstack/core';\n\nexport interface CreateContainerOptions {\n config: Config;\n wpaths: WstackPaths;\n logger: Logger;\n modelsRegistry: ModelsRegistry;\n /**\n * Optional event bus — passed to DefaultMemoryStore so plugins and\n * subsystems can react to memory mutations in real time.\n */\n events?: EventBus | undefined;\n permission?: {\n yolo?: boolean | undefined;\n yoloDestructive?: boolean | undefined;\n /** @deprecated Use `yoloDestructive`. */\n forceAllYolo?: boolean | undefined;\n /** When true, destructive ops prompt even in YOLO mode. */\n confirmDestructive?: boolean | undefined;\n promptDelegate?: (\n tool: Tool,\n input: unknown,\n suggestedPattern: string,\n ) => Promise<'yes' | 'no' | 'always' | 'deny'>;\n };\n compactor?: { preserveK?: number | undefined; eliseThreshold?: number | undefined };\n systemPrompt?: Partial<DefaultSystemPromptBuilderOptions> | undefined;\n /** Bundled skills directory path (resolved at boot time). */\n bundledSkillsDir?: string | undefined;\n /** Bundled prompt dataset directory path (`<core>/data/prompts`, resolved at boot). */\n bundledPromptsDir?: string | undefined;\n}\n\n/**\n * Create a Container pre-bound with all default service implementations.\n * Both CLI and WebUI use this factory so container wiring stays in one place.\n */\nexport function createDefaultContainer(opts: CreateContainerOptions): Container {\n const { config, wpaths, logger, modelsRegistry } = opts;\n const container = new Container();\n\n const configStore = new DefaultConfigStore(config);\n container.bind(TOKENS.ConfigStore, () => configStore);\n container.bind(TOKENS.Logger, () => logger);\n container.bind(TOKENS.SecretScrubber, () => new DefaultSecretScrubber());\n container.bind(TOKENS.RetryPolicy, () => new DefaultRetryPolicy());\n // Wire the compactor into the recovery chain so a 413 / context-overflow\n // response can shed tokens and retry. Without an explicit compactor the\n // default `context_overflow_reduce` strategy is a no-op. The Compactor\n // binding is resolved lazily (it is registered further below).\n container.bind(\n TOKENS.ErrorHandler,\n () =>\n new DefaultErrorHandler(\n buildRecoveryStrategies({\n compactor: container.resolve(TOKENS.Compactor),\n modelsRegistry,\n getConfig: () => configStore.get(),\n }),\n ),\n );\n container.bind(TOKENS.ModelsRegistry, () => modelsRegistry);\n container.bind(\n TOKENS.TokenCounter,\n () => new DefaultTokenCounter({ registry: modelsRegistry, providerId: config.provider, events: opts.events }),\n );\n\n const modeStore = new DefaultModeStore({ directory: wpaths.configDir });\n container.bind(TOKENS.ModeStore, () => modeStore);\n container.bind(\n TOKENS.SessionStore,\n () =>\n new DefaultSessionStore({\n dir: wpaths.projectSessions,\n // Scrub secrets out of persisted user/model turns (F-06). Tool output\n // is already scrubbed by the executor.\n secretScrubber: container.resolve(TOKENS.SecretScrubber),\n }),\n );\n\n const memoryStore = new DefaultMemoryStore({ paths: wpaths, events: opts.events });\n container.bind(TOKENS.MemoryStore, () => memoryStore);\n\n const skillLoader = new DefaultSkillLoader({ paths: wpaths, bundledDir: opts.bundledSkillsDir });\n container.bind(TOKENS.SkillLoader, () => skillLoader);\n\n const promptLoader = new DefaultPromptLoader({ paths: wpaths, bundledDir: opts.bundledPromptsDir });\n container.bind(TOKENS.PromptLoader, () => promptLoader);\n\n if (opts.systemPrompt) {\n container.bind(\n TOKENS.SystemPromptBuilder,\n () =>\n new DefaultSystemPromptBuilder({\n instructionPaths: {\n globalDir: wpaths.globalInstructions,\n projectDir: wpaths.inProjectInstructions,\n },\n ...(opts.systemPrompt as DefaultSystemPromptBuilderOptions),\n }),\n );\n }\n\n container.bind(\n TOKENS.PermissionPolicy,\n () => {\n const policyOptions: ConstructorParameters<typeof DefaultPermissionPolicy>[0] = {\n trustFile: wpaths.projectTrust,\n yolo: opts.permission?.yolo ?? false,\n yoloDestructive: opts.permission?.yoloDestructive ?? opts.permission?.forceAllYolo ?? false,\n confirmDestructive: opts.permission?.confirmDestructive ?? false,\n };\n if (opts.permission?.promptDelegate !== undefined) {\n policyOptions.promptDelegate = opts.permission.promptDelegate;\n }\n return new DefaultPermissionPolicy(policyOptions);\n },\n );\n\n container.bind(\n TOKENS.Compactor,\n () =>\n // Strategy comes from config.context.strategy: 'hybrid' (default, lossless\n // rules, no LLM), 'intelligent' (LLM summarization), or 'selective'\n // (LLM-driven selection). The LLM strategies resolve their provider from\n // ctx at compact()-time, so binding here (before context.provider exists)\n // is safe. preserveK / eliseThreshold are class-level fallbacks; the active\n // ContextWindowPolicy in ctx.meta normally overrides both at runtime.\n // eliseThreshold is a TOKEN COUNT — a previous value of 0.7 elided\n // essentially every tool_result (anything > 1 token).\n createStrategyCompactor({\n strategy: config.context?.strategy,\n preserveK: opts.compactor?.preserveK ?? 10,\n eliseThreshold: opts.compactor?.eliseThreshold ?? 2000,\n smart: true,\n summarizerModel: config.context?.summarizerModel,\n llmSelector: config.context?.llmSelector,\n }),\n );\n\n return container;\n}\n","import * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { assertNotPrivateHost } from '@wrongstack/core';\nimport type { ContentBlock, Context, ImageBlock, Tool, ToolRegistry } from '@wrongstack/core';\n\nexport interface VisionAdapterInput {\n image: ImageBlock;\n prompt?: string | undefined;\n ctx: Context;\n signal: AbortSignal;\n}\n\nexport interface VisionAdapter {\n name: string;\n describe(input: VisionAdapterInput): Promise<string>;\n}\n\nexport type VisionAdapters =\n | readonly VisionAdapter[]\n | (() => readonly VisionAdapter[] | Promise<readonly VisionAdapter[]>);\n\nexport interface VisionRoutingOptions {\n supportsVision: boolean;\n adapters?: VisionAdapters | undefined;\n ctx: Context;\n signal: AbortSignal;\n prompt?: string | undefined;\n providerId?: string | undefined;\n model?: string | undefined;\n}\n\nexport interface VisionRoutingResult {\n blocks: ContentBlock[];\n route: 'native' | 'adapter' | 'none';\n convertedImages: number;\n adapterName?: string | undefined;\n}\n\nexport class ImageInputUnsupportedError extends Error {\n constructor(opts: { providerId?: string | undefined; model?: string | undefined; imageCount: number }) {\n const target = [opts.providerId, opts.model].filter(Boolean).join('/') || 'current model';\n super(\n `${target} does not support image input, and no image-understanding adapter is available for ${opts.imageCount} image${opts.imageCount === 1 ? '' : 's'}. Switch to a vision model or enable an MCP/tool adapter that can describe images.`,\n );\n this.name = 'ImageInputUnsupportedError';\n }\n}\n\n/**\n * Thrown when an image URL targets a private / loopback / IMDS address.\n * Vision adapters forward URLs straight to the underlying tool, so without\n * this check a malicious (or accidentally-malformed) `image.source.url`\n * could turn image analysis into an SSRF vector hitting localhost, RFC1918\n * ranges, or the cloud metadata endpoint.\n *\n * Carries the rejected URL so callers can log / surface it without parsing\n * the message.\n */\nexport class VisionUrlBlockedError extends Error {\n readonly url: string;\n\n constructor(opts: { url: string; reason: string }) {\n super(`vision: blocked unsafe image URL \"${opts.url}\" (${opts.reason})`);\n this.name = 'VisionUrlBlockedError';\n this.url = opts.url;\n }\n}\n\nexport async function routeImagesForModel(\n blocks: ContentBlock[],\n opts: VisionRoutingOptions,\n): Promise<VisionRoutingResult> {\n const images = blocks.filter((b): b is ImageBlock => b.type === 'image');\n if (images.length === 0) {\n return { blocks, route: 'none', convertedImages: 0 };\n }\n if (opts.supportsVision) {\n return { blocks, route: 'native', convertedImages: 0 };\n }\n\n const adapters = await resolveAdapters(opts.adapters);\n if (adapters.length === 0) {\n throw new ImageInputUnsupportedError({\n providerId: opts.providerId,\n model: opts.model,\n imageCount: images.length,\n });\n }\n\n const out: ContentBlock[] = [];\n let convertedImages = 0;\n let lastErr: unknown;\n let adapterName: string | undefined;\n for (const block of blocks) {\n if (block.type !== 'image') {\n out.push(block);\n continue;\n }\n let description: string | undefined;\n for (const adapter of adapters) {\n try {\n description = await adapter.describe({\n image: block,\n prompt: opts.prompt,\n ctx: opts.ctx,\n signal: opts.signal,\n });\n adapterName = adapter.name;\n break;\n } catch (err) {\n lastErr = err;\n }\n }\n if (!description?.trim()) {\n throw new Error(\n `No image-understanding adapter could process an image.${lastErr instanceof Error ? ` Last error: ${lastErr.message}` : ''}`,\n );\n }\n convertedImages++;\n out.push({\n type: 'text',\n text: `[Image ${convertedImages} analyzed via ${adapterName ?? 'vision adapter'}]\\n${description.trim()}`,\n });\n }\n\n return { blocks: out, route: 'adapter', convertedImages, adapterName };\n}\n\nasync function resolveAdapters(adapters: VisionAdapters | undefined): Promise<readonly VisionAdapter[]> {\n if (!adapters) return [];\n return typeof adapters === 'function' ? await adapters() : adapters;\n}\n\nexport interface ToolVisionAdapterOptions {\n prompt?: string | undefined;\n}\n\nexport function createToolVisionAdapters(\n registry: ToolRegistry,\n opts: ToolVisionAdapterOptions = {},\n): VisionAdapter[] {\n return registry\n .list()\n .filter(isLikelyVisionTool)\n .map((tool) => ({\n name: tool.name,\n async describe(input: VisionAdapterInput): Promise<string> {\n const currentTool = registry.get(tool.name);\n if (!currentTool) {\n throw new Error(`Tool \"${tool.name}\" is no longer registered`);\n }\n const built = await buildToolPayload(currentTool, input.image, input.prompt ?? opts.prompt);\n if (!built) {\n throw new Error(`Tool \"${currentTool.name}\" does not expose a supported image input schema`);\n }\n try {\n const result = await currentTool.execute(built.payload, input.ctx, {\n signal: input.signal,\n });\n return stringifyToolResult(result);\n } finally {\n await built.cleanup?.();\n }\n },\n }));\n}\n\nfunction isLikelyVisionTool(tool: Tool): boolean {\n if (tool.permission !== 'auto' || tool.mutating) return false;\n const haystack = `${tool.name} ${tool.description ?? ''} ${tool.usageHint ?? ''}`.toLowerCase();\n if (/(generate|create|draw|paint|edit|upscale|remove|write|delete)/.test(haystack)) return false;\n if (!/(vision|image|screenshot|ocr|describe|analy[sz]e)/.test(haystack)) return false;\n const props = schemaProperties(tool);\n return [\n 'image',\n 'base64',\n 'data',\n 'url',\n 'image_url',\n 'imageUrl',\n 'path',\n 'image_path',\n 'imagePath',\n 'image_url',\n 'imageUrl',\n 'file_path',\n 'filePath',\n 'filename',\n 'file',\n 'mediaType',\n 'mimeType',\n ].some((key) => key in props);\n}\n\nasync function buildToolPayload(\n tool: Tool,\n image: ImageBlock,\n prompt = 'Describe this image for a coding agent. Include visible text, UI state, errors, layout, and any details needed to answer the user.',\n): Promise<{ payload: Record<string, unknown>; cleanup?: () => Promise<void> } | null> {\n const props = schemaProperties(tool);\n const payload: Record<string, unknown> = {};\n const mediaType = image.source.media_type ?? 'image/png';\n const data = image.source.data;\n const url = image.source.url;\n let cleanup: (() => Promise<void>) | undefined;\n\n // SSRF guard: when the image is referenced by URL, validate the host\n // BEFORE forwarding it to the underlying vision tool. The tool may\n // itself fetch the URL (the typical case for an MCP image-understanding\n // adapter), so a URL pointing at localhost / 127.0.0.1 / 169.254.169.254\n // / RFC1918 ranges would otherwise become an SSRF vector. Without this\n // gate, vision is a back-door around the fetch.ts SSRF guard (which\n // only applies when the explicit `fetch` tool is invoked).\n if (image.source.type === 'url' && url) {\n try {\n await assertNotPrivateHost(new URL(url).hostname);\n } catch (err) {\n const reason =\n err instanceof Error && err.message.startsWith('fetch:')\n ? err.message.slice('fetch:'.length).trim()\n : 'unresolvable host';\n throw new VisionUrlBlockedError({ url, reason });\n }\n }\n\n const pathKey = firstPresent(props, [\n 'path',\n 'image_path',\n 'imagePath',\n 'image_url',\n 'imageUrl',\n 'file_path',\n 'filePath',\n 'filename',\n 'file',\n ]);\n if (pathKey && image.source.type === 'base64' && data) {\n const p = await writeTempImage(data, mediaType);\n payload[pathKey] = p;\n cleanup = async () => {\n await fs.unlink(p).catch(() => undefined);\n await fs.rmdir(path.dirname(p)).catch(() => undefined);\n };\n } else if ('image' in props) {\n payload.image =\n image.source.type === 'base64'\n ? { type: 'base64', mediaType, media_type: mediaType, data }\n : { type: 'url', url };\n } else if (image.source.type === 'base64' && 'base64' in props) {\n payload.base64 = data;\n } else if (image.source.type === 'base64' && 'data' in props) {\n payload.data = data;\n } else if (image.source.type === 'url' && 'url' in props) {\n payload.url = url;\n } else if (image.source.type === 'url' && 'image_url' in props) {\n payload.image_url = url;\n } else if (image.source.type === 'url' && 'imageUrl' in props) {\n payload.imageUrl = url;\n } else {\n return null;\n }\n\n if ('mediaType' in props) payload.mediaType = mediaType;\n if ('mimeType' in props) payload.mimeType = mediaType;\n if ('media_type' in props) payload.media_type = mediaType;\n if ('prompt' in props) payload.prompt = prompt;\n if ('query' in props) payload.query = prompt;\n if ('instruction' in props) payload.instruction = prompt;\n const built: { payload: Record<string, unknown>; cleanup?: () => Promise<void> } = { payload };\n if (cleanup !== undefined) built.cleanup = cleanup;\n return built;\n}\n\nfunction firstPresent(props: Record<string, unknown>, keys: string[]): string | undefined {\n return keys.find((key) => key in props);\n}\n\nasync function writeTempImage(data: string, mediaType: string): Promise<string> {\n const ext = mediaType.includes('jpeg') || mediaType.includes('jpg') ? 'jpg' : 'png';\n const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'wstack-vision-'));\n const file = path.join(dir, `image.${ext}`);\n await fs.writeFile(file, data, 'base64');\n return file;\n}\n\nfunction schemaProperties(tool: Tool): Record<string, unknown> {\n const schema = tool.inputSchema;\n if (!schema || typeof schema !== 'object') return {};\n const props = (schema as { properties?: unknown | undefined }).properties;\n return props && typeof props === 'object' ? (props as Record<string, unknown>) : {};\n}\n\nfunction stringifyToolResult(value: unknown): string {\n if (typeof value === 'string') return value;\n if (Array.isArray(value)) {\n return value\n .map((item) => {\n if (item && typeof item === 'object' && 'text' in item) {\n return String((item as { text?: unknown | undefined }).text ?? '');\n }\n return typeof item === 'string' ? item : JSON.stringify(item);\n })\n .join('\\n');\n }\n if (value && typeof value === 'object' && 'text' in value) {\n return String((value as { text?: unknown | undefined }).text ?? '');\n }\n return JSON.stringify(value);\n}\n","import { spawn } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { buildChildEnv } from '@wrongstack/core';\n\nexport interface ClipboardImage {\n base64: string;\n mediaType: 'image/png';\n bytes: number;\n}\n\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024;\n\nexport async function readClipboardImage(): Promise<ClipboardImage | null> {\n const platform = process.platform;\n if (platform === 'win32') return readWindows();\n if (platform === 'darwin') return readDarwin();\n if (platform === 'linux') return readLinux();\n return null;\n}\n\n/**\n * Read plain text from the system clipboard. Returns `null` when the clipboard\n * holds no text (or only an image), the read failed, or the platform is\n * unsupported. Used by the TUI's Ctrl+V handler: terminals in raw mode deliver\n * Ctrl+V to the app as a control byte rather than performing a native paste, so\n * we read the clipboard ourselves.\n */\nexport async function readClipboardText(): Promise<string | null> {\n const platform = process.platform;\n if (platform === 'win32') {\n // -Raw preserves embedded newlines; force UTF-8 so non-ASCII survives the\n // pipe. PowerShell appends one trailing newline to stdout — strip it.\n const ps =\n '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Clipboard -Raw';\n const out = await runCmd('powershell', ['-NoProfile', '-Command', ps]);\n if (out == null) return null;\n const text = out.replace(/\\r?\\n$/, '');\n return text.length > 0 ? text : null;\n }\n if (platform === 'darwin') {\n const out = await runCmd('pbpaste', []);\n return out && out.length > 0 ? out : null;\n }\n if (platform === 'linux') {\n const tries: Array<[string, string[]]> = [\n ['wl-paste', ['--no-newline']],\n ['xclip', ['-selection', 'clipboard', '-o']],\n ];\n for (const [cmd, args] of tries) {\n const out = await runCmd(cmd, args);\n if (out && out.length > 0) return out;\n }\n return null;\n }\n return null;\n}\n\nasync function readWindows(): Promise<ClipboardImage | null> {\n const tmp = path.join(os.tmpdir(), `wstack-clip-${randomUUID()}.png`);\n const ps = [\n 'Add-Type -AssemblyName System.Windows.Forms',\n 'Add-Type -AssemblyName System.Drawing',\n '$img = [System.Windows.Forms.Clipboard]::GetImage()',\n 'if ($img -eq $null) { Write-Output \"NO_IMAGE\"; exit 0 }',\n `$img.Save('${tmp.replace(/\\\\/g, '\\\\\\\\')}', [System.Drawing.Imaging.ImageFormat]::Png)`,\n 'Write-Output \"OK\"',\n ].join('; ');\n const out = await runCmd('powershell', ['-NoProfile', '-Command', ps]);\n if (!out || out.trim() === 'NO_IMAGE') return null;\n if (!out.includes('OK')) return null;\n return readPngFile(tmp);\n}\n\nasync function readDarwin(): Promise<ClipboardImage | null> {\n const tmp = path.join(os.tmpdir(), `wstack-clip-${randomUUID()}.png`);\n const script = [\n 'try',\n ` set the_file to (open for access POSIX file \"${tmp}\" with write permission)`,\n ' write (the clipboard as «class PNGf») to the_file',\n ' close access the_file',\n 'on error',\n ' try',\n ' close access POSIX file \"' + tmp + '\"',\n ' end try',\n ' return \"NO_IMAGE\"',\n 'end try',\n 'return \"OK\"',\n ].join('\\n');\n const out = await runCmd('osascript', ['-e', script]);\n if (out?.trim() !== 'OK') return null;\n return readPngFile(tmp);\n}\n\nasync function readLinux(): Promise<ClipboardImage | null> {\n const tmp = path.join(os.tmpdir(), `wstack-clip-${randomUUID()}.png`);\n const tries: Array<[string, string[]]> = [\n ['wl-paste', ['--type', 'image/png']],\n ['xclip', ['-selection', 'clipboard', '-t', 'image/png', '-o']],\n ];\n for (const [cmd, args] of tries) {\n const ok = await runCmdToFile(cmd, args, tmp).catch(() => false);\n if (ok) return readPngFile(tmp);\n }\n return null;\n}\n\nasync function readPngFile(p: string): Promise<ClipboardImage | null> {\n try {\n const buf = await fs.readFile(p);\n if (buf.length === 0) {\n await fs.unlink(p).catch(() => undefined);\n return null;\n }\n if (buf.length > MAX_IMAGE_BYTES) {\n await fs.unlink(p).catch(() => undefined);\n throw new Error(`Clipboard image exceeds ${MAX_IMAGE_BYTES / 1024 / 1024}MB limit`);\n }\n if (buf[0] !== 0x89 || buf[1] !== 0x50 || buf[2] !== 0x4e || buf[3] !== 0x47) {\n await fs.unlink(p).catch(() => undefined);\n return null;\n }\n await fs.unlink(p).catch(() => undefined);\n return { base64: buf.toString('base64'), mediaType: 'image/png', bytes: buf.length };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\n/**\n * Hard ceiling for a clipboard subprocess. Reading the clipboard must never\n * hang the TUI: on a headless/loaded CI runner the PowerShell/xclip/wl-paste\n * read can stall indefinitely (no display, slow shell start). After this we\n * kill the child and resolve the safe default.\n */\nconst CLIPBOARD_CMD_TIMEOUT_MS = 5_000;\n\nfunction runCmd(cmd: string, args: string[]): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(cmd, args, { env: buildChildEnv(), stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });\n let out = '';\n let settled = false;\n const finish = (value: string | null) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(value);\n };\n const timer = setTimeout(() => {\n child.kill('SIGTERM');\n finish(null);\n }, CLIPBOARD_CMD_TIMEOUT_MS);\n child.stdout.on('data', (c) => {\n out += String(c);\n });\n child.on('error', () => finish(null));\n child.on('exit', (code) => finish(code === 0 ? out : null));\n });\n}\n\nfunction runCmdToFile(cmd: string, args: string[], outPath: string): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(cmd, args, { env: buildChildEnv(), stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });\n const chunks: Buffer[] = [];\n let settled = false;\n const finish = (value: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(value);\n };\n const timer = setTimeout(() => {\n child.kill('SIGTERM');\n finish(false);\n }, CLIPBOARD_CMD_TIMEOUT_MS);\n child.stdout.on('data', (c: Buffer) => chunks.push(c));\n child.on('error', () => finish(false));\n child.on('exit', async (code) => {\n if (code !== 0 || chunks.length === 0) return finish(false);\n try {\n await fs.writeFile(outPath, Buffer.concat(chunks));\n finish(true);\n } catch {\n finish(false);\n }\n });\n });\n}\n","// makeLightSubagentFactory — a dependency-light `AgentFactory` that builds a\n// fresh, isolated `Agent` per subagent task WITHOUT the full director / budget /\n// ACP machinery of the CLI's `MultiAgentHost`.\n//\n// Why this exists: `MultiAgentHost` lives in `@wrongstack/cli`, which the WebUI\n// packages cannot import (layer rule: webui ⇏ cli). But `SddParallelRun` only\n// needs an `AgentFactory` (a core interface) to run real parallel waves with\n// per-task git-worktree isolation. This factory provides exactly that, built\n// from primitives both webui servers already have (a DI container + the provider\n// and tool registries + a session writer). It deliberately does NOT touch the\n// budget/watchdog/director subsystems — those stay owned by the CLI host.\n//\n// Each call constructs a fresh `Context` + `EventBus` (true isolation) and\n// honours `SubagentConfig.cwd` so per-task worktrees don't collide. Subagents\n// cannot answer interactive permission prompts, so they run under an\n// `AutoApprovePermissionPolicy` granted the wide work capabilities (fs.write,\n// shell, …) — the user authorised the work when they pressed \"Start Run\".\n\nimport {\n Agent,\n AutoApprovePermissionPolicy,\n type AgentFactory,\n type AgentFactoryResult,\n type Config,\n type Container,\n Context,\n createDefaultPipelines,\n createFallbackModelExtension,\n EventBus,\n resolveModelMatrix,\n resolveModelTargetFromEntry,\n type ProviderRegistry,\n type SessionWriter,\n type SubagentConfig,\n type TextBlock,\n type Tool,\n ToolExecutor,\n ToolRegistry,\n TOKENS,\n WIDE_SUBAGENT_CAPABILITIES,\n} from '@wrongstack/core';\n\nexport interface LightSubagentFactoryDeps {\n /** DI container — used to resolve configStore / tokenCounter / scrubber / prompt builder. */\n container: Container;\n /** Provider registry (already populated by the host) used to build per-subagent providers. */\n providerRegistry: ProviderRegistry;\n /** Full tool registry — each subagent gets an isolated clone of it. */\n toolRegistry: ToolRegistry;\n /** Parent session writer; subagent events are interleaved via a guarded shim. */\n session: SessionWriter;\n /** Project root anchor. */\n projectRoot: string;\n /** Default cwd when a SubagentConfig doesn't pin one (worktree path otherwise). */\n cwd?: string | undefined;\n}\n\n/**\n * Build a default subagent baseline so a leaf worker knows it's running under a\n * run, not as the user-facing leader. Kept terse — the system-prompt builder\n * already supplies identity/tools/skills when `subagent: true`.\n */\nconst SUBAGENT_BASELINE =\n 'You are a subagent executing one delegated task end-to-end. Work autonomously with your tools; do not ask for confirmation on routine in-project actions. Keep output concise.';\n\n// Slot in ctx.meta where the per-subagent AbortController is stored.\n// Callers retrieve it via abortLightSubagent(agent).\nconst _SUBAGENT_ABORT = 'wrongstack:subagent-abort-controller';\n\n/**\n * Retrieve and abort a light subagent's AbortController (stored in ctx.meta\n * by makeLightSubagentFactory). Idempotent — calling abort() on an already-aborted\n * signal is a no-op.\n */\nexport function abortLightSubagent(agent: Agent): void {\n const ac = agent.ctx.meta[_SUBAGENT_ABORT] as AbortController | undefined;\n ac?.abort();\n}\n\nexport function makeLightSubagentFactory(deps: LightSubagentFactoryDeps): AgentFactory {\n const configStore = deps.container.resolve(TOKENS.ConfigStore);\n const tokenCounter = deps.container.resolve(TOKENS.TokenCounter);\n const secretScrubber = deps.container.resolve(TOKENS.SecretScrubber);\n const systemPromptBuilder = deps.container.resolve(TOKENS.SystemPromptBuilder);\n\n return async (subCfg: SubagentConfig): Promise<AgentFactoryResult> => {\n const events = new EventBus();\n const config = configStore.get();\n\n const matrixEntry = subCfg.model\n ? undefined\n : resolveModelMatrix(config.modelMatrix, subCfg.role);\n const matrixTarget = resolveModelTargetFromEntry(config, matrixEntry);\n const effProvider = subCfg.provider ?? matrixTarget?.provider ?? config.provider;\n const effModel = subCfg.model ?? matrixTarget?.model ?? config.model;\n const provider = buildProvider(deps.providerRegistry, config, effProvider, effModel);\n\n const subCwd = subCfg.cwd ?? deps.cwd ?? deps.projectRoot;\n\n // Isolated tool registry per subagent: the run wraps this factory with\n // `withDisabledToolFiltering`, which unregister()s tools (e.g. delegate) on\n // the agent's registry — that must never mutate the shared parent registry.\n const allowed = filterToolList(deps.toolRegistry, subCfg.tools);\n const subRegistry = new ToolRegistry();\n for (const t of allowed) subRegistry.register(t);\n\n const baseSystem: TextBlock[] = await systemPromptBuilder.build({\n cwd: subCwd,\n projectRoot: deps.projectRoot,\n tools: allowed,\n model: effModel,\n provider: effProvider,\n subagent: true,\n });\n baseSystem.unshift({ type: 'text', text: SUBAGENT_BASELINE });\n if (subCfg.systemPromptOverride) {\n baseSystem.push({ type: 'text', text: subCfg.systemPromptOverride });\n }\n\n const agentName = subCfg.name ?? subCfg.id ?? `sub_${cryptoId()}`;\n const session = makeSubagentSessionShim(deps.session);\n\n // Keep the AbortController reference so callers can abort this subagent's\n // work. Stored with a symbol key so it is opaque to general-purpose consumers.\n const ac = new AbortController();\n const ctx = new Context({\n systemPrompt: baseSystem,\n provider,\n session,\n signal: ac.signal,\n tokenCounter,\n cwd: subCwd,\n projectRoot: deps.projectRoot,\n allowOutsideProjectRoot:\n config.features?.allowOutsideProjectRoot ?? !(config.tools?.restrictToProjectRoot ?? false),\n model: effModel,\n tools: allowed,\n agentId: agentName,\n agentName,\n });\n if (subCfg.role) ctx.meta['agentRole'] = subCfg.role;\n // Store the AbortController so abortLightSubagent() can retrieve it.\n (ctx.meta[_SUBAGENT_ABORT] as AbortController) = ac;\n\n // Subagents can't answer prompts — auto-approve the wide work capability set\n // (the spawn site may narrow it via allowedCapabilities). `source: 'yolo'`\n // from this policy is the authoritative-auto waiver the ToolExecutor trusts\n // for dangerous caps (fs.write, shell), so code edits actually go through.\n const caps = subCfg.allowedCapabilities ?? WIDE_SUBAGENT_CAPABILITIES;\n const permissionPolicy = new AutoApprovePermissionPolicy(caps);\n\n const toolExecutor = new ToolExecutor(subRegistry, {\n permissionPolicy,\n secretScrubber,\n events,\n confirmAwaiter: undefined,\n iterationTimeoutMs: config.tools?.iterationTimeoutMs ?? 120_000,\n perIterationOutputCapBytes: config.tools?.perIterationOutputCapBytes ?? 100_000,\n tracer: undefined,\n });\n\n const agent = new Agent({\n container: deps.container,\n tools: subRegistry,\n providers: deps.providerRegistry,\n events,\n pipelines: createDefaultPipelines(),\n context: ctx,\n permissionPolicy,\n toolExecutor,\n });\n\n // Fallback chain for THIS worker: a per-task `fallbackModels` (set in the\n // WebUI) overrides the live config's chain; otherwise the config's explicit\n // list or smart default applies. Without this a 429/529/5xx on a worker's\n // model — after its own retries — fails the task instead of rotating. Mirrors\n // the CLI host factory so both surfaces behave identically.\n const subFallbacks = subCfg.fallbackModels;\n const matrixFallbacks = matrixTarget?.fallbackModels;\n agent.extensions.register(\n createFallbackModelExtension({\n getConfig: () => {\n const live = configStore.get();\n if (subFallbacks && subFallbacks.length) return { ...live, fallbackModels: subFallbacks };\n if (matrixFallbacks && matrixFallbacks.length) return { ...live, fallbackModels: matrixFallbacks };\n return live;\n },\n buildProvider: (id) => buildProvider(deps.providerRegistry, configStore.get(), id, effModel),\n events,\n }),\n );\n\n return { agent, events };\n };\n}\n\n// ── helpers ──────────────────────────────────────────────────────────────────\n\nfunction filterToolList(registry: ToolRegistry, allow?: string[]): Tool[] {\n const all = registry.list();\n if (!allow || allow.length === 0) return all;\n const allowSet = new Set(allow);\n return all.filter((t) => allowSet.has(t.name));\n}\n\nfunction buildProvider(\n registry: ProviderRegistry,\n config: Config,\n providerId: string,\n model: string,\n): ReturnType<ProviderRegistry['create']> {\n const providerConfig = config.providers?.[providerId] ?? {\n type: providerId,\n apiKey: config.apiKey,\n baseUrl: config.baseUrl,\n };\n if (!registry.has(providerId)) {\n throw new Error(\n `No provider factory registered for \"${providerId}\" — cannot build a subagent provider for the SDD run.`,\n );\n }\n return registry.create({ ...providerConfig, type: providerId, model });\n}\n\n/**\n * Guarded SessionWriter shim that interleaves subagent events into the parent\n * JSONL while NEVER touching checkpoint / in-flight / lifecycle state — those\n * belong to the parent and a subagent writing them would corrupt the parent's\n * rewind + crash-recovery markers. Mirrors the CLI host's fallback shim.\n */\nfunction makeSubagentSessionShim(parent: SessionWriter): SessionWriter {\n return {\n id: parent.id,\n transcriptPath: parent.transcriptPath,\n get pendingToolUses(): string[] {\n return [];\n },\n append: (ev) => parent.append({ ...ev }),\n appendBatch: (evs) => parent.appendBatch(evs.map((e) => ({ ...e }))),\n flush: () => parent.flush(),\n close: async () => {},\n recordFileChange: () => {},\n recordSideEffect: () => {},\n writeCheckpoint: async () => {},\n writeFileSnapshot: async () => {},\n truncateToCheckpoint: async () => 0,\n clearSession: async () => {},\n writeInFlightMarker: async () => {},\n clearInFlightMarker: async () => {},\n } satisfies SessionWriter;\n}\n\nfunction cryptoId(): string {\n return crypto.randomUUID().slice(0, 8);\n}\n"]}
1
+ {"version":3,"sources":["../src/clipboard.ts","../src/container.ts","../src/fleet/light-subagent-factory.ts","../src/host.ts","../src/local-llm-probe.ts","../src/vision.ts"],"names":["TOKENS","randomUUID","elapsed","fs2","path2","os2"],"mappings":"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","file":"index.js","sourcesContent":["import { spawn } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { buildChildEnv } from '@wrongstack/core';\n\nexport interface ClipboardImage {\n base64: string;\n mediaType: 'image/png';\n bytes: number;\n}\n\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024;\n\nexport async function readClipboardImage(): Promise<ClipboardImage | null> {\n const platform = process.platform;\n if (platform === 'win32') return readWindows();\n if (platform === 'darwin') return readDarwin();\n if (platform === 'linux') return readLinux();\n return null;\n}\n\n/**\n * Read plain text from the system clipboard. Returns `null` when the clipboard\n * holds no text (or only an image), the read failed, or the platform is\n * unsupported. Used by the TUI's Ctrl+V handler: terminals in raw mode deliver\n * Ctrl+V to the app as a control byte rather than performing a native paste, so\n * we read the clipboard ourselves.\n */\nexport async function readClipboardText(): Promise<string | null> {\n const platform = process.platform;\n if (platform === 'win32') {\n // -Raw preserves embedded newlines; force UTF-8 so non-ASCII survives the\n // pipe. PowerShell appends one trailing newline to stdout — strip it.\n const ps = '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Clipboard -Raw';\n const out = await runCmd('powershell', ['-NoProfile', '-Command', ps]);\n if (out == null) return null;\n const text = out.replace(/\\r?\\n$/, '');\n return text.length > 0 ? text : null;\n }\n if (platform === 'darwin') {\n const out = await runCmd('pbpaste', []);\n return out && out.length > 0 ? out : null;\n }\n if (platform === 'linux') {\n const tries: Array<[string, string[]]> = [\n ['wl-paste', ['--no-newline']],\n ['xclip', ['-selection', 'clipboard', '-o']],\n ];\n for (const [cmd, args] of tries) {\n const out = await runCmd(cmd, args);\n if (out && out.length > 0) return out;\n }\n return null;\n }\n return null;\n}\n\nasync function readWindows(): Promise<ClipboardImage | null> {\n const tmp = path.join(os.tmpdir(), `wstack-clip-${randomUUID()}.png`);\n const ps = [\n 'Add-Type -AssemblyName System.Windows.Forms',\n 'Add-Type -AssemblyName System.Drawing',\n '$img = [System.Windows.Forms.Clipboard]::GetImage()',\n 'if ($img -eq $null) { Write-Output \"NO_IMAGE\"; exit 0 }',\n `$img.Save('${tmp.replace(/\\\\/g, '\\\\\\\\')}', [System.Drawing.Imaging.ImageFormat]::Png)`,\n 'Write-Output \"OK\"',\n ].join('; ');\n const out = await runCmd('powershell', ['-NoProfile', '-Command', ps]);\n if (!out || out.trim() === 'NO_IMAGE') return null;\n if (!out.includes('OK')) return null;\n return readPngFile(tmp);\n}\n\nasync function readDarwin(): Promise<ClipboardImage | null> {\n const tmp = path.join(os.tmpdir(), `wstack-clip-${randomUUID()}.png`);\n const script = [\n 'try',\n ` set the_file to (open for access POSIX file \"${tmp}\" with write permission)`,\n ' write (the clipboard as «class PNGf») to the_file',\n ' close access the_file',\n 'on error',\n ' try',\n ' close access POSIX file \"' + tmp + '\"',\n ' end try',\n ' return \"NO_IMAGE\"',\n 'end try',\n 'return \"OK\"',\n ].join('\\n');\n const out = await runCmd('osascript', ['-e', script]);\n if (out?.trim() !== 'OK') return null;\n return readPngFile(tmp);\n}\n\nasync function readLinux(): Promise<ClipboardImage | null> {\n const tmp = path.join(os.tmpdir(), `wstack-clip-${randomUUID()}.png`);\n const tries: Array<[string, string[]]> = [\n ['wl-paste', ['--type', 'image/png']],\n ['xclip', ['-selection', 'clipboard', '-t', 'image/png', '-o']],\n ];\n for (const [cmd, args] of tries) {\n const ok = await runCmdToFile(cmd, args, tmp).catch(() => false);\n if (ok) return readPngFile(tmp);\n }\n return null;\n}\n\nasync function readPngFile(p: string): Promise<ClipboardImage | null> {\n try {\n const buf = await fs.readFile(p);\n if (buf.length === 0) {\n await fs.unlink(p).catch(() => undefined);\n return null;\n }\n if (buf.length > MAX_IMAGE_BYTES) {\n await fs.unlink(p).catch(() => undefined);\n throw new Error(`Clipboard image exceeds ${MAX_IMAGE_BYTES / 1024 / 1024}MB limit`);\n }\n if (buf[0] !== 0x89 || buf[1] !== 0x50 || buf[2] !== 0x4e || buf[3] !== 0x47) {\n await fs.unlink(p).catch(() => undefined);\n return null;\n }\n await fs.unlink(p).catch(() => undefined);\n return { base64: buf.toString('base64'), mediaType: 'image/png', bytes: buf.length };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\n/**\n * Hard ceiling for a clipboard subprocess. Reading the clipboard must never\n * hang the TUI: on a headless/loaded CI runner the PowerShell/xclip/wl-paste\n * read can stall indefinitely (no display, slow shell start). After this we\n * kill the child and resolve the safe default.\n */\nconst CLIPBOARD_CMD_TIMEOUT_MS = 5_000;\n\nfunction runCmd(cmd: string, args: string[]): Promise<string | null> {\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n env: buildChildEnv(),\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n });\n let out = '';\n let settled = false;\n let killedByTimeout = false;\n const finish = (value: string | null) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n clearTimeout(killCap);\n resolve(value);\n };\n const timer = setTimeout(() => {\n killedByTimeout = true;\n child.kill('SIGTERM');\n }, CLIPBOARD_CMD_TIMEOUT_MS);\n // Safety cap: if the child ignores SIGTERM, do not hang forever.\n const killCap = setTimeout(() => finish(null), CLIPBOARD_CMD_TIMEOUT_MS + 2_000);\n child.stdout.on('data', (c) => {\n out += String(c);\n });\n child.on('error', () => finish(null));\n child.on('exit', (code) => {\n if (killedByTimeout) return finish(null);\n finish(code === 0 ? out : null);\n });\n });\n}\n\nfunction runCmdToFile(cmd: string, args: string[], outPath: string): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n env: buildChildEnv(),\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n });\n const chunks: Buffer[] = [];\n let settled = false;\n let killedByTimeout = false;\n const finish = (value: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n clearTimeout(killCap);\n resolve(value);\n };\n const timer = setTimeout(() => {\n killedByTimeout = true;\n child.kill('SIGTERM');\n }, CLIPBOARD_CMD_TIMEOUT_MS);\n // Safety cap: if the child ignores SIGTERM, do not hang forever.\n const killCap = setTimeout(() => finish(false), CLIPBOARD_CMD_TIMEOUT_MS + 2_000);\n child.stdout.on('data', (c: Buffer) => chunks.push(c));\n child.on('error', () => finish(false));\n child.on('exit', async (code) => {\n if (killedByTimeout) return finish(false);\n if (code !== 0 || chunks.length === 0) return finish(false);\n try {\n await fs.writeFile(outPath, Buffer.concat(chunks));\n finish(true);\n } catch {\n finish(false);\n }\n });\n });\n}\n","import {\n buildRecoveryStrategies,\n type Config,\n Container,\n createStrategyCompactor,\n DefaultConfigStore,\n DefaultErrorHandler,\n DefaultMemoryStore,\n DefaultModeStore,\n DefaultPermissionPolicy,\n DefaultPromptLoader,\n DefaultRetryPolicy,\n DefaultSecretScrubber,\n DefaultSessionStore,\n DefaultSkillLoader,\n DefaultSystemPromptBuilder,\n type DefaultSystemPromptBuilderOptions,\n DefaultTokenCounter,\n type EventBus,\n type Logger,\n type ModelsRegistry,\n TOKENS,\n type Tool,\n type WstackPaths,\n} from '@wrongstack/core';\n\nexport interface CreateContainerOptions {\n config: Config;\n wpaths: WstackPaths;\n logger: Logger;\n modelsRegistry: ModelsRegistry;\n /**\n * Optional event bus — passed to DefaultMemoryStore so plugins and\n * subsystems can react to memory mutations in real time.\n */\n events?: EventBus | undefined;\n permission?: {\n yolo?: boolean | undefined;\n yoloDestructive?: boolean | undefined;\n /** @deprecated Use `yoloDestructive`. */\n forceAllYolo?: boolean | undefined;\n /** When true, destructive ops prompt even in YOLO mode. */\n confirmDestructive?: boolean | undefined;\n promptDelegate?: (\n tool: Tool,\n input: unknown,\n suggestedPattern: string,\n ) => Promise<'yes' | 'no' | 'always' | 'deny'>;\n };\n compactor?: { preserveK?: number | undefined; eliseThreshold?: number | undefined };\n systemPrompt?: Partial<DefaultSystemPromptBuilderOptions> | undefined;\n /** Bundled skills directory path (resolved at boot time). */\n bundledSkillsDir?: string | undefined;\n /** Bundled prompt dataset directory path (`<core>/data/prompts`, resolved at boot). */\n bundledPromptsDir?: string | undefined;\n}\n\n/**\n * Create a Container pre-bound with all default service implementations.\n * Both CLI and WebUI use this factory so container wiring stays in one place.\n */\nexport function createDefaultContainer(opts: CreateContainerOptions): Container {\n const { config, wpaths, logger, modelsRegistry } = opts;\n const container = new Container();\n\n const configStore = new DefaultConfigStore(config);\n container.bind(TOKENS.ConfigStore, () => configStore);\n container.bind(TOKENS.Logger, () => logger);\n container.bind(TOKENS.SecretScrubber, () => new DefaultSecretScrubber());\n container.bind(TOKENS.RetryPolicy, () => new DefaultRetryPolicy());\n // Wire the compactor into the recovery chain so a 413 / context-overflow\n // response can shed tokens and retry. Without an explicit compactor the\n // default `context_overflow_reduce` strategy is a no-op. The Compactor\n // binding is resolved lazily (it is registered further below).\n container.bind(\n TOKENS.ErrorHandler,\n () =>\n new DefaultErrorHandler(\n buildRecoveryStrategies({\n compactor: container.resolve(TOKENS.Compactor),\n modelsRegistry,\n getConfig: () => configStore.get(),\n }),\n ),\n );\n container.bind(TOKENS.ModelsRegistry, () => modelsRegistry);\n container.bind(\n TOKENS.TokenCounter,\n () =>\n new DefaultTokenCounter({\n registry: modelsRegistry,\n providerId: config.provider,\n events: opts.events,\n }),\n );\n\n const modeStore = new DefaultModeStore({ directory: wpaths.configDir });\n container.bind(TOKENS.ModeStore, () => modeStore);\n container.bind(\n TOKENS.SessionStore,\n () =>\n new DefaultSessionStore({\n dir: wpaths.projectSessions,\n // Scrub secrets out of persisted user/model turns (F-06). Tool output\n // is already scrubbed by the executor.\n secretScrubber: container.resolve(TOKENS.SecretScrubber),\n }),\n );\n\n const memoryStore = new DefaultMemoryStore({ paths: wpaths, events: opts.events });\n container.bind(TOKENS.MemoryStore, () => memoryStore);\n\n const skillLoader = new DefaultSkillLoader({\n paths: wpaths,\n bundledDir: opts.bundledSkillsDir,\n readClaudeSkills: config.skills?.readClaudeSkills,\n foreignSources: config.skills?.foreignSources,\n extraDirs: config.skills?.extraDirs,\n });\n container.bind(TOKENS.SkillLoader, () => skillLoader);\n\n const promptLoader = new DefaultPromptLoader({\n paths: wpaths,\n bundledDir: opts.bundledPromptsDir,\n });\n container.bind(TOKENS.PromptLoader, () => promptLoader);\n\n if (opts.systemPrompt) {\n container.bind(\n TOKENS.SystemPromptBuilder,\n () =>\n new DefaultSystemPromptBuilder({\n instructionPaths: {\n globalDir: wpaths.globalInstructions,\n projectDir: wpaths.inProjectInstructions,\n },\n skillMode: config.skills?.mode,\n skillEagerMaxChars: config.skills?.eagerMaxChars,\n ...opts.systemPrompt,\n }),\n );\n }\n\n container.bind(TOKENS.PermissionPolicy, () => {\n const policyOptions: ConstructorParameters<typeof DefaultPermissionPolicy>[0] = {\n trustFile: wpaths.projectTrust,\n yolo: opts.permission?.yolo ?? false,\n yoloDestructive: opts.permission?.yoloDestructive ?? opts.permission?.forceAllYolo ?? false,\n confirmDestructive: opts.permission?.confirmDestructive ?? false,\n };\n if (opts.permission?.promptDelegate !== undefined) {\n policyOptions.promptDelegate = opts.permission.promptDelegate;\n }\n return new DefaultPermissionPolicy(policyOptions);\n });\n\n container.bind(TOKENS.Compactor, () =>\n // Strategy comes from config.context.strategy: 'hybrid' (default, lossless\n // rules, no LLM), 'intelligent' (LLM summarization), or 'selective'\n // (LLM-driven selection). The LLM strategies resolve their provider from\n // ctx at compact()-time, so binding here (before context.provider exists)\n // is safe. preserveK / eliseThreshold are class-level fallbacks; the active\n // ContextWindowPolicy in ctx.meta normally overrides both at runtime.\n // eliseThreshold is a TOKEN COUNT — a previous value of 0.7 elided\n // essentially every tool_result (anything > 1 token).\n createStrategyCompactor({\n strategy: config.context?.strategy,\n preserveK: opts.compactor?.preserveK ?? 10,\n eliseThreshold: opts.compactor?.eliseThreshold ?? 2000,\n smart: true,\n summarizerModel: config.context?.summarizerModel,\n llmSelector: config.context?.llmSelector,\n }),\n );\n\n return container;\n}\n","// makeLightSubagentFactory — a dependency-light `AgentFactory` that builds a\n// fresh, isolated `Agent` per subagent task WITHOUT the full director / budget /\n// ACP machinery of the CLI's `MultiAgentHost`.\n//\n// Why this exists: `MultiAgentHost` lives in `@wrongstack/cli`, which the WebUI\n// packages cannot import (layer rule: webui ⇏ cli). But `SddParallelRun` only\n// needs an `AgentFactory` (a core interface) to run real parallel waves with\n// per-task git-worktree isolation. This factory provides exactly that, built\n// from primitives both webui servers already have (a DI container + the provider\n// and tool registries + a session writer). It deliberately does NOT touch the\n// budget/watchdog/director subsystems — those stay owned by the CLI host.\n//\n// Each call constructs a fresh `Context` + `EventBus` (true isolation) and\n// honours `SubagentConfig.cwd` so per-task worktrees don't collide. Subagents\n// cannot answer interactive permission prompts, so they run under an\n// `AutoApprovePermissionPolicy` granted the wide work capabilities (fs.write,\n// shell, …) — the user authorised the work when they pressed \"Start Run\".\n\nimport { randomUUID } from 'node:crypto';\nimport {\n Agent,\n type AgentFactory,\n type AgentFactoryResult,\n applyModelRuntime,\n AutoApprovePermissionPolicy,\n type Config,\n type Container,\n Context,\n createDefaultPipelines,\n createFallbackModelExtension,\n EventBus,\n mergeModelRuntime,\n type ModelsRegistry,\n type ProviderRegistry,\n type ReasoningConfig,\n type Request,\n resolveModelMatrix,\n resolveModelTargetFromEntry,\n type SessionWriter,\n type SubagentConfig,\n type TextBlock,\n TOKENS,\n type Tool,\n ToolExecutor,\n ToolRegistry,\n WIDE_SUBAGENT_CAPABILITIES,\n} from '@wrongstack/core';\n\nexport interface LightSubagentFactoryDeps {\n /** DI container — used to resolve configStore / tokenCounter / scrubber / prompt builder. */\n container: Container;\n /** Provider registry (already populated by the host) used to build per-subagent providers. */\n providerRegistry: ProviderRegistry;\n /** Full tool registry — each subagent gets an isolated clone of it. */\n toolRegistry: ToolRegistry;\n /** Optional models catalog used to gate per-subagent reasoning settings. */\n modelsRegistry?: ModelsRegistry | undefined;\n /** Parent session writer; subagent events are interleaved via a guarded shim. */\n session: SessionWriter;\n /** Project root anchor. */\n projectRoot: string;\n /** Default cwd when a SubagentConfig doesn't pin one (worktree path otherwise). */\n cwd?: string | undefined;\n}\n\n/**\n * Build a default subagent baseline so a leaf worker knows it's running under a\n * run, not as the user-facing leader. Kept terse — the system-prompt builder\n * already supplies identity/tools/skills when `subagent: true`.\n */\nconst SUBAGENT_BASELINE =\n 'You are a subagent executing one delegated task end-to-end. Work autonomously with your tools; do not ask for confirmation on routine in-project actions. Keep output concise.';\n\n// Slot in ctx.meta where the per-subagent AbortController is stored.\n// Callers retrieve it via abortLightSubagent(agent).\nconst _SUBAGENT_ABORT = 'wrongstack:subagent-abort-controller';\n\n/**\n * Retrieve and abort a light subagent's AbortController (stored in ctx.meta\n * by makeLightSubagentFactory). Idempotent — calling abort() on an already-aborted\n * signal is a no-op.\n */\nexport function abortLightSubagent(agent: Agent): void {\n const ac = agent.ctx.meta[_SUBAGENT_ABORT] as AbortController | undefined;\n ac?.abort();\n}\n\nexport function makeLightSubagentFactory(deps: LightSubagentFactoryDeps): AgentFactory {\n const configStore = deps.container.resolve(TOKENS.ConfigStore);\n const tokenCounter = deps.container.resolve(TOKENS.TokenCounter);\n const secretScrubber = deps.container.resolve(TOKENS.SecretScrubber);\n const systemPromptBuilder = deps.container.resolve(TOKENS.SystemPromptBuilder);\n\n return async (subCfg: SubagentConfig): Promise<AgentFactoryResult> => {\n const events = new EventBus();\n const config = configStore.get();\n const modelsRegistry = deps.modelsRegistry ?? deps.container.safeResolve(TOKENS.ModelsRegistry);\n\n const matrixEntry = subCfg.model\n ? undefined\n : resolveModelMatrix(config.modelMatrix, subCfg.role);\n const matrixTarget = resolveModelTargetFromEntry(config, matrixEntry);\n const effProvider = subCfg.provider ?? matrixTarget?.provider ?? config.provider;\n const effModel = subCfg.model ?? matrixTarget?.model ?? config.model;\n const provider = buildProvider(deps.providerRegistry, config, effProvider, effModel);\n let subReasoningConfig = await resolveReasoningConfig(modelsRegistry, effProvider, effModel);\n const runtimeOverride = subCfg.modelRuntime ?? matrixTarget?.modelRuntime;\n\n const subCwd = subCfg.cwd ?? deps.cwd ?? deps.projectRoot;\n\n // Isolated tool registry per subagent: the run wraps this factory with\n // `withDisabledToolFiltering`, which unregister()s tools (e.g. delegate) on\n // the agent's registry — that must never mutate the shared parent registry.\n const allowed = filterToolList(deps.toolRegistry, subCfg.tools);\n const subRegistry = new ToolRegistry();\n for (const t of allowed) subRegistry.register(t);\n\n const baseSystem: TextBlock[] = await systemPromptBuilder.build({\n cwd: subCwd,\n projectRoot: deps.projectRoot,\n tools: allowed,\n model: effModel,\n provider: effProvider,\n subagent: true,\n });\n baseSystem.unshift({ type: 'text', text: SUBAGENT_BASELINE });\n if (subCfg.systemPromptOverride) {\n baseSystem.push({ type: 'text', text: subCfg.systemPromptOverride });\n }\n\n const agentName = subCfg.name ?? subCfg.id ?? `sub_${cryptoId()}`;\n const session = makeSubagentSessionShim(deps.session);\n\n // Keep the AbortController reference so callers can abort this subagent's\n // work. Stored with a symbol key so it is opaque to general-purpose consumers.\n const ac = new AbortController();\n const ctx = new Context({\n systemPrompt: baseSystem,\n provider,\n session,\n signal: ac.signal,\n tokenCounter,\n cwd: subCwd,\n projectRoot: deps.projectRoot,\n allowOutsideProjectRoot:\n config.features?.allowOutsideProjectRoot ?? !(config.tools?.restrictToProjectRoot ?? false),\n model: effModel,\n tools: allowed,\n agentId: agentName,\n agentName,\n traceId: deps.session.traceId,\n });\n if (subCfg.role) ctx.meta['agentRole'] = subCfg.role;\n // Store the AbortController so abortLightSubagent() can retrieve it.\n (ctx.meta[_SUBAGENT_ABORT] as AbortController) = ac;\n\n const pipelines = createDefaultPipelines();\n pipelines.request.use({\n name: 'ModelRuntimeSettings',\n async handler(req: Request) {\n return applyModelRuntime(req, {\n getSettings: () => mergeModelRuntime(configStore.get().modelRuntime, runtimeOverride),\n getReasoningConfig: () => subReasoningConfig,\n getCapabilities: () => ctx.provider.capabilities,\n });\n },\n });\n\n // Subagents can't answer prompts — auto-approve the wide work capability set\n // (the spawn site may narrow it via allowedCapabilities). `source: 'yolo'`\n // from this policy is the authoritative-auto waiver the ToolExecutor trusts\n // for dangerous caps (fs.write, shell), so code edits actually go through.\n const caps = subCfg.allowedCapabilities ?? WIDE_SUBAGENT_CAPABILITIES;\n const permissionPolicy = new AutoApprovePermissionPolicy(caps);\n\n const toolExecutor = new ToolExecutor(subRegistry, {\n permissionPolicy,\n secretScrubber,\n events,\n confirmAwaiter: undefined,\n iterationTimeoutMs: config.tools?.iterationTimeoutMs ?? 120_000,\n perIterationOutputCapBytes: config.tools?.perIterationOutputCapBytes ?? 100_000,\n tracer: undefined,\n });\n\n const agent = new Agent({\n container: deps.container,\n tools: subRegistry,\n providers: deps.providerRegistry,\n events,\n pipelines,\n context: ctx,\n permissionPolicy,\n toolExecutor,\n });\n\n // Fallback chain for THIS worker: a per-task `fallbackModels` (set in the\n // WebUI) overrides the live config's chain; otherwise the config's explicit\n // list or smart default applies. Without this a 429/529/5xx on a worker's\n // model — after its own retries — fails the task instead of rotating. Mirrors\n // the CLI host factory so both surfaces behave identically.\n const subFallbacks = subCfg.fallbackModels;\n const matrixFallbacks = matrixTarget?.fallbackModels;\n agent.extensions.register(\n createFallbackModelExtension({\n getConfig: () => {\n const live = configStore.get();\n if (subFallbacks?.length) return { ...live, fallbackModels: subFallbacks };\n if (matrixFallbacks?.length) return { ...live, fallbackModels: matrixFallbacks };\n return live;\n },\n buildProvider: (id, model) =>\n buildProvider(deps.providerRegistry, configStore.get(), id, model ?? effModel),\n onModelSwitch: async (id, model) => {\n subReasoningConfig = await resolveReasoningConfig(modelsRegistry, id, model);\n },\n events,\n }),\n );\n\n return { agent, events };\n };\n}\n\n// ── helpers ──────────────────────────────────────────────────────────────────\n\nfunction filterToolList(registry: ToolRegistry, allow?: string[]): Tool[] {\n const all = registry.list();\n if (!allow || allow.length === 0) return all;\n const allowSet = new Set(allow);\n return all.filter((t) => allowSet.has(t.name));\n}\n\nfunction buildProvider(\n registry: ProviderRegistry,\n config: Config,\n providerId: string,\n model: string,\n): ReturnType<ProviderRegistry['create']> {\n const providerConfig = config.providers?.[providerId] ?? {\n type: providerId,\n apiKey: config.apiKey,\n baseUrl: config.baseUrl,\n };\n if (!registry.has(providerId)) {\n throw new Error(\n `No provider factory registered for \"${providerId}\" — cannot build a subagent provider for the SDD run.`,\n );\n }\n return registry.create({ ...providerConfig, type: providerId, model });\n}\n\nasync function resolveReasoningConfig(\n registry: ModelsRegistry | undefined,\n providerId: string,\n modelId: string,\n): Promise<ReasoningConfig | undefined> {\n if (!registry) return undefined;\n try {\n return (await registry.getModel(providerId, modelId))?.capabilities.reasoningConfig;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Guarded SessionWriter shim that interleaves subagent events into the parent\n * JSONL while NEVER touching checkpoint / in-flight / lifecycle state — those\n * belong to the parent and a subagent writing them would corrupt the parent's\n * rewind + crash-recovery markers. Mirrors the CLI host's fallback shim.\n */\nfunction makeSubagentSessionShim(parent: SessionWriter): SessionWriter {\n return {\n id: parent.id,\n transcriptPath: parent.transcriptPath,\n get traceId(): string | undefined {\n return parent.traceId;\n },\n set traceId(value: string | undefined) {\n parent.traceId = value;\n },\n get pendingToolUses(): string[] {\n return [];\n },\n append: (ev) => parent.append({ ...ev }),\n appendBatch: (evs) => parent.appendBatch(evs.map((e) => ({ ...e }))),\n flush: () => parent.flush(),\n close: async () => {},\n recordFileChange: () => {},\n recordSideEffect: () => {},\n writeCheckpoint: async () => {},\n writeFileSnapshot: async () => {},\n truncateToCheckpoint: async () => 0,\n clearSession: async () => {},\n writeInFlightMarker: async () => {},\n clearInFlightMarker: async () => {},\n } satisfies SessionWriter;\n}\n\nfunction cryptoId(): string {\n return randomUUID().slice(0, 8);\n}\n","import type {\n Agent,\n Context,\n EventBus,\n ExtensionRegistry,\n PluginAPI,\n ProviderRegistry,\n SessionWriter,\n SlashCommandRegistry,\n ToolRegistry,\n} from '@wrongstack/core';\nimport type { WrongStackPack } from './pack.js';\n\nexport interface RuntimeHost {\n agent: Agent;\n context: Context;\n events: EventBus;\n tools: ToolRegistry;\n providers: ProviderRegistry;\n slashCommands: SlashCommandRegistry;\n session: SessionWriter;\n extensions?: ExtensionRegistry | undefined;\n shutdown(): Promise<void>;\n}\n\nexport interface RuntimeHostParts {\n agent: Agent;\n context: Context;\n events: EventBus;\n tools: ToolRegistry;\n providers: ProviderRegistry;\n slashCommands: SlashCommandRegistry;\n session: SessionWriter;\n extensions?: ExtensionRegistry | undefined;\n shutdown?: (() => void | Promise<void>) | undefined;\n}\n\nexport function createRuntimeHostFromParts(parts: RuntimeHostParts): RuntimeHost {\n return {\n agent: parts.agent,\n context: parts.context,\n events: parts.events,\n tools: parts.tools,\n providers: parts.providers,\n slashCommands: parts.slashCommands,\n session: parts.session,\n extensions: parts.extensions,\n async shutdown() {\n await parts.shutdown?.();\n },\n };\n}\n\nexport interface ApplyPackOptions {\n owner?: string | undefined;\n api?: PluginAPI | undefined;\n}\n\nexport interface AppliedPack {\n pack: WrongStackPack;\n owner: string;\n teardown(): Promise<void>;\n}\n\nexport async function applyWrongStackPack(\n host: Pick<RuntimeHost, 'tools' | 'providers' | 'slashCommands'> & {\n extensions?: ExtensionRegistry | undefined;\n },\n pack: WrongStackPack,\n opts: ApplyPackOptions = {},\n): Promise<AppliedPack> {\n const owner = opts.owner ?? pack.name;\n const unregisterExtensions: Array<() => void> = [];\n\n // Track registered tool names, command names, and provider types so teardown\n // can reverse everything in registration order.\n const registeredToolNames: string[] = [];\n const registeredCommandNames: string[] = [];\n const registeredProviderTypes: string[] = [];\n\n if (pack.tools) {\n const tools = [...pack.tools];\n host.tools.registerAllOrThrow(tools, owner);\n for (const t of tools) registeredToolNames.push(t.name);\n }\n if (pack.providers) {\n const providers = [...pack.providers];\n host.providers.registerAll(providers);\n for (const p of providers) registeredProviderTypes.push(p.type);\n }\n if (pack.slashCommands) {\n const cmds = [...pack.slashCommands];\n host.slashCommands.registerAll(cmds, owner);\n // SlashCommandRegistry stores plugin-owned commands under `${owner}:${name}`;\n // track the real lookup key so teardown can unregister them.\n for (const c of cmds)\n registeredCommandNames.push(owner === 'core' ? c.name : `${owner}:${c.name}`);\n }\n if (pack.extensions && host.extensions) {\n for (const ext of pack.extensions) {\n unregisterExtensions.push(host.extensions.register(ext));\n }\n }\n\n // If setup() throws after registration, roll back everything we registered above.\n // This makes applyWrongStackPack() transactional from the caller's perspective —\n // either the pack is fully applied or it is not.\n if (pack.setup) {\n if (!opts.api) {\n throw new Error(`Pack \"${pack.name}\" defines setup() but no PluginAPI was provided`);\n }\n try {\n await pack.setup(opts.api);\n } catch (setupErr) {\n // Roll back in reverse order: extensions first, then commands,\n // then tools, then providers. Extensions are unregistered before\n // tools/commands because extensions may depend on those capabilities;\n // tearing them down first avoids dangling refs.\n for (let i = unregisterExtensions.length - 1; i >= 0; i--) {\n unregisterExtensions[i]!();\n }\n for (let i = registeredCommandNames.length - 1; i >= 0; i--) {\n host.slashCommands.unregister(registeredCommandNames[i]!);\n }\n for (let i = registeredToolNames.length - 1; i >= 0; i--) {\n host.tools.unregister(registeredToolNames[i]!);\n }\n for (let i = registeredProviderTypes.length - 1; i >= 0; i--) {\n host.providers.unregister(registeredProviderTypes[i]!);\n }\n throw setupErr;\n }\n }\n\n return {\n pack,\n owner,\n async teardown() {\n for (let i = unregisterExtensions.length - 1; i >= 0; i--) {\n unregisterExtensions[i]!();\n }\n // Unregister commands, tools, and providers so the same pack can be\n // re-loaded cleanly without name/type conflicts.\n for (let i = registeredCommandNames.length - 1; i >= 0; i--) {\n host.slashCommands.unregister(registeredCommandNames[i]!);\n }\n for (let i = registeredToolNames.length - 1; i >= 0; i--) {\n host.tools.unregister(registeredToolNames[i]!);\n }\n for (let i = registeredProviderTypes.length - 1; i >= 0; i--) {\n host.providers.unregister(registeredProviderTypes[i]!);\n }\n if (pack.teardown) {\n if (!opts.api) {\n throw new Error(`Pack \"${pack.name}\" defines teardown() but no PluginAPI was provided`);\n }\n await pack.teardown(opts.api);\n }\n },\n };\n}\n\nexport async function applyWrongStackPacks(\n host: Pick<RuntimeHost, 'tools' | 'providers' | 'slashCommands'> & {\n extensions?: ExtensionRegistry | undefined;\n },\n packs: readonly WrongStackPack[],\n opts: ApplyPackOptions = {},\n): Promise<AppliedPack[]> {\n const applied: AppliedPack[] = [];\n try {\n for (const pack of packs) {\n applied.push(await applyWrongStackPack(host, pack, opts));\n }\n return applied;\n } catch (err) {\n // Roll back already-mounted packs. Surface teardown failures via\n // process.emitWarning so they don't mask the original error but\n // remain visible — a silent teardown failure can leave state\n // half-initialized in ways that make the next run fail mysteriously.\n for (let i = applied.length - 1; i >= 0; i--) {\n const mounted = applied[i]!;\n await mounted.teardown().catch((teardownErr) => {\n const detail = teardownErr instanceof Error ? teardownErr.message : String(teardownErr);\n process.emitWarning(\n `Pack teardown during error rollback failed: ${detail}`,\n 'PackRollbackWarning',\n );\n });\n }\n throw err;\n }\n}\n","/**\n * Local-LLM health probe — `GET <baseUrl>/v1/models`.\n *\n * This module lives in `@wrongstack/runtime` (not `@wrongstack/cli` or\n * `@wrongstack/providers`) so the WebUI server can reuse it without\n * pulling in the entire CLI dependency graph. The function is\n * identical to the one in `@wrongstack/cli/src/auth-menu/local.ts` —\n * we keep a single canonical implementation here and have the CLI\n * re-export from this one.\n *\n * The probe:\n * - Hits `GET <baseUrl>/models` (OpenAI-compatible)\n * - Sends an optional `Authorization: Bearer <key>` header\n * - Scrubs every result through the `SecretScrubber` so a Bearer\n * token accidentally captured in an error page never reaches\n * the renderer\n * - Returns a `ProbeResult` (never throws) so the caller can\n * decide how to react to each `status`\n */\nimport type { SecretScrubber } from '@wrongstack/core';\n\n/** Default probe timeout. Local servers should respond in < 100ms. */\nconst PROBE_TIMEOUT_MS = 3_000;\n\nexport interface ProbeOptions {\n baseUrl: string;\n apiKey: string | undefined;\n noAuth: boolean;\n /**\n * Display label for the probed server — the CLI uses this in the\n * rendered probe result (\"Ollama health probe ok\"). Optional; the\n * probe itself doesn't care.\n */\n presetLabel?: string | undefined;\n /** Used to scrub error-page bodies and network error messages. */\n scrubber: SecretScrubber;\n fetchImpl?: typeof fetch | undefined;\n timeoutMs?: number | undefined;\n}\n\nexport interface ProbeResult {\n ok: boolean;\n status:\n | 'ok'\n | 'unreachable'\n | 'timeout'\n | 'http_error'\n | 'invalid_response'\n | 'skipped'\n | 'no_provider'\n | 'no_base_url';\n httpStatus?: number | undefined;\n elapsedMs?: number | undefined;\n modelCount?: number | undefined;\n /**\n * The actual model ids returned by the server, deduplicated, in\n * server-reported order. Empty (not undefined) when the server\n * returned a valid empty list.\n */\n modelIds?: string[] | undefined;\n /** Redactable error detail (e.g. ECONNREFUSED). */\n detail?: string | undefined;\n}\n\n/**\n * Probe a local LLM server by hitting the OpenAI-compatible\n * `GET /v1/models` endpoint.\n *\n * The probe is fully isolated from the config layer — it only\n * returns a `ProbeResult` and never throws.\n */\nexport async function probeLocalLlm(opts: ProbeOptions): Promise<ProbeResult> {\n const { baseUrl, apiKey, noAuth, scrubber, fetchImpl, timeoutMs } = opts;\n const fetchFn = fetchImpl ?? fetch;\n const timeout = timeoutMs ?? PROBE_TIMEOUT_MS;\n\n // Normalize the URL: append `/models` if the user gave us the chat\n // completions base. Strip trailing slashes so we can just concatenate.\n const base = baseUrl.replace(/\\/+$/, '');\n const url = /\\/models$/.test(base) ? base : `${base}/models`;\n\n const headers: Record<string, string> = { accept: 'application/json' };\n if (!noAuth && apiKey) {\n headers['authorization'] = `Bearer ${apiKey}`;\n }\n\n const started = Date.now();\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'GET',\n headers,\n signal: AbortSignal.timeout(timeout),\n });\n } catch (err) {\n const elapsed = Date.now() - started;\n const name = (err as { name?: string } | null)?.name;\n if (name === 'TimeoutError' || name === 'AbortError') {\n return { ok: false, status: 'timeout', elapsedMs: elapsed, detail: `> ${timeout}ms` };\n }\n const detail = scrubber.scrub((err as Error)?.message ?? String(err));\n return { ok: false, status: 'unreachable', elapsedMs: elapsed, detail };\n }\n\n const elapsed = Date.now() - started;\n\n if (!res.ok) {\n let bodySlice = '';\n try {\n const txt = await res.text();\n bodySlice = txt.slice(0, 200);\n } catch {\n // ignore\n }\n return {\n ok: false,\n status: 'http_error',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: scrubber.scrub(bodySlice) || undefined,\n };\n }\n\n const modelIds: string[] = [];\n try {\n const parsed = (await res.json()) as unknown;\n if (!parsed || typeof parsed !== 'object') {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: 'response is not a JSON object',\n };\n }\n const obj = parsed as Record<string, unknown>;\n const dataList = obj['data'];\n const modelsList = obj['models'];\n const rawList: unknown[] | null = Array.isArray(dataList)\n ? (dataList as unknown[])\n : Array.isArray(modelsList)\n ? (modelsList as unknown[])\n : null;\n if (rawList === null) {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: 'no `data` or `models` array in response',\n };\n }\n const seen = new Set<string>();\n for (const entry of rawList) {\n if (!entry || typeof entry !== 'object') continue;\n const e = entry as Record<string, unknown>;\n const raw =\n typeof e['id'] === 'string' ? e['id'] : typeof e['name'] === 'string' ? e['name'] : null;\n if (raw === null) continue;\n const id = scrubber.scrub(raw).trim();\n if (id.length === 0) continue;\n if (seen.has(id)) continue;\n seen.add(id);\n modelIds.push(id);\n }\n } catch (err) {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: scrubber.scrub((err as Error)?.message ?? 'parse failed'),\n };\n }\n\n return {\n ok: true,\n status: 'ok',\n httpStatus: res.status,\n elapsedMs: elapsed,\n modelCount: modelIds.length,\n modelIds,\n };\n}\n","import * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { ContentBlock, Context, ImageBlock, Tool, ToolRegistry } from '@wrongstack/core';\nimport { assertNotPrivateHost } from '@wrongstack/core';\n\nexport interface VisionAdapterInput {\n image: ImageBlock;\n prompt?: string | undefined;\n ctx: Context;\n signal: AbortSignal;\n}\n\nexport interface VisionAdapter {\n name: string;\n describe(input: VisionAdapterInput): Promise<string>;\n}\n\nexport type VisionAdapters =\n | readonly VisionAdapter[]\n | (() => readonly VisionAdapter[] | Promise<readonly VisionAdapter[]>);\n\nexport interface VisionRoutingOptions {\n supportsVision: boolean;\n adapters?: VisionAdapters | undefined;\n ctx: Context;\n signal: AbortSignal;\n prompt?: string | undefined;\n providerId?: string | undefined;\n model?: string | undefined;\n}\n\nexport interface VisionRoutingResult {\n blocks: ContentBlock[];\n route: 'native' | 'adapter' | 'none';\n convertedImages: number;\n adapterName?: string | undefined;\n}\n\nexport class ImageInputUnsupportedError extends Error {\n constructor(opts: {\n providerId?: string | undefined;\n model?: string | undefined;\n imageCount: number;\n }) {\n const target = [opts.providerId, opts.model].filter(Boolean).join('/') || 'current model';\n super(\n `${target} does not support image input, and no image-understanding adapter is available for ${opts.imageCount} image${opts.imageCount === 1 ? '' : 's'}. Switch to a vision model or enable an MCP/tool adapter that can describe images.`,\n );\n this.name = 'ImageInputUnsupportedError';\n }\n}\n\n/**\n * Thrown when an image URL targets a private / loopback / IMDS address.\n * Vision adapters forward URLs straight to the underlying tool, so without\n * this check a malicious (or accidentally-malformed) `image.source.url`\n * could turn image analysis into an SSRF vector hitting localhost, RFC1918\n * ranges, or the cloud metadata endpoint.\n *\n * Carries the rejected URL so callers can log / surface it without parsing\n * the message.\n */\nexport class VisionUrlBlockedError extends Error {\n readonly url: string;\n\n constructor(opts: { url: string; reason: string }) {\n super(`vision: blocked unsafe image URL \"${opts.url}\" (${opts.reason})`);\n this.name = 'VisionUrlBlockedError';\n this.url = opts.url;\n }\n}\n\nexport async function routeImagesForModel(\n blocks: ContentBlock[],\n opts: VisionRoutingOptions,\n): Promise<VisionRoutingResult> {\n const images = blocks.filter((b): b is ImageBlock => b.type === 'image');\n if (images.length === 0) {\n return { blocks, route: 'none', convertedImages: 0 };\n }\n if (opts.supportsVision) {\n // Native vision providers typically fetch image URLs server-side, so\n // enforce the same SSRF guard used for adapter routes.\n for (const img of images) {\n if (img.source.type === 'url' && img.source.url) {\n try {\n await assertNotPrivateHost(new URL(img.source.url).hostname);\n } catch (err) {\n const reason =\n err instanceof Error && err.message.startsWith('fetch:')\n ? err.message.slice('fetch:'.length).trim()\n : 'unresolvable host';\n throw new VisionUrlBlockedError({ url: img.source.url, reason });\n }\n }\n }\n return { blocks, route: 'native', convertedImages: 0 };\n }\n\n const adapters = await resolveAdapters(opts.adapters);\n if (adapters.length === 0) {\n throw new ImageInputUnsupportedError({\n providerId: opts.providerId,\n model: opts.model,\n imageCount: images.length,\n });\n }\n\n const out: ContentBlock[] = [];\n let convertedImages = 0;\n let lastErr: unknown;\n let adapterName: string | undefined;\n for (const block of blocks) {\n if (block.type !== 'image') {\n out.push(block);\n continue;\n }\n let description: string | undefined;\n for (const adapter of adapters) {\n try {\n description = await adapter.describe({\n image: block,\n prompt: opts.prompt,\n ctx: opts.ctx,\n signal: opts.signal,\n });\n adapterName = adapter.name;\n break;\n } catch (err) {\n lastErr = err;\n }\n }\n if (!description?.trim()) {\n throw new Error(\n `No image-understanding adapter could process an image.${lastErr instanceof Error ? ` Last error: ${lastErr.message}` : ''}`,\n );\n }\n convertedImages++;\n out.push({\n type: 'text',\n text: `[Image ${convertedImages} analyzed via ${adapterName ?? 'vision adapter'}]\\n${description.trim()}`,\n });\n }\n\n return { blocks: out, route: 'adapter', convertedImages, adapterName };\n}\n\nasync function resolveAdapters(\n adapters: VisionAdapters | undefined,\n): Promise<readonly VisionAdapter[]> {\n if (!adapters) return [];\n return typeof adapters === 'function' ? await adapters() : adapters;\n}\n\nexport interface ToolVisionAdapterOptions {\n prompt?: string | undefined;\n}\n\nexport function createToolVisionAdapters(\n registry: ToolRegistry,\n opts: ToolVisionAdapterOptions = {},\n): VisionAdapter[] {\n return registry\n .list()\n .filter(isLikelyVisionTool)\n .map((tool) => ({\n name: tool.name,\n async describe(input: VisionAdapterInput): Promise<string> {\n const currentTool = registry.get(tool.name);\n if (!currentTool) {\n throw new Error(`Tool \"${tool.name}\" is no longer registered`);\n }\n const built = await buildToolPayload(currentTool, input.image, input.prompt ?? opts.prompt);\n if (!built) {\n throw new Error(\n `Tool \"${currentTool.name}\" does not expose a supported image input schema`,\n );\n }\n try {\n const result = await currentTool.execute(built.payload, input.ctx, {\n signal: input.signal,\n });\n return stringifyToolResult(result);\n } finally {\n await built.cleanup?.();\n }\n },\n }));\n}\n\nexport const VISION_IMAGE_KEYS = [\n 'image',\n 'base64',\n 'data',\n 'url',\n 'image_url',\n 'imageUrl',\n 'path',\n 'image_path',\n 'imagePath',\n 'file_path',\n 'filePath',\n 'filename',\n 'file',\n 'mediaType',\n 'mimeType',\n] as const;\n\nexport const VISION_PATH_KEYS = [\n 'path',\n 'image_path',\n 'imagePath',\n 'image_url',\n 'imageUrl',\n 'file_path',\n 'filePath',\n 'filename',\n 'file',\n] as const;\n\nexport const VISION_MEDIA_TYPE_KEYS = ['mediaType', 'mimeType', 'media_type'] as const;\nexport const VISION_PROMPT_KEYS = ['prompt', 'query', 'instruction'] as const;\n\nfunction isLikelyVisionTool(tool: Tool): boolean {\n if (tool.permission !== 'auto' || tool.mutating) return false;\n const haystack = `${tool.name} ${tool.description ?? ''} ${tool.usageHint ?? ''}`.toLowerCase();\n if (/(generate|create|draw|paint|edit|upscale|remove|write|delete)/.test(haystack)) return false;\n if (!/(vision|image|screenshot|ocr|describe|analy[sz]e)/.test(haystack)) return false;\n const props = schemaProperties(tool);\n return VISION_IMAGE_KEYS.some((key) => key in props);\n}\n\nasync function buildToolPayload(\n tool: Tool,\n image: ImageBlock,\n prompt = 'Describe this image for a coding agent. Include visible text, UI state, errors, layout, and any details needed to answer the user.',\n): Promise<{ payload: Record<string, unknown>; cleanup?: () => Promise<void> } | null> {\n const props = schemaProperties(tool);\n const payload: Record<string, unknown> = {};\n const mediaType = image.source.media_type ?? 'image/png';\n const data = image.source.data;\n const url = image.source.url;\n let cleanup: (() => Promise<void>) | undefined;\n\n // SSRF guard: when the image is referenced by URL, validate the host\n // BEFORE forwarding it to the underlying vision tool. The tool may\n // itself fetch the URL (the typical case for an MCP image-understanding\n // adapter), so a URL pointing at localhost / 127.0.0.1 / 169.254.169.254\n // / RFC1918 ranges would otherwise become an SSRF vector. Without this\n // gate, vision is a back-door around the fetch.ts SSRF guard (which\n // only applies when the explicit `fetch` tool is invoked).\n if (image.source.type === 'url' && url) {\n try {\n await assertNotPrivateHost(new URL(url).hostname);\n } catch (err) {\n const reason =\n err instanceof Error && err.message.startsWith('fetch:')\n ? err.message.slice('fetch:'.length).trim()\n : 'unresolvable host';\n throw new VisionUrlBlockedError({ url, reason });\n }\n }\n\n const pathKey = firstPresent(props, [...VISION_PATH_KEYS]);\n if (pathKey && image.source.type === 'base64' && data) {\n const p = await writeTempImage(data, mediaType);\n payload[pathKey] = p;\n cleanup = async () => {\n await fs.unlink(p).catch(() => undefined);\n await fs.rmdir(path.dirname(p)).catch(() => undefined);\n };\n } else if ('image' in props) {\n payload.image =\n image.source.type === 'base64'\n ? { type: 'base64', mediaType, media_type: mediaType, data }\n : { type: 'url', url };\n } else if (image.source.type === 'base64' && 'base64' in props) {\n payload.base64 = data;\n } else if (image.source.type === 'base64' && 'data' in props) {\n payload.data = data;\n } else if (image.source.type === 'url' && 'url' in props) {\n payload.url = url;\n } else if (image.source.type === 'url' && 'image_url' in props) {\n payload.image_url = url;\n } else if (image.source.type === 'url' && 'imageUrl' in props) {\n payload.imageUrl = url;\n } else {\n return null;\n }\n\n for (const key of VISION_MEDIA_TYPE_KEYS) {\n if (key in props) payload[key] = mediaType;\n }\n for (const key of VISION_PROMPT_KEYS) {\n if (key in props) payload[key] = prompt;\n }\n const built: { payload: Record<string, unknown>; cleanup?: () => Promise<void> } = { payload };\n if (cleanup !== undefined) built.cleanup = cleanup;\n return built;\n}\n\nfunction firstPresent(props: Record<string, unknown>, keys: string[]): string | undefined {\n return keys.find((key) => key in props);\n}\n\nasync function writeTempImage(data: string, mediaType: string): Promise<string> {\n const ext = mediaType.includes('jpeg') || mediaType.includes('jpg') ? 'jpg' : 'png';\n const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'wstack-vision-'));\n const file = path.join(dir, `image.${ext}`);\n await fs.writeFile(file, data, 'base64');\n return file;\n}\n\nfunction schemaProperties(tool: Tool): Record<string, unknown> {\n const schema = tool.inputSchema;\n if (!schema || typeof schema !== 'object') return {};\n const props = (schema as { properties?: unknown | undefined }).properties;\n return props && typeof props === 'object' ? (props as Record<string, unknown>) : {};\n}\n\nfunction stringifyToolResult(value: unknown): string {\n if (typeof value === 'string') return value;\n if (Array.isArray(value)) {\n return value\n .map((item) => {\n if (item && typeof item === 'object' && 'text' in item) {\n return String((item as { text?: unknown | undefined }).text ?? '');\n }\n return typeof item === 'string' ? item : JSON.stringify(item);\n })\n .join('\\n');\n }\n if (value && typeof value === 'object' && 'text' in value) {\n return String((value as { text?: unknown | undefined }).text ?? '');\n }\n return JSON.stringify(value);\n}\n"]}
package/dist/probe.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/local-llm-probe.ts"],"names":["elapsed"],"mappings":"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","file":"probe.js","sourcesContent":["/**\n * Local-LLM health probe — `GET <baseUrl>/v1/models`.\n *\n * This module lives in `@wrongstack/runtime` (not `@wrongstack/cli` or\n * `@wrongstack/providers`) so the WebUI server can reuse it without\n * pulling in the entire CLI dependency graph. The function is\n * identical to the one in `@wrongstack/cli/src/auth-menu/local.ts` —\n * we keep a single canonical implementation here and have the CLI\n * re-export from this one.\n *\n * The probe:\n * - Hits `GET <baseUrl>/models` (OpenAI-compatible)\n * - Sends an optional `Authorization: Bearer <key>` header\n * - Scrubs every result through the `SecretScrubber` so a Bearer\n * token accidentally captured in an error page never reaches\n * the renderer\n * - Returns a `ProbeResult` (never throws) so the caller can\n * decide how to react to each `status`\n */\nimport type { SecretScrubber } from '@wrongstack/core';\n\n/** Default probe timeout. Local servers should respond in < 100ms. */\nconst PROBE_TIMEOUT_MS = 3_000;\n\nexport interface ProbeOptions {\n baseUrl: string;\n apiKey: string | undefined;\n noAuth: boolean;\n /**\n * Display label for the probed server — the CLI uses this in the\n * rendered probe result (\"Ollama health probe ok\"). Optional; the\n * probe itself doesn't care.\n */\n presetLabel?: string | undefined;\n /** Used to scrub error-page bodies and network error messages. */\n scrubber: SecretScrubber;\n fetchImpl?: typeof fetch | undefined;\n timeoutMs?: number | undefined;\n}\n\nexport interface ProbeResult {\n ok: boolean;\n status:\n | 'ok'\n | 'unreachable'\n | 'timeout'\n | 'http_error'\n | 'invalid_response'\n | 'skipped'\n | 'no_provider'\n | 'no_base_url';\n httpStatus?: number | undefined;\n elapsedMs?: number | undefined;\n modelCount?: number | undefined;\n /**\n * The actual model ids returned by the server, deduplicated, in\n * server-reported order. Empty (not undefined) when the server\n * returned a valid empty list.\n */\n modelIds?: string[] | undefined;\n /** Redactable error detail (e.g. ECONNREFUSED). */\n detail?: string | undefined;\n}\n\n/**\n * Probe a local LLM server by hitting the OpenAI-compatible\n * `GET /v1/models` endpoint.\n *\n * The probe is fully isolated from the config layer — it only\n * returns a `ProbeResult` and never throws.\n */\nexport async function probeLocalLlm(opts: ProbeOptions): Promise<ProbeResult> {\n const { baseUrl, apiKey, noAuth, scrubber, fetchImpl, timeoutMs } = opts;\n const fetchFn = fetchImpl ?? fetch;\n const timeout = timeoutMs ?? PROBE_TIMEOUT_MS;\n\n // Normalize the URL: append `/models` if the user gave us the chat\n // completions base. Strip trailing slashes so we can just concatenate.\n const base = baseUrl.replace(/\\/+$/, '');\n const url = /\\/models$/.test(base) ? base : `${base}/models`;\n\n const headers: Record<string, string> = { accept: 'application/json' };\n if (!noAuth && apiKey) {\n headers['authorization'] = `Bearer ${apiKey}`;\n }\n\n const started = Date.now();\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'GET',\n headers,\n signal: AbortSignal.timeout(timeout),\n });\n } catch (err) {\n const elapsed = Date.now() - started;\n const name = (err as { name?: string } | null)?.name;\n if (name === 'TimeoutError' || name === 'AbortError') {\n return { ok: false, status: 'timeout', elapsedMs: elapsed, detail: `> ${timeout}ms` };\n }\n const detail = scrubber.scrub((err as Error)?.message ?? String(err));\n return { ok: false, status: 'unreachable', elapsedMs: elapsed, detail };\n }\n\n const elapsed = Date.now() - started;\n\n if (!res.ok) {\n let bodySlice = '';\n try {\n const txt = await res.text();\n bodySlice = txt.slice(0, 200);\n } catch {\n // ignore\n }\n return {\n ok: false,\n status: 'http_error',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: scrubber.scrub(bodySlice) || undefined,\n };\n }\n\n const modelIds: string[] = [];\n try {\n const parsed = (await res.json()) as unknown;\n if (!parsed || typeof parsed !== 'object') {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: 'response is not a JSON object',\n };\n }\n const obj = parsed as Record<string, unknown>;\n const dataList = obj['data'];\n const modelsList = obj['models'];\n const rawList: unknown[] | null = Array.isArray(dataList)\n ? (dataList as unknown[])\n : Array.isArray(modelsList)\n ? (modelsList as unknown[])\n : null;\n if (rawList === null) {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: 'no `data` or `models` array in response',\n };\n }\n const seen = new Set<string>();\n for (const entry of rawList) {\n if (!entry || typeof entry !== 'object') continue;\n const e = entry as Record<string, unknown>;\n const raw =\n typeof e['id'] === 'string'\n ? e['id']\n : typeof e['name'] === 'string'\n ? e['name']\n : null;\n if (raw === null) continue;\n const id = scrubber.scrub(raw).trim();\n if (id.length === 0) continue;\n if (seen.has(id)) continue;\n seen.add(id);\n modelIds.push(id);\n }\n } catch (err) {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: scrubber.scrub((err as Error)?.message ?? 'parse failed'),\n };\n }\n\n return {\n ok: true,\n status: 'ok',\n httpStatus: res.status,\n elapsedMs: elapsed,\n modelCount: modelIds.length,\n modelIds,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/local-llm-probe.ts"],"names":["elapsed"],"mappings":"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","file":"probe.js","sourcesContent":["/**\n * Local-LLM health probe — `GET <baseUrl>/v1/models`.\n *\n * This module lives in `@wrongstack/runtime` (not `@wrongstack/cli` or\n * `@wrongstack/providers`) so the WebUI server can reuse it without\n * pulling in the entire CLI dependency graph. The function is\n * identical to the one in `@wrongstack/cli/src/auth-menu/local.ts` —\n * we keep a single canonical implementation here and have the CLI\n * re-export from this one.\n *\n * The probe:\n * - Hits `GET <baseUrl>/models` (OpenAI-compatible)\n * - Sends an optional `Authorization: Bearer <key>` header\n * - Scrubs every result through the `SecretScrubber` so a Bearer\n * token accidentally captured in an error page never reaches\n * the renderer\n * - Returns a `ProbeResult` (never throws) so the caller can\n * decide how to react to each `status`\n */\nimport type { SecretScrubber } from '@wrongstack/core';\n\n/** Default probe timeout. Local servers should respond in < 100ms. */\nconst PROBE_TIMEOUT_MS = 3_000;\n\nexport interface ProbeOptions {\n baseUrl: string;\n apiKey: string | undefined;\n noAuth: boolean;\n /**\n * Display label for the probed server — the CLI uses this in the\n * rendered probe result (\"Ollama health probe ok\"). Optional; the\n * probe itself doesn't care.\n */\n presetLabel?: string | undefined;\n /** Used to scrub error-page bodies and network error messages. */\n scrubber: SecretScrubber;\n fetchImpl?: typeof fetch | undefined;\n timeoutMs?: number | undefined;\n}\n\nexport interface ProbeResult {\n ok: boolean;\n status:\n | 'ok'\n | 'unreachable'\n | 'timeout'\n | 'http_error'\n | 'invalid_response'\n | 'skipped'\n | 'no_provider'\n | 'no_base_url';\n httpStatus?: number | undefined;\n elapsedMs?: number | undefined;\n modelCount?: number | undefined;\n /**\n * The actual model ids returned by the server, deduplicated, in\n * server-reported order. Empty (not undefined) when the server\n * returned a valid empty list.\n */\n modelIds?: string[] | undefined;\n /** Redactable error detail (e.g. ECONNREFUSED). */\n detail?: string | undefined;\n}\n\n/**\n * Probe a local LLM server by hitting the OpenAI-compatible\n * `GET /v1/models` endpoint.\n *\n * The probe is fully isolated from the config layer — it only\n * returns a `ProbeResult` and never throws.\n */\nexport async function probeLocalLlm(opts: ProbeOptions): Promise<ProbeResult> {\n const { baseUrl, apiKey, noAuth, scrubber, fetchImpl, timeoutMs } = opts;\n const fetchFn = fetchImpl ?? fetch;\n const timeout = timeoutMs ?? PROBE_TIMEOUT_MS;\n\n // Normalize the URL: append `/models` if the user gave us the chat\n // completions base. Strip trailing slashes so we can just concatenate.\n const base = baseUrl.replace(/\\/+$/, '');\n const url = /\\/models$/.test(base) ? base : `${base}/models`;\n\n const headers: Record<string, string> = { accept: 'application/json' };\n if (!noAuth && apiKey) {\n headers['authorization'] = `Bearer ${apiKey}`;\n }\n\n const started = Date.now();\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'GET',\n headers,\n signal: AbortSignal.timeout(timeout),\n });\n } catch (err) {\n const elapsed = Date.now() - started;\n const name = (err as { name?: string } | null)?.name;\n if (name === 'TimeoutError' || name === 'AbortError') {\n return { ok: false, status: 'timeout', elapsedMs: elapsed, detail: `> ${timeout}ms` };\n }\n const detail = scrubber.scrub((err as Error)?.message ?? String(err));\n return { ok: false, status: 'unreachable', elapsedMs: elapsed, detail };\n }\n\n const elapsed = Date.now() - started;\n\n if (!res.ok) {\n let bodySlice = '';\n try {\n const txt = await res.text();\n bodySlice = txt.slice(0, 200);\n } catch {\n // ignore\n }\n return {\n ok: false,\n status: 'http_error',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: scrubber.scrub(bodySlice) || undefined,\n };\n }\n\n const modelIds: string[] = [];\n try {\n const parsed = (await res.json()) as unknown;\n if (!parsed || typeof parsed !== 'object') {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: 'response is not a JSON object',\n };\n }\n const obj = parsed as Record<string, unknown>;\n const dataList = obj['data'];\n const modelsList = obj['models'];\n const rawList: unknown[] | null = Array.isArray(dataList)\n ? (dataList as unknown[])\n : Array.isArray(modelsList)\n ? (modelsList as unknown[])\n : null;\n if (rawList === null) {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: 'no `data` or `models` array in response',\n };\n }\n const seen = new Set<string>();\n for (const entry of rawList) {\n if (!entry || typeof entry !== 'object') continue;\n const e = entry as Record<string, unknown>;\n const raw =\n typeof e['id'] === 'string' ? e['id'] : typeof e['name'] === 'string' ? e['name'] : null;\n if (raw === null) continue;\n const id = scrubber.scrub(raw).trim();\n if (id.length === 0) continue;\n if (seen.has(id)) continue;\n seen.add(id);\n modelIds.push(id);\n }\n } catch (err) {\n return {\n ok: false,\n status: 'invalid_response',\n httpStatus: res.status,\n elapsedMs: elapsed,\n detail: scrubber.scrub((err as Error)?.message ?? 'parse failed'),\n };\n }\n\n return {\n ok: true,\n status: 'ok',\n httpStatus: res.status,\n elapsedMs: elapsed,\n modelCount: modelIds.length,\n modelIds,\n };\n}\n"]}
package/dist/vision.d.ts CHANGED
@@ -55,5 +55,9 @@ interface ToolVisionAdapterOptions {
55
55
  prompt?: string | undefined;
56
56
  }
57
57
  declare function createToolVisionAdapters(registry: ToolRegistry, opts?: ToolVisionAdapterOptions): VisionAdapter[];
58
+ declare const VISION_IMAGE_KEYS: readonly ["image", "base64", "data", "url", "image_url", "imageUrl", "path", "image_path", "imagePath", "file_path", "filePath", "filename", "file", "mediaType", "mimeType"];
59
+ declare const VISION_PATH_KEYS: readonly ["path", "image_path", "imagePath", "image_url", "imageUrl", "file_path", "filePath", "filename", "file"];
60
+ declare const VISION_MEDIA_TYPE_KEYS: readonly ["mediaType", "mimeType", "media_type"];
61
+ declare const VISION_PROMPT_KEYS: readonly ["prompt", "query", "instruction"];
58
62
 
59
- export { ImageInputUnsupportedError, type ToolVisionAdapterOptions, type VisionAdapter, type VisionAdapterInput, type VisionAdapters, type VisionRoutingOptions, type VisionRoutingResult, VisionUrlBlockedError, createToolVisionAdapters, routeImagesForModel };
63
+ export { ImageInputUnsupportedError, type ToolVisionAdapterOptions, VISION_IMAGE_KEYS, VISION_MEDIA_TYPE_KEYS, VISION_PATH_KEYS, VISION_PROMPT_KEYS, type VisionAdapter, type VisionAdapterInput, type VisionAdapters, type VisionRoutingOptions, type VisionRoutingResult, VisionUrlBlockedError, createToolVisionAdapters, routeImagesForModel };
package/dist/vision.js CHANGED
@@ -27,6 +27,16 @@ async function routeImagesForModel(blocks, opts) {
27
27
  return { blocks, route: "none", convertedImages: 0 };
28
28
  }
29
29
  if (opts.supportsVision) {
30
+ for (const img of images) {
31
+ if (img.source.type === "url" && img.source.url) {
32
+ try {
33
+ await assertNotPrivateHost(new URL(img.source.url).hostname);
34
+ } catch (err) {
35
+ const reason = err instanceof Error && err.message.startsWith("fetch:") ? err.message.slice("fetch:".length).trim() : "unresolvable host";
36
+ throw new VisionUrlBlockedError({ url: img.source.url, reason });
37
+ }
38
+ }
39
+ }
30
40
  return { blocks, route: "native", convertedImages: 0 };
31
41
  }
32
42
  const adapters = await resolveAdapters(opts.adapters);
@@ -89,7 +99,9 @@ function createToolVisionAdapters(registry, opts = {}) {
89
99
  }
90
100
  const built = await buildToolPayload(currentTool, input.image, input.prompt ?? opts.prompt);
91
101
  if (!built) {
92
- throw new Error(`Tool "${currentTool.name}" does not expose a supported image input schema`);
102
+ throw new Error(
103
+ `Tool "${currentTool.name}" does not expose a supported image input schema`
104
+ );
93
105
  }
94
106
  try {
95
107
  const result = await currentTool.execute(built.payload, input.ctx, {
@@ -102,31 +114,43 @@ function createToolVisionAdapters(registry, opts = {}) {
102
114
  }
103
115
  }));
104
116
  }
117
+ var VISION_IMAGE_KEYS = [
118
+ "image",
119
+ "base64",
120
+ "data",
121
+ "url",
122
+ "image_url",
123
+ "imageUrl",
124
+ "path",
125
+ "image_path",
126
+ "imagePath",
127
+ "file_path",
128
+ "filePath",
129
+ "filename",
130
+ "file",
131
+ "mediaType",
132
+ "mimeType"
133
+ ];
134
+ var VISION_PATH_KEYS = [
135
+ "path",
136
+ "image_path",
137
+ "imagePath",
138
+ "image_url",
139
+ "imageUrl",
140
+ "file_path",
141
+ "filePath",
142
+ "filename",
143
+ "file"
144
+ ];
145
+ var VISION_MEDIA_TYPE_KEYS = ["mediaType", "mimeType", "media_type"];
146
+ var VISION_PROMPT_KEYS = ["prompt", "query", "instruction"];
105
147
  function isLikelyVisionTool(tool) {
106
148
  if (tool.permission !== "auto" || tool.mutating) return false;
107
149
  const haystack = `${tool.name} ${tool.description ?? ""} ${tool.usageHint ?? ""}`.toLowerCase();
108
150
  if (/(generate|create|draw|paint|edit|upscale|remove|write|delete)/.test(haystack)) return false;
109
151
  if (!/(vision|image|screenshot|ocr|describe|analy[sz]e)/.test(haystack)) return false;
110
152
  const props = schemaProperties(tool);
111
- return [
112
- "image",
113
- "base64",
114
- "data",
115
- "url",
116
- "image_url",
117
- "imageUrl",
118
- "path",
119
- "image_path",
120
- "imagePath",
121
- "image_url",
122
- "imageUrl",
123
- "file_path",
124
- "filePath",
125
- "filename",
126
- "file",
127
- "mediaType",
128
- "mimeType"
129
- ].some((key) => key in props);
153
+ return VISION_IMAGE_KEYS.some((key) => key in props);
130
154
  }
131
155
  async function buildToolPayload(tool, image, prompt = "Describe this image for a coding agent. Include visible text, UI state, errors, layout, and any details needed to answer the user.") {
132
156
  const props = schemaProperties(tool);
@@ -143,17 +167,7 @@ async function buildToolPayload(tool, image, prompt = "Describe this image for a
143
167
  throw new VisionUrlBlockedError({ url, reason });
144
168
  }
145
169
  }
146
- const pathKey = firstPresent(props, [
147
- "path",
148
- "image_path",
149
- "imagePath",
150
- "image_url",
151
- "imageUrl",
152
- "file_path",
153
- "filePath",
154
- "filename",
155
- "file"
156
- ]);
170
+ const pathKey = firstPresent(props, [...VISION_PATH_KEYS]);
157
171
  if (pathKey && image.source.type === "base64" && data) {
158
172
  const p = await writeTempImage(data, mediaType);
159
173
  payload[pathKey] = p;
@@ -176,12 +190,12 @@ async function buildToolPayload(tool, image, prompt = "Describe this image for a
176
190
  } else {
177
191
  return null;
178
192
  }
179
- if ("mediaType" in props) payload.mediaType = mediaType;
180
- if ("mimeType" in props) payload.mimeType = mediaType;
181
- if ("media_type" in props) payload.media_type = mediaType;
182
- if ("prompt" in props) payload.prompt = prompt;
183
- if ("query" in props) payload.query = prompt;
184
- if ("instruction" in props) payload.instruction = prompt;
193
+ for (const key of VISION_MEDIA_TYPE_KEYS) {
194
+ if (key in props) payload[key] = mediaType;
195
+ }
196
+ for (const key of VISION_PROMPT_KEYS) {
197
+ if (key in props) payload[key] = prompt;
198
+ }
185
199
  const built = { payload };
186
200
  if (cleanup !== void 0) built.cleanup = cleanup;
187
201
  return built;
@@ -218,6 +232,6 @@ function stringifyToolResult(value) {
218
232
  return JSON.stringify(value);
219
233
  }
220
234
 
221
- export { ImageInputUnsupportedError, VisionUrlBlockedError, createToolVisionAdapters, routeImagesForModel };
235
+ export { ImageInputUnsupportedError, VISION_IMAGE_KEYS, VISION_MEDIA_TYPE_KEYS, VISION_PATH_KEYS, VISION_PROMPT_KEYS, VisionUrlBlockedError, createToolVisionAdapters, routeImagesForModel };
222
236
  //# sourceMappingURL=vision.js.map
223
237
  //# sourceMappingURL=vision.js.map