diff options
| author | Adam Malczewski <[email protected]> | 2026-05-22 15:24:13 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-22 15:24:13 +0900 |
| commit | 9ecaabd87c0e51b8a7408dabb0133a9344586859 (patch) | |
| tree | 4b5809ab23948a5e3f558f3aa34c52d5038f4e19 /packages/core/tests | |
| parent | 8f1dd855f0c4c877bff8d3a4ba193432b268b1c2 (diff) | |
| download | dispatch-9ecaabd87c0e51b8a7408dabb0133a9344586859.tar.gz dispatch-9ecaabd87c0e51b8a7408dabb0133a9344586859.zip | |
feat: agent builder, CWD support, auto-save, UI polish, unavailable tool handling
- Agent Builder: full CRUD with card grid, drag-and-drop model reorder, edit/delete
- Auto-save on edit with 600ms debounce, AbortController for concurrency, fieldset disabled until name entered
- Agent definitions stored as TOML with cwd field, loaded from global/project dirs
- Working directory: per-tab CWD override in Chat Settings, agent default CWD, auto-create on first message
- CWD validation: check-dir endpoint with ~ expansion, real-time validity indicator
- Subagent CWD validated against parent's effective CWD using path.relative
- Unavailable tool calls: caught gracefully, shown as tool call with error badge, model retries
- UI: tab bar border radius, sidebar border removed, chat input ghost style, scroll-to-bottom rectangle
- Skills dir collapse uses CSS rotation, Model Choice renamed to Chat Settings, System Prompt view removed
- Reusable SkillsBrowser/ToolPermissions with external mode for Agent Builder
- ModelSelector: Agent/Manual toggle, agent list, Agent Settings link
- Page router, skills recursive scanning, bin/up gopass removed, docker volume mounts
Diffstat (limited to 'packages/core/tests')
| -rw-r--r-- | packages/core/tests/config/loader.test.ts | 2 | ||||
| -rw-r--r-- | packages/core/tests/llm/provider.test.ts | 40 |
2 files changed, 28 insertions, 14 deletions
diff --git a/packages/core/tests/config/loader.test.ts b/packages/core/tests/config/loader.test.ts index 5c02326..a572425 100644 --- a/packages/core/tests/config/loader.test.ts +++ b/packages/core/tests/config/loader.test.ts @@ -1,7 +1,7 @@ +import { mkdirSync, rmSync, writeFileSync } from "node:fs"; import { homedir } from "node:os"; import { join, sep } from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { writeFileSync, mkdirSync, rmSync } from "node:fs"; import { configToRuleset, loadConfig } from "../../src/config/loader.js"; const TMP = join("/tmp/opencode", "dispatch-config-test"); diff --git a/packages/core/tests/llm/provider.test.ts b/packages/core/tests/llm/provider.test.ts index 9b5439e..2a98556 100644 --- a/packages/core/tests/llm/provider.test.ts +++ b/packages/core/tests/llm/provider.test.ts @@ -31,16 +31,21 @@ const { createProvider } = await import("../../src/llm/provider.js"); // A helper that runs the middleware's transformParams on a prompt // and returns the resulting normalized prompt. -async function runTransform( - prompt: unknown[], -): Promise<unknown[]> { +async function runTransform(prompt: unknown[]): Promise<unknown[]> { const wrappedModel = createProvider({ apiKey: "test-key", baseURL: "https://example.com/v1", })("test-model"); const middleware = ( - (wrappedModel as unknown) as { _middleware: Array<{ transformParams: (args: { type: string; params: Record<string, unknown> }) => Promise<unknown> }> } + wrappedModel as unknown as { + _middleware: Array<{ + transformParams: (args: { + type: string; + params: Record<string, unknown>; + }) => Promise<unknown>; + }>; + } )._middleware; const result = await middleware[0]!.transformParams({ @@ -59,7 +64,14 @@ describe("createProvider middleware", () => { })("test-model"); const middleware = ( - (wrappedModel as unknown) as { _middleware: Array<{ transformParams: (args: { type: string; params: Record<string, unknown> }) => Promise<unknown> }> } + wrappedModel as unknown as { + _middleware: Array<{ + transformParams: (args: { + type: string; + params: Record<string, unknown>; + }) => Promise<unknown>; + }>; + } )._middleware; const params = { prompt: [], temperature: 0.5 }; @@ -108,9 +120,7 @@ describe("createProvider middleware", () => { const prompt = [ { role: "assistant", - content: [ - { type: "text", text: "Hello!" }, - ], + content: [{ type: "text", text: "Hello!" }], }, ]; @@ -141,9 +151,7 @@ describe("createProvider middleware", () => { }); it("does not modify system messages", async () => { - const prompt = [ - { role: "system", content: "You are a helpful assistant." }, - ]; + const prompt = [{ role: "system", content: "You are a helpful assistant." }]; const normalized = await runTransform(prompt); expect(normalized).toEqual(prompt); @@ -274,11 +282,17 @@ describe("createProvider middleware", () => { const normalized = await runTransform(prompt); const msg1 = normalized[0] as Record<string, unknown>; - const compat1 = (msg1.providerMetadata as Record<string, unknown>).openaiCompatible as Record<string, unknown>; + const compat1 = (msg1.providerMetadata as Record<string, unknown>).openaiCompatible as Record< + string, + unknown + >; expect(compat1.reasoning_content).toBe("First thought."); const msg2 = normalized[1] as Record<string, unknown>; - const compat2 = (msg2.providerMetadata as Record<string, unknown>).openaiCompatible as Record<string, unknown>; + const compat2 = (msg2.providerMetadata as Record<string, unknown>).openaiCompatible as Record< + string, + unknown + >; expect(compat2.reasoning_content).toBe("Second thought."); }); }); |
