diff options
| author | Adam Malczewski <[email protected]> | 2026-06-01 01:46:13 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-01 01:46:13 +0900 |
| commit | 8b9533c22a47bbf6f916667e2c25d8e8e419da37 (patch) | |
| tree | 715a6a3d6f43781395e7dc7c8cdb519cef46a870 /packages/core/src/llm | |
| parent | 1853dd1d40308deb829bc621beb79c5d39b9c57f (diff) | |
| download | dispatch-8b9533c22a47bbf6f916667e2c25d8e8e419da37.tar.gz dispatch-8b9533c22a47bbf6f916667e2c25d8e8e419da37.zip | |
feat(tabs): tab-to-tab agent communication via short handles
Add send_to_tab / read_tab tools so an agent can message or read another
tab by a git-style short handle (shortest unique prefix of the tab UUID,
min 4 chars), shown in the tab bar.
- core/db/tabs: resolveTabPrefix + shortestUniquePrefix (open tabs only,
LIKE-sanitized prefix matching)
- new tools read-tab.ts / send-to-tab.ts (+ tests) decoupled from the DB
TabRow via a minimal ResolvedTabRef projection
- agent-manager: unified deliverMessage routing (busy -> queue, idle ->
new turn) shared by POST /chat and send_to_tab; agent->agent auto-wake
budget (MAX_AGENT_AUTO_WAKES) to bound ping-pong loops
- summon/loader: send_to_tab + read_tab as grantable tools
- frontend: shortHandleFor + handle badge in TabBar; perm toggles
- notes: tab-comm / user-agents / todo-redesign plans
- chore: biome format fixes (debug-logger, summon.test)
Refs notes/plan-tab-comm.md
Diffstat (limited to 'packages/core/src/llm')
| -rw-r--r-- | packages/core/src/llm/debug-logger.ts | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/packages/core/src/llm/debug-logger.ts b/packages/core/src/llm/debug-logger.ts index 2b7420c..072a7a1 100644 --- a/packages/core/src/llm/debug-logger.ts +++ b/packages/core/src/llm/debug-logger.ts @@ -281,11 +281,7 @@ export function logStepLifecycle(data: { * Log agent loop-level events (loop start, break conditions, etc.). * Only logs at verbosity >= 3. */ -export function logAgentLoop(data: { - tabId?: string; - event: string; - detail?: unknown; -}): void { +export function logAgentLoop(data: { tabId?: string; event: string; detail?: unknown }): void { if (!ENABLED || VERBOSITY < 3) return; const detail = data.detail !== undefined ? ` ${JSON.stringify(data.detail)}` : ""; console.error(`[dispatch-debug] AGENT tab=${data.tabId ?? "?"} ${data.event}${detail}`); @@ -308,16 +304,14 @@ export function logAgentLoop(data: { * we just clone and read once via `.text()` — simpler and safe because * non-streaming bodies are bounded. */ -export function wrapFetchWithLogging< - F extends (...args: never[]) => Promise<Response> | Response, ->(baseFetch: F, opts: { tabId?: string; modelHint?: string }): F { +export function wrapFetchWithLogging<F extends (...args: never[]) => Promise<Response> | Response>( + baseFetch: F, + opts: { tabId?: string; modelHint?: string }, +): F { if (!ENABLED) return baseFetch; const wrapped = async (...args: Parameters<F>) => { const requestId = ++seq; - const [input, init] = args as unknown as [ - RequestInfo | URL, - RequestInit | undefined, - ]; + const [input, init] = args as unknown as [RequestInfo | URL, RequestInit | undefined]; const url = typeof input === "string" ? input @@ -325,7 +319,8 @@ export function wrapFetchWithLogging< ? input.toString() : (input as Request).url; const method = - init?.method ?? (typeof input === "object" && "method" in input ? (input as Request).method : "POST"); + init?.method ?? + (typeof input === "object" && "method" in input ? (input as Request).method : "POST"); // Snapshot headers as a plain object for logging. const headerObj: Record<string, string> = {}; |
