@wrongstack/runtime 0.293.0 → 0.295.1
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/README.md +10 -11
- package/dist/clipboard.js +1 -1
- package/dist/clipboard.js.map +1 -1
- package/dist/container.d.ts +5 -2
- package/dist/container.d.ts.map +1 -1
- package/dist/fleet/light-subagent-factory.d.ts +11 -1
- package/dist/fleet/light-subagent-factory.d.ts.map +1 -1
- package/dist/host.d.ts +5 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js.map +2 -2
- package/dist/index.d.ts +4 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +93 -61
- package/dist/index.js.map +4 -4
- package/dist/local-llm-probe.d.ts +1 -1
- package/dist/local-llm-probe.d.ts.map +1 -1
- package/dist/pack.d.ts +2 -1
- package/dist/pack.d.ts.map +1 -1
- package/dist/probe.js.map +1 -1
- package/dist/tool-registration.d.ts +26 -0
- package/dist/tool-registration.d.ts.map +1 -0
- package/dist/tool-registration.js +46 -0
- package/dist/tool-registration.js.map +7 -0
- package/dist/vision.d.ts +3 -1
- package/dist/vision.d.ts.map +1 -1
- package/dist/vision.js +1 -1
- package/dist/vision.js.map +2 -2
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
# @wrongstack/runtime
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Host composition and platform adapters for WrongStack.
|
|
4
4
|
|
|
5
|
-
`@wrongstack/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
models, skills, and host-level assembly helpers.
|
|
5
|
+
`@wrongstack/runtime` owns container composition, canonical host-tool
|
|
6
|
+
registration, image routing, clipboard access, the local-model probe, and
|
|
7
|
+
light-subagent assembly. These are real implementations, not aliases.
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
Core defaults are intentionally not re-exported. Import their declared Core
|
|
10
|
+
subpaths directly. The R4 observability pilot proved that moving a Core-owned
|
|
11
|
+
implementation here while retaining Core compatibility would create the
|
|
12
|
+
`Core -> Runtime -> Core` package cycle prohibited by ADR-004.
|
|
14
13
|
|
|
15
14
|
```ts
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
15
|
+
import { createDefaultContainer } from '@wrongstack/runtime';
|
|
16
|
+
import { DefaultTokenCounter } from '@wrongstack/core/infrastructure';
|
|
18
17
|
```
|
|
19
18
|
|
|
20
19
|
The `WrongStackPack` interface in `@wrongstack/runtime/pack` is the target shape
|
package/dist/clipboard.js
CHANGED
|
@@ -4,7 +4,7 @@ import { randomUUID } from "node:crypto";
|
|
|
4
4
|
import * as fs from "node:fs/promises";
|
|
5
5
|
import * as os from "node:os";
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import { buildChildEnv } from "@wrongstack/core";
|
|
7
|
+
import { buildChildEnv } from "@wrongstack/core/utils";
|
|
8
8
|
var MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
9
9
|
async function readClipboardImage() {
|
|
10
10
|
const platform = process.platform;
|
package/dist/clipboard.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/clipboard.ts"],
|
|
4
|
-
"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 \u2014 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 \u00ABclass PNGf\u00BB) 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"],
|
|
4
|
+
"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/utils';\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 \u2014 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 \u00ABclass PNGf\u00BB) 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"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/container.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type DefaultSystemPromptBuilderOptions } from '@wrongstack/core/agent';
|
|
2
|
+
import { Container, type EventBus } from '@wrongstack/core/kernel';
|
|
3
|
+
import type { Config, Logger, ModelsRegistry, Tool } from '@wrongstack/core/types';
|
|
4
|
+
import type { WstackPaths } from '@wrongstack/core/utils';
|
|
2
5
|
export interface CreateContainerOptions {
|
|
3
6
|
config: Config;
|
|
4
7
|
wpaths: WstackPaths;
|
|
5
8
|
logger: Logger;
|
|
6
9
|
modelsRegistry: ModelsRegistry;
|
|
7
10
|
/**
|
|
8
|
-
* Optional event bus — passed to
|
|
11
|
+
* Optional event bus — passed to SageStore so plugins and
|
|
9
12
|
* subsystems can react to memory mutations in real time.
|
|
10
13
|
*/
|
|
11
14
|
events?: EventBus | undefined;
|
package/dist/container.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iCAAiC,EAEvC,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAU,MAAM,yBAAyB,CAAC;AAS3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQ1D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,cAAc,CAAC;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC3B,cAAc,CAAC,EAAE,CACf,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,OAAO,EACd,gBAAgB,EAAE,MAAM,KACrB,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;KAChD,CAAC;IACF,SAAS,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IACpF,YAAY,CAAC,EAAE,OAAO,CAAC,iCAAiC,CAAC,GAAG,SAAS,CAAC;IACtE,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,SAAS,CA4L9E"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import { Agent
|
|
1
|
+
import { Agent } from '@wrongstack/core/agent';
|
|
2
|
+
import { type AgentFactory } from '@wrongstack/core/coordination';
|
|
3
|
+
import { type Container } from '@wrongstack/core/kernel';
|
|
4
|
+
import { type ProviderRegistry, ToolRegistry } from '@wrongstack/core/registry';
|
|
5
|
+
import type { ModelsRegistry, SessionWriter } from '@wrongstack/core/types';
|
|
2
6
|
export interface LightSubagentFactoryDeps {
|
|
3
7
|
/** DI container — used to resolve configStore / tokenCounter / scrubber / prompt builder. */
|
|
4
8
|
container: Container;
|
|
@@ -14,6 +18,12 @@ export interface LightSubagentFactoryDeps {
|
|
|
14
18
|
projectRoot: string;
|
|
15
19
|
/** Default cwd when a SubagentConfig doesn't pin one (worktree path otherwise). */
|
|
16
20
|
cwd?: string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Test hook — overrides the fallback extension's `now()` so cooldown
|
|
23
|
+
* assertions don't depend on real wall-clock time. Production callers
|
|
24
|
+
* should leave this unset.
|
|
25
|
+
*/
|
|
26
|
+
now?: (() => number) | undefined;
|
|
17
27
|
}
|
|
18
28
|
/**
|
|
19
29
|
* Retrieve and abort a light subagent's AbortController (stored in ctx.meta
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"light-subagent-factory.d.ts","sourceRoot":"","sources":["../../src/fleet/light-subagent-factory.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,EACL,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"light-subagent-factory.d.ts","sourceRoot":"","sources":["../../src/fleet/light-subagent-factory.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,EAKN,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,+BAA+B,CAAC;AAOvC,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,KAAK,EAEV,cAAc,EAGd,aAAa,EAId,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,wBAAwB;IACvC,6FAA6F;IAC7F,SAAS,EAAE,SAAS,CAAC;IACrB,8FAA8F;IAC9F,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,uEAAuE;IACvE,YAAY,EAAE,YAAY,CAAC;IAC3B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAC5C,iFAAiF;IACjF,OAAO,EAAE,aAAa,CAAC;IACvB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB;;;;OAIG;IACH,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CAClC;AAcD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAGrD;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,wBAAwB,GAAG,YAAY,CAoKrF"}
|
package/dist/host.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type { Agent, Context
|
|
1
|
+
import type { Agent, Context } from '@wrongstack/core/agent';
|
|
2
|
+
import type { ExtensionRegistry } from '@wrongstack/core/extension';
|
|
3
|
+
import type { EventBus } from '@wrongstack/core/kernel';
|
|
4
|
+
import type { ProviderRegistry, SlashCommandRegistry, ToolRegistry } from '@wrongstack/core/registry';
|
|
5
|
+
import type { PluginAPI, SessionWriter } from '@wrongstack/core/types';
|
|
2
6
|
import type { WrongStackPack } from './pack.js';
|
|
3
7
|
export interface RuntimeHost {
|
|
4
8
|
agent: Agent;
|
package/dist/host.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACb,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,aAAa,EAAE,oBAAoB,CAAC;IACpC,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC3C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,aAAa,EAAE,oBAAoB,CAAC;IACpC,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,EAAE,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC;CACrD;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAc/E;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,WAAW,GAAG,eAAe,CAAC,GAAG;IACjE,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC5C,EACD,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,WAAW,CAAC,CA0FtB;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,WAAW,GAAG,eAAe,CAAC,GAAG;IACjE,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC5C,EACD,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,WAAW,EAAE,CAAC,CAwBxB"}
|
package/dist/host.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/host.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["import type { Agent, Context } from '@wrongstack/core/agent';\nimport type { ExtensionRegistry } from '@wrongstack/core/extension';\nimport type { EventBus } from '@wrongstack/core/kernel';\nimport type {\n ProviderRegistry,\n SlashCommandRegistry,\n ToolRegistry,\n} from '@wrongstack/core/registry';\nimport type { PluginAPI, SessionWriter } from '@wrongstack/core/types';\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 \u2014\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 \u2014 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @wrongstack/runtime
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* - @wrongstack/core: kernel, agent runtime, registries, public contracts.
|
|
8
|
-
* - @wrongstack/runtime: default storage, security, config, observability,
|
|
9
|
-
* compaction, models, skills, and host composition helpers.
|
|
10
|
-
*
|
|
11
|
-
* For this first refactor slice, the implementations still physically live in
|
|
12
|
-
* @wrongstack/core and are re-exported here. That gives hosts a stable import
|
|
13
|
-
* target while later moves can happen behind this facade.
|
|
4
|
+
* Concrete host composition and platform adapters. Core-owned defaults are
|
|
5
|
+
* deliberately not re-exported: doing so obscures ownership and makes a
|
|
6
|
+
* Core-compatible Runtime implementation move cyclic at package level.
|
|
14
7
|
*/
|
|
15
|
-
export { DefaultSystemPromptBuilder, type DefaultSystemPromptBuilderOptions, } from '@wrongstack/core';
|
|
16
|
-
export * from '@wrongstack/core/defaults';
|
|
17
|
-
export { DefaultPathResolver, DefaultTokenCounter, } from '@wrongstack/core/infrastructure';
|
|
18
8
|
export * from './clipboard.js';
|
|
19
9
|
export * from './container.js';
|
|
20
|
-
export { type LightSubagentFactoryDeps, makeLightSubagentFactory, } from './fleet/light-subagent-factory.js';
|
|
10
|
+
export { abortLightSubagent, type LightSubagentFactoryDeps, makeLightSubagentFactory, } from './fleet/light-subagent-factory.js';
|
|
21
11
|
export * from './host.js';
|
|
22
12
|
export { type ProbeOptions, type ProbeResult, probeLocalLlm } from './local-llm-probe.js';
|
|
23
13
|
export * from './pack.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1F,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
import {
|
|
3
|
-
DefaultSystemPromptBuilder as DefaultSystemPromptBuilder2
|
|
4
|
-
} from "@wrongstack/core";
|
|
5
|
-
export * from "@wrongstack/core/defaults";
|
|
6
|
-
import {
|
|
7
|
-
DefaultPathResolver,
|
|
8
|
-
DefaultTokenCounter as DefaultTokenCounter2
|
|
9
|
-
} from "@wrongstack/core/infrastructure";
|
|
10
|
-
|
|
11
1
|
// src/clipboard.ts
|
|
12
2
|
import { spawn } from "node:child_process";
|
|
13
3
|
import { randomUUID } from "node:crypto";
|
|
14
4
|
import * as fs from "node:fs/promises";
|
|
15
5
|
import * as os from "node:os";
|
|
16
6
|
import * as path from "node:path";
|
|
17
|
-
import { buildChildEnv } from "@wrongstack/core";
|
|
7
|
+
import { buildChildEnv } from "@wrongstack/core/utils";
|
|
18
8
|
var MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
19
9
|
async function readClipboardImage() {
|
|
20
10
|
const platform = process.platform;
|
|
@@ -188,26 +178,32 @@ function runCmdToFile(cmd, args, outPath) {
|
|
|
188
178
|
}
|
|
189
179
|
|
|
190
180
|
// src/container.ts
|
|
181
|
+
import * as fs2 from "node:fs";
|
|
182
|
+
import * as path2 from "node:path";
|
|
183
|
+
import {
|
|
184
|
+
DefaultSystemPromptBuilder,
|
|
185
|
+
FallbackProfileManager
|
|
186
|
+
} from "@wrongstack/core/agent";
|
|
191
187
|
import {
|
|
192
|
-
Container,
|
|
193
188
|
createStrategyCompactor,
|
|
194
|
-
DefaultConfigStore,
|
|
195
189
|
DefaultErrorHandler,
|
|
196
|
-
FallbackProfileManager,
|
|
197
|
-
DefaultModeStore,
|
|
198
|
-
DefaultPermissionPolicy,
|
|
199
190
|
DefaultPromptLoader,
|
|
200
191
|
DefaultRetryPolicy,
|
|
192
|
+
DefaultSkillLoader
|
|
193
|
+
} from "@wrongstack/core/execution";
|
|
194
|
+
import { Container, TOKENS } from "@wrongstack/core/kernel";
|
|
195
|
+
import { DefaultModeStore } from "@wrongstack/core/models";
|
|
196
|
+
import {
|
|
197
|
+
DirectoryPermissionPolicy,
|
|
198
|
+
DefaultPermissionPolicy,
|
|
201
199
|
DefaultSecretScrubber,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
TOKENS
|
|
206
|
-
} from "@wrongstack/core";
|
|
200
|
+
validateDirectoryPolicy
|
|
201
|
+
} from "@wrongstack/core/security";
|
|
202
|
+
import { DefaultConfigStore, DefaultSessionStore } from "@wrongstack/core/storage";
|
|
207
203
|
import { buildRecoveryStrategies } from "@wrongstack/core/execution";
|
|
208
204
|
import { DefaultTokenCounter } from "@wrongstack/core/infrastructure";
|
|
209
205
|
import { getSessionRegistry } from "@wrongstack/core/storage";
|
|
210
|
-
import {
|
|
206
|
+
import { createSqliteMemoryPort, isSqliteAvailable } from "@wrongstack/sage";
|
|
211
207
|
function createDefaultContainer(opts) {
|
|
212
208
|
const { config, wpaths, logger, modelsRegistry } = opts;
|
|
213
209
|
const container = new Container();
|
|
@@ -268,23 +264,18 @@ function createDefaultContainer(opts) {
|
|
|
268
264
|
}
|
|
269
265
|
})
|
|
270
266
|
);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
logger.warn(
|
|
275
|
-
"Super Memory: SQLite engine requested but node:sqlite is unavailable in this runtime. Falling back to JSONL backend. (SQLite requires Node >= 22.5.)"
|
|
267
|
+
if (!isSqliteAvailable()) {
|
|
268
|
+
throw new Error(
|
|
269
|
+
"SAGE requires Node built-in SQLite (node:sqlite; Node >= 22.5). The JSONL compatibility fallback has been removed."
|
|
276
270
|
);
|
|
277
271
|
}
|
|
278
|
-
const memoryStore =
|
|
279
|
-
projectRoot: wpaths.projectRoot,
|
|
280
|
-
directory: config.superMemory?.storage?.directory,
|
|
281
|
-
events: opts.events
|
|
282
|
-
}) : new SuperMemoryStore({
|
|
272
|
+
const memoryStore = createSqliteMemoryPort({
|
|
283
273
|
projectRoot: wpaths.projectRoot,
|
|
284
|
-
directory: config.
|
|
274
|
+
directory: config.Sage?.storage?.directory,
|
|
285
275
|
events: opts.events
|
|
286
276
|
});
|
|
287
277
|
container.bind(TOKENS.MemoryStore, () => memoryStore);
|
|
278
|
+
container.bind(TOKENS.MemoryPort, () => memoryStore);
|
|
288
279
|
const skillLoader = new DefaultSkillLoader({
|
|
289
280
|
paths: wpaths,
|
|
290
281
|
bundledDir: opts.bundledSkillsDir,
|
|
@@ -308,7 +299,7 @@ function createDefaultContainer(opts) {
|
|
|
308
299
|
},
|
|
309
300
|
skillMode: config.skills?.mode,
|
|
310
301
|
skillEagerMaxChars: config.skills?.eagerMaxChars,
|
|
311
|
-
//
|
|
302
|
+
// SAGE's turn middleware owns memory injection — don't also
|
|
312
303
|
// inject a static prompt section. Callers may override via
|
|
313
304
|
// opts.systemPrompt if they truly want the static section.
|
|
314
305
|
injectMemory: false,
|
|
@@ -316,6 +307,28 @@ function createDefaultContainer(opts) {
|
|
|
316
307
|
})
|
|
317
308
|
);
|
|
318
309
|
}
|
|
310
|
+
const directoryPolicyPath = path2.join(wpaths.projectRoot, ".wrongstack", "directory-rules.json");
|
|
311
|
+
let directoryPolicy = {
|
|
312
|
+
schemaVersion: 1,
|
|
313
|
+
rules: []
|
|
314
|
+
};
|
|
315
|
+
try {
|
|
316
|
+
const parsed = JSON.parse(fs2.readFileSync(directoryPolicyPath, "utf8"));
|
|
317
|
+
const validation = validateDirectoryPolicy(parsed);
|
|
318
|
+
if (!validation.ok) {
|
|
319
|
+
throw new Error(
|
|
320
|
+
validation.diagnostics.map((diagnostic) => `${diagnostic.path}: ${diagnostic.message}`).join("; ")
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
directoryPolicy = validation.policy;
|
|
324
|
+
} catch (error) {
|
|
325
|
+
if (error.code !== "ENOENT") {
|
|
326
|
+
throw new Error(
|
|
327
|
+
`Invalid directory permission policy at ${directoryPolicyPath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
328
|
+
{ cause: error }
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
319
332
|
container.bind(TOKENS.PermissionPolicy, () => {
|
|
320
333
|
const policyOptions = {
|
|
321
334
|
trustFile: wpaths.projectTrust,
|
|
@@ -324,7 +337,9 @@ function createDefaultContainer(opts) {
|
|
|
324
337
|
if (opts.permission?.promptDelegate !== void 0) {
|
|
325
338
|
policyOptions.promptDelegate = opts.permission.promptDelegate;
|
|
326
339
|
}
|
|
327
|
-
return new DefaultPermissionPolicy(policyOptions)
|
|
340
|
+
return new DirectoryPermissionPolicy(new DefaultPermissionPolicy(policyOptions), {
|
|
341
|
+
policy: directoryPolicy
|
|
342
|
+
});
|
|
328
343
|
});
|
|
329
344
|
container.bind(
|
|
330
345
|
TOKENS.Compactor,
|
|
@@ -354,27 +369,36 @@ function createDefaultContainer(opts) {
|
|
|
354
369
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
355
370
|
import {
|
|
356
371
|
Agent,
|
|
357
|
-
AutoApprovePermissionPolicy,
|
|
358
|
-
applyModelRuntime,
|
|
359
372
|
FallbackProfileManager as FallbackProfileManager2,
|
|
360
373
|
Context,
|
|
361
374
|
createDefaultPipelines,
|
|
362
|
-
createFallbackModelExtension
|
|
363
|
-
|
|
375
|
+
createFallbackModelExtension
|
|
376
|
+
} from "@wrongstack/core/agent";
|
|
377
|
+
import {
|
|
378
|
+
resolveSubagentModelTarget
|
|
379
|
+
} from "@wrongstack/core/coordination";
|
|
380
|
+
import {
|
|
381
|
+
applyModelRuntime,
|
|
364
382
|
installSubagentAutoCompaction,
|
|
365
383
|
mergeModelRuntime,
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
} from "@wrongstack/core";
|
|
384
|
+
ToolExecutor
|
|
385
|
+
} from "@wrongstack/core/execution";
|
|
386
|
+
import { EventBus, TOKENS as TOKENS2 } from "@wrongstack/core/kernel";
|
|
387
|
+
import { ToolRegistry } from "@wrongstack/core/registry";
|
|
388
|
+
import { AutoApprovePermissionPolicy, WIDE_SUBAGENT_CAPABILITIES } from "@wrongstack/core/security";
|
|
372
389
|
var SUBAGENT_BASELINE = "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.";
|
|
373
390
|
var _SUBAGENT_ABORT = "wrongstack:subagent-abort-controller";
|
|
391
|
+
function abortLightSubagent(agent) {
|
|
392
|
+
const ac = agent.ctx.meta[_SUBAGENT_ABORT];
|
|
393
|
+
ac?.abort();
|
|
394
|
+
}
|
|
374
395
|
function makeLightSubagentFactory(deps) {
|
|
375
396
|
const configStore = deps.container.resolve(TOKENS2.ConfigStore);
|
|
376
|
-
const
|
|
377
|
-
|
|
397
|
+
const existingManager = deps.container.safeResolve(TOKENS2.FallbackProfileManager);
|
|
398
|
+
const fallbackProfileManager = existingManager ?? new FallbackProfileManager2(configStore.get());
|
|
399
|
+
if (!existingManager) {
|
|
400
|
+
configStore.watch((next) => fallbackProfileManager.reload(next));
|
|
401
|
+
}
|
|
378
402
|
const tokenCounter = deps.container.resolve(TOKENS2.TokenCounter);
|
|
379
403
|
const secretScrubber = deps.container.resolve(TOKENS2.SecretScrubber);
|
|
380
404
|
const systemPromptBuilder = deps.container.resolve(TOKENS2.SystemPromptBuilder);
|
|
@@ -469,15 +493,25 @@ function makeLightSubagentFactory(deps) {
|
|
|
469
493
|
});
|
|
470
494
|
agent.extensions.register(
|
|
471
495
|
createFallbackModelExtension({
|
|
472
|
-
|
|
496
|
+
// Pin provider/model to THIS worker's target so the extension restores
|
|
497
|
+
// to the worker, not the leader. Other fields stay live so WebUI edits
|
|
498
|
+
// to chains/profiles still reach active workers.
|
|
499
|
+
getConfig: () => ({ ...configStore.get(), provider: effProvider, model: effModel }),
|
|
473
500
|
fallbackProfileManager,
|
|
474
501
|
getFallbackModels: () => subCfg.fallbackModels,
|
|
475
502
|
getFallbackProfile: () => fallbackProfile,
|
|
476
|
-
buildProvider: (id, model) => buildProvider(
|
|
503
|
+
buildProvider: (id, model) => buildProvider(
|
|
504
|
+
deps.providerRegistry,
|
|
505
|
+
configStore.get(),
|
|
506
|
+
id,
|
|
507
|
+
/* v8 ignore next -- core fallback entries always carry a model; keep the interface fallback defensive */
|
|
508
|
+
model ?? effModel
|
|
509
|
+
),
|
|
477
510
|
onModelSwitch: async (id, model) => {
|
|
478
511
|
subReasoningConfig = await resolveReasoningConfig(modelsRegistry, id, model);
|
|
479
512
|
},
|
|
480
|
-
events
|
|
513
|
+
events,
|
|
514
|
+
...deps.now ? { now: deps.now } : {}
|
|
481
515
|
})
|
|
482
516
|
);
|
|
483
517
|
return { agent, events };
|
|
@@ -763,10 +797,10 @@ async function probeLocalLlm(opts) {
|
|
|
763
797
|
}
|
|
764
798
|
|
|
765
799
|
// src/vision.ts
|
|
766
|
-
import * as
|
|
800
|
+
import * as fs3 from "node:fs/promises";
|
|
767
801
|
import * as os2 from "node:os";
|
|
768
|
-
import * as
|
|
769
|
-
import { assertNotPrivateHost } from "@wrongstack/core";
|
|
802
|
+
import * as path3 from "node:path";
|
|
803
|
+
import { assertNotPrivateHost } from "@wrongstack/core/utils";
|
|
770
804
|
var ImageInputUnsupportedError = class extends Error {
|
|
771
805
|
constructor(opts) {
|
|
772
806
|
const target = [opts.providerId, opts.model].filter(Boolean).join("/") || "current model";
|
|
@@ -935,8 +969,8 @@ async function buildToolPayload(tool, image, prompt = "Describe this image for a
|
|
|
935
969
|
const p = await writeTempImage(data, mediaType);
|
|
936
970
|
payload[pathKey] = p;
|
|
937
971
|
cleanup = async () => {
|
|
938
|
-
await
|
|
939
|
-
await
|
|
972
|
+
await fs3.unlink(p).catch(() => void 0);
|
|
973
|
+
await fs3.rmdir(path3.dirname(p)).catch(() => void 0);
|
|
940
974
|
};
|
|
941
975
|
} else if ("image" in props) {
|
|
942
976
|
payload.image = image.source.type === "base64" ? { type: "base64", mediaType, media_type: mediaType, data } : { type: "url", url };
|
|
@@ -968,9 +1002,9 @@ function firstPresent(props, keys) {
|
|
|
968
1002
|
}
|
|
969
1003
|
async function writeTempImage(data, mediaType) {
|
|
970
1004
|
const ext = mediaType.includes("jpeg") || mediaType.includes("jpg") ? "jpg" : "png";
|
|
971
|
-
const dir = await
|
|
972
|
-
const file =
|
|
973
|
-
await
|
|
1005
|
+
const dir = await fs3.mkdtemp(path3.join(os2.tmpdir(), "wstack-vision-"));
|
|
1006
|
+
const file = path3.join(dir, `image.${ext}`);
|
|
1007
|
+
await fs3.writeFile(file, data, "base64");
|
|
974
1008
|
return file;
|
|
975
1009
|
}
|
|
976
1010
|
function schemaProperties(tool) {
|
|
@@ -995,15 +1029,13 @@ function stringifyToolResult(value) {
|
|
|
995
1029
|
return JSON.stringify(value);
|
|
996
1030
|
}
|
|
997
1031
|
export {
|
|
998
|
-
DefaultPathResolver,
|
|
999
|
-
DefaultSystemPromptBuilder2 as DefaultSystemPromptBuilder,
|
|
1000
|
-
DefaultTokenCounter2 as DefaultTokenCounter,
|
|
1001
1032
|
ImageInputUnsupportedError,
|
|
1002
1033
|
VISION_IMAGE_KEYS,
|
|
1003
1034
|
VISION_MEDIA_TYPE_KEYS,
|
|
1004
1035
|
VISION_PATH_KEYS,
|
|
1005
1036
|
VISION_PROMPT_KEYS,
|
|
1006
1037
|
VisionUrlBlockedError,
|
|
1038
|
+
abortLightSubagent,
|
|
1007
1039
|
applyWrongStackPack,
|
|
1008
1040
|
applyWrongStackPacks,
|
|
1009
1041
|
createDefaultContainer,
|