uxnan-bridge 0.0.1-alpha.20260621
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.
Potentially problematic release.
This version of uxnan-bridge might be problematic. Click here for more details.
- package/README.md +150 -0
- package/dist/src/account-status.d.ts +13 -0
- package/dist/src/account-status.js +78 -0
- package/dist/src/account-status.js.map +1 -0
- package/dist/src/adapters/base-adapter.d.ts +18 -0
- package/dist/src/adapters/base-adapter.js +15 -0
- package/dist/src/adapters/base-adapter.js.map +1 -0
- package/dist/src/adapters/claude-adapter.d.ts +102 -0
- package/dist/src/adapters/claude-adapter.js +486 -0
- package/dist/src/adapters/claude-adapter.js.map +1 -0
- package/dist/src/adapters/claude-tools.d.ts +25 -0
- package/dist/src/adapters/claude-tools.js +146 -0
- package/dist/src/adapters/claude-tools.js.map +1 -0
- package/dist/src/adapters/codex-adapter.d.ts +116 -0
- package/dist/src/adapters/codex-adapter.js +912 -0
- package/dist/src/adapters/codex-adapter.js.map +1 -0
- package/dist/src/adapters/codex-app-server.d.ts +74 -0
- package/dist/src/adapters/codex-app-server.js +225 -0
- package/dist/src/adapters/codex-app-server.js.map +1 -0
- package/dist/src/adapters/codex-approval.d.ts +88 -0
- package/dist/src/adapters/codex-approval.js +160 -0
- package/dist/src/adapters/codex-approval.js.map +1 -0
- package/dist/src/adapters/codex-tools.d.ts +18 -0
- package/dist/src/adapters/codex-tools.js +106 -0
- package/dist/src/adapters/codex-tools.js.map +1 -0
- package/dist/src/adapters/content-blocks.d.ts +68 -0
- package/dist/src/adapters/content-blocks.js +205 -0
- package/dist/src/adapters/content-blocks.js.map +1 -0
- package/dist/src/adapters/echo-agent-adapter.d.ts +23 -0
- package/dist/src/adapters/echo-agent-adapter.js +72 -0
- package/dist/src/adapters/echo-agent-adapter.js.map +1 -0
- package/dist/src/adapters/gemini-adapter.d.ts +87 -0
- package/dist/src/adapters/gemini-adapter.js +594 -0
- package/dist/src/adapters/gemini-adapter.js.map +1 -0
- package/dist/src/adapters/gemini-tools.d.ts +4 -0
- package/dist/src/adapters/gemini-tools.js +48 -0
- package/dist/src/adapters/gemini-tools.js.map +1 -0
- package/dist/src/adapters/opencode-adapter.d.ts +74 -0
- package/dist/src/adapters/opencode-adapter.js +418 -0
- package/dist/src/adapters/opencode-adapter.js.map +1 -0
- package/dist/src/adapters/opencode-tools.d.ts +2 -0
- package/dist/src/adapters/opencode-tools.js +41 -0
- package/dist/src/adapters/opencode-tools.js.map +1 -0
- package/dist/src/adapters/pi-adapter.d.ts +92 -0
- package/dist/src/adapters/pi-adapter.js +467 -0
- package/dist/src/adapters/pi-adapter.js.map +1 -0
- package/dist/src/adapters/pi-tools.d.ts +10 -0
- package/dist/src/adapters/pi-tools.js +72 -0
- package/dist/src/adapters/pi-tools.js.map +1 -0
- package/dist/src/adapters/process-agent-adapter.d.ts +24 -0
- package/dist/src/adapters/process-agent-adapter.js +111 -0
- package/dist/src/adapters/process-agent-adapter.js.map +1 -0
- package/dist/src/adapters/resolve-claude.d.ts +13 -0
- package/dist/src/adapters/resolve-claude.js +57 -0
- package/dist/src/adapters/resolve-claude.js.map +1 -0
- package/dist/src/adapters/resolve-codex.d.ts +13 -0
- package/dist/src/adapters/resolve-codex.js +48 -0
- package/dist/src/adapters/resolve-codex.js.map +1 -0
- package/dist/src/adapters/resolve-gemini.d.ts +13 -0
- package/dist/src/adapters/resolve-gemini.js +47 -0
- package/dist/src/adapters/resolve-gemini.js.map +1 -0
- package/dist/src/adapters/resolve-opencode.d.ts +11 -0
- package/dist/src/adapters/resolve-opencode.js +49 -0
- package/dist/src/adapters/resolve-opencode.js.map +1 -0
- package/dist/src/adapters/resolve-pi.d.ts +13 -0
- package/dist/src/adapters/resolve-pi.js +46 -0
- package/dist/src/adapters/resolve-pi.js.map +1 -0
- package/dist/src/adapters/run-options.d.ts +22 -0
- package/dist/src/adapters/run-options.js +48 -0
- package/dist/src/adapters/run-options.js.map +1 -0
- package/dist/src/adapters/spawn.d.ts +20 -0
- package/dist/src/adapters/spawn.js +16 -0
- package/dist/src/adapters/spawn.js.map +1 -0
- package/dist/src/agents/agent-manager.d.ts +98 -0
- package/dist/src/agents/agent-manager.js +433 -0
- package/dist/src/agents/agent-manager.js.map +1 -0
- package/dist/src/agents/attachments.d.ts +28 -0
- package/dist/src/agents/attachments.js +121 -0
- package/dist/src/agents/attachments.js.map +1 -0
- package/dist/src/bridge-context.d.ts +45 -0
- package/dist/src/bridge-context.js +2 -0
- package/dist/src/bridge-context.js.map +1 -0
- package/dist/src/bridge-status.d.ts +12 -0
- package/dist/src/bridge-status.js +17 -0
- package/dist/src/bridge-status.js.map +1 -0
- package/dist/src/bridge.d.ts +37 -0
- package/dist/src/bridge.js +446 -0
- package/dist/src/bridge.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +194 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/conversation/session-history.d.ts +27 -0
- package/dist/src/conversation/session-history.js +1082 -0
- package/dist/src/conversation/session-history.js.map +1 -0
- package/dist/src/conversation/thread-store.d.ts +74 -0
- package/dist/src/conversation/thread-store.js +366 -0
- package/dist/src/conversation/thread-store.js.map +1 -0
- package/dist/src/daemon-config.d.ts +123 -0
- package/dist/src/daemon-config.js +64 -0
- package/dist/src/daemon-config.js.map +1 -0
- package/dist/src/daemon-state.d.ts +27 -0
- package/dist/src/daemon-state.js +76 -0
- package/dist/src/daemon-state.js.map +1 -0
- package/dist/src/git/git-runner.d.ts +24 -0
- package/dist/src/git/git-runner.js +63 -0
- package/dist/src/git/git-runner.js.map +1 -0
- package/dist/src/git/git-service.d.ts +76 -0
- package/dist/src/git/git-service.js +435 -0
- package/dist/src/git/git-service.js.map +1 -0
- package/dist/src/handler-router.d.ts +34 -0
- package/dist/src/handler-router.js +67 -0
- package/dist/src/handler-router.js.map +1 -0
- package/dist/src/handlers/account-handler.d.ts +4 -0
- package/dist/src/handlers/account-handler.js +27 -0
- package/dist/src/handlers/account-handler.js.map +1 -0
- package/dist/src/handlers/agent-handler.d.ts +2 -0
- package/dist/src/handlers/agent-handler.js +8 -0
- package/dist/src/handlers/agent-handler.js.map +1 -0
- package/dist/src/handlers/bridge-control-handler.d.ts +2 -0
- package/dist/src/handlers/bridge-control-handler.js +64 -0
- package/dist/src/handlers/bridge-control-handler.js.map +1 -0
- package/dist/src/handlers/desktop-handler.d.ts +12 -0
- package/dist/src/handlers/desktop-handler.js +5 -0
- package/dist/src/handlers/desktop-handler.js.map +1 -0
- package/dist/src/handlers/git-handler.d.ts +2 -0
- package/dist/src/handlers/git-handler.js +82 -0
- package/dist/src/handlers/git-handler.js.map +1 -0
- package/dist/src/handlers/index.d.ts +8 -0
- package/dist/src/handlers/index.js +22 -0
- package/dist/src/handlers/index.js.map +1 -0
- package/dist/src/handlers/not-implemented.d.ts +10 -0
- package/dist/src/handlers/not-implemented.js +21 -0
- package/dist/src/handlers/not-implemented.js.map +1 -0
- package/dist/src/handlers/notifications-handler.d.ts +2 -0
- package/dist/src/handlers/notifications-handler.js +62 -0
- package/dist/src/handlers/notifications-handler.js.map +1 -0
- package/dist/src/handlers/params.d.ts +11 -0
- package/dist/src/handlers/params.js +72 -0
- package/dist/src/handlers/params.js.map +1 -0
- package/dist/src/handlers/project-handler.d.ts +2 -0
- package/dist/src/handlers/project-handler.js +6 -0
- package/dist/src/handlers/project-handler.js.map +1 -0
- package/dist/src/handlers/thread-context-handler.d.ts +2 -0
- package/dist/src/handlers/thread-context-handler.js +211 -0
- package/dist/src/handlers/thread-context-handler.js.map +1 -0
- package/dist/src/handlers/workspace-handler.d.ts +2 -0
- package/dist/src/handlers/workspace-handler.js +101 -0
- package/dist/src/handlers/workspace-handler.js.map +1 -0
- package/dist/src/hooks/claude-approval-hook.d.ts +7 -0
- package/dist/src/hooks/claude-approval-hook.js +95 -0
- package/dist/src/hooks/claude-approval-hook.js.map +1 -0
- package/dist/src/hooks/gemini-approval-hook.d.ts +7 -0
- package/dist/src/hooks/gemini-approval-hook.js +113 -0
- package/dist/src/hooks/gemini-approval-hook.js.map +1 -0
- package/dist/src/index.d.ts +62 -0
- package/dist/src/index.js +65 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/keyring-secret-store.d.ts +36 -0
- package/dist/src/keyring-secret-store.js +70 -0
- package/dist/src/keyring-secret-store.js.map +1 -0
- package/dist/src/lock-file.d.ts +18 -0
- package/dist/src/lock-file.js +60 -0
- package/dist/src/lock-file.js.map +1 -0
- package/dist/src/logger.d.ts +28 -0
- package/dist/src/logger.js +99 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/pairing/pairing-code-service.d.ts +45 -0
- package/dist/src/pairing/pairing-code-service.js +183 -0
- package/dist/src/pairing/pairing-code-service.js.map +1 -0
- package/dist/src/projects/project-registry.d.ts +14 -0
- package/dist/src/projects/project-registry.js +60 -0
- package/dist/src/projects/project-registry.js.map +1 -0
- package/dist/src/push/push-sender.d.ts +21 -0
- package/dist/src/push/push-sender.js +96 -0
- package/dist/src/push/push-sender.js.map +1 -0
- package/dist/src/push/push-service.d.ts +122 -0
- package/dist/src/push/push-service.js +260 -0
- package/dist/src/push/push-service.js.map +1 -0
- package/dist/src/qr.d.ts +17 -0
- package/dist/src/qr.js +31 -0
- package/dist/src/qr.js.map +1 -0
- package/dist/src/secret-store.d.ts +23 -0
- package/dist/src/secret-store.js +27 -0
- package/dist/src/secret-store.js.map +1 -0
- package/dist/src/secure-device-state.d.ts +16 -0
- package/dist/src/secure-device-state.js +63 -0
- package/dist/src/secure-device-state.js.map +1 -0
- package/dist/src/service-installer.d.ts +57 -0
- package/dist/src/service-installer.js +254 -0
- package/dist/src/service-installer.js.map +1 -0
- package/dist/src/session-state.d.ts +14 -0
- package/dist/src/session-state.js +19 -0
- package/dist/src/session-state.js.map +1 -0
- package/dist/src/transport/crypto.d.ts +43 -0
- package/dist/src/transport/crypto.js +78 -0
- package/dist/src/transport/crypto.js.map +1 -0
- package/dist/src/transport/lan-server.d.ts +33 -0
- package/dist/src/transport/lan-server.js +105 -0
- package/dist/src/transport/lan-server.js.map +1 -0
- package/dist/src/transport/local-hosts.d.ts +17 -0
- package/dist/src/transport/local-hosts.js +30 -0
- package/dist/src/transport/local-hosts.js.map +1 -0
- package/dist/src/transport/mdns-advertiser.d.ts +83 -0
- package/dist/src/transport/mdns-advertiser.js +282 -0
- package/dist/src/transport/mdns-advertiser.js.map +1 -0
- package/dist/src/transport/message-io.d.ts +33 -0
- package/dist/src/transport/message-io.js +87 -0
- package/dist/src/transport/message-io.js.map +1 -0
- package/dist/src/transport/outbound-log.d.ts +24 -0
- package/dist/src/transport/outbound-log.js +78 -0
- package/dist/src/transport/outbound-log.js.map +1 -0
- package/dist/src/transport/relay-client.d.ts +19 -0
- package/dist/src/transport/relay-client.js +27 -0
- package/dist/src/transport/relay-client.js.map +1 -0
- package/dist/src/transport/secure-channel.d.ts +33 -0
- package/dist/src/transport/secure-channel.js +81 -0
- package/dist/src/transport/secure-channel.js.map +1 -0
- package/dist/src/transport/server-handshake.d.ts +49 -0
- package/dist/src/transport/server-handshake.js +137 -0
- package/dist/src/transport/server-handshake.js.map +1 -0
- package/dist/src/transport/session-handler.d.ts +19 -0
- package/dist/src/transport/session-handler.js +134 -0
- package/dist/src/transport/session-handler.js.map +1 -0
- package/dist/src/transport/session-registry.d.ts +58 -0
- package/dist/src/transport/session-registry.js +91 -0
- package/dist/src/transport/session-registry.js.map +1 -0
- package/dist/src/transport/trust-store.d.ts +23 -0
- package/dist/src/transport/trust-store.js +33 -0
- package/dist/src/transport/trust-store.js.map +1 -0
- package/dist/src/transport/ws-adapter.d.ts +7 -0
- package/dist/src/transport/ws-adapter.js +16 -0
- package/dist/src/transport/ws-adapter.js.map +1 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +13 -0
- package/dist/src/version.js.map +1 -0
- package/dist/src/workspace/browse-service.d.ts +10 -0
- package/dist/src/workspace/browse-service.js +97 -0
- package/dist/src/workspace/browse-service.js.map +1 -0
- package/dist/src/workspace/checkpoint-service.d.ts +21 -0
- package/dist/src/workspace/checkpoint-service.js +219 -0
- package/dist/src/workspace/checkpoint-service.js.map +1 -0
- package/dist/src/workspace/path-guard.d.ts +7 -0
- package/dist/src/workspace/path-guard.js +51 -0
- package/dist/src/workspace/path-guard.js.map +1 -0
- package/dist/src/workspace/workspace-service.d.ts +8 -0
- package/dist/src/workspace/workspace-service.js +111 -0
- package/dist/src/workspace/workspace-service.js.map +1 -0
- package/package.json +46 -0
- package/scripts/extract-gemini-hook.mjs +16 -0
- package/scripts/fake-approval-bridge.mjs +23 -0
- package/scripts/install-service-linux.sh +38 -0
- package/scripts/install-service-macos.sh +38 -0
- package/scripts/install-service-windows.ps1 +26 -0
- package/scripts/test-gemini-hook-e2e.mjs +168 -0
- package/scripts/write-gemini-settings.mjs +31 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrates agent turns: routes `turn/send` to the right adapter, persists the
|
|
3
|
+
* streamed output to the {@link ThreadStore}, and pushes streaming notifications
|
|
4
|
+
* to connected phones.
|
|
5
|
+
*
|
|
6
|
+
* Source: architecture/02a-system-architecture.md §5.2 / §5.8.
|
|
7
|
+
*
|
|
8
|
+
* FOR-DEV: the agent is currently chosen by a single `defaultAgent`; resolve it
|
|
9
|
+
* per project/thread from the project's AgentConfig once project management lands
|
|
10
|
+
* (src/agents/agent-manager.ts).
|
|
11
|
+
*/
|
|
12
|
+
import { type AccessMode, type AgentDescriptor, type AgentId, type AgentModel, type ApprovalDecision, type IAgentAdapter, type TurnAttachment } from '@uxnan/shared';
|
|
13
|
+
import type { ThreadStore } from '../conversation/thread-store.js';
|
|
14
|
+
import type { Logger } from '../logger.js';
|
|
15
|
+
/** Display metadata + availability for a registered adapter, surfaced by `agent/list`. */
|
|
16
|
+
export interface AgentMeta {
|
|
17
|
+
displayName: string;
|
|
18
|
+
available: boolean;
|
|
19
|
+
defaultModel?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface TurnEndInfo {
|
|
22
|
+
threadId: string;
|
|
23
|
+
turnId: string;
|
|
24
|
+
status: 'completed' | 'error';
|
|
25
|
+
text?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface AgentManagerOptions {
|
|
28
|
+
store: ThreadStore;
|
|
29
|
+
/** Broadcast a JSON-RPC notification to connected phones. */
|
|
30
|
+
notify: (message: unknown) => void;
|
|
31
|
+
now: () => number;
|
|
32
|
+
logger: Logger;
|
|
33
|
+
defaultAgent: AgentId;
|
|
34
|
+
/** Optional hook fired when a turn completes or errors (e.g. push notifications). */
|
|
35
|
+
onTurnEnd?: (info: TurnEndInfo) => void;
|
|
36
|
+
}
|
|
37
|
+
export interface SendTurnOptions {
|
|
38
|
+
agentId?: AgentId;
|
|
39
|
+
service?: string;
|
|
40
|
+
effort?: string;
|
|
41
|
+
/** Chosen per-model run-option values keyed by `AgentModelOption.key`. */
|
|
42
|
+
options?: Record<string, string | boolean>;
|
|
43
|
+
/** Inline image attachments delivered to the agent for this turn. */
|
|
44
|
+
attachments?: TurnAttachment[];
|
|
45
|
+
cwd?: string;
|
|
46
|
+
/** The thread's persisted access (approval) mode, applied to this turn. */
|
|
47
|
+
accessMode?: AccessMode;
|
|
48
|
+
}
|
|
49
|
+
export declare class AgentManager {
|
|
50
|
+
#private;
|
|
51
|
+
constructor(options: AgentManagerOptions);
|
|
52
|
+
register(adapter: IAgentAdapter, meta?: Partial<AgentMeta>): void;
|
|
53
|
+
hasAdapter(agentId: AgentId): boolean;
|
|
54
|
+
/** Whether the agent's binary resolved (its CLI is installed/usable). */
|
|
55
|
+
isAvailable(agentId: AgentId): boolean;
|
|
56
|
+
/** Registered agents the phone can pick, with capabilities + availability. */
|
|
57
|
+
listAgents(): AgentDescriptor[];
|
|
58
|
+
/** The bridge's configured default agent. */
|
|
59
|
+
get defaultAgent(): AgentId;
|
|
60
|
+
/** Models the given agent's CLI reports (empty if it can't enumerate them). */
|
|
61
|
+
getModels(agentId: AgentId): Promise<AgentModel[]>;
|
|
62
|
+
/** Start a turn: persist the user message, drive the adapter, return the turn id. */
|
|
63
|
+
sendTurn(threadId: string, userText: string, options?: SendTurnOptions): Promise<{
|
|
64
|
+
turnId: string;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* Ask the user (via the phone) whether an agent tool may run. Emits an
|
|
68
|
+
* `approval` content block on the thread's in-flight turn and resolves once
|
|
69
|
+
* {@link respondApproval} arrives (or after {@link APPROVAL_TIMEOUT_MS} →
|
|
70
|
+
* `reject`).
|
|
71
|
+
*
|
|
72
|
+
* The return type is the full {@link ApprovalDecision}: callers translate it
|
|
73
|
+
* into the wire shape their protocol expects — the Claude `PreToolUse` hook
|
|
74
|
+
* uses `allow`/`deny`, the Codex app-server uses the `ReviewDecision` oneOf
|
|
75
|
+
* (`approved` / `approved_for_session` / `denied` / `abort` / `timed_out`).
|
|
76
|
+
* A common pending map + common resolver keeps the phone's reply path
|
|
77
|
+
* (`turn/send { approvalResponse }`) uniform for both backends.
|
|
78
|
+
*/
|
|
79
|
+
requestApproval(threadId: string, info: {
|
|
80
|
+
toolName: string;
|
|
81
|
+
input: Record<string, unknown>;
|
|
82
|
+
}): Promise<ApprovalDecision>;
|
|
83
|
+
/**
|
|
84
|
+
* Route a user's approval decision. Resolves a pending approval (shared by
|
|
85
|
+
* the Claude `PreToolUse` hook round-trip AND the Codex app-server
|
|
86
|
+
* elicitations) with the user's {@link ApprovalDecision}; the caller that
|
|
87
|
+
* started the request translates that into its protocol's wire shape.
|
|
88
|
+
* Otherwise, when no hook/app-server approval is pending, forwards to the
|
|
89
|
+
* agent adapter's `respondApproval` (e.g. the Echo demo) — no new turn is
|
|
90
|
+
* created. Returns the in-flight turn id (or `''`) so the `turn/send` reply
|
|
91
|
+
* still carries a `turnId`.
|
|
92
|
+
*/
|
|
93
|
+
respondApproval(threadId: string, approvalId: string, decision: ApprovalDecision): Promise<{
|
|
94
|
+
turnId: string;
|
|
95
|
+
}>;
|
|
96
|
+
cancelTurn(threadId: string, turnId: string, agentId?: AgentId): Promise<void>;
|
|
97
|
+
stopAll(): Promise<void>;
|
|
98
|
+
}
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrates agent turns: routes `turn/send` to the right adapter, persists the
|
|
3
|
+
* streamed output to the {@link ThreadStore}, and pushes streaming notifications
|
|
4
|
+
* to connected phones.
|
|
5
|
+
*
|
|
6
|
+
* Source: architecture/02a-system-architecture.md §5.2 / §5.8.
|
|
7
|
+
*
|
|
8
|
+
* FOR-DEV: the agent is currently chosen by a single `defaultAgent`; resolve it
|
|
9
|
+
* per project/thread from the project's AgentConfig once project management lands
|
|
10
|
+
* (src/agents/agent-manager.ts).
|
|
11
|
+
*/
|
|
12
|
+
import { JsonRpcErrorCode, RpcError, StreamNotification, makeNotification, } from '@uxnan/shared';
|
|
13
|
+
import { rm } from 'node:fs/promises';
|
|
14
|
+
import { materializeAttachments } from './attachments.js';
|
|
15
|
+
import { approvalBlock } from '../adapters/content-blocks.js';
|
|
16
|
+
/** How long a tool approval waits for the user before defaulting to deny. */
|
|
17
|
+
const APPROVAL_TIMEOUT_MS = 5 * 60 * 1000;
|
|
18
|
+
/** Build the `approval` content block for a tool the agent wants to run. */
|
|
19
|
+
function approvalContent(approvalId, toolName, input) {
|
|
20
|
+
const detail = approvalDetail(input);
|
|
21
|
+
const action = detail ? `Allow ${toolName}: ${detail}` : `Allow ${toolName}`;
|
|
22
|
+
const t = toolName.toLowerCase();
|
|
23
|
+
const risk = t === 'bash' || t === 'write' || t === 'edit' || t.includes('delete') ? 'high' : 'medium';
|
|
24
|
+
return approvalBlock(approvalId, action, { risk, ...(detail ? { detail } : {}) });
|
|
25
|
+
}
|
|
26
|
+
/** Short human description of a tool's input (command / path) for the card. */
|
|
27
|
+
function approvalDetail(input) {
|
|
28
|
+
if (!input || typeof input !== 'object')
|
|
29
|
+
return '';
|
|
30
|
+
for (const key of ['command', 'file_path', 'path', 'url', 'pattern']) {
|
|
31
|
+
const value = input[key];
|
|
32
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
33
|
+
return value.length > 200 ? `${value.slice(0, 200)}…` : value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
export class AgentManager {
|
|
39
|
+
#adapters = new Map();
|
|
40
|
+
#meta = new Map();
|
|
41
|
+
#started = new Set();
|
|
42
|
+
#assistantByTurn = new Map();
|
|
43
|
+
/** threadId → agent driving it, so we can read its native session id on completion. */
|
|
44
|
+
#agentByThread = new Map();
|
|
45
|
+
/** threadId → in-flight turn id, so an approval reply can name the turn it answers. */
|
|
46
|
+
#activeTurnByThread = new Map();
|
|
47
|
+
/** turnId → temp attachment dir to remove once the turn ends (best-effort). */
|
|
48
|
+
#attachmentDirByTurn = new Map();
|
|
49
|
+
/** approvalId → resolver for a pending approval (covers the Claude `PreToolUse`
|
|
50
|
+
* hook round-trip AND the Codex app-server approval elicitations; the pending
|
|
51
|
+
* map is shared so a single `respondApproval` call resolves both). The
|
|
52
|
+
* resolver takes the user's `ApprovalDecision`; the caller (the hook server
|
|
53
|
+
* or the Codex adapter) translates that into the wire shape its protocol
|
|
54
|
+
* expects (`'allow' | 'deny'` for the Claude hook, `ReviewDecision` for
|
|
55
|
+
* Codex). */
|
|
56
|
+
#pendingHookApprovals = new Map();
|
|
57
|
+
#approvalSeq = 0;
|
|
58
|
+
#options;
|
|
59
|
+
constructor(options) {
|
|
60
|
+
this.#options = options;
|
|
61
|
+
}
|
|
62
|
+
register(adapter, meta) {
|
|
63
|
+
this.#adapters.set(adapter.agentId, adapter);
|
|
64
|
+
this.#meta.set(adapter.agentId, {
|
|
65
|
+
displayName: meta?.displayName ?? adapter.agentId,
|
|
66
|
+
available: meta?.available ?? true,
|
|
67
|
+
...(meta?.defaultModel !== undefined ? { defaultModel: meta.defaultModel } : {}),
|
|
68
|
+
});
|
|
69
|
+
adapter.onEvent((event) => {
|
|
70
|
+
void this.#onEvent(event);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
hasAdapter(agentId) {
|
|
74
|
+
return this.#adapters.has(agentId);
|
|
75
|
+
}
|
|
76
|
+
/** Whether the agent's binary resolved (its CLI is installed/usable). */
|
|
77
|
+
isAvailable(agentId) {
|
|
78
|
+
return this.#meta.get(agentId)?.available ?? false;
|
|
79
|
+
}
|
|
80
|
+
/** Registered agents the phone can pick, with capabilities + availability. */
|
|
81
|
+
listAgents() {
|
|
82
|
+
return [...this.#adapters.values()].map((adapter) => {
|
|
83
|
+
const meta = this.#meta.get(adapter.agentId);
|
|
84
|
+
return {
|
|
85
|
+
agentId: adapter.agentId,
|
|
86
|
+
displayName: meta?.displayName ?? adapter.agentId,
|
|
87
|
+
available: meta?.available ?? true,
|
|
88
|
+
capabilities: adapter.capabilities,
|
|
89
|
+
...(meta?.defaultModel !== undefined ? { defaultModel: meta.defaultModel } : {}),
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** The bridge's configured default agent. */
|
|
94
|
+
get defaultAgent() {
|
|
95
|
+
return this.#options.defaultAgent;
|
|
96
|
+
}
|
|
97
|
+
/** Models the given agent's CLI reports (empty if it can't enumerate them). */
|
|
98
|
+
async getModels(agentId) {
|
|
99
|
+
const adapter = this.#adapters.get(agentId);
|
|
100
|
+
if (!adapter?.listModels)
|
|
101
|
+
return [];
|
|
102
|
+
try {
|
|
103
|
+
return await adapter.listModels();
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** Start a turn: persist the user message, drive the adapter, return the turn id. */
|
|
110
|
+
async sendTurn(threadId, userText, options = {}) {
|
|
111
|
+
const agentId = options.agentId ?? this.#options.defaultAgent;
|
|
112
|
+
const adapter = this.#adapters.get(agentId);
|
|
113
|
+
if (!adapter) {
|
|
114
|
+
throw new RpcError(JsonRpcErrorCode.AgentNotRunning, `no adapter registered for agent '${agentId}'`);
|
|
115
|
+
}
|
|
116
|
+
const attachments = options.attachments ?? [];
|
|
117
|
+
// Persist a faithful user message (no temp paths): the original text, or a
|
|
118
|
+
// short placeholder for an image-only turn so history isn't a blank bubble.
|
|
119
|
+
const persistText = userText.length > 0
|
|
120
|
+
? userText
|
|
121
|
+
: attachments.length > 0
|
|
122
|
+
? `[${attachments.length} image attachment${attachments.length > 1 ? 's' : ''}]`
|
|
123
|
+
: userText;
|
|
124
|
+
const started = await this.#options.store.startTurn(threadId, persistText, this.#options.now());
|
|
125
|
+
this.#assistantByTurn.set(started.turnId, started.assistantMessageId);
|
|
126
|
+
this.#agentByThread.set(threadId, agentId);
|
|
127
|
+
this.#activeTurnByThread.set(threadId, started.turnId);
|
|
128
|
+
if (!this.#started.has(agentId)) {
|
|
129
|
+
await adapter.start({ agentId, ...(options.cwd !== undefined ? { cwd: options.cwd } : {}) });
|
|
130
|
+
this.#started.add(agentId);
|
|
131
|
+
}
|
|
132
|
+
// Materialize image attachments to temp files and reference them in the
|
|
133
|
+
// prompt so any file/vision-capable agent CLI can open them. Best-effort:
|
|
134
|
+
// a failure to write degrades to a text-only turn, never aborts it.
|
|
135
|
+
let agentText = userText;
|
|
136
|
+
if (attachments.length > 0) {
|
|
137
|
+
try {
|
|
138
|
+
const materialized = await materializeAttachments(attachments, started.turnId, {
|
|
139
|
+
...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
|
|
140
|
+
});
|
|
141
|
+
if (materialized.note) {
|
|
142
|
+
agentText =
|
|
143
|
+
userText.length > 0 ? `${userText}\n\n${materialized.note}` : materialized.note;
|
|
144
|
+
}
|
|
145
|
+
if (materialized.dir)
|
|
146
|
+
this.#attachmentDirByTurn.set(started.turnId, materialized.dir);
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
this.#options.logger.warn(`attachment materialization failed: ${String(err)}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
await adapter.sendTurn({
|
|
153
|
+
threadId,
|
|
154
|
+
turnId: started.turnId,
|
|
155
|
+
text: agentText,
|
|
156
|
+
...(options.service !== undefined ? { service: options.service } : {}),
|
|
157
|
+
...(options.effort !== undefined ? { effort: options.effort } : {}),
|
|
158
|
+
...(options.options !== undefined ? { options: options.options } : {}),
|
|
159
|
+
...(attachments.length > 0 ? { attachments } : {}),
|
|
160
|
+
...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
|
|
161
|
+
...(options.accessMode !== undefined ? { accessMode: options.accessMode } : {}),
|
|
162
|
+
});
|
|
163
|
+
return { turnId: started.turnId };
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Ask the user (via the phone) whether an agent tool may run. Emits an
|
|
167
|
+
* `approval` content block on the thread's in-flight turn and resolves once
|
|
168
|
+
* {@link respondApproval} arrives (or after {@link APPROVAL_TIMEOUT_MS} →
|
|
169
|
+
* `reject`).
|
|
170
|
+
*
|
|
171
|
+
* The return type is the full {@link ApprovalDecision}: callers translate it
|
|
172
|
+
* into the wire shape their protocol expects — the Claude `PreToolUse` hook
|
|
173
|
+
* uses `allow`/`deny`, the Codex app-server uses the `ReviewDecision` oneOf
|
|
174
|
+
* (`approved` / `approved_for_session` / `denied` / `abort` / `timed_out`).
|
|
175
|
+
* A common pending map + common resolver keeps the phone's reply path
|
|
176
|
+
* (`turn/send { approvalResponse }`) uniform for both backends.
|
|
177
|
+
*/
|
|
178
|
+
async requestApproval(threadId, info) {
|
|
179
|
+
const turnId = this.#activeTurnByThread.get(threadId);
|
|
180
|
+
if (!turnId)
|
|
181
|
+
return 'reject'; // no in-flight turn to attach the approval to
|
|
182
|
+
const approvalId = `appr-${turnId}-${(this.#approvalSeq += 1)}`;
|
|
183
|
+
const messageId = this.#assistantByTurn.get(turnId) ?? '';
|
|
184
|
+
const content = approvalContent(approvalId, info.toolName, info.input);
|
|
185
|
+
try {
|
|
186
|
+
await this.#options.store.appendBlock(threadId, turnId, content, this.#options.now());
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
/* best-effort persistence */
|
|
190
|
+
}
|
|
191
|
+
this.#options.notify(makeNotification(StreamNotification.ContentBlock, { threadId, turnId, messageId, content }));
|
|
192
|
+
return new Promise((resolve) => {
|
|
193
|
+
const timer = setTimeout(() => {
|
|
194
|
+
this.#pendingHookApprovals.delete(approvalId);
|
|
195
|
+
resolve('reject');
|
|
196
|
+
}, APPROVAL_TIMEOUT_MS);
|
|
197
|
+
this.#pendingHookApprovals.set(approvalId, { resolve, timer });
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Route a user's approval decision. Resolves a pending approval (shared by
|
|
202
|
+
* the Claude `PreToolUse` hook round-trip AND the Codex app-server
|
|
203
|
+
* elicitations) with the user's {@link ApprovalDecision}; the caller that
|
|
204
|
+
* started the request translates that into its protocol's wire shape.
|
|
205
|
+
* Otherwise, when no hook/app-server approval is pending, forwards to the
|
|
206
|
+
* agent adapter's `respondApproval` (e.g. the Echo demo) — no new turn is
|
|
207
|
+
* created. Returns the in-flight turn id (or `''`) so the `turn/send` reply
|
|
208
|
+
* still carries a `turnId`.
|
|
209
|
+
*/
|
|
210
|
+
async respondApproval(threadId, approvalId, decision) {
|
|
211
|
+
const pending = this.#pendingHookApprovals.get(approvalId);
|
|
212
|
+
if (pending) {
|
|
213
|
+
clearTimeout(pending.timer);
|
|
214
|
+
this.#pendingHookApprovals.delete(approvalId);
|
|
215
|
+
pending.resolve(decision);
|
|
216
|
+
return { turnId: this.#activeTurnByThread.get(threadId) ?? '' };
|
|
217
|
+
}
|
|
218
|
+
const agentId = this.#agentByThread.get(threadId);
|
|
219
|
+
const adapter = agentId ? this.#adapters.get(agentId) : undefined;
|
|
220
|
+
if (!adapter) {
|
|
221
|
+
throw new RpcError(JsonRpcErrorCode.AgentNotRunning, `no active agent for thread '${threadId}'`);
|
|
222
|
+
}
|
|
223
|
+
if (!adapter.respondApproval) {
|
|
224
|
+
throw new RpcError(JsonRpcErrorCode.InvalidParams, `agent '${agentId}' does not support approvals`);
|
|
225
|
+
}
|
|
226
|
+
await adapter.respondApproval(threadId, approvalId, decision);
|
|
227
|
+
return { turnId: this.#activeTurnByThread.get(threadId) ?? '' };
|
|
228
|
+
}
|
|
229
|
+
async cancelTurn(threadId, turnId, agentId) {
|
|
230
|
+
const adapter = this.#adapters.get(agentId ?? this.#options.defaultAgent);
|
|
231
|
+
if (adapter) {
|
|
232
|
+
await adapter.cancelTurn(threadId, turnId);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async stopAll() {
|
|
236
|
+
for (const [agentId, adapter] of this.#adapters) {
|
|
237
|
+
if (this.#started.has(agentId)) {
|
|
238
|
+
await adapter.stop().catch(() => undefined);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
this.#started.clear();
|
|
242
|
+
}
|
|
243
|
+
async #onEvent(event) {
|
|
244
|
+
const { threadId, turnId } = event;
|
|
245
|
+
const messageId = this.#assistantByTurn.get(turnId) ?? '';
|
|
246
|
+
const now = this.#options.now();
|
|
247
|
+
try {
|
|
248
|
+
switch (event.type) {
|
|
249
|
+
case 'turn_started':
|
|
250
|
+
this.#options.notify(makeNotification(StreamNotification.TurnStarted, { threadId, turnId }));
|
|
251
|
+
break;
|
|
252
|
+
case 'model_resolved': {
|
|
253
|
+
const model = readText(event.data);
|
|
254
|
+
if (model) {
|
|
255
|
+
this.#options.notify(makeNotification(StreamNotification.ModelResolved, { threadId, turnId, model }));
|
|
256
|
+
}
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
case 'delta': {
|
|
260
|
+
const delta = readText(event.data);
|
|
261
|
+
await this.#options.store.appendDelta(threadId, turnId, delta, now);
|
|
262
|
+
this.#options.notify(makeNotification(StreamNotification.MessageDelta, {
|
|
263
|
+
threadId,
|
|
264
|
+
turnId,
|
|
265
|
+
messageId,
|
|
266
|
+
delta,
|
|
267
|
+
}));
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
case 'thinking': {
|
|
271
|
+
const delta = readText(event.data);
|
|
272
|
+
await this.#options.store.appendThinking(threadId, turnId, delta, now);
|
|
273
|
+
this.#options.notify(makeNotification(StreamNotification.ThinkingDelta, {
|
|
274
|
+
threadId,
|
|
275
|
+
turnId,
|
|
276
|
+
messageId,
|
|
277
|
+
delta,
|
|
278
|
+
}));
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
case 'block': {
|
|
282
|
+
const content = readContent(event.data);
|
|
283
|
+
if (content !== undefined) {
|
|
284
|
+
await this.#options.store.appendBlock(threadId, turnId, content, now);
|
|
285
|
+
this.#options.notify(makeNotification(StreamNotification.ContentBlock, {
|
|
286
|
+
threadId,
|
|
287
|
+
turnId,
|
|
288
|
+
messageId,
|
|
289
|
+
content,
|
|
290
|
+
}));
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case 'turn_completed': {
|
|
295
|
+
const provided = readOptionalText(event.data);
|
|
296
|
+
await this.#options.store.completeTurn(threadId, turnId, provided, now);
|
|
297
|
+
const text = await this.#assistantText(turnId, provided);
|
|
298
|
+
const usage = readUsage(event.data);
|
|
299
|
+
if (usage)
|
|
300
|
+
await this.#options.store.setUsage(threadId, turnId, usage, now);
|
|
301
|
+
this.#options.notify(makeNotification(StreamNotification.TurnCompleted, {
|
|
302
|
+
threadId,
|
|
303
|
+
turnId,
|
|
304
|
+
messageId,
|
|
305
|
+
text,
|
|
306
|
+
...(usage !== undefined ? { usage } : {}),
|
|
307
|
+
}));
|
|
308
|
+
this.#assistantByTurn.delete(turnId);
|
|
309
|
+
this.#activeTurnByThread.delete(threadId);
|
|
310
|
+
void this.#cleanupAttachments(turnId);
|
|
311
|
+
await this.#persistAgentSession(threadId, now);
|
|
312
|
+
this.#options.onTurnEnd?.({ threadId, turnId, status: 'completed', text });
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
case 'turn_error': {
|
|
316
|
+
const message = readOptionalText(event.data) ?? 'agent error';
|
|
317
|
+
await this.#options.store.failTurn(threadId, turnId, now);
|
|
318
|
+
this.#options.notify(makeNotification(StreamNotification.TurnError, {
|
|
319
|
+
threadId,
|
|
320
|
+
turnId,
|
|
321
|
+
error: { code: JsonRpcErrorCode.BridgeError, message },
|
|
322
|
+
}));
|
|
323
|
+
this.#assistantByTurn.delete(turnId);
|
|
324
|
+
this.#activeTurnByThread.delete(threadId);
|
|
325
|
+
void this.#cleanupAttachments(turnId);
|
|
326
|
+
await this.#persistAgentSession(threadId, now);
|
|
327
|
+
this.#options.onTurnEnd?.({ threadId, turnId, status: 'error', text: message });
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
case 'turn_aborted':
|
|
331
|
+
await this.#options.store.abortTurn(threadId, turnId, now);
|
|
332
|
+
this.#options.notify(makeNotification(StreamNotification.TurnAborted, { threadId, turnId }));
|
|
333
|
+
this.#assistantByTurn.delete(turnId);
|
|
334
|
+
this.#activeTurnByThread.delete(threadId);
|
|
335
|
+
void this.#cleanupAttachments(turnId);
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
this.#options.logger.warn(`agent event handling failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Remove a turn's temp attachment directory once the turn ends. Best-effort:
|
|
345
|
+
* the agent has already read the files by completion, and a failure to delete
|
|
346
|
+
* (e.g. the dir vanished) is non-fatal.
|
|
347
|
+
*/
|
|
348
|
+
async #cleanupAttachments(turnId) {
|
|
349
|
+
const dir = this.#attachmentDirByTurn.get(turnId);
|
|
350
|
+
if (!dir)
|
|
351
|
+
return;
|
|
352
|
+
this.#attachmentDirByTurn.delete(turnId);
|
|
353
|
+
try {
|
|
354
|
+
await rm(dir, { recursive: true, force: true });
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
/* best-effort */
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Persist the agent's native session id for a thread so the on-disk history
|
|
362
|
+
* fallback can locate its session log after a restart. Best-effort + idempotent.
|
|
363
|
+
*/
|
|
364
|
+
async #persistAgentSession(threadId, now) {
|
|
365
|
+
const agentId = this.#agentByThread.get(threadId);
|
|
366
|
+
if (!agentId)
|
|
367
|
+
return;
|
|
368
|
+
// `nativeSessionId` is an optional adapter capability (not in the shared
|
|
369
|
+
// interface), so read it through a structural type rather than a hard dep.
|
|
370
|
+
const adapter = this.#adapters.get(agentId);
|
|
371
|
+
const sessionId = adapter?.nativeSessionId?.(threadId);
|
|
372
|
+
if (!sessionId)
|
|
373
|
+
return;
|
|
374
|
+
try {
|
|
375
|
+
await this.#options.store.setAgentSession(threadId, sessionId, now);
|
|
376
|
+
}
|
|
377
|
+
catch (err) {
|
|
378
|
+
this.#options.logger.warn(`persist agent session failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
async #assistantText(turnId, provided) {
|
|
382
|
+
if (provided !== undefined)
|
|
383
|
+
return provided;
|
|
384
|
+
try {
|
|
385
|
+
const turn = await this.#options.store.getTurn(turnId);
|
|
386
|
+
const assistant = turn.messages.find((m) => m.role === 'assistant');
|
|
387
|
+
return typeof assistant?.content === 'string' ? assistant.content : '';
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
return '';
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
function readText(data) {
|
|
395
|
+
if (data && typeof data === 'object' && 'text' in data) {
|
|
396
|
+
const text = data.text;
|
|
397
|
+
if (typeof text === 'string')
|
|
398
|
+
return text;
|
|
399
|
+
}
|
|
400
|
+
return '';
|
|
401
|
+
}
|
|
402
|
+
/** Extract a structured `content` block (MessageContent JSON) from a block event. */
|
|
403
|
+
function readContent(data) {
|
|
404
|
+
if (data && typeof data === 'object' && 'content' in data) {
|
|
405
|
+
return data.content;
|
|
406
|
+
}
|
|
407
|
+
return undefined;
|
|
408
|
+
}
|
|
409
|
+
function readOptionalText(data) {
|
|
410
|
+
if (data && typeof data === 'object' && 'text' in data) {
|
|
411
|
+
const text = data.text;
|
|
412
|
+
if (typeof text === 'string')
|
|
413
|
+
return text;
|
|
414
|
+
}
|
|
415
|
+
return undefined;
|
|
416
|
+
}
|
|
417
|
+
/** Extract `{ tokens, contextWindow? }` from a turn_completed event's data. */
|
|
418
|
+
function readUsage(data) {
|
|
419
|
+
if (!data || typeof data !== 'object' || !('usage' in data))
|
|
420
|
+
return undefined;
|
|
421
|
+
const usage = data.usage;
|
|
422
|
+
if (!usage || typeof usage !== 'object')
|
|
423
|
+
return undefined;
|
|
424
|
+
const tokens = usage.tokens;
|
|
425
|
+
if (typeof tokens !== 'number')
|
|
426
|
+
return undefined;
|
|
427
|
+
const window = usage.contextWindow;
|
|
428
|
+
return {
|
|
429
|
+
tokens,
|
|
430
|
+
...(typeof window === 'number' ? { contextWindow: window } : {}),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
//# sourceMappingURL=agent-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-manager.js","sourceRoot":"","sources":["../../../src/agents/agent-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TurnAttachment } from '@uxnan/shared';
|
|
2
|
+
/** Sub-directory (under the thread cwd) the bridge drops turn attachments into. */
|
|
3
|
+
export declare const ATTACHMENTS_DIRNAME = ".uxnan-attachments";
|
|
4
|
+
export interface MaterializedAttachments {
|
|
5
|
+
/** Absolute paths of the files written to disk (for the turn-end cleanup). */
|
|
6
|
+
paths: string[];
|
|
7
|
+
/** Absolute directory the files were written under (removed on turn end). */
|
|
8
|
+
dir?: string;
|
|
9
|
+
/** A prompt note referencing the paths, or `''` when nothing was written. */
|
|
10
|
+
note: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MaterializeOptions {
|
|
13
|
+
/**
|
|
14
|
+
* The agent's working directory. When set, files are written under
|
|
15
|
+
* `<cwd>/.uxnan-attachments/<turnId>/` and referenced by a cwd-relative path
|
|
16
|
+
* so sandboxed agents can open them. When unset, falls back to the OS temp
|
|
17
|
+
* dir with an absolute reference.
|
|
18
|
+
*/
|
|
19
|
+
cwd?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Writes each inline attachment to a file under the thread's working directory
|
|
23
|
+
* and returns the absolute paths plus a ready-to-append prompt note (which
|
|
24
|
+
* references the files by a cwd-relative path). Tolerant: attachments without
|
|
25
|
+
* usable `base64Data` are skipped (an attachment that is only a workspace
|
|
26
|
+
* `path` is referenced by that path). Never throws on a single bad attachment.
|
|
27
|
+
*/
|
|
28
|
+
export declare function materializeAttachments(attachments: readonly TurnAttachment[], turnId: string, options?: MaterializeOptions): Promise<MaterializedAttachments>;
|