| Age | Commit message (Collapse) | Author |
|
batching, error/system chunks
|
|
symlink-safe path resolution
|
|
SDK compat
- Implement Anthropic prompt caching: first system message + last 2 non-system messages get cache_control: ephemeral, mirroring OpenCode's applyCaching strategy. Move system prompt inline into messages array so providerOptions can attach.
- Add opencode-anthropic provider variant routing MiniMax/Qwen models through the /messages endpoint with x-api-key auth, distinct from the Claude OAuth flow's Bearer auth and Claude Code mimicry.
- Split isAnthropic into isClaudeOAuth (billing header, mcp_ tool prefix, thinking config) and usesAnthropicSDK (cache markers) so non-OAuth Anthropic-format gateways get the right treatment.
- Pin @ai-sdk/anthropic to ^1.2.12: v3 returns LanguageModelV3-spec models that ai v4's streamText rejects at runtime ('AI SDK 4 only supports models that implement specification version v1'). Drop unnecessary V1 casts.
- Restore Opus 4.7 extended thinking by rewriting the outgoing /messages body in the Claude OAuth fetch interceptor: inject thinking: { type: 'adaptive' } (v1 SDK can't emit it), strip temperature/top_p/top_k (Anthropic rejects them with thinking enabled). Gated on max_tokens > 4096 so effort=none still works.
- Bump MAX_STEPS from 10 to 50 to align with AI SDK's stepCountIs(20) default and reduce mid-task halts.
- Fix pre-existing typecheck errors in agent-manager.ts (entry/nextEntry narrowing), app.ts (agentModels body field), KeyUsage.svelte (m guards), and a TS2742 in provider.ts via explicit ModelFactory return type.
- buildFallbackSequence now always returns at least one entry so processMessage runs the agent loop even without keyId/modelId (fixes 4 broken agent-manager tests).
|
|
filter
- Added Google (Gemini) as a provider: add-key UI, env var resolution via resolveApiKey, usage tracking via native models endpoint + gemini.google.com cookie scraping
- @ai-sdk/anthropic upgraded to v3 (adaptive thinking support) with LanguageModelV1 cast for ai v4 compat
- Claude Opus 4.7 uses adaptive thinking (type: adaptive); all other models keep explicit budget tokens
- Model selector modal: search filter with space matching dash/underscore
- Copy button: all tool results truncated at 300 chars
- Sidebar layout fix: Claude Reset panel removed from flex-1 fill to prevent overlap
|
|
- SidebarPanel root div now has min-h-0 so sidebar scroll container can constrain it
- Claude Reset removed from flex-1 fill list; its wake schedule grid is fixed-size
- Only Key Usage and Tasks remain as flex-1 fill panels
|
|
- Added model-changed event: backend emits it on fallback, frontend updates tab keyId/modelId
- Range slider embedded inside active agent card when >1 model configured
- Live label updates on drag (oninput), backend call only on release (onchange)
- Slider auto-positions when fallback occurs via model-changed WS event
|
|
copy truncation
- Agent rate-limit fallback now iterates through agent's configured models[] in strict order
- Frontend sends agentModels with each /chat request; backend uses buildFallbackSequence()
- Emits notice event on fallback so chat shows which key failed and what's being tried next
- Child agents inherit parent's agentModels for fallback
- Added statusCode propagation from AI SDK errors for programmatic 429 detection
- Copy button truncates all tool results at 300 chars (was 200 for 4 specific tools)
- run_shell, summon, youtube_transcribe: background mode support
- summon: blocking mode by default with getResult callback
|
|
- Resolve relative cwd paths (e.g. ./subtask) against parent's working directory at runtime
- check-dir endpoint resolves relative paths and returns the resolved absolute path
- AgentBuilder shows resolved path below input for relative paths, updated helper text
- tab-created event now includes workingDirectory so subagent tabs display their cwd in sidebar
- Add workingDirectory to tab-created AgentEvent type definition
- spawnChildAgent stores resolved absolute path instead of raw relative path
|
|
- Add is_subagent checkbox to agent editor; subagents are hidden from Chat Settings
- Add is_subagent field to AgentDefinition type, TOML serialization, and API route
- Filter subagents from ModelSelector agent list
- Fix all biome lint/format errors across codebase (useLiteralKeys, noNonNullAssertion, noExplicitAny, formatting, import sorting)
- Fix svelte-check errors (type narrowing in SkillsBrowser, ToolPermissions, SidebarPanel)
- Fix a11y warnings in App.svelte (label-control associations)
- Fix test mocks missing BackgroundShellStore, BackgroundTranscriptStore, createWebSearchTool, createYoutubeTranscribeTool
- Update stale 409 test to match current message-queuing behavior
- Exclude packaging/ and release/ dirs from biome to avoid linting stale build artifacts
|
|
retrieve
- youtube_transcribe now polls until transcript is ready (waits estimated_seconds - 2s, min 2s)
- Times out after 10 minutes of polling
- When user interrupts, polling continues in background with youtube_transcribe_<uuid> job ID
- BackgroundTranscriptStore holds polling jobs, retrieve tool resolves them
- ToolCallDisplay shows 'interrupted' badge (blue) when result contains [USER INTERRUPT]
- Applies to all interruptible tools: run_shell, youtube_transcribe, retrieve
|
|
fixes
- Add web_search tool (Firecrawl POST to /v1/search with query, limit, lang, country, scrapeOptions)
- Add youtube_transcribe tool (GET to transcriber service, handles completed/queued/failed statuses)
- Both tools registered for parent agents (always) and child agents (permission-gated)
- Added to summon enum, TOOL_DESCRIPTIONS, and core exports
- Shell interrupt: run_shell now races against user queue interrupt
- When interrupted, command continues in background with run_shell_<uuid> job ID
- BackgroundShellStore holds running processes, auto-cleans 10min after completion
- retrieve tool extended to handle both agent IDs and shell job IDs
- Tool error detection: results starting with 'Error:' now marked isError in UI
- Fix TS error: cast unavailMatch[1] regex capture group to string
- Docker: network_mode host for Tailscale/LAN access to external services
- Bun.serve idleTimeout set to 60s (was default 10s)
- KeyUsage: clearer message when OpenCode usage data unavailable
- Firecrawl: only send scrapeOptions when scrape=true (avoid 400 on instances without scrape support)
|
|
- Add message queue allowing users to send messages while agent is running
- Queue messages are injected into tool results as [USER INTERRUPT]
- Retrieve tool interrupted via Promise.race when user message arrives
- Queued messages show with 'queued' badge and cancel button
- Consumed messages repositioned and chat splits at interrupt point
- New assistant message block created after interrupt for clean flow
- Add POST /chat/cancel endpoint for cancelling queued messages
- Fix CORS to allow any origin (Tailscale/LAN access)
- Fix crypto.randomUUID fallback for non-secure contexts (HTTP)
- Fix frontend API URL derivation from page hostname
- Auto-create DB tab if missing on processMessage (foreign key fix)
- Add error logging to processMessage catch block
- Fix working directory input sync on agent switch
- Fix agent mode button to re-apply agent settings
|
|
- Add POST /models/add-key and POST /models/remove-key API endpoints
- Add 'Add New Key' modal (page-level) with provider selection
- Add remove button per key in Model Status view
- Add configurable backend URL setting in Settings panel with localStorage persistence
- Convert systemd service from system to user service (systemctl --user)
- Fix Docker entrypoint to chown all nested node_modules dirs
- Update dispatch.toml credential paths to use -pro/-max naming
- Make API port configurable via PORT env var (default 3000, prod 18390)
|
|
and Windows exe build
- Add Electron wrapper (main.cjs, preload.cjs) for desktop frontend
- Add systemd service unit, env config, and sysusers for backend API
- Add PKGBUILD and .install for Arch package (makepkg -si)
- Add desktop entry, SVG/PNG icon, and wrapper scripts
- Add bin/build-pkg, bin/install-pkg, bin/windows-pkg scripts
- Make API port configurable via PORT env var (default 3000, prod 18390)
- Add electron-builder config for Windows exe cross-compilation
- Set vite base to './' for Electron file:// loading
|
|
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
|
|
- Split tab bar into user tabs (top) and subagent tabs (bottom row)
- Bottom row only visible when active user tab has child agents
- Parent user tab stays highlighted when viewing a subagent tab
- Temp tabs auto-disappear when agent completes, click to promote to persistent
- 'Open Tab' button on summon tool calls to view/reopen subagent history
- Reopening archived tabs fetches full chat history from backend
- Add parent_tab_id column to DB with safe ALTER TABLE migration
- Persist keyId, modelId, parentTabId on child tab creation
- Flush partial assistant messages on abort/error (finally block)
- Defensive JSON.parse in message restoration
- Allow all Vite hosts for local development
- Fix nested button in ToolCallDisplay (button inside button)
|
|
Include keyId and modelId in the tab-created WebSocket event so child
agent tabs inherit the parent's model selection on the frontend.
|
|
double-execution bug fix
- Add summon/retrieve tools for spawning child agents in new tabs
- summon: non-blocking, returns agent_id immediately
- retrieve: blocking, waits for child to finish, returns result
- Child tools are intersected with parent permissions (no privilege escalation)
- Working directory validated to stay within workspace
- Abort controller stops orphaned agents on tab close
- Rename task_list tool to todo with comprehensive usage guidance in system prompt
- Rename PermissionLog.svelte to ToolPermissions.svelte
- Add 'Summon agents' toggle to tool permissions UI
- Redesign TaskListPanel with DaisyUI checkboxes (indeterminate for in-progress)
- Remove 'blocked' status from task system
- Add tab-created WebSocket event for child agent tab visibility
- Add HMR cleanup for WebSocket connections (close stale connections on hot reload)
- Fix ensureAssistantMessage to not throw on closed tabs
- Fix double tool execution: remove execute from AI SDK tool() in registry.ts
(agent.ts already executes tools manually via executeToolWithStreaming)
- Fix all pre-existing test failures (missing mocks, stale API signatures)
- Add debug info to copy button (tab ID, injected skills, all tab IDs)
- Add tab ID and tools to conversation copy output
|
|
- Add skills toggle system: check skills in sidebar to inject with next message
- Auto-check default skills on new tab creation for first-message injection
- Track injected skills per tab with visual highlights in skills browser
- Redesign tab bar: double-click background for new tab, larger close button
- Update default system prompt
- Fix streaming text duplication: change WS callbacks from array to Set
- Fix biome config: exclude references/ directory
- Auto-format with biome
|
|
sidebar, UI polish
- System Prompt sidebar view: editable textarea, save-on-send, reset button
- Tool permissions: save-on-send pattern (not immediate), reset button
- Dynamic system prompt: buildSystemPrompt reads from DB, tool list auto-generated
- Responsive sidebar: overlay on small screens with backdrop
- Chat bubbles: user=fit-width, assistant=full-width
- Fix infinite loops (use onMount for data fetching)
- Fix sendMessage race condition (await settings saves before chat POST)
- Model selector: auto-open model modal after key selection
- Rename views: Permissions->Tools, Tab Settings->Model Choice
- Shared appSettings store for cross-component reactive state
- Delete old chat.svelte.ts
|
|
- Tool permissions (read, edit, bash) stored in DB and control Agent tool registration
- Agent invalidated when permissions change; cache warning in Permissions panel
- Default: read=allow, edit=ask, bash=ask (matches UI checkboxes)
- Settings: auto-save title model on selection (removed save button)
- Settings: auto-expand thinking checkbox with shared reactive store
- Permissions panel: renamed from Permission Log, shows tool toggles + collapsible log
- Sidebar: renamed Current Model to Model Choice
- Chat input: allow typing while agent runs (just disable send)
- Chat cursor: fix doubled rectangle (removed unicode char)
- Generic GET/PUT /tabs/settings/:key endpoints for key-value settings
|
|
- Add tabs, messages, and settings tables to SQLite database
- Backend: refactor AgentManager to manage per-tab Agent instances via Map<tabId, TabAgent>
- Backend: WebSocket events tagged with tabId for multiplexing
- Backend: tab CRUD routes (create, list, update, archive, messages)
- Backend: persist user and assistant messages to DB during chat
- Frontend: new tabStore replaces single chatStore with multi-tab reactive state
- Frontend: TabBar component using DaisyUI tabs-lift style with status dots
- Frontend: Settings sidebar panel for title generation model selection
- Frontend: wire ChatPanel, ChatInput, Header to use tabStore
- Fix HMR listener accumulation via wsClient.clearCallbacks()
- Delete old single-chat chatStore (chat.svelte.ts)
|
|
- Remove ModelResolver, model definitions, model tags, fallback order, agent templates
- Remove all [[models]], [agents], and fallback from dispatch.toml and config schema
- ModelRegistry is now a pure key-state manager
- dispatch.toml reduced to keys + permissions only
- Docker: fix entrypoint for existing UID, skip bun install in frontend container
- Docker: scoped build cache prune in bin/clean
|
|
- Add SQLite database at ~/.local/share/dispatch/dispatch.db with tables: credentials, api_keys, wake_schedule, usage_cache
- Store Claude OAuth credentials in DB with import button in Model Status UI
- Store OpenCode/Copilot API keys in DB with paste-to-import modal
- Store OpenCode cookie and workspace IDs in DB
- Migrate wake schedule from .wake-schedule.json to DB
- Migrate usage cache from in-memory Map + localStorage to DB
- Remove all env var and file fallbacks — DB is the single source of truth
- Add seed scripts: bin/import-credentials.ts, bin/seed-opencode-keys.ts
- Docker: container runs as host UID/GID with matching home directory
- Clean up dispatch.toml: remove env fields, update comments
- Progress bar time markers for usage cycle tracking
|
|
display names
- Wake scheduler: fix Bun timer leak, make recurring daily, persist to disk, retry failed wakes every 5min for 30min, start at boot
- Key usage: localStorage cache survives page refresh, spinner during all refreshes, show cached data immediately
- Credential filtering: key-usage and wake only use configured credentials_file, exclude unconfigured accounts
- Display: remove counter suffix from Claude labels, format opencode/copilot key names
|
|
refreshes in background
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Replaced POST /wake-schedule (full-replace) with
POST /wake-schedule/toggle (atomic single-hour toggle)
to eliminate race conditions between frontend and scheduler
- Recursive setTimeout prevents overlapping wake executions
- HMR-safe via global timer reference
- Frontend now uses toggle endpoint instead of full schedule POST
- Display shows reset time (wake hour + 5h) in American 12h format
e.g. '8:15 → Reset at 1:00 PM' instead of European 24h
|
|
- Added claude-pro key pointing to default credentials, claude-max
pointing to .credentials-2.json (docker path /root/.claude/)
- POST /models/wake sends 'hi' to haiku for all Claude accounts
- ClaudeReset.svelte: 2 AM rows + 2 PM rows of 6 hour blocks each
(12-hour American format). Click blocks to schedule wake at :15
- Key Usage now groups all Claude accounts under one 'Claude' card
instead of duplicating under claude-pro and claude-max cards
|
|
- Each key now loads independently with its own spinner
- Claude account sub-cards separated by border + spacing
- Fixed Svelte 5 if/else chain and class: directive issues
|
|
- /key-usage route now returns all Claude accounts (not just first)
- Added ClaudeAccountUsage type for per-account data
- Frontend shows all keys stacked in scrollable cards
- Each Claude account rendered separately with label + subscription badge
- Removed key selector dropdown
|
|
Adds 'Key Usage' to the sidebar dropdown with per-provider live usage:
- Claude: 5-hour and weekly utilization bars with reset timestamps
(normalizes Anthropic's 0-100% API response to 0-1 internally)
- OpenCode: Scrapes usage from workspace page via OPENCODE_COOKIE
session cookie, mapping key IDs to OPENCODE_WS1_ID/OPENCODE_WS2_ID
- Copilot: Fetches from api.github.com/copilot_internal/user with
entitlement/remaining/quota reset tracking
New files: opencode.ts, copilot.ts (usage fetchers), KeyUsage.svelte
New route: GET /models/key-usage?keyId=X dispatches by provider
|
|
effort, and dynamic model listing
|
|
inset-0
|
|
- Sidebar uses absolute inset-0 with overflow-y-auto for proper scrolling
- Border moved to inner div so it hides with sidebar
- Copilot auth script uses portable sed instead of grep -P (macOS compat)
- dispatch.toml with 3 keys, 4 models, fallback order
- .env.dispatch with key placeholders and script reference
- docker-compose loads .env.dispatch via env_file
|
|
- Config system: TOML-based dispatch.toml with hot-reload via chokidar
- Model/key resolution: tag-based model selection, key fallback chains
- Skills system: directory loader with TOML frontmatter, agent mappings
- Task list tool: add/update/list/get operations with WebSocket events
- API routes: GET /config, /skills, /skills/:name, /models, /models/resolve
- Frontend: sidebar with model status, task list, config viewer, skills browser, permission log
- Sliding sidebar animation using CSS transitions (not Svelte transitions)
|
|
|
|
|
|
up, scroll-to-bottom button
|
|
|
|
preload set
|