bridge.d.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * API surface definition for @anthropic-ai/claude-agent-sdk/bridge.
  3. *
  4. * This file is the source of truth for the /bridge export's public types.
  5. * It imports ONLY from agentSdkTypes.ts so the compiled .d.ts has exactly
  6. * one import to rewrite (./agentSdkTypes → ./sdk) for the flat package layout.
  7. *
  8. * Compiled by scripts/build-ant-sdk-typings.sh; see build-agent-sdk.sh for the
  9. * copy into the package. Runtime code is in agentSdkBridge.ts (separate file,
  10. * bun-built to bridge.mjs).
  11. *
  12. * The two type definitions below are copied from src/bridge/sessionHandle.ts.
  13. * Keep in sync — sessionHandle.ts is the implementation source of truth;
  14. * this file exists to produce a clean .d.ts without walking the implementation
  15. * import graph.
  16. */
  17. import type { PermissionMode, SDKControlRequest, SDKControlResponse, SDKMessage } from './agentSdkTypes.js';
  18. /**
  19. * Session state reported to the CCR /worker endpoint.
  20. * @alpha
  21. */
  22. export type SessionState = 'idle' | 'running' | 'requires_action';
  23. /**
  24. * Per-session bridge transport handle.
  25. *
  26. * Auth is instance-scoped — the JWT lives in this handle's closure, not a
  27. * process-wide env var, so multiple handles can coexist without stomping
  28. * each other.
  29. * @alpha
  30. */
  31. export type BridgeSessionHandle = {
  32. readonly sessionId: string;
  33. /**
  34. * Live SSE event-stream high-water mark. Updates as the underlying
  35. * transport receives frames. Persist this and pass back as
  36. * `initialSequenceNum` on re-attach so the server resumes instead of
  37. * replaying full history.
  38. */
  39. getSequenceNum(): number;
  40. /** True once the write path (CCRClient initialize) is ready. */
  41. isConnected(): boolean;
  42. /** Write a single SDKMessage. `session_id` is injected automatically. */
  43. write(msg: SDKMessage): void;
  44. /** Signal turn boundary — claude.ai stops the "working" spinner. */
  45. sendResult(): void;
  46. /** Forward a permission request (`can_use_tool`) to claude.ai. */
  47. sendControlRequest(req: SDKControlRequest): void;
  48. /** Forward a permission response back through the bridge. */
  49. sendControlResponse(res: SDKControlResponse): void;
  50. /**
  51. * Tell claude.ai to dismiss a pending permission prompt (e.g. caller
  52. * aborted the turn locally before the user answered).
  53. */
  54. sendControlCancelRequest(requestId: string): void;
  55. /**
  56. * Swap the underlying transport in place with a fresh JWT (and epoch).
  57. * Carries the SSE sequence number so the server resumes the stream.
  58. * Call this when the poll loop re-dispatches work for the same session
  59. * with a fresh secret (JWT is 4h; backend mints a new one every dispatch).
  60. *
  61. * Throws if `createV2ReplTransport` fails (registerWorker error, etc).
  62. * Caller should treat that as a close and drop this handle.
  63. */
  64. reconnectTransport(opts: {
  65. ingressToken: string;
  66. apiBaseUrl: string;
  67. /** Omit to call registerWorker; provide if the server already bumped. */
  68. epoch?: number;
  69. }): Promise<void>;
  70. /**
  71. * PUT /worker state. Multi-session workers: `running` on turn start,
  72. * `requires_action` on permission prompt, `idle` on turn end. Daemon
  73. * callers don't need this — user watches the REPL locally.
  74. */
  75. reportState(state: SessionState): void;
  76. /** PUT /worker external_metadata (branch, dir shown on claude.ai). */
  77. reportMetadata(metadata: Record<string, unknown>): void;
  78. /**
  79. * POST /worker/events/{id}/delivery. Populates CCR's processing_at /
  80. * processed_at columns. `received` is auto-fired internally; this
  81. * surfaces `processing` (turn start) and `processed` (turn end).
  82. */
  83. reportDelivery(eventId: string, status: 'processing' | 'processed'): void;
  84. /** Drain the write queue. Call before close() when delivery matters. */
  85. flush(): Promise<void>;
  86. close(): void;
  87. };
  88. /** @alpha */
  89. export type AttachBridgeSessionOptions = {
  90. /**
  91. * Session ID (`cse_*` form). Comes from `WorkResponse.data.id` in the
  92. * poll-loop path, or from whatever created the session.
  93. */
  94. sessionId: string;
  95. /** Worker JWT. Comes from `decodeWorkSecret(work.secret).session_ingress_token`. */
  96. ingressToken: string;
  97. /** `WorkSecret.api_base_url` or wherever the session ingress lives. */
  98. apiBaseUrl: string;
  99. /**
  100. * Worker epoch if already known (e.g. from a `/bridge` call that bumps
  101. * epoch server-side). Omit to have `createV2ReplTransport` call
  102. * `registerWorker` itself — correct for poll-loop callers where the
  103. * work secret doesn't carry epoch.
  104. */
  105. epoch?: number;
  106. /**
  107. * SSE sequence-number high-water mark from a prior handle or persisted
  108. * state. Seeds the first SSE connect's `from_sequence_num` so the server
  109. * resumes instead of replaying full history. Omit (→ 0) for genuinely
  110. * fresh attach.
  111. */
  112. initialSequenceNum?: number;
  113. /** CCRClient heartbeat interval. Defaults to 20s (server TTL is 60s). */
  114. heartbeatIntervalMs?: number;
  115. /**
  116. * When true, the bridge only forwards events outbound (local → CCR). The
  117. * SSE read stream is not opened — no inbound events are received. Control
  118. * requests that arrive via the write-path ACK channel reply with an error
  119. * instead of false-success. onInboundMessage is never called. Use for
  120. * mirror-mode attachments where the remote UI should see the session but
  121. * not be able to drive it.
  122. */
  123. outboundOnly?: boolean;
  124. /**
  125. * User message typed on claude.ai. Echoes of outbound writes and
  126. * re-deliveries of prompts already forwarded are filtered before this
  127. * fires. May be async (e.g. attachment resolution).
  128. */
  129. onInboundMessage?: (msg: SDKMessage) => void | Promise<void>;
  130. /**
  131. * `control_response` from claude.ai — the user answered a `can_use_tool`
  132. * prompt sent via `sendControlRequest`. Caller correlates by `request_id`.
  133. */
  134. onPermissionResponse?: (res: SDKControlResponse) => void;
  135. /** `interrupt` control_request from claude.ai. Already auto-replied-to. */
  136. onInterrupt?: () => void;
  137. onSetModel?: (model: string | undefined) => void;
  138. onSetMaxThinkingTokens?: (tokens: number | null) => void;
  139. /**
  140. * `set_permission_mode` from claude.ai. Return an error verdict to send
  141. * an error control_response (vs silently false-succeeding). Omit if
  142. * the caller doesn't support permission modes — the shared handler
  143. * returns a "not supported in this context" error.
  144. */
  145. onSetPermissionMode?: (mode: PermissionMode) => {
  146. ok: true;
  147. } | {
  148. ok: false;
  149. error: string;
  150. };
  151. /**
  152. * Transport died permanently. 401 = JWT expired (re-attach with fresh
  153. * secret), 4090 = epoch superseded (409, newer worker registered),
  154. * 4091 = CCRClient init failed. Anything else = SSE reconnect budget
  155. * exhausted. Transient disconnects are handled transparently inside
  156. * SSETransport and do NOT fire this.
  157. */
  158. onClose?: (code?: number) => void;
  159. };
  160. /**
  161. * Attach to an existing bridge session. Creates the v2 transport
  162. * (SSETransport + CCRClient), wires ingress routing and control dispatch,
  163. * returns a handle scoped to this one session.
  164. *
  165. * Throws if `createV2ReplTransport` fails (registerWorker error, etc).
  166. *
  167. * ALPHA STABILITY. This is a separate versioning universe from the main
  168. * `query()` surface: breaking changes here do NOT bump the package major.
  169. * @alpha
  170. */
  171. export declare function attachBridgeSession(opts: AttachBridgeSessionOptions): Promise<BridgeSessionHandle>;
  172. /**
  173. * Worker credentials from `POST /v1/code/sessions/{id}/bridge`.
  174. * Each call bumps `worker_epoch` server-side — the call IS the worker register.
  175. * @alpha
  176. */
  177. export type RemoteCredentials = {
  178. worker_jwt: string;
  179. api_base_url: string;
  180. expires_in: number;
  181. worker_epoch: number;
  182. };
  183. /**
  184. * `POST /v1/code/sessions` — create a fresh CCR session. Returns the `cse_*`
  185. * session id, or null on any failure (HTTP error, malformed response).
  186. *
  187. * Callers supply their own OAuth token — this is a thin HTTP wrapper with no
  188. * implicit auth, so it works from any process (not just the CLI).
  189. * @alpha
  190. */
  191. export declare function createCodeSession(baseUrl: string, accessToken: string, title: string, timeoutMs: number, tags?: string[]): Promise<string | null>;
  192. /**
  193. * `POST /v1/code/sessions/{id}/bridge` — mint a worker JWT for the session.
  194. * Returns credentials or null on failure. The call IS the worker register
  195. * (bumps epoch server-side), so pass `epoch: creds.worker_epoch` to
  196. * `attachBridgeSession` to skip a redundant register.
  197. *
  198. * `trustedDeviceToken` sets the `X-Trusted-Device-Token` header. Required
  199. * when the server's `sessions_elevated_auth_enforcement` flag is on
  200. * (bridge sessions are SecurityTier=ELEVATED). See anthropics/anthropic#274559.
  201. * @alpha
  202. */
  203. export declare function fetchRemoteCredentials(sessionId: string, baseUrl: string, accessToken: string, timeoutMs: number, trustedDeviceToken?: string): Promise<RemoteCredentials | null>;