@dxos/edge-client 0.9.0 → 0.9.1-main.c7dcc2e112

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.
Files changed (40) hide show
  1. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  2. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  3. package/dist/lib/neutral/cors-proxy.mjs +1 -0
  4. package/dist/lib/neutral/edge-ws-muxer.mjs +1 -0
  5. package/dist/lib/neutral/index.mjs +82 -7
  6. package/dist/lib/neutral/index.mjs.map +3 -3
  7. package/dist/lib/neutral/meta.json +1 -1
  8. package/dist/lib/neutral/service/index.mjs +134 -0
  9. package/dist/lib/neutral/service/index.mjs.map +7 -0
  10. package/dist/lib/neutral/testing/index.mjs +1 -0
  11. package/dist/lib/neutral/testing/index.mjs.map +1 -1
  12. package/dist/types/src/edge-ai-http-client.d.ts +39 -0
  13. package/dist/types/src/edge-ai-http-client.d.ts.map +1 -1
  14. package/dist/types/src/edge-ai-http-client.test.d.ts +2 -0
  15. package/dist/types/src/edge-ai-http-client.test.d.ts.map +1 -0
  16. package/dist/types/src/edge-http-client.d.ts +17 -2
  17. package/dist/types/src/edge-http-client.d.ts.map +1 -1
  18. package/dist/types/src/hub-http-client.d.ts +8 -1
  19. package/dist/types/src/hub-http-client.d.ts.map +1 -1
  20. package/dist/types/src/service/Image.d.ts +25 -0
  21. package/dist/types/src/service/Image.d.ts.map +1 -0
  22. package/dist/types/src/service/edge-service.d.ts +36 -0
  23. package/dist/types/src/service/edge-service.d.ts.map +1 -0
  24. package/dist/types/src/service/edge-service.test.d.ts +2 -0
  25. package/dist/types/src/service/edge-service.test.d.ts.map +1 -0
  26. package/dist/types/src/service/image-service.e2e.test.d.ts +2 -0
  27. package/dist/types/src/service/image-service.e2e.test.d.ts.map +1 -0
  28. package/dist/types/src/service/index.d.ts +3 -0
  29. package/dist/types/src/service/index.d.ts.map +1 -0
  30. package/dist/types/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +20 -15
  32. package/src/edge-ai-http-client.test.ts +37 -0
  33. package/src/edge-ai-http-client.ts +87 -2
  34. package/src/edge-http-client.ts +18 -6
  35. package/src/hub-http-client.ts +20 -0
  36. package/src/service/Image.ts +61 -0
  37. package/src/service/edge-service.test.ts +151 -0
  38. package/src/service/edge-service.ts +139 -0
  39. package/src/service/image-service.e2e.test.ts +53 -0
  40. package/src/service/index.ts +7 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/index.ts", "../../../src/auth.ts", "../../../src/edge-client.ts", "../../../src/edge-identity.ts", "../../../src/edge-ws-connection.ts", "../../../src/errors.ts", "../../../src/utils.ts", "../../../src/base-http-client.ts", "../../../src/http-client.ts", "../../../src/edge-ai-http-client.ts", "../../../src/edge-http-client.ts", "../../../src/hub-http-client.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './auth';\nexport * from './cors-proxy';\nexport * from './defs';\nexport * from './edge-client';\nexport * from './errors';\nexport * from './protocol';\nexport * from './base-http-client';\nexport * from './edge-ai-http-client';\nexport * from './edge-http-client';\nexport * from './hub-http-client';\nexport * from './edge-identity';\nexport * from './edge-ws-muxer';\nexport * from './http-client';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { createCredential, signPresentation } from '@dxos/credentials';\nimport { type Signer } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { Keyring } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { type Chain, type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nimport type { EdgeIdentity } from './edge-identity';\n\n/**\n * Edge identity backed by a device key without a credential chain.\n */\nexport const createDeviceEdgeIdentity = async (signer: Signer, key: PublicKey): Promise<EdgeIdentity> => {\n return {\n identityKey: key.toHex(),\n peerKey: key.toHex(),\n presentCredentials: async ({ challenge }) => {\n return signPresentation({\n presentation: {\n credentials: [\n // Verifier requires at least one credential in the presentation to establish the subject.\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: key,\n subject: key,\n signer,\n }),\n ],\n },\n signer,\n signerKey: key,\n nonce: challenge,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a chain of credentials.\n */\nexport const createChainEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n peerKey: PublicKey,\n chain: Chain | undefined,\n credentials: Credential[],\n): Promise<EdgeIdentity> => {\n const credentialsToSign =\n credentials.length > 0\n ? credentials\n : [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n chain,\n signingKey: peerKey,\n }),\n ];\n\n return {\n identityKey: identityKey.toHex(),\n peerKey: peerKey.toHex(),\n presentCredentials: async ({ challenge }) => {\n // TODO: make chain required after device invitation flow update release\n invariant(chain);\n return signPresentation({\n presentation: {\n credentials: credentialsToSign,\n },\n signer,\n nonce: challenge,\n signerKey: peerKey,\n chain,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a random ephemeral key without HALO.\n */\nexport const createEphemeralEdgeIdentity = async (): Promise<EdgeIdentity> => {\n const keyring = new Keyring();\n const key = await keyring.createKey();\n return createDeviceEdgeIdentity(keyring, key);\n};\n\n/**\n * Creates a HALO chain of credentials to act as an edge identity.\n */\nexport const createTestHaloEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n deviceKey: PublicKey,\n): Promise<EdgeIdentity> => {\n const deviceAdmission = await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.AuthorizedDevice',\n deviceKey,\n identityKey,\n },\n issuer: identityKey,\n subject: deviceKey,\n signer,\n });\n return createChainEdgeIdentity(signer, identityKey, deviceKey, { credential: deviceAdmission }, [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n }),\n ]);\n};\n\nexport const createStubEdgeIdentity = (): EdgeIdentity => {\n const identityKey = PublicKey.random();\n const deviceKey = PublicKey.random();\n return {\n identityKey: identityKey.toHex(),\n peerKey: deviceKey.toHex(),\n presentCredentials: async () => {\n throw new Error('Stub identity does not support authentication.');\n },\n };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport {\n Event,\n PersistentLifecycle,\n Trigger,\n TriggerState,\n scheduleMicroTask,\n scheduleTaskInterval,\n} from '@dxos/async';\nimport { Context, TRACE_SPAN_ATTRIBUTE, type TraceContextData } from '@dxos/context';\nimport { type Lifecycle, Resource } from '@dxos/context';\nimport { log, logInfo } from '@dxos/log';\nimport { type Message } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';\n\nimport { protocol } from './defs';\nimport { type EdgeIdentity, handleAuthChallenge } from './edge-identity';\nimport { EdgeWsConnection } from './edge-ws-connection';\nimport { EdgeConnectionClosedError, EdgeIdentityChangedError } from './errors';\nimport { type Protocol } from './protocol';\nimport { getEdgeUrlWithProtocol } from './utils';\n\nconst DEFAULT_TIMEOUT = 10_000;\n\n// Refresh status every second: rtt, rate counters.\nconst STATUS_REFRESH_INTERVAL = 1000;\n\nexport type MessageListener = (message: Message) => void;\nexport type ReconnectListener = () => void;\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n disableAuth?: boolean;\n /** Sent as `X-DXOS-Client-Tag` on the WebSocket upgrade (Node/`ws` only; ignored in browsers). */\n clientTag?: string;\n};\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n statusChanged: Event<EdgeStatus>;\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n get status(): EdgeStatus;\n setIdentity(identity: EdgeIdentity): void;\n send(ctx: Context, message: Message): Promise<void>;\n onMessage(listener: MessageListener): () => void;\n onReconnected(listener: ReconnectListener): () => void;\n}\n\n/**\n * Messenger client for EDGE:\n * - While open, uses PersistentLifecycle to keep an open EdgeWsConnection, reconnecting on failures.\n * - Manages identity and re-create EdgeWsConnection when identity changes.\n * - Dispatches connection state and message notifications.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public readonly statusChanged = new Event<EdgeStatus>();\n\n private readonly _persistentLifecycle = new PersistentLifecycle<EdgeWsConnection>({\n start: async () => this._connect(),\n stop: async (state: EdgeWsConnection) => this._disconnect(state),\n });\n\n private readonly _messageListeners = new Set<MessageListener>();\n private readonly _reconnectListeners = new Set<ReconnectListener>();\n private readonly _baseWsUrl: string;\n private readonly _baseHttpUrl: string;\n private _currentConnection?: EdgeWsConnection = undefined;\n private _ready = new Trigger();\n\n constructor(\n private _identity: EdgeIdentity,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._baseWsUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, 'ws');\n this._baseHttpUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, 'http');\n }\n\n @logInfo\n public get info() {\n return {\n open: this.isOpen,\n status: this.status,\n identity: this._identity.identityKey,\n device: this._identity.peerKey,\n };\n }\n\n get status(): EdgeStatus {\n return {\n state:\n Boolean(this._currentConnection) && this._ready.state === TriggerState.RESOLVED\n ? EdgeStatus.ConnectionState.CONNECTED\n : EdgeStatus.ConnectionState.NOT_CONNECTED,\n uptime: this._currentConnection?.uptime ?? 0,\n rtt: this._currentConnection?.rtt ?? 0,\n rateBytesUp: this._currentConnection?.uploadRate ?? 0,\n rateBytesDown: this._currentConnection?.downloadRate ?? 0,\n messagesSent: this._currentConnection?.messagesSent ?? 0,\n messagesReceived: this._currentConnection?.messagesReceived ?? 0,\n };\n }\n\n get identityKey() {\n return this._identity.identityKey;\n }\n\n get peerKey() {\n return this._identity.peerKey;\n }\n\n setIdentity(identity: EdgeIdentity) {\n if (identity.identityKey !== this._identity.identityKey || identity.peerKey !== this._identity.peerKey) {\n log('Edge identity changed', { identity, oldIdentity: this._identity });\n this._identity = identity;\n this._closeCurrentConnection(new EdgeIdentityChangedError());\n void this._persistentLifecycle.scheduleRestart();\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(ctx: Context, message: Message) {\n if (this._ready.state !== TriggerState.RESOLVED) {\n log('waiting for websocket');\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n\n if (!this._currentConnection) {\n throw new EdgeConnectionClosedError();\n }\n\n if (\n message.source &&\n (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)\n ) {\n throw new EdgeIdentityChangedError();\n }\n\n const traceCtx = ctx.getAttribute(TRACE_SPAN_ATTRIBUTE) as TraceContextData | undefined;\n if (traceCtx) {\n message.traceContext = {\n $typeName: 'dxos.edge.messenger.TraceContext',\n traceparent: traceCtx.traceparent,\n tracestate: traceCtx.tracestate,\n };\n }\n\n this._currentConnection.send(message);\n }\n\n public onMessage(listener: MessageListener) {\n this._messageListeners.add(listener);\n return () => this._messageListeners.delete(listener);\n }\n\n public onReconnected(listener: ReconnectListener) {\n this._reconnectListeners.add(listener);\n if (this._ready.state === TriggerState.RESOLVED) {\n // Microtask so that listener is always called asynchronously, no matter the state of the ready trigger\n // at the moment of registration.\n scheduleMicroTask(this._ctx, () => {\n if (this._reconnectListeners.has(listener)) {\n try {\n listener();\n } catch (error) {\n log.catch(error);\n }\n }\n });\n }\n\n return () => this._reconnectListeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open(): Promise<void> {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n\n // Notify about status changes (rtt, rate counters).\n scheduleTaskInterval(\n this._ctx,\n async () => {\n if (!this._currentConnection) {\n return;\n }\n this.statusChanged.emit(this.status);\n },\n STATUS_REFRESH_INTERVAL,\n );\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close(): Promise<void> {\n log('closing...', { peerKey: this._identity.peerKey });\n this._closeCurrentConnection();\n await this._persistentLifecycle.close();\n }\n\n private async _connect(): Promise<EdgeWsConnection | undefined> {\n if (this._ctx.disposed) {\n return undefined;\n }\n\n const identity = this._identity;\n const path = `/ws/${identity.identityKey}/${identity.peerKey}`;\n const protocolHeader = this._config.disableAuth ? undefined : await this._createAuthHeader(path);\n if (this._identity !== identity) {\n log('identity changed during auth header request');\n return undefined;\n }\n\n const restartRequired = new Trigger();\n const url = new URL(path, this._baseWsUrl);\n log('Opening websocket', { url: url.toString(), protocolHeader });\n const connection = new EdgeWsConnection(\n identity,\n {\n url,\n protocolHeader,\n headers: this._config.clientTag ? { 'X-DXOS-Client-Tag': this._config.clientTag } : undefined,\n },\n {\n onConnected: () => {\n if (this._isActive(connection)) {\n this._ready.wake();\n this._notifyReconnected();\n } else {\n log.verbose('connected callback ignored, because connection is not active');\n }\n },\n onRestartRequired: () => {\n if (this._isActive(connection)) {\n this._closeCurrentConnection();\n void this._persistentLifecycle.scheduleRestart();\n } else {\n log.verbose('restart requested by inactive connection');\n }\n restartRequired.wake();\n },\n onMessage: (message) => {\n if (this._isActive(connection)) {\n this._notifyMessageReceived(message);\n } else {\n log.verbose('ignored a message on inactive connection', {\n from: message.source,\n type: message.payload?.typeUrl,\n });\n }\n },\n },\n );\n this._currentConnection = connection;\n\n await connection.open();\n\n // The connection is only a successful start once the socket becomes ready. A socket that\n // closes or errors before becoming ready (or never connects within the timeout) is a failed\n // start: throwing lets PersistentLifecycle apply its backoff. Returning here would mark the\n // attempt as successful and reset the backoff, degenerating reconnects into a hot loop when\n // the server accepts then immediately drops the socket.\n const becameReady = await Promise.race([\n this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT }).then(\n () => true,\n () => false,\n ),\n restartRequired.wait().then(() => false),\n ]);\n if (!becameReady) {\n throw new EdgeConnectionClosedError();\n }\n\n return connection;\n }\n\n private async _disconnect(state: EdgeWsConnection): Promise<void> {\n await state.close();\n this.statusChanged.emit(this.status);\n }\n\n private _closeCurrentConnection(error: Error = new EdgeConnectionClosedError()): void {\n this._currentConnection = undefined;\n this._ready.throw(error);\n this._ready.reset();\n this.statusChanged.emit(this.status);\n }\n\n private _notifyReconnected(): void {\n this.statusChanged.emit(this.status);\n for (const listener of this._reconnectListeners) {\n try {\n listener();\n } catch (err) {\n log.error('ws reconnect listener failed', { err });\n }\n }\n }\n\n private _notifyMessageReceived(message: Message): void {\n for (const listener of this._messageListeners) {\n try {\n listener(message);\n } catch (err) {\n log.error('ws incoming message processing failed', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n\n private async _createAuthHeader(path: string): Promise<string | undefined> {\n const httpUrl = new URL(path, this._baseHttpUrl);\n httpUrl.protocol = getEdgeUrlWithProtocol(this._baseWsUrl.toString(), 'http');\n const response = await fetch(httpUrl, { method: 'GET' });\n if (response.status === 401) {\n return encodePresentationWsAuthHeader(await handleAuthChallenge(response, this._identity));\n } else {\n log.warn('no auth challenge from edge', { status: response.status, statusText: response.statusText });\n return undefined;\n }\n }\n\n private _isActive = (connection: EdgeWsConnection) => connection === this._currentConnection;\n}\n\nconst encodePresentationWsAuthHeader = (encodedPresentation: Uint8Array): string => {\n // '=' and '/' characters are not allowed in the WebSocket subprotocol header.\n const encodedToken = Buffer.from(encodedPresentation).toString('base64').replace(/=*$/, '').replaceAll('/', '|');\n return `base64url.bearer.authorization.dxos.org.${encodedToken}`;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Presentation } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nexport interface EdgeIdentity {\n peerKey: string;\n identityKey: string;\n /**\n * Returns credential presentation issued by the identity key.\n * Presentation must have the provided challenge.\n * Presentation may include ServiceAccess credentials.\n */\n presentCredentials({ challenge }: { challenge: Uint8Array }): Promise<Presentation>;\n}\n\nexport const handleAuthChallenge = async (failedResponse: Response, identity: EdgeIdentity): Promise<Uint8Array> => {\n invariant(failedResponse.status === 401);\n\n const headerValue = failedResponse.headers.get('Www-Authenticate');\n invariant(headerValue?.startsWith('VerifiablePresentation challenge='));\n\n const challenge = headerValue?.slice('VerifiablePresentation challenge='.length);\n invariant(challenge);\n\n const presentation = await identity.presentCredentials({ challenge: Buffer.from(challenge, 'base64') });\n return schema.getCodecForType('dxos.halo.credentials.Presentation').encode(presentation);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { scheduleTask, scheduleTaskInterval } from '@dxos/async';\nimport { Context, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log, logInfo } from '@dxos/log';\nimport { EdgeWebsocketProtocol } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { type EdgeIdentity } from './edge-identity';\nimport { CLOUDFLARE_MESSAGE_MAX_BYTES, WebSocketMuxer } from './edge-ws-muxer';\nimport { toUint8Array } from './protocol';\n\nconst SIGNAL_KEEPALIVE_INTERVAL = 4_000;\nconst SIGNAL_KEEPALIVE_TIMEOUT = 12_000;\n\nexport type EdgeWsConnectionCallbacks = {\n onConnected: () => void;\n onMessage: (message: Message) => void;\n onRestartRequired: () => void;\n};\n\nexport class EdgeWsConnection extends Resource {\n private _inactivityTimeoutCtx: Context | undefined;\n private _ws: WebSocket | undefined;\n private _wsMuxer: WebSocketMuxer | undefined;\n private _lastReceivedMessageTimestamp = Date.now();\n\n private _openTimestamp: number | undefined;\n\n // Latency tracking.\n private _pingTimestamp: number | undefined;\n private _rtt = 0;\n\n // Rate tracking with sliding window.\n private _uploadRate = 0;\n private _downloadRate = 0;\n private readonly _rateWindow = 10000; // 10 second sliding window.\n private readonly _rateUpdateInterval = 1000; // Update rates every second.\n private _bytesSamples: Array<{ timestamp: number; sent: number; received: number }> = [];\n\n private _messagesSent = 0;\n private _messagesReceived = 0;\n\n constructor(\n private readonly _identity: EdgeIdentity,\n private readonly _connectionInfo: { url: URL; protocolHeader?: string; headers?: Record<string, string> },\n private readonly _callbacks: EdgeWsConnectionCallbacks,\n ) {\n super();\n }\n\n @logInfo\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identity.identityKey,\n device: this._identity.peerKey,\n };\n }\n\n public get rtt(): number {\n return this._rtt;\n }\n\n public get uptime(): number {\n return this._openTimestamp ? (Date.now() - this._openTimestamp) / 1000 : 0;\n }\n\n public get uploadRate(): number {\n return this._uploadRate;\n }\n\n public get downloadRate(): number {\n return this._downloadRate;\n }\n\n public get messagesSent(): number {\n return this._messagesSent;\n }\n\n public get messagesReceived(): number {\n return this._messagesReceived;\n }\n\n public send(message: Message): void {\n invariant(this._ws);\n invariant(this._wsMuxer);\n log('sending...', { peerKey: this._identity.peerKey, payload: protocol.getPayloadType(message) });\n this._messagesSent++;\n if (this._ws?.protocol.includes(EdgeWebsocketProtocol.V0)) {\n const binary = buf.toBinary(MessageSchema, message);\n if (binary.length > CLOUDFLARE_MESSAGE_MAX_BYTES) {\n log.error('Message dropped because it was too large (>1MB).', {\n byteLength: binary.byteLength,\n serviceId: message.serviceId,\n payload: protocol.getPayloadType(message),\n });\n return;\n }\n this._recordBytes(binary.byteLength, 0);\n this._ws.send(binary);\n } else {\n // For muxer, we need to track the size of the message being sent.\n const binary = buf.toBinary(MessageSchema, message);\n this._recordBytes(binary.byteLength, 0);\n this._wsMuxer.send(message).catch((e) => log.catch(e));\n }\n }\n\n protected override async _open(): Promise<void> {\n const baseProtocols = [...Object.values(EdgeWebsocketProtocol)];\n this._ws = new WebSocket(\n this._connectionInfo.url.toString(),\n this._connectionInfo.protocolHeader\n ? [...baseProtocols, this._connectionInfo.protocolHeader]\n : [...baseProtocols],\n this._connectionInfo.headers ? { headers: this._connectionInfo.headers } : undefined,\n );\n const muxer = new WebSocketMuxer(this._ws);\n this._wsMuxer = muxer;\n\n this._ws.onopen = () => {\n if (this.isOpen) {\n log('connected');\n this._openTimestamp = Date.now();\n this._callbacks.onConnected();\n this._scheduleHeartbeats();\n this._scheduleRateCalculation();\n } else {\n log.verbose('connected after becoming inactive', { currentIdentity: this._identity });\n }\n };\n this._ws.onclose = (event: WebSocket.CloseEvent) => {\n if (this.isOpen) {\n log.warn('server disconnected', { code: event.code, reason: event.reason });\n this._callbacks.onRestartRequired();\n muxer.destroy();\n }\n };\n this._ws.onerror = (event: WebSocket.ErrorEvent) => {\n if (this.isOpen) {\n log.warn('edge connection socket error', { error: event.error, info: event.message });\n this._callbacks.onRestartRequired();\n } else {\n log.verbose('error ignored on closed connection', { error: event.error });\n }\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event: WebSocket.MessageEvent) => {\n if (!this.isOpen) {\n log.verbose('message ignored on closed connection', { event: event.type });\n return;\n }\n this._lastReceivedMessageTimestamp = Date.now();\n if (event.data === '__pong__') {\n // Calculate latency.\n if (this._pingTimestamp) {\n this._rtt = Date.now() - this._pingTimestamp;\n this._pingTimestamp = undefined;\n }\n this._rescheduleHeartbeatTimeout();\n return;\n }\n const bytes = await toUint8Array(event.data);\n this._recordBytes(0, bytes.byteLength);\n if (!this.isOpen) {\n return;\n }\n\n this._messagesReceived++;\n\n const message = this._ws?.protocol?.includes(EdgeWebsocketProtocol.V0)\n ? buf.fromBinary(MessageSchema, bytes)\n : muxer.receiveData(bytes);\n\n if (message) {\n log('received', { from: message.source, payload: protocol.getPayloadType(message) });\n this._callbacks.onMessage(message);\n }\n };\n }\n\n protected override async _close(): Promise<void> {\n void this._inactivityTimeoutCtx?.dispose().catch(() => {});\n\n try {\n this._ws?.close();\n this._ws = undefined;\n this._wsMuxer?.destroy();\n this._wsMuxer = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('error closing websocket', { err });\n }\n }\n\n private _scheduleHeartbeats(): void {\n invariant(this._ws);\n scheduleTaskInterval(\n this._ctx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._pingTimestamp = Date.now();\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._pingTimestamp = Date.now();\n this._ws.send('__ping__');\n this._rescheduleHeartbeatTimeout();\n }\n\n private _rescheduleHeartbeatTimeout(): void {\n if (!this.isOpen) {\n return;\n }\n void this._inactivityTimeoutCtx?.dispose();\n this._inactivityTimeoutCtx = new Context();\n scheduleTask(\n this._inactivityTimeoutCtx,\n () => {\n if (this.isOpen) {\n if (Date.now() - this._lastReceivedMessageTimestamp > SIGNAL_KEEPALIVE_TIMEOUT) {\n log.warn('restart due to inactivity timeout', {\n lastReceivedMessageTimestamp: this._lastReceivedMessageTimestamp,\n });\n this._callbacks.onRestartRequired();\n } else {\n this._rescheduleHeartbeatTimeout();\n }\n }\n },\n SIGNAL_KEEPALIVE_TIMEOUT,\n );\n }\n\n private _recordBytes(sent: number, received: number): void {\n const now = Date.now();\n\n // Find if we have a sample for the current second.\n const currentSecond = Math.floor(now / 1000) * 1000;\n const existingSample = this._bytesSamples.find((s) => Math.floor(s.timestamp / 1000) * 1000 === currentSecond);\n\n if (existingSample) {\n existingSample.sent += sent;\n existingSample.received += received;\n } else {\n this._bytesSamples.push({ timestamp: now, sent, received });\n }\n }\n\n private _scheduleRateCalculation(): void {\n scheduleTaskInterval(\n this._ctx,\n async () => {\n this._calculateRates();\n },\n this._rateUpdateInterval,\n );\n // Calculate initial rates.\n this._calculateRates();\n }\n\n private _calculateRates(): void {\n const now = Date.now();\n const cutoff = now - this._rateWindow;\n\n // Remove old samples.\n this._bytesSamples = this._bytesSamples.filter((s) => s.timestamp > cutoff);\n\n if (this._bytesSamples.length === 0) {\n this._uploadRate = 0;\n this._downloadRate = 0;\n return;\n }\n\n // Calculate total bytes and time span.\n let totalSent = 0;\n let totalReceived = 0;\n const oldestTimestamp = Math.min(...this._bytesSamples.map((s) => s.timestamp));\n const timeSpan = (now - oldestTimestamp) / 1000; // Convert to seconds.\n\n for (const sample of this._bytesSamples) {\n totalSent += sample.sent;\n totalReceived += sample.received;\n }\n\n // Calculate rates (bytes per second).\n this._uploadRate = timeSpan > 0 ? Math.round(totalSent / timeSpan) : 0;\n this._downloadRate = timeSpan > 0 ? Math.round(totalReceived / timeSpan) : 0;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class EdgeConnectionClosedError extends Error {\n constructor() {\n super('Edge connection closed.');\n }\n}\n\nexport class EdgeIdentityChangedError extends Error {\n constructor() {\n super('Edge identity changed.');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const getEdgeUrlWithProtocol = (baseUrl: string, protocol: 'http' | 'ws') => {\n const isSecure = baseUrl.startsWith('https') || baseUrl.startsWith('wss');\n const url = new URL(baseUrl);\n url.protocol = protocol + (isSecure ? 's' : '');\n return url.toString();\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { sleep } from '@dxos/async';\nimport { Context, TRACE_SPAN_ATTRIBUTE, type TraceContextData } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { EDGE_CLIENT_TAG_HEADER, EdgeAuthChallengeError, EdgeCallFailedError, type EdgeFailure } from '@dxos/protocols';\n\nimport { type EdgeIdentity, handleAuthChallenge } from './edge-identity';\nimport { encodeAuthHeader } from './http-client';\nimport { getEdgeUrlWithProtocol } from './utils';\n\nconst DEFAULT_RETRY_TIMEOUT = 1500;\nconst DEFAULT_RETRY_JITTER = 500;\nconst DEFAULT_MAX_RETRIES_COUNT = 3;\nconst WARNING_BODY_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport type RetryConfig = {\n /** Number of retries, not counting the initial request. */\n count: number;\n /** Delay before retries in ms. */\n timeout?: number;\n /** Random additional delay to spread retries. */\n jitter?: number;\n};\n\nexport type EdgeHttpCallArgs = {\n retry?: RetryConfig;\n /**\n * Force authentication by pre-fetching `/auth` to obtain the challenge before\n * sending the body. Use for requests with large bodies to avoid sending twice.\n * Not available on HubHttpClient (hub-service has no `/auth` endpoint).\n */\n auth?: boolean;\n};\n\nexport type BaseHttpClientOptions = {\n /**\n * Tag included in the {@link EDGE_CLIENT_TAG_HEADER} header on every request.\n * Used on Edge to classify traffic for metering (e.g. `ci-e2e`).\n */\n clientTag?: string;\n};\n\ntype HttpRequestArgs = {\n method: string;\n retry?: RetryConfig;\n body?: any;\n /** @default true */\n json?: boolean;\n auth?: boolean;\n};\n\nexport abstract class BaseHttpClient {\n protected readonly _baseUrl: string;\n protected readonly _clientTag: string | undefined;\n protected _edgeIdentity: EdgeIdentity | undefined;\n /** Auth header cached until next 401. */\n protected _authHeader: string | undefined;\n\n constructor(baseUrl: string, options?: BaseHttpClientOptions) {\n this._baseUrl = getEdgeUrlWithProtocol(baseUrl, 'http');\n this._clientTag = options?.clientTag;\n log('created', { url: this._baseUrl });\n }\n\n get baseUrl() {\n return this._baseUrl;\n }\n\n setIdentity(identity: EdgeIdentity): void {\n if (this._edgeIdentity?.identityKey !== identity.identityKey || this._edgeIdentity?.peerKey !== identity.peerKey) {\n this._edgeIdentity = identity;\n this._authHeader = undefined;\n }\n }\n\n // TODO(mykola): Extend `_call` to support streaming/raw `Response` returns so\n // `EdgeHttpClient.anthropicAiRequest` can be absorbed here and the auth/retry loop\n // stops being duplicated across the two paths.\n protected async _call<T>(ctx: Context, url: URL, args: HttpRequestArgs): Promise<T> {\n const shouldRetry = createRetryHandler(args);\n // Log presence/size only — never log raw body contents which may contain PII.\n log('fetch', {\n url,\n hasBody: args.body !== undefined,\n bodySize: typeof args.body === 'string' ? args.body.length : undefined,\n });\n\n const traceHeaders = getTraceHeaders(ctx);\n\n let handledAuth = false;\n const tryCount = 1;\n while (true) {\n let processingError: EdgeCallFailedError | undefined = undefined;\n try {\n if (!this._authHeader && args.auth) {\n const response = await fetch(new URL('/auth', this._baseUrl));\n if (response.status === 401) {\n this._authHeader = await this._handleUnauthorized(response);\n }\n }\n\n const request = createRequest(args, this._authHeader, traceHeaders, this._clientTag);\n log('call', { url, tryCount, authHeader: !!this._authHeader });\n const response = await fetch(url, request);\n\n if (response.ok) {\n const contentType = response.headers.get('Content-Type') ?? '';\n // No-content responses (204, empty body, non-JSON) — return undefined.\n if (\n response.status === 204 ||\n response.headers.get('Content-Length') === '0' ||\n !contentType.includes('application/json')\n ) {\n return undefined as T;\n }\n const body = await response.clone().json();\n if (typeof body !== 'object' || body === null) {\n return body;\n }\n if (!('success' in body)) {\n return body;\n }\n if (body.success) {\n return body.data;\n }\n } else if (response.status === 401 && response.headers.get('WWW-Authenticate') !== null && !handledAuth) {\n // Only retry edge auth when the 401 came from edge's own auth layer. Edge always sets\n // `WWW-Authenticate` on its own 401s; upstream-forwarded 401s lack it.\n this._authHeader = await this._handleUnauthorized(response);\n handledAuth = true;\n continue;\n }\n\n const contentType = response.headers.get('Content-Type') ?? '';\n const body: EdgeFailure = contentType.startsWith('application/json')\n ? await response.clone().json()\n : undefined;\n\n invariant(!body?.success, 'Expected body to not be a failure response or undefined.');\n\n if (body?.data?.type === 'auth_challenge' && typeof body?.data?.challenge === 'string') {\n processingError = new EdgeAuthChallengeError(body.data.challenge, body.data);\n } else if (body?.success === false) {\n processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);\n } else {\n invariant(!response.ok, 'Expected response to not be ok.');\n processingError = await EdgeCallFailedError.fromHttpFailure(response);\n }\n } catch (error: any) {\n processingError = EdgeCallFailedError.fromProcessingFailureCause(error);\n }\n\n if (processingError?.isRetryable && (await shouldRetry(ctx, processingError.retryAfterMs))) {\n log.verbose('retrying request', { url, processingError });\n } else {\n throw processingError!;\n }\n }\n }\n\n protected async _handleUnauthorized(response: Response): Promise<string> {\n if (!this._edgeIdentity) {\n log.warn('unauthorized response received before identity was set');\n throw await EdgeCallFailedError.fromHttpFailure(response);\n }\n const challenge = await handleAuthChallenge(response, this._edgeIdentity);\n return encodeAuthHeader(challenge);\n }\n}\n\nconst createRequest = (\n { method, body, json = true }: HttpRequestArgs,\n authHeader: string | undefined,\n traceHeaders?: Record<string, string>,\n clientTag?: string,\n): RequestInit => {\n let requestBody: BodyInit | undefined;\n const headers: HeadersInit = {};\n\n if (json) {\n requestBody = body === undefined ? undefined : JSON.stringify(body);\n headers['Content-Type'] = 'application/json';\n } else {\n requestBody = body;\n }\n\n if (typeof requestBody === 'string' && requestBody.length > WARNING_BODY_SIZE) {\n log.warn('Request with large body', { bodySize: requestBody.length });\n }\n\n if (authHeader) {\n headers['Authorization'] = authHeader;\n }\n\n if (traceHeaders) {\n Object.assign(headers, traceHeaders);\n }\n\n if (clientTag) {\n headers[EDGE_CLIENT_TAG_HEADER] = clientTag;\n }\n\n return { method, body: requestBody, headers };\n};\n\nconst getTraceHeaders = (ctx: Context): Record<string, string> | undefined => {\n const traceCtx = ctx.getAttribute(TRACE_SPAN_ATTRIBUTE) as TraceContextData | undefined;\n if (!traceCtx) {\n return undefined;\n }\n const headers: Record<string, string> = { traceparent: traceCtx.traceparent };\n if (traceCtx.tracestate) {\n headers.tracestate = traceCtx.tracestate;\n }\n return headers;\n};\n\n/** @deprecated */\nconst createRetryHandler = ({ retry }: HttpRequestArgs) => {\n if (!retry || retry.count < 1) {\n return async () => false;\n }\n let retries = 0;\n const maxRetries = retry.count ?? DEFAULT_MAX_RETRIES_COUNT;\n const baseTimeout = retry.timeout ?? DEFAULT_RETRY_TIMEOUT;\n const jitter = retry.jitter ?? DEFAULT_RETRY_JITTER;\n return async (ctx: Context, retryAfter?: number) => {\n if (++retries > maxRetries || ctx.disposed) {\n return false;\n }\n if (retryAfter) {\n await sleep(retryAfter);\n } else {\n const timeout = baseTimeout + Math.random() * jitter;\n await sleep(timeout);\n }\n return true;\n };\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as HttpClient from '@effect/platform/HttpClient';\nimport type * as HttpClientError from '@effect/platform/HttpClientError';\nimport type * as HttpClientResponse from '@effect/platform/HttpClientResponse';\nimport * as Context from 'effect/Context';\nimport * as Duration from 'effect/Duration';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Schedule from 'effect/Schedule';\n\nimport { log } from '@dxos/log';\n\n// TODO(burdon): Factor out.\n\nexport type RetryOptions = {\n timeout: Duration.Duration;\n retryTimes: number;\n retryBaseDelay: Duration.Duration;\n};\n\n// Layer pattern.\nexport class HttpConfig extends Context.Tag('HttpConfig')<HttpConfig, RetryOptions>() {\n static default = Layer.succeed(HttpConfig, {\n timeout: Duration.millis(1_000),\n retryTimes: 3,\n retryBaseDelay: Duration.millis(1_000),\n });\n}\n\n// HOC pattern.\nexport const withRetry = (\n effect: Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError, HttpClient.HttpClient>,\n {\n timeout = Duration.millis(1_000),\n retryBaseDelay = Duration.millis(1_000),\n retryTimes = 3,\n }: Partial<RetryOptions> = {},\n) => {\n return effect.pipe(\n Effect.flatMap((res) =>\n // Treat 500 errors as retryable?\n res.status === 500 ? Effect.fail(new Error(res.status.toString())) : res.json,\n ),\n Effect.timeout(timeout),\n Effect.retry({\n schedule: Schedule.exponential(retryBaseDelay).pipe(Schedule.jittered),\n times: retryTimes,\n }),\n );\n};\n\nexport const withRetryConfig = (\n effect: Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError, HttpClient.HttpClient>,\n) =>\n Effect.gen(function* () {\n const config = yield* HttpConfig;\n return yield* withRetry(effect, config);\n });\n\nexport const withLogging = <A extends HttpClientResponse.HttpClientResponse, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.tap((res) => {\n log.info('response', { status: res.status });\n }),\n );\n\n/**\n *\n */\n// TODO(burdon): Document.\nexport const encodeAuthHeader = (challenge: Uint8Array) => {\n const encodedChallenge = Buffer.from(challenge).toString('base64');\n return `VerifiablePresentation pb;base64,${encodedChallenge}`;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Headers from '@effect/platform/Headers';\nimport * as HttpClient from '@effect/platform/HttpClient';\nimport * as HttpClientError from '@effect/platform/HttpClientError';\nimport * as HttpClientResponse from '@effect/platform/HttpClientResponse';\nimport * as Effect from 'effect/Effect';\nimport * as FiberRef from 'effect/FiberRef';\nimport * as Layer from 'effect/Layer';\nimport * as Stream from 'effect/Stream';\n\nimport { BaseError, type BaseErrorOptions } from '@dxos/errors';\nimport { log } from '@dxos/log';\nimport { BYOK_HEADER } from '@dxos/protocols';\n\nimport { type EdgeHttpClient } from './edge-http-client';\n\nexport type GetEdgeHttpClient = () => EdgeHttpClient;\n\n/**\n * Thrown by {@link EdgeAiHttpClient} when an AI request carrying {@link BYOK_HEADER} is rejected\n * with 401/403 by the upstream provider — i.e. the user-supplied API key is invalid. Wrapped as\n * the `cause` of an `HttpClientError.ResponseError` so it flows through `@effect/ai`'s error\n * mapping; callers walk the cause chain (via {@link ByokError.is}) to render a useful message.\n */\nexport class ByokError extends BaseError.extend('ByokError', 'BYOK authentication failed') {\n constructor(options: { status: number; provider: string } & BaseErrorOptions) {\n super({ context: { status: options.status, provider: options.provider }, ...options });\n }\n}\n\n/**\n * Copy pasted from https://github.com/Effect-TS/effect/blob/main/packages/platform/src/internal/fetchHttpClient.ts\n */\nexport const requestInitTagKey = '@effect/platform/FetchHttpClient/FetchOptions';\n\n/**\n * An `@effect/platform` {@link HttpClient.HttpClient} that routes requests through the\n * authenticated EDGE AI endpoint via {@link EdgeHttpClient.anthropicAiRequest}, instead of\n * fetching the AI service directly.\n *\n * Provide this layer in place of `FetchHttpClient.layer` when constructing an Anthropic client,\n * e.g. `AnthropicClient.layer({ apiUrl: 'http://edge' }).pipe(Layer.provide(EdgeAiHttpClient.layer(() => edgeClient)))`.\n * The `apiUrl` host is a sentinel; only the request path is forwarded (see `anthropicAiRequest`).\n *\n * Modeled on `FunctionsAiHttpClient` in `@dxos/functions`.\n */\nexport class EdgeAiHttpClient {\n static make = (getClient: GetEdgeHttpClient) =>\n HttpClient.make((request, url, signal, fiber) => {\n const edgeClient = getClient();\n const context = fiber.getFiberRef(FiberRef.currentContext);\n const options: RequestInit = context.unsafeMap.get(requestInitTagKey) ?? {};\n const headers = options.headers\n ? Headers.merge(Headers.fromInput(options.headers), request.headers)\n : request.headers;\n\n const carriedByok = !!headers[BYOK_HEADER.toLowerCase()];\n\n const send = (body: BodyInit | undefined) =>\n Effect.tryPromise({\n try: () =>\n edgeClient.anthropicAiRequest(\n new Request(url, {\n ...options,\n method: request.method,\n headers,\n body,\n signal,\n }),\n ),\n catch: (cause) => {\n log.error('Failed to fetch', { cause });\n return new HttpClientError.RequestError({\n request,\n reason: 'Transport',\n cause,\n });\n },\n }).pipe(\n Effect.flatMap((response) => {\n const httpResponse = HttpClientResponse.fromWeb(request, response);\n // A 401/403 on a BYOK-carrying request means the user's upstream key was rejected.\n // Wrap as a typed ResponseError with `cause: ByokError` so it survives AiError's\n // `fromRequestError` mapping; callers walk the cause chain to render a useful message.\n if (carriedByok && (response.status === 401 || response.status === 403)) {\n return Effect.tryPromise({\n try: () => response.clone().json() as Promise<{ error?: { message?: string } } | undefined>,\n catch: () => undefined,\n }).pipe(\n Effect.orElseSucceed(() => undefined),\n Effect.flatMap((body) =>\n Effect.fail(\n new HttpClientError.ResponseError({\n request,\n response: httpResponse,\n reason: 'StatusCode',\n cause: new ByokError({\n status: response.status,\n provider: 'anthropic.com',\n message: body?.error?.message ?? 'Authentication failed',\n }),\n }),\n ),\n ),\n );\n }\n return Effect.succeed(httpResponse);\n }),\n );\n\n switch (request.body._tag) {\n case 'Raw':\n case 'Uint8Array':\n return send(request.body.body as any);\n case 'FormData':\n return send(request.body.formData);\n case 'Stream':\n return Stream.toReadableStreamEffect(request.body.stream).pipe(Effect.flatMap(send));\n }\n\n return send(undefined);\n });\n\n static layer = (getClient: GetEdgeHttpClient) =>\n Layer.succeed(HttpClient.HttpClient, EdgeAiHttpClient.make(getClient));\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as FetchHttpClient from '@effect/platform/FetchHttpClient';\nimport * as HttpClient from '@effect/platform/HttpClient';\nimport * as HttpClientRequest from '@effect/platform/HttpClientRequest';\nimport * as Effect from 'effect/Effect';\nimport * as Function from 'effect/Function';\n\nimport { type Context } from '@dxos/context';\nimport { EffectEx } from '@dxos/effect';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n type CompleteOAuthRegistrationRequest,\n type CompleteOAuthRegistrationResponse,\n type CreateAgentRequestBody,\n type CreateAgentResponseBody,\n type CreateSpaceRequest,\n type CreateSpaceResponseBody,\n EDGE_CLIENT_TAG_HEADER,\n type EdgeStatus,\n type ExecuteWorkflowResponseBody,\n type ExportBundleRequest,\n type ExportBundleResponse,\n type FeedProtocol,\n type GetAgentStatusResponseBody,\n type GetNotarizationResponseBody,\n type GetPluginVersionsResponseBody,\n type GetPluginsResponseBody,\n type ImportBundleRequest,\n type InitiateOAuthFlowRequest,\n type InitiateOAuthFlowResponse,\n type JoinSpaceRequest,\n type JoinSpaceResponseBody,\n type ObjectId,\n type PostNotarizationRequestBody,\n type RecoverIdentityRequest,\n type RecoverIdentityResponseBody,\n type UploadFunctionRequest,\n type UploadFunctionResponseBody,\n} from '@dxos/protocols';\nimport {\n type QueryRequest as QueryRequestProto,\n type QueryResponse as QueryResponseProto,\n} from '@dxos/protocols/proto/dxos/echo/query';\nimport { createUrl } from '@dxos/util';\n\nimport { BaseHttpClient, type BaseHttpClientOptions, type EdgeHttpCallArgs } from './base-http-client';\nimport { proxyFetchLegacy } from './cors-proxy';\nimport { HttpConfig, withLogging, withRetryConfig } from './http-client';\n\nexport type { EdgeHttpCallArgs, RetryConfig } from './base-http-client';\n\n/**\n * HTTP wire shape returned by `/queue/.../query`.\n */\nexport type EdgeQueryQueueResponse = {\n objects?: unknown[];\n nextCursor?: string;\n prevCursor?: string;\n};\n\nexport type TriggersDispatcherStatus = {\n isActive: boolean;\n nextCronTaskRunTimestamp?: number;\n registeredTriggers: string[];\n stopAfterTimestamp?: number;\n remainingMs?: number;\n nextAlarmTimestamp?: number;\n};\n\nexport type GetCronTriggersResponse = {\n cronIds: string[];\n};\n\nexport type EdgeHttpClientOptions = BaseHttpClientOptions;\n\n/**\n * HTTP client for the edge worker API (spaces, queues, functions, agents, etc.).\n *\n * Hub-service API (accounts, invitations) lives in {@link HubHttpClient} — the two\n * services run at different URLs and are never both available from the same base URL.\n */\nexport class EdgeHttpClient extends BaseHttpClient {\n constructor(baseUrl: string, options?: EdgeHttpClientOptions) {\n super(baseUrl, options);\n log('created', { url: this.baseUrl });\n }\n\n //\n // Status\n //\n\n public async getStatus(ctx: Context, args?: EdgeHttpCallArgs): Promise<EdgeStatus> {\n return this._call(ctx, new URL('/status', this.baseUrl), { ...args, method: 'GET', auth: true });\n }\n\n //\n // Agents\n //\n\n public createAgent(\n ctx: Context,\n body: CreateAgentRequestBody,\n args?: EdgeHttpCallArgs,\n ): Promise<CreateAgentResponseBody> {\n return this._call(ctx, new URL('/agents/create', this.baseUrl), { ...args, method: 'POST', body });\n }\n\n public getAgentStatus(\n ctx: Context,\n request: { ownerIdentityKey: PublicKey },\n args?: EdgeHttpCallArgs,\n ): Promise<GetAgentStatusResponseBody> {\n return this._call(ctx, new URL(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, this.baseUrl), {\n ...args,\n method: 'GET',\n });\n }\n\n //\n // Credentials\n //\n\n public getCredentialsForNotarization(\n ctx: Context,\n spaceId: SpaceId,\n args?: EdgeHttpCallArgs,\n ): Promise<GetNotarizationResponseBody> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async notarizeCredentials(\n ctx: Context,\n spaceId: SpaceId,\n body: PostNotarizationRequestBody,\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n await this._call(ctx, new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Identity\n //\n\n public async recoverIdentity(\n ctx: Context,\n body: RecoverIdentityRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<RecoverIdentityResponseBody> {\n return this._call(ctx, new URL('/identity/recover', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Invitations (space join)\n //\n\n public async joinSpaceByInvitation(\n ctx: Context,\n spaceId: SpaceId,\n body: JoinSpaceRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<JoinSpaceResponseBody> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/join`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // OAuth\n //\n\n public async initiateOAuthFlow(\n ctx: Context,\n body: InitiateOAuthFlowRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<InitiateOAuthFlowResponse> {\n return this._call(ctx, new URL('/oauth/initiate', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n public async completeOAuthRegistration(\n ctx: Context,\n body: CompleteOAuthRegistrationRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<CompleteOAuthRegistrationResponse> {\n return this._call(ctx, new URL('/oauth/registration/complete', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Spaces\n //\n\n async createSpace(ctx: Context, body: CreateSpaceRequest, args?: EdgeHttpCallArgs): Promise<CreateSpaceResponseBody> {\n return this._call(ctx, new URL('/spaces/create', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Queues\n //\n\n public async queryQueue(\n ctx: Context,\n subspaceTag: string,\n spaceId: SpaceId,\n query: FeedProtocol.QueueQuery,\n args?: EdgeHttpCallArgs,\n ): Promise<EdgeQueryQueueResponse> {\n const queueId = query.queueIds?.[0];\n invariant(queueId, 'queueId required');\n return this._call(\n ctx,\n createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}/query`, this.baseUrl), {\n after: query.after,\n before: query.before,\n limit: query.limit,\n reverse: query.reverse,\n objectIds: query.objectIds?.join(','),\n }),\n { ...args, method: 'GET' },\n );\n }\n\n public async insertIntoQueue(\n ctx: Context,\n subspaceTag: string,\n spaceId: SpaceId,\n queueId: ObjectId,\n objects: unknown[],\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n return this._call(ctx, new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {\n ...args,\n body: { objects },\n method: 'POST',\n });\n }\n\n public async deleteFromQueue(\n ctx: Context,\n subspaceTag: string,\n spaceId: SpaceId,\n queueId: ObjectId,\n objectIds: ObjectId[],\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n return this._call(\n ctx,\n createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {\n ids: objectIds.join(','),\n }),\n { ...args, method: 'DELETE' },\n );\n }\n\n //\n // Functions\n //\n\n public async uploadFunction(\n ctx: Context,\n pathParts: { functionId?: string },\n body: UploadFunctionRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<UploadFunctionResponseBody> {\n const formData = new FormData();\n formData.append('name', body.name ?? '');\n formData.append('version', body.version);\n formData.append('ownerPublicKey', body.ownerPublicKey);\n formData.append('entryPoint', body.entryPoint);\n body.runtime && formData.append('runtime', body.runtime);\n for (const [filename, content] of Object.entries(body.assets)) {\n formData.append(\n 'assets',\n new Blob([content as Uint8Array<ArrayBuffer>], { type: getFileMimeType(filename) }),\n filename,\n );\n }\n const path = ['functions', ...(pathParts.functionId ? [pathParts.functionId] : [])].join('/');\n return this._call(ctx, new URL(path, this.baseUrl), { ...args, body: formData, method: 'PUT', json: false });\n }\n\n public async listFunctions(ctx: Context, args?: EdgeHttpCallArgs): Promise<any> {\n return this._call(ctx, new URL('/functions', this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async invokeFunction(\n ctx: Context,\n params: {\n functionId: string;\n version?: string;\n spaceId?: SpaceId;\n cpuTimeLimit?: number;\n subrequestsLimit?: number;\n },\n input: unknown,\n args?: EdgeHttpCallArgs,\n ): Promise<any> {\n const url = new URL(`/functions/${params.functionId}`, this.baseUrl);\n if (params.version) {\n url.searchParams.set('version', params.version);\n }\n if (params.spaceId) {\n url.searchParams.set('spaceId', params.spaceId.toString());\n }\n if (params.cpuTimeLimit) {\n url.searchParams.set('cpuTimeLimit', params.cpuTimeLimit.toString());\n }\n if (params.subrequestsLimit) {\n url.searchParams.set('subrequestsLimit', params.subrequestsLimit.toString());\n }\n return this._call(ctx, url, { ...args, body: input, method: 'POST' });\n }\n\n //\n // Workflows\n //\n\n public async executeWorkflow(\n ctx: Context,\n spaceId: SpaceId,\n graphId: ObjectId,\n input: any,\n args?: EdgeHttpCallArgs,\n ): Promise<ExecuteWorkflowResponseBody> {\n return this._call(ctx, new URL(`/workflows/${spaceId}/${graphId}`, this.baseUrl), {\n ...args,\n body: input,\n method: 'POST',\n });\n }\n\n //\n // Triggers\n //\n\n public async getCronTriggers(ctx: Context, spaceId: SpaceId): Promise<GetCronTriggersResponse> {\n return this._call<GetCronTriggersResponse>(ctx, new URL(`/functions/${spaceId}/triggers/crons`, this.baseUrl), {\n method: 'GET',\n });\n }\n\n public async getTriggersDispatcherStatus(\n ctx: Context,\n spaceId: SpaceId,\n args?: EdgeHttpCallArgs,\n ): Promise<TriggersDispatcherStatus> {\n return this._call<TriggersDispatcherStatus>(ctx, new URL(`/triggers/${spaceId}/status`, this.baseUrl), {\n ...args,\n method: 'GET',\n auth: true,\n });\n }\n\n public async forceRunCronTrigger(ctx: Context, spaceId: SpaceId, triggerId: ObjectId) {\n return this._call(ctx, new URL(`/functions/${spaceId}/triggers/crons/${triggerId}/run`, this.baseUrl), {\n method: 'POST',\n });\n }\n\n //\n // Query\n //\n\n public async execQuery(\n ctx: Context,\n spaceId: SpaceId,\n body: QueryRequestProto,\n args?: EdgeHttpCallArgs,\n ): Promise<QueryResponseProto> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/exec-query`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Registry\n //\n\n public async getRegistryPlugins(ctx: Context, args?: EdgeHttpCallArgs): Promise<GetPluginsResponseBody> {\n return this._call(ctx, new URL('/registry/plugins', this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async getRegistryPluginVersions(\n ctx: Context,\n repo: string,\n args?: EdgeHttpCallArgs,\n ): Promise<GetPluginVersionsResponseBody> {\n return this._call(ctx, new URL(`/registry/plugins/${encodeURIComponent(repo)}/versions`, this.baseUrl), {\n ...args,\n method: 'GET',\n });\n }\n\n //\n // Import/Export\n //\n\n public async importBundle(\n ctx: Context,\n spaceId: SpaceId,\n body: ImportBundleRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/import`, this.baseUrl), { ...args, body, method: 'PUT' });\n }\n\n public async exportBundle(\n ctx: Context,\n spaceId: SpaceId,\n body: ExportBundleRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<ExportBundleResponse> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/export`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Proxy\n //\n\n /**\n * Fetch through the edge proxy for third-party REST APIs.\n * TEMPORARY: currently routes through legacy open proxy. See https://github.com/dxos/edge/pull/576.\n */\n public async proxyFetch(target: URL, init: RequestInit = {}): Promise<Response> {\n return proxyFetchLegacy(target, init, this._clientTag);\n }\n\n //\n // AI service.\n //\n\n /**\n * Issue an authenticated request to the EDGE AI route (`/ai/generate/anthropic/*`), which\n * proxies to the AI service. Used as the backend HTTP client for the Anthropic AI provider\n * (see {@link EdgeAiHttpClient}).\n *\n * Returns the raw `Response` so streaming bodies are forwarded unchanged to `@effect/ai`.\n * Requires an identity to have been set via {@link setIdentity}.\n */\n // TODO(mykola): Merge into `BaseHttpClient._call` once it can return a streaming/raw `Response`;\n // the auth/retry loop below duplicates the one in `_call`.\n public async anthropicAiRequest(request: Request): Promise<Response> {\n const incoming = new URL(request.url);\n const base = this.baseUrl.replace(/\\/$/, '');\n const target = new URL(`${base}/ai/generate/anthropic${incoming.pathname}${incoming.search}`);\n\n const method = request.method;\n const body = method === 'GET' || method === 'HEAD' ? undefined : await request.arrayBuffer();\n\n let handledAuth = false;\n while (true) {\n if (!this._authHeader) {\n const authResponse = await fetch(new URL('/auth', this.baseUrl));\n if (authResponse.status === 401) {\n this._authHeader = await this._handleUnauthorized(authResponse);\n }\n }\n\n const headers = new Headers(request.headers);\n if (this._authHeader) {\n headers.set('Authorization', this._authHeader);\n }\n if (this._clientTag) {\n headers.set(EDGE_CLIENT_TAG_HEADER, this._clientTag);\n }\n\n const response = await fetch(target, { method, headers, body, signal: request.signal });\n // Only retry edge auth when the 401 came from edge's own auth layer. Edge always sets\n // `WWW-Authenticate` on its own 401s; upstream-forwarded 401s (e.g. invalid BYOK rejected\n // by Anthropic) lack it and must be surfaced verbatim.\n if (response.status === 401 && response.headers.get('WWW-Authenticate') !== null && !handledAuth) {\n this._authHeader = await this._handleUnauthorized(response);\n handledAuth = true;\n continue;\n }\n\n return response;\n }\n }\n\n //\n // Internal (Effect-based, used by tests)\n //\n\n public async _fetch<T>(url: URL, _args: { method: string }): Promise<T> {\n return Function.pipe(\n HttpClient.execute(HttpClientRequest.make(_args.method as any)(url.toString())),\n withLogging,\n withRetryConfig,\n Effect.provide(FetchHttpClient.layer),\n Effect.provide(HttpConfig.default),\n Effect.withSpan('EdgeHttpClient'),\n EffectEx.runAndForwardErrors,\n ) as T;\n }\n}\n\nconst getFileMimeType = (filename: string) =>\n ['.js', '.mjs'].some((ext) => filename.endsWith(ext))\n ? 'application/javascript+module'\n : filename.endsWith('.wasm')\n ? 'application/wasm'\n : 'application/octet-stream';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Context } from '@dxos/context';\nimport {\n type CheckEmailExistsResponse,\n type GetAccountResponse,\n type IssueInvitationResponse,\n type ListAccountInvitationsResponse,\n type LoginRequest,\n type LoginResponse,\n type RedeemInvitationCodeRequest,\n type RedeemInvitationCodeResponse,\n type RequestAccessRequest,\n type RequestAccessResponse,\n type ResendVerificationEmailResponse,\n type ValidateInvitationCodeResponse,\n} from '@dxos/protocols';\n\nimport { BaseHttpClient, type BaseHttpClientOptions, type EdgeHttpCallArgs } from './base-http-client';\n\n/**\n * HTTP client for the hub-service API (accounts, invitations, email verification).\n *\n * Hub-service and the edge worker are separate Cloudflare Workers deployed at different\n * URLs (`DX_HUB_URL` vs `DX_EDGE_URL`). This client is never used to talk to the edge\n * worker, and vice versa — keep them separate.\n *\n * NOTE: Do NOT set `auth: true` on any call here. Hub-service has no `/auth` VP-challenge\n * endpoint (it has an admin login page that 302s and is not CORS-enabled). Auth is handled\n * via the regular request → 401 → WWW-Authenticate challenge → retry path.\n */\nexport class HubHttpClient extends BaseHttpClient {\n constructor(hubUrl: string, options?: BaseHttpClientOptions) {\n super(hubUrl, options);\n }\n\n //\n // Public (unauthenticated) endpoints\n //\n\n public async checkEmailExists(\n ctx: Context,\n body: { email: string },\n args?: EdgeHttpCallArgs,\n ): Promise<CheckEmailExistsResponse> {\n return this._call(ctx, new URL('/account/email/exists', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n public async validateInvitationCode(\n ctx: Context,\n body: { code: string },\n args?: EdgeHttpCallArgs,\n ): Promise<ValidateInvitationCodeResponse> {\n return this._call(ctx, new URL('/account/invitation-code/validate', this.baseUrl), {\n ...args,\n body,\n method: 'POST',\n });\n }\n\n public async redeemInvitationCode(\n ctx: Context,\n body: RedeemInvitationCodeRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<RedeemInvitationCodeResponse> {\n return this._call(ctx, new URL('/account/invitation-code/redeem', this.baseUrl), {\n ...args,\n body,\n method: 'POST',\n });\n }\n\n /**\n * Existing-account email login. Server inlines `token` for test emails; regular\n * emails are delivered out-of-band. Response is identical for unknown emails\n * (enumeration-safe).\n */\n public async login(ctx: Context, body: LoginRequest, args?: EdgeHttpCallArgs): Promise<LoginResponse> {\n return this._call(ctx, new URL('/account/login', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n public async requestAccess(\n ctx: Context,\n body: RequestAccessRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<RequestAccessResponse> {\n return this._call(ctx, new URL('/account/request-access', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Authenticated (VP) endpoints\n //\n\n public async getAccount(ctx: Context, args?: EdgeHttpCallArgs): Promise<GetAccountResponse> {\n return this._call(ctx, new URL('/account/me', this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async deleteAccount(ctx: Context, args?: EdgeHttpCallArgs): Promise<{ deleted: boolean }> {\n return this._call(ctx, new URL('/account/me', this.baseUrl), { ...args, method: 'DELETE' });\n }\n\n public async listAccountInvitations(ctx: Context, args?: EdgeHttpCallArgs): Promise<ListAccountInvitationsResponse> {\n return this._call(ctx, new URL('/account/invitation', this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async issueAccountInvitation(ctx: Context, args?: EdgeHttpCallArgs): Promise<IssueInvitationResponse> {\n return this._call(ctx, new URL('/account/invitation/issue', this.baseUrl), { ...args, method: 'POST' });\n }\n\n public async resendVerificationEmail(\n ctx: Context,\n args?: EdgeHttpCallArgs,\n ): Promise<ResendVerificationEmailResponse> {\n return this._call(ctx, new URL('/account/email/resend-verification', this.baseUrl), { ...args, method: 'POST' });\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["createCredential", "signPresentation", "invariant", "Keyring", "PublicKey", "identityKey", "peerKey", "presentCredentials", "presentation", "issuer", "key", "subject", "signer", "signerKey", "nonce", "chain", "signingKey", "challenge", "credentialsToSign", "createDeviceEdgeIdentity", "assertion", "deviceKey", "Error", "TRACE_SPAN_ATTRIBUTE", "scheduleTaskInterval", "Resource", "log", "EdgeStatus", "protocol", "invariant", "schema", "__dxlog_file", "handleAuthChallenge", "headerValue", "failedResponse", "headers", "startsWith", "challenge", "slice", "presentation", "identity", "presentCredentials", "Buffer", "getCodecForType", "Context", "Resource", "invariant", "log", "EdgeWebsocketProtocol", "buf", "MessageSchema", "protocol", "SIGNAL_KEEPALIVE_TIMEOUT", "EdgeWsConnection", "_inactivityTimeoutCtx", "_ws", "_wsMuxer", "_lastReceivedMessageTimestamp", "_openTimestamp", "_rtt", "_downloadRate", "_rateWindow", "_rateUpdateInterval", "_bytesSamples", "_messagesSent", "_messagesReceived", "_identity", "_connectionInfo", "open", "identity", "device", "peerKey", "_uploadRate", "send", "invariant", "__dxlog_file", "log", "payload", "protocol", "getPayloadType", "binary", "toBinary", "MessageSchema", "message", "length", "CLOUDFLARE_MESSAGE_MAX_BYTES", "error", "byteLength", "serviceId", "_recordBytes", "e", "baseProtocols", "EdgeWebsocketProtocol", "headers", "undefined", "muxer", "isOpen", "Date", "_callbacks", "onConnected", "_scheduleHeartbeats", "_scheduleRateCalculation", "currentIdentity", "warn", "code", "reason", "event", "onRestartRequired", "info", "verbose", "_pingTimestamp", "from", "err", "scheduleTaskInterval", "_ctx", "SIGNAL_KEEPALIVE_INTERVAL", "now", "_rescheduleHeartbeatTimeout", "Context", "scheduleTask", "lastReceivedMessageTimestamp", "existingSample", "find", "sent", "received", "timestamp", "_calculateRates", "cutoff", "totalReceived", "oldestTimestamp", "timeSpan", "sample", "totalSent", "Math", "round", "EdgeConnectionClosedError", "Error", "EdgeIdentityChangedError", "getEdgeUrlWithProtocol", "baseUrl", "protocol", "isSecure", "startsWith", "url", "URL", "toString", "statusChanged", "_persistentLifecycle", "_connect", "stop", "state", "_disconnect", "_messageListeners", "_reconnectListeners", "Set", "_baseWsUrl", "_baseHttpUrl", "_currentConnection", "_ready", "Trigger", "_identity", "getEdgeUrlWithProtocol", "_config", "socketEndpoint", "open", "status", "identity", "device", "peerKey", "uptime", "rtt", "rateBytesUp", "rateBytesDown", "downloadRate", "messagesSent", "messagesReceived", "setIdentity", "identityKey", "log", "oldIdentity", "_closeCurrentConnection", "scheduleRestart", "__dxlog_file", "timeout", "EdgeConnectionClosedError", "EdgeIdentityChangedError", "traceCtx", "message", "traceContext", "$typeName", "traceparent", "tracestate", "onMessage", "delete", "onReconnected", "TriggerState", "has", "listener", "error", "catch", "info", "err", "STATUS_REFRESH_INTERVAL", "undefined", "path", "protocolHeader", "disableAuth", "url", "connection", "EdgeWsConnection", "headers", "_isActive", "wake", "_notifyReconnected", "onRestartRequired", "restartRequired", "_notifyMessageReceived", "from", "type", "payload", "then", "wait", "close", "reset", "URL", "httpUrl", "response", "method", "encodePresentationWsAuthHeader", "statusText", "encodedToken", "sleep", "TRACE_SPAN_ATTRIBUTE", "invariant", "log", "EDGE_CLIENT_TAG_HEADER", "EdgeAuthChallengeError", "EdgeCallFailedError", "Context", "Duration", "Effect", "Layer", "Schedule", "log", "__dxlog_file", "timeout", "retryTimes", "retryBaseDelay", "millis", "status", "fail", "toString", "retry", "schedule", "exponential", "times", "withRetry", "effect", "config", "withLogging", "pipe", "__dxlog_file", "DEFAULT_RETRY_TIMEOUT", "DEFAULT_MAX_RETRIES_COUNT", "WARNING_BODY_SIZE", "BaseHttpClient", "_baseUrl", "_clientTag", "_edgeIdentity", "getEdgeUrlWithProtocol", "options", "log", "url", "baseUrl", "setIdentity", "identity", "_authHeader", "undefined", "hasBody", "args", "bodySize", "traceHeaders", "getTraceHeaders", "ctx", "handledAuth", "tryCount", "processingError", "response", "_handleUnauthorized", "authHeader", "fetch", "ok", "contentType", "headers", "get", "body", "success", "status", "invariant", "data", "challenge", "EdgeAuthChallengeError", "EdgeCallFailedError", "fromUnsuccessfulResponse", "isRetryable", "shouldRetry", "handleAuthChallenge", "json", "requestBody", "clientTag", "traceCtx", "tracestate", "retry", "retries", "baseTimeout", "jitter", "DEFAULT_RETRY_JITTER", "retryAfter", "maxRetries", "timeout", "Headers", "HttpClient", "HttpClientError", "HttpClientResponse", "Effect", "FiberRef", "Layer", "Stream", "BaseError", "log", "BYOK_HEADER", "__dxlog_file", "context", "provider", "options", "getClient", "getFiberRef", "currentContext", "unsafeMap", "headers", "merge", "fromInput", "carriedByok", "send", "body", "edgeClient", "anthropicAiRequest", "Request", "method", "request", "signal", "cause", "reason", "response", "clone", "undefined", "pipe", "orElseSucceed", "httpResponse", "status", "message", "error", "_tag", "formData", "toReadableStreamEffect", "layer", "FetchHttpClient", "HttpClient", "HttpClientRequest", "Effect", "Function", "EffectEx", "invariant", "log", "EDGE_CLIENT_TAG_HEADER", "createUrl", "__dxlog_file", "baseUrl", "options", "url", "log", "method", "auth", "args", "body", "getAgentStatus", "invariant", "queueId", "_call", "ctx", "after", "before", "query", "limit", "reverse", "objectIds", "formData", "append", "ownerPublicKey", "entryPoint", "runtime", "filename", "Object", "entries", "content", "type", "path", "pathParts", "json", "version", "searchParams", "params", "cpuTimeLimit", "subrequestsLimit", "input", "replace", "target", "URL", "request", "undefined", "arrayBuffer", "handledAuth", "_authHeader", "authResponse", "status", "_handleUnauthorized", "headers", "_clientTag", "response", "signal", "some", "HubHttpClient", "BaseHttpClient", "hubUrl", "options", "checkEmailExists", "ctx", "body", "args", "_call", "URL", "baseUrl", "method", "validateInvitationCode", "redeemInvitationCode", "login", "requestAccess", "getAccount", "deleteAccount", "listAccountInvitations", "issueAccountInvitation", "resendVerificationEmail"]
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nexport * from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nexport * from './auth';\nexport * from './cors-proxy';\nexport * from './defs';\nexport * from './edge-client';\nexport * from './errors';\nexport * from './protocol';\nexport * from './base-http-client';\nexport * from './edge-ai-http-client';\nexport * from './edge-http-client';\nexport * from './hub-http-client';\nexport * from './edge-identity';\nexport * from './edge-ws-muxer';\nexport * from './http-client';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { createCredential, signPresentation } from '@dxos/credentials';\nimport { type Signer } from '@dxos/crypto';\nimport { invariant } from '@dxos/invariant';\nimport { Keyring } from '@dxos/keyring';\nimport { PublicKey } from '@dxos/keys';\nimport { type Chain, type Credential } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nimport type { EdgeIdentity } from './edge-identity';\n\n/**\n * Edge identity backed by a device key without a credential chain.\n */\nexport const createDeviceEdgeIdentity = async (signer: Signer, key: PublicKey): Promise<EdgeIdentity> => {\n return {\n identityKey: key.toHex(),\n peerKey: key.toHex(),\n presentCredentials: async ({ challenge }) => {\n return signPresentation({\n presentation: {\n credentials: [\n // Verifier requires at least one credential in the presentation to establish the subject.\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: key,\n subject: key,\n signer,\n }),\n ],\n },\n signer,\n signerKey: key,\n nonce: challenge,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a chain of credentials.\n */\nexport const createChainEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n peerKey: PublicKey,\n chain: Chain | undefined,\n credentials: Credential[],\n): Promise<EdgeIdentity> => {\n const credentialsToSign =\n credentials.length > 0\n ? credentials\n : [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n chain,\n signingKey: peerKey,\n }),\n ];\n\n return {\n identityKey: identityKey.toHex(),\n peerKey: peerKey.toHex(),\n presentCredentials: async ({ challenge }) => {\n // TODO: make chain required after device invitation flow update release\n invariant(chain);\n return signPresentation({\n presentation: {\n credentials: credentialsToSign,\n },\n signer,\n nonce: challenge,\n signerKey: peerKey,\n chain,\n });\n },\n };\n};\n\n/**\n * Edge identity backed by a random ephemeral key without HALO.\n */\nexport const createEphemeralEdgeIdentity = async (): Promise<EdgeIdentity> => {\n const keyring = new Keyring();\n const key = await keyring.createKey();\n return createDeviceEdgeIdentity(keyring, key);\n};\n\n/**\n * Creates a HALO chain of credentials to act as an edge identity.\n */\nexport const createTestHaloEdgeIdentity = async (\n signer: Signer,\n identityKey: PublicKey,\n deviceKey: PublicKey,\n): Promise<EdgeIdentity> => {\n const deviceAdmission = await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.AuthorizedDevice',\n deviceKey,\n identityKey,\n },\n issuer: identityKey,\n subject: deviceKey,\n signer,\n });\n return createChainEdgeIdentity(signer, identityKey, deviceKey, { credential: deviceAdmission }, [\n await createCredential({\n assertion: {\n '@type': 'dxos.halo.credentials.Auth',\n },\n issuer: identityKey,\n subject: identityKey,\n signer,\n }),\n ]);\n};\n\nexport const createStubEdgeIdentity = (): EdgeIdentity => {\n const identityKey = PublicKey.random();\n const deviceKey = PublicKey.random();\n return {\n identityKey: identityKey.toHex(),\n peerKey: deviceKey.toHex(),\n presentCredentials: async () => {\n throw new Error('Stub identity does not support authentication.');\n },\n };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport {\n Event,\n PersistentLifecycle,\n Trigger,\n TriggerState,\n scheduleMicroTask,\n scheduleTaskInterval,\n} from '@dxos/async';\nimport { Context, TRACE_SPAN_ATTRIBUTE, type TraceContextData } from '@dxos/context';\nimport { type Lifecycle, Resource } from '@dxos/context';\nimport { log, logInfo } from '@dxos/log';\nimport { type Message } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\nimport { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';\n\nimport { protocol } from './defs';\nimport { type EdgeIdentity, handleAuthChallenge } from './edge-identity';\nimport { EdgeWsConnection } from './edge-ws-connection';\nimport { EdgeConnectionClosedError, EdgeIdentityChangedError } from './errors';\nimport { type Protocol } from './protocol';\nimport { getEdgeUrlWithProtocol } from './utils';\n\nconst DEFAULT_TIMEOUT = 10_000;\n\n// Refresh status every second: rtt, rate counters.\nconst STATUS_REFRESH_INTERVAL = 1000;\n\nexport type MessageListener = (message: Message) => void;\nexport type ReconnectListener = () => void;\n\nexport type MessengerConfig = {\n socketEndpoint: string;\n timeout?: number;\n protocol?: Protocol;\n disableAuth?: boolean;\n /** Sent as `X-DXOS-Client-Tag` on the WebSocket upgrade (Node/`ws` only; ignored in browsers). */\n clientTag?: string;\n};\n\nexport interface EdgeConnection extends Required<Lifecycle> {\n statusChanged: Event<EdgeStatus>;\n get info(): any;\n get identityKey(): string;\n get peerKey(): string;\n get isOpen(): boolean;\n get status(): EdgeStatus;\n setIdentity(identity: EdgeIdentity): void;\n send(ctx: Context, message: Message): Promise<void>;\n onMessage(listener: MessageListener): () => void;\n onReconnected(listener: ReconnectListener): () => void;\n}\n\n/**\n * Messenger client for EDGE:\n * - While open, uses PersistentLifecycle to keep an open EdgeWsConnection, reconnecting on failures.\n * - Manages identity and re-create EdgeWsConnection when identity changes.\n * - Dispatches connection state and message notifications.\n */\nexport class EdgeClient extends Resource implements EdgeConnection {\n public readonly statusChanged = new Event<EdgeStatus>();\n\n private readonly _persistentLifecycle = new PersistentLifecycle<EdgeWsConnection>({\n start: async () => this._connect(),\n stop: async (state: EdgeWsConnection) => this._disconnect(state),\n });\n\n private readonly _messageListeners = new Set<MessageListener>();\n private readonly _reconnectListeners = new Set<ReconnectListener>();\n private readonly _baseWsUrl: string;\n private readonly _baseHttpUrl: string;\n private _currentConnection?: EdgeWsConnection = undefined;\n private _ready = new Trigger();\n\n constructor(\n private _identity: EdgeIdentity,\n private readonly _config: MessengerConfig,\n ) {\n super();\n this._baseWsUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, 'ws');\n this._baseHttpUrl = getEdgeUrlWithProtocol(_config.socketEndpoint, 'http');\n }\n\n @logInfo\n public get info() {\n return {\n open: this.isOpen,\n status: this.status,\n identity: this._identity.identityKey,\n device: this._identity.peerKey,\n };\n }\n\n get status(): EdgeStatus {\n return {\n state:\n Boolean(this._currentConnection) && this._ready.state === TriggerState.RESOLVED\n ? EdgeStatus.ConnectionState.CONNECTED\n : EdgeStatus.ConnectionState.NOT_CONNECTED,\n uptime: this._currentConnection?.uptime ?? 0,\n rtt: this._currentConnection?.rtt ?? 0,\n rateBytesUp: this._currentConnection?.uploadRate ?? 0,\n rateBytesDown: this._currentConnection?.downloadRate ?? 0,\n messagesSent: this._currentConnection?.messagesSent ?? 0,\n messagesReceived: this._currentConnection?.messagesReceived ?? 0,\n };\n }\n\n get identityKey() {\n return this._identity.identityKey;\n }\n\n get peerKey() {\n return this._identity.peerKey;\n }\n\n setIdentity(identity: EdgeIdentity) {\n if (identity.identityKey !== this._identity.identityKey || identity.peerKey !== this._identity.peerKey) {\n log('Edge identity changed', { identity, oldIdentity: this._identity });\n this._identity = identity;\n this._closeCurrentConnection(new EdgeIdentityChangedError());\n void this._persistentLifecycle.scheduleRestart();\n }\n }\n\n /**\n * Send message.\n * NOTE: The message is guaranteed to be delivered but the service must respond with a message to confirm processing.\n */\n public async send(ctx: Context, message: Message) {\n if (this._ready.state !== TriggerState.RESOLVED) {\n log('waiting for websocket');\n await this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT });\n }\n\n if (!this._currentConnection) {\n throw new EdgeConnectionClosedError();\n }\n\n if (\n message.source &&\n (message.source.peerKey !== this._identity.peerKey || message.source.identityKey !== this.identityKey)\n ) {\n throw new EdgeIdentityChangedError();\n }\n\n const traceCtx = ctx.getAttribute(TRACE_SPAN_ATTRIBUTE) as TraceContextData | undefined;\n if (traceCtx) {\n message.traceContext = {\n $typeName: 'dxos.edge.messenger.TraceContext',\n traceparent: traceCtx.traceparent,\n tracestate: traceCtx.tracestate,\n };\n }\n\n this._currentConnection.send(message);\n }\n\n public onMessage(listener: MessageListener) {\n this._messageListeners.add(listener);\n return () => this._messageListeners.delete(listener);\n }\n\n public onReconnected(listener: ReconnectListener) {\n this._reconnectListeners.add(listener);\n if (this._ready.state === TriggerState.RESOLVED) {\n // Microtask so that listener is always called asynchronously, no matter the state of the ready trigger\n // at the moment of registration.\n scheduleMicroTask(this._ctx, () => {\n if (this._reconnectListeners.has(listener)) {\n try {\n listener();\n } catch (error) {\n log.catch(error);\n }\n }\n });\n }\n\n return () => this._reconnectListeners.delete(listener);\n }\n\n /**\n * Open connection to messaging service.\n */\n protected override async _open(): Promise<void> {\n log('opening...', { info: this.info });\n this._persistentLifecycle.open().catch((err) => {\n log.warn('Error while opening connection', { err });\n });\n\n // Notify about status changes (rtt, rate counters).\n scheduleTaskInterval(\n this._ctx,\n async () => {\n if (!this._currentConnection) {\n return;\n }\n this.statusChanged.emit(this.status);\n },\n STATUS_REFRESH_INTERVAL,\n );\n }\n\n /**\n * Close connection and free resources.\n */\n protected override async _close(): Promise<void> {\n log('closing...', { peerKey: this._identity.peerKey });\n this._closeCurrentConnection();\n await this._persistentLifecycle.close();\n }\n\n private async _connect(): Promise<EdgeWsConnection | undefined> {\n if (this._ctx.disposed) {\n return undefined;\n }\n\n const identity = this._identity;\n const path = `/ws/${identity.identityKey}/${identity.peerKey}`;\n const protocolHeader = this._config.disableAuth ? undefined : await this._createAuthHeader(path);\n if (this._identity !== identity) {\n log('identity changed during auth header request');\n return undefined;\n }\n\n const restartRequired = new Trigger();\n const url = new URL(path, this._baseWsUrl);\n log('Opening websocket', { url: url.toString(), protocolHeader });\n const connection = new EdgeWsConnection(\n identity,\n {\n url,\n protocolHeader,\n headers: this._config.clientTag ? { 'X-DXOS-Client-Tag': this._config.clientTag } : undefined,\n },\n {\n onConnected: () => {\n if (this._isActive(connection)) {\n this._ready.wake();\n this._notifyReconnected();\n } else {\n log.verbose('connected callback ignored, because connection is not active');\n }\n },\n onRestartRequired: () => {\n if (this._isActive(connection)) {\n this._closeCurrentConnection();\n void this._persistentLifecycle.scheduleRestart();\n } else {\n log.verbose('restart requested by inactive connection');\n }\n restartRequired.wake();\n },\n onMessage: (message) => {\n if (this._isActive(connection)) {\n this._notifyMessageReceived(message);\n } else {\n log.verbose('ignored a message on inactive connection', {\n from: message.source,\n type: message.payload?.typeUrl,\n });\n }\n },\n },\n );\n this._currentConnection = connection;\n\n await connection.open();\n\n // The connection is only a successful start once the socket becomes ready. A socket that\n // closes or errors before becoming ready (or never connects within the timeout) is a failed\n // start: throwing lets PersistentLifecycle apply its backoff. Returning here would mark the\n // attempt as successful and reset the backoff, degenerating reconnects into a hot loop when\n // the server accepts then immediately drops the socket.\n const becameReady = await Promise.race([\n this._ready.wait({ timeout: this._config.timeout ?? DEFAULT_TIMEOUT }).then(\n () => true,\n () => false,\n ),\n restartRequired.wait().then(() => false),\n ]);\n if (!becameReady) {\n throw new EdgeConnectionClosedError();\n }\n\n return connection;\n }\n\n private async _disconnect(state: EdgeWsConnection): Promise<void> {\n await state.close();\n this.statusChanged.emit(this.status);\n }\n\n private _closeCurrentConnection(error: Error = new EdgeConnectionClosedError()): void {\n this._currentConnection = undefined;\n this._ready.throw(error);\n this._ready.reset();\n this.statusChanged.emit(this.status);\n }\n\n private _notifyReconnected(): void {\n this.statusChanged.emit(this.status);\n for (const listener of this._reconnectListeners) {\n try {\n listener();\n } catch (err) {\n log.error('ws reconnect listener failed', { err });\n }\n }\n }\n\n private _notifyMessageReceived(message: Message): void {\n for (const listener of this._messageListeners) {\n try {\n listener(message);\n } catch (err) {\n log.error('ws incoming message processing failed', { err, payload: protocol.getPayloadType(message) });\n }\n }\n }\n\n private async _createAuthHeader(path: string): Promise<string | undefined> {\n const httpUrl = new URL(path, this._baseHttpUrl);\n httpUrl.protocol = getEdgeUrlWithProtocol(this._baseWsUrl.toString(), 'http');\n const response = await fetch(httpUrl, { method: 'GET' });\n if (response.status === 401) {\n return encodePresentationWsAuthHeader(await handleAuthChallenge(response, this._identity));\n } else {\n log.warn('no auth challenge from edge', { status: response.status, statusText: response.statusText });\n return undefined;\n }\n }\n\n private _isActive = (connection: EdgeWsConnection) => connection === this._currentConnection;\n}\n\nconst encodePresentationWsAuthHeader = (encodedPresentation: Uint8Array): string => {\n // '=' and '/' characters are not allowed in the WebSocket subprotocol header.\n const encodedToken = Buffer.from(encodedPresentation).toString('base64').replace(/=*$/, '').replaceAll('/', '|');\n return `base64url.bearer.authorization.dxos.org.${encodedToken}`;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Presentation } from '@dxos/protocols/proto/dxos/halo/credentials';\n\nexport interface EdgeIdentity {\n peerKey: string;\n identityKey: string;\n /**\n * Returns credential presentation issued by the identity key.\n * Presentation must have the provided challenge.\n * Presentation may include ServiceAccess credentials.\n */\n presentCredentials({ challenge }: { challenge: Uint8Array }): Promise<Presentation>;\n}\n\nexport const handleAuthChallenge = async (failedResponse: Response, identity: EdgeIdentity): Promise<Uint8Array> => {\n invariant(failedResponse.status === 401);\n\n const headerValue = failedResponse.headers.get('Www-Authenticate');\n invariant(headerValue?.startsWith('VerifiablePresentation challenge='));\n\n const challenge = headerValue?.slice('VerifiablePresentation challenge='.length);\n invariant(challenge);\n\n const presentation = await identity.presentCredentials({ challenge: Buffer.from(challenge, 'base64') });\n return schema.getCodecForType('dxos.halo.credentials.Presentation').encode(presentation);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { scheduleTask, scheduleTaskInterval } from '@dxos/async';\nimport { Context, Resource } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log, logInfo } from '@dxos/log';\nimport { EdgeWebsocketProtocol } from '@dxos/protocols';\nimport { buf } from '@dxos/protocols/buf';\nimport { type Message, MessageSchema } from '@dxos/protocols/buf/dxos/edge/messenger_pb';\n\nimport { protocol } from './defs';\nimport { type EdgeIdentity } from './edge-identity';\nimport { CLOUDFLARE_MESSAGE_MAX_BYTES, WebSocketMuxer } from './edge-ws-muxer';\nimport { toUint8Array } from './protocol';\n\nconst SIGNAL_KEEPALIVE_INTERVAL = 4_000;\nconst SIGNAL_KEEPALIVE_TIMEOUT = 12_000;\n\nexport type EdgeWsConnectionCallbacks = {\n onConnected: () => void;\n onMessage: (message: Message) => void;\n onRestartRequired: () => void;\n};\n\nexport class EdgeWsConnection extends Resource {\n private _inactivityTimeoutCtx: Context | undefined;\n private _ws: WebSocket | undefined;\n private _wsMuxer: WebSocketMuxer | undefined;\n private _lastReceivedMessageTimestamp = Date.now();\n\n private _openTimestamp: number | undefined;\n\n // Latency tracking.\n private _pingTimestamp: number | undefined;\n private _rtt = 0;\n\n // Rate tracking with sliding window.\n private _uploadRate = 0;\n private _downloadRate = 0;\n private readonly _rateWindow = 10000; // 10 second sliding window.\n private readonly _rateUpdateInterval = 1000; // Update rates every second.\n private _bytesSamples: Array<{ timestamp: number; sent: number; received: number }> = [];\n\n private _messagesSent = 0;\n private _messagesReceived = 0;\n\n constructor(\n private readonly _identity: EdgeIdentity,\n private readonly _connectionInfo: { url: URL; protocolHeader?: string; headers?: Record<string, string> },\n private readonly _callbacks: EdgeWsConnectionCallbacks,\n ) {\n super();\n }\n\n @logInfo\n public get info() {\n return {\n open: this.isOpen,\n identity: this._identity.identityKey,\n device: this._identity.peerKey,\n };\n }\n\n public get rtt(): number {\n return this._rtt;\n }\n\n public get uptime(): number {\n return this._openTimestamp ? (Date.now() - this._openTimestamp) / 1000 : 0;\n }\n\n public get uploadRate(): number {\n return this._uploadRate;\n }\n\n public get downloadRate(): number {\n return this._downloadRate;\n }\n\n public get messagesSent(): number {\n return this._messagesSent;\n }\n\n public get messagesReceived(): number {\n return this._messagesReceived;\n }\n\n public send(message: Message): void {\n invariant(this._ws);\n invariant(this._wsMuxer);\n log('sending...', { peerKey: this._identity.peerKey, payload: protocol.getPayloadType(message) });\n this._messagesSent++;\n if (this._ws?.protocol.includes(EdgeWebsocketProtocol.V0)) {\n const binary = buf.toBinary(MessageSchema, message);\n if (binary.length > CLOUDFLARE_MESSAGE_MAX_BYTES) {\n log.error('Message dropped because it was too large (>1MB).', {\n byteLength: binary.byteLength,\n serviceId: message.serviceId,\n payload: protocol.getPayloadType(message),\n });\n return;\n }\n this._recordBytes(binary.byteLength, 0);\n this._ws.send(binary);\n } else {\n // For muxer, we need to track the size of the message being sent.\n const binary = buf.toBinary(MessageSchema, message);\n this._recordBytes(binary.byteLength, 0);\n this._wsMuxer.send(message).catch((e) => log.catch(e));\n }\n }\n\n protected override async _open(): Promise<void> {\n const baseProtocols = [...Object.values(EdgeWebsocketProtocol)];\n this._ws = new WebSocket(\n this._connectionInfo.url.toString(),\n this._connectionInfo.protocolHeader\n ? [...baseProtocols, this._connectionInfo.protocolHeader]\n : [...baseProtocols],\n this._connectionInfo.headers ? { headers: this._connectionInfo.headers } : undefined,\n );\n const muxer = new WebSocketMuxer(this._ws);\n this._wsMuxer = muxer;\n\n this._ws.onopen = () => {\n if (this.isOpen) {\n log('connected');\n this._openTimestamp = Date.now();\n this._callbacks.onConnected();\n this._scheduleHeartbeats();\n this._scheduleRateCalculation();\n } else {\n log.verbose('connected after becoming inactive', { currentIdentity: this._identity });\n }\n };\n this._ws.onclose = (event: WebSocket.CloseEvent) => {\n if (this.isOpen) {\n log.warn('server disconnected', { code: event.code, reason: event.reason });\n this._callbacks.onRestartRequired();\n muxer.destroy();\n }\n };\n this._ws.onerror = (event: WebSocket.ErrorEvent) => {\n if (this.isOpen) {\n log.warn('edge connection socket error', { error: event.error, info: event.message });\n this._callbacks.onRestartRequired();\n } else {\n log.verbose('error ignored on closed connection', { error: event.error });\n }\n };\n /**\n * https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n */\n this._ws.onmessage = async (event: WebSocket.MessageEvent) => {\n if (!this.isOpen) {\n log.verbose('message ignored on closed connection', { event: event.type });\n return;\n }\n this._lastReceivedMessageTimestamp = Date.now();\n if (event.data === '__pong__') {\n // Calculate latency.\n if (this._pingTimestamp) {\n this._rtt = Date.now() - this._pingTimestamp;\n this._pingTimestamp = undefined;\n }\n this._rescheduleHeartbeatTimeout();\n return;\n }\n const bytes = await toUint8Array(event.data);\n this._recordBytes(0, bytes.byteLength);\n if (!this.isOpen) {\n return;\n }\n\n this._messagesReceived++;\n\n const message = this._ws?.protocol?.includes(EdgeWebsocketProtocol.V0)\n ? buf.fromBinary(MessageSchema, bytes)\n : muxer.receiveData(bytes);\n\n if (message) {\n log('received', { from: message.source, payload: protocol.getPayloadType(message) });\n this._callbacks.onMessage(message);\n }\n };\n }\n\n protected override async _close(): Promise<void> {\n void this._inactivityTimeoutCtx?.dispose().catch(() => {});\n\n try {\n this._ws?.close();\n this._ws = undefined;\n this._wsMuxer?.destroy();\n this._wsMuxer = undefined;\n } catch (err) {\n if (err instanceof Error && err.message.includes('WebSocket is closed before the connection is established.')) {\n return;\n }\n log.warn('error closing websocket', { err });\n }\n }\n\n private _scheduleHeartbeats(): void {\n invariant(this._ws);\n scheduleTaskInterval(\n this._ctx,\n async () => {\n // TODO(mykola): use RFC6455 ping/pong once implemented in the browser?\n // Cloudflare's worker responds to this `without interrupting hibernation`. https://developers.cloudflare.com/durable-objects/api/websockets/#setwebsocketautoresponse\n this._pingTimestamp = Date.now();\n this._ws?.send('__ping__');\n },\n SIGNAL_KEEPALIVE_INTERVAL,\n );\n this._pingTimestamp = Date.now();\n this._ws.send('__ping__');\n this._rescheduleHeartbeatTimeout();\n }\n\n private _rescheduleHeartbeatTimeout(): void {\n if (!this.isOpen) {\n return;\n }\n void this._inactivityTimeoutCtx?.dispose();\n this._inactivityTimeoutCtx = new Context();\n scheduleTask(\n this._inactivityTimeoutCtx,\n () => {\n if (this.isOpen) {\n if (Date.now() - this._lastReceivedMessageTimestamp > SIGNAL_KEEPALIVE_TIMEOUT) {\n log.warn('restart due to inactivity timeout', {\n lastReceivedMessageTimestamp: this._lastReceivedMessageTimestamp,\n });\n this._callbacks.onRestartRequired();\n } else {\n this._rescheduleHeartbeatTimeout();\n }\n }\n },\n SIGNAL_KEEPALIVE_TIMEOUT,\n );\n }\n\n private _recordBytes(sent: number, received: number): void {\n const now = Date.now();\n\n // Find if we have a sample for the current second.\n const currentSecond = Math.floor(now / 1000) * 1000;\n const existingSample = this._bytesSamples.find((s) => Math.floor(s.timestamp / 1000) * 1000 === currentSecond);\n\n if (existingSample) {\n existingSample.sent += sent;\n existingSample.received += received;\n } else {\n this._bytesSamples.push({ timestamp: now, sent, received });\n }\n }\n\n private _scheduleRateCalculation(): void {\n scheduleTaskInterval(\n this._ctx,\n async () => {\n this._calculateRates();\n },\n this._rateUpdateInterval,\n );\n // Calculate initial rates.\n this._calculateRates();\n }\n\n private _calculateRates(): void {\n const now = Date.now();\n const cutoff = now - this._rateWindow;\n\n // Remove old samples.\n this._bytesSamples = this._bytesSamples.filter((s) => s.timestamp > cutoff);\n\n if (this._bytesSamples.length === 0) {\n this._uploadRate = 0;\n this._downloadRate = 0;\n return;\n }\n\n // Calculate total bytes and time span.\n let totalSent = 0;\n let totalReceived = 0;\n const oldestTimestamp = Math.min(...this._bytesSamples.map((s) => s.timestamp));\n const timeSpan = (now - oldestTimestamp) / 1000; // Convert to seconds.\n\n for (const sample of this._bytesSamples) {\n totalSent += sample.sent;\n totalReceived += sample.received;\n }\n\n // Calculate rates (bytes per second).\n this._uploadRate = timeSpan > 0 ? Math.round(totalSent / timeSpan) : 0;\n this._downloadRate = timeSpan > 0 ? Math.round(totalReceived / timeSpan) : 0;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport class EdgeConnectionClosedError extends Error {\n constructor() {\n super('Edge connection closed.');\n }\n}\n\nexport class EdgeIdentityChangedError extends Error {\n constructor() {\n super('Edge identity changed.');\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const getEdgeUrlWithProtocol = (baseUrl: string, protocol: 'http' | 'ws') => {\n const isSecure = baseUrl.startsWith('https') || baseUrl.startsWith('wss');\n const url = new URL(baseUrl);\n url.protocol = protocol + (isSecure ? 's' : '');\n return url.toString();\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { sleep } from '@dxos/async';\nimport { Context, TRACE_SPAN_ATTRIBUTE, type TraceContextData } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { EDGE_CLIENT_TAG_HEADER, EdgeAuthChallengeError, EdgeCallFailedError, type EdgeFailure } from '@dxos/protocols';\n\nimport { type EdgeIdentity, handleAuthChallenge } from './edge-identity';\nimport { encodeAuthHeader } from './http-client';\nimport { getEdgeUrlWithProtocol } from './utils';\n\nconst DEFAULT_RETRY_TIMEOUT = 1500;\nconst DEFAULT_RETRY_JITTER = 500;\nconst DEFAULT_MAX_RETRIES_COUNT = 3;\nconst WARNING_BODY_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport type RetryConfig = {\n /** Number of retries, not counting the initial request. */\n count: number;\n /** Delay before retries in ms. */\n timeout?: number;\n /** Random additional delay to spread retries. */\n jitter?: number;\n};\n\nexport type EdgeHttpCallArgs = {\n retry?: RetryConfig;\n /**\n * Force authentication by pre-fetching `/auth` to obtain the challenge before\n * sending the body. Use for requests with large bodies to avoid sending twice.\n * Not available on HubHttpClient (hub-service has no `/auth` endpoint).\n */\n auth?: boolean;\n};\n\nexport type BaseHttpClientOptions = {\n /**\n * Tag included in the {@link EDGE_CLIENT_TAG_HEADER} header on every request.\n * Used on Edge to classify traffic for metering (e.g. `ci-e2e`).\n */\n clientTag?: string;\n};\n\ntype HttpRequestArgs = {\n method: string;\n retry?: RetryConfig;\n body?: any;\n /** @default true */\n json?: boolean;\n auth?: boolean;\n};\n\nexport abstract class BaseHttpClient {\n protected readonly _baseUrl: string;\n protected readonly _clientTag: string | undefined;\n protected _edgeIdentity: EdgeIdentity | undefined;\n /** Auth header cached until next 401. */\n protected _authHeader: string | undefined;\n\n constructor(baseUrl: string, options?: BaseHttpClientOptions) {\n this._baseUrl = getEdgeUrlWithProtocol(baseUrl, 'http');\n this._clientTag = options?.clientTag;\n log('created', { url: this._baseUrl });\n }\n\n get baseUrl() {\n return this._baseUrl;\n }\n\n setIdentity(identity: EdgeIdentity): void {\n if (this._edgeIdentity?.identityKey !== identity.identityKey || this._edgeIdentity?.peerKey !== identity.peerKey) {\n this._edgeIdentity = identity;\n this._authHeader = undefined;\n }\n }\n\n // TODO(mykola): Extend `_call` to support streaming/raw `Response` returns so\n // `EdgeHttpClient.anthropicAiRequest` can be absorbed here and the auth/retry loop\n // stops being duplicated across the two paths.\n protected async _call<T>(ctx: Context, url: URL, args: HttpRequestArgs): Promise<T> {\n const shouldRetry = createRetryHandler(args);\n // Log presence/size only — never log raw body contents which may contain PII.\n log('fetch', {\n url,\n hasBody: args.body !== undefined,\n bodySize: typeof args.body === 'string' ? args.body.length : undefined,\n });\n\n const traceHeaders = getTraceHeaders(ctx);\n\n let handledAuth = false;\n const tryCount = 1;\n while (true) {\n let processingError: EdgeCallFailedError | undefined = undefined;\n try {\n if (!this._authHeader && args.auth) {\n const response = await fetch(new URL('/auth', this._baseUrl));\n if (response.status === 401) {\n this._authHeader = await this._handleUnauthorized(response);\n }\n }\n\n const request = createRequest(args, this._authHeader, traceHeaders, this._clientTag);\n log('call', { url, tryCount, authHeader: !!this._authHeader });\n const response = await fetch(url, request);\n\n if (response.ok) {\n const contentType = response.headers.get('Content-Type') ?? '';\n // No-content responses (204, empty body, non-JSON) — return undefined.\n if (\n response.status === 204 ||\n response.headers.get('Content-Length') === '0' ||\n !contentType.includes('application/json')\n ) {\n return undefined as T;\n }\n const body = await response.clone().json();\n if (typeof body !== 'object' || body === null) {\n return body;\n }\n if (!('success' in body)) {\n return body;\n }\n if (body.success) {\n return body.data;\n }\n } else if (response.status === 401 && response.headers.get('WWW-Authenticate') !== null && !handledAuth) {\n // Only retry edge auth when the 401 came from edge's own auth layer. Edge always sets\n // `WWW-Authenticate` on its own 401s; upstream-forwarded 401s lack it.\n this._authHeader = await this._handleUnauthorized(response);\n handledAuth = true;\n continue;\n }\n\n const contentType = response.headers.get('Content-Type') ?? '';\n const body: EdgeFailure = contentType.startsWith('application/json')\n ? await response.clone().json()\n : undefined;\n\n invariant(!body?.success, 'Expected body to not be a failure response or undefined.');\n\n if (body?.data?.type === 'auth_challenge' && typeof body?.data?.challenge === 'string') {\n processingError = new EdgeAuthChallengeError(body.data.challenge, body.data);\n } else if (body?.success === false) {\n processingError = EdgeCallFailedError.fromUnsuccessfulResponse(response, body);\n } else {\n invariant(!response.ok, 'Expected response to not be ok.');\n processingError = await EdgeCallFailedError.fromHttpFailure(response);\n }\n } catch (error: any) {\n processingError = EdgeCallFailedError.fromProcessingFailureCause(error);\n }\n\n if (processingError?.isRetryable && (await shouldRetry(ctx, processingError.retryAfterMs))) {\n log.verbose('retrying request', { url, processingError });\n } else {\n throw processingError!;\n }\n }\n }\n\n protected async _handleUnauthorized(response: Response): Promise<string> {\n if (!this._edgeIdentity) {\n log.warn('unauthorized response received before identity was set');\n throw await EdgeCallFailedError.fromHttpFailure(response);\n }\n const challenge = await handleAuthChallenge(response, this._edgeIdentity);\n return encodeAuthHeader(challenge);\n }\n}\n\nconst createRequest = (\n { method, body, json = true }: HttpRequestArgs,\n authHeader: string | undefined,\n traceHeaders?: Record<string, string>,\n clientTag?: string,\n): RequestInit => {\n let requestBody: BodyInit | undefined;\n const headers: HeadersInit = {};\n\n if (json) {\n requestBody = body === undefined ? undefined : JSON.stringify(body);\n headers['Content-Type'] = 'application/json';\n } else {\n requestBody = body;\n }\n\n if (typeof requestBody === 'string' && requestBody.length > WARNING_BODY_SIZE) {\n log.warn('Request with large body', { bodySize: requestBody.length });\n }\n\n if (authHeader) {\n headers['Authorization'] = authHeader;\n }\n\n if (traceHeaders) {\n Object.assign(headers, traceHeaders);\n }\n\n if (clientTag) {\n headers[EDGE_CLIENT_TAG_HEADER] = clientTag;\n }\n\n return { method, body: requestBody, headers };\n};\n\nconst getTraceHeaders = (ctx: Context): Record<string, string> | undefined => {\n const traceCtx = ctx.getAttribute(TRACE_SPAN_ATTRIBUTE) as TraceContextData | undefined;\n if (!traceCtx) {\n return undefined;\n }\n const headers: Record<string, string> = { traceparent: traceCtx.traceparent };\n if (traceCtx.tracestate) {\n headers.tracestate = traceCtx.tracestate;\n }\n return headers;\n};\n\n/** @deprecated */\nconst createRetryHandler = ({ retry }: HttpRequestArgs) => {\n if (!retry || retry.count < 1) {\n return async () => false;\n }\n let retries = 0;\n const maxRetries = retry.count ?? DEFAULT_MAX_RETRIES_COUNT;\n const baseTimeout = retry.timeout ?? DEFAULT_RETRY_TIMEOUT;\n const jitter = retry.jitter ?? DEFAULT_RETRY_JITTER;\n return async (ctx: Context, retryAfter?: number) => {\n if (++retries > maxRetries || ctx.disposed) {\n return false;\n }\n if (retryAfter) {\n await sleep(retryAfter);\n } else {\n const timeout = baseTimeout + Math.random() * jitter;\n await sleep(timeout);\n }\n return true;\n };\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport type * as HttpClient from '@effect/platform/HttpClient';\nimport type * as HttpClientError from '@effect/platform/HttpClientError';\nimport type * as HttpClientResponse from '@effect/platform/HttpClientResponse';\nimport * as Context from 'effect/Context';\nimport * as Duration from 'effect/Duration';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport * as Schedule from 'effect/Schedule';\n\nimport { log } from '@dxos/log';\n\n// TODO(burdon): Factor out.\n\nexport type RetryOptions = {\n timeout: Duration.Duration;\n retryTimes: number;\n retryBaseDelay: Duration.Duration;\n};\n\n// Layer pattern.\nexport class HttpConfig extends Context.Tag('HttpConfig')<HttpConfig, RetryOptions>() {\n static default = Layer.succeed(HttpConfig, {\n timeout: Duration.millis(1_000),\n retryTimes: 3,\n retryBaseDelay: Duration.millis(1_000),\n });\n}\n\n// HOC pattern.\nexport const withRetry = (\n effect: Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError, HttpClient.HttpClient>,\n {\n timeout = Duration.millis(1_000),\n retryBaseDelay = Duration.millis(1_000),\n retryTimes = 3,\n }: Partial<RetryOptions> = {},\n) => {\n return effect.pipe(\n Effect.flatMap((res) =>\n // Treat 500 errors as retryable?\n res.status === 500 ? Effect.fail(new Error(res.status.toString())) : res.json,\n ),\n Effect.timeout(timeout),\n Effect.retry({\n schedule: Schedule.exponential(retryBaseDelay).pipe(Schedule.jittered),\n times: retryTimes,\n }),\n );\n};\n\nexport const withRetryConfig = (\n effect: Effect.Effect<HttpClientResponse.HttpClientResponse, HttpClientError.HttpClientError, HttpClient.HttpClient>,\n) =>\n Effect.gen(function* () {\n const config = yield* HttpConfig;\n return yield* withRetry(effect, config);\n });\n\nexport const withLogging = <A extends HttpClientResponse.HttpClientResponse, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.tap((res) => {\n log.info('response', { status: res.status });\n }),\n );\n\n/**\n *\n */\n// TODO(burdon): Document.\nexport const encodeAuthHeader = (challenge: Uint8Array) => {\n const encodedChallenge = Buffer.from(challenge).toString('base64');\n return `VerifiablePresentation pb;base64,${encodedChallenge}`;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Headers from '@effect/platform/Headers';\nimport * as HttpClient from '@effect/platform/HttpClient';\nimport * as HttpClientError from '@effect/platform/HttpClientError';\nimport * as HttpClientResponse from '@effect/platform/HttpClientResponse';\nimport * as Effect from 'effect/Effect';\nimport * as FiberRef from 'effect/FiberRef';\nimport * as Layer from 'effect/Layer';\nimport * as Stream from 'effect/Stream';\n\nimport { BaseError, type BaseErrorOptions } from '@dxos/errors';\nimport { log } from '@dxos/log';\nimport { BYOK_HEADER } from '@dxos/protocols';\n\nimport { type EdgeHttpClient } from './edge-http-client';\n\nexport type GetEdgeHttpClient = () => EdgeHttpClient;\n\n/**\n * Thrown by {@link EdgeAiHttpClient} when an AI request carrying {@link BYOK_HEADER} is rejected\n * with 401/403 by the upstream provider — i.e. the user-supplied API key is invalid. Wrapped as\n * the `cause` of an `HttpClientError.ResponseError` so it flows through `@effect/ai`'s error\n * mapping; callers walk the cause chain (via {@link ByokError.is}) to render a useful message.\n */\nexport class ByokError extends BaseError.extend('ByokError', 'BYOK authentication failed') {\n constructor(options: { status: number; provider: string } & BaseErrorOptions) {\n super({ context: { status: options.status, provider: options.provider }, ...options });\n }\n}\n\n/**\n * Thrown by {@link EdgeAiHttpClient} when EDGE rejects an AI request with 429 because the\n * authenticated profile exceeded a metering limit. Wrapped as the `cause` of an\n * {@link HttpClientError.ResponseError} so it survives `@effect/ai`'s error mapping.\n */\nexport class UsageQuotaExceededError extends BaseError.extend('UsageQuotaExceededError', 'Usage quota exceeded') {}\n\n/**\n * Copy pasted from https://github.com/Effect-TS/effect/blob/main/packages/platform/src/internal/fetchHttpClient.ts\n */\nexport const requestInitTagKey = '@effect/platform/FetchHttpClient/FetchOptions';\n\ntype AnthropicMessagesPayload = {\n tools?: ReadonlyArray<Record<string, unknown>>;\n};\n\nconst isUserDefinedAnthropicTool = (tool: Record<string, unknown>): boolean =>\n tool.input_schema != null && typeof tool.input_schema === 'object';\n\n/**\n * Enables Anthropic fine-grained tool input streaming for client-defined tools.\n * Provider tools (bash, web_search, etc.) are left unchanged.\n */\nexport const patchAnthropicMessagesRequestBody = (body: BodyInit | undefined): BodyInit | undefined => {\n if (body == null) {\n return body;\n }\n\n const decodeBody = (): string | undefined => {\n if (typeof body === 'string') {\n return body;\n }\n if (body instanceof Uint8Array) {\n return new TextDecoder().decode(body);\n }\n return undefined;\n };\n\n const text = decodeBody();\n if (text == null) {\n return body;\n }\n\n try {\n const payload = JSON.parse(text) as AnthropicMessagesPayload;\n if (!Array.isArray(payload.tools)) {\n return body;\n }\n\n payload.tools = payload.tools.map((tool) =>\n isUserDefinedAnthropicTool(tool) ? { ...tool, eager_input_streaming: true } : tool,\n );\n\n const patched = JSON.stringify(payload);\n return typeof body === 'string' ? patched : new TextEncoder().encode(patched);\n } catch {\n return body;\n }\n};\n\nconst readStreamBody = (stream: ReadableStream<Uint8Array>): Effect.Effect<string | undefined> =>\n Effect.promise(async () => {\n const response = new Response(stream);\n return await response.text();\n });\n\n/**\n * An `@effect/platform` {@link HttpClient.HttpClient} that routes requests through the\n * authenticated EDGE AI endpoint via {@link EdgeHttpClient.anthropicAiRequest}, instead of\n * fetching the AI service directly.\n *\n * Provide this layer in place of `FetchHttpClient.layer` when constructing an Anthropic client,\n * e.g. `AnthropicClient.layer({ apiUrl: 'http://edge' }).pipe(Layer.provide(EdgeAiHttpClient.layer(() => edgeClient)))`.\n * The `apiUrl` host is a sentinel; only the request path is forwarded (see `anthropicAiRequest`).\n *\n * Modeled on `FunctionsAiHttpClient` in `@dxos/functions`.\n */\nexport class EdgeAiHttpClient {\n static make = (getClient: GetEdgeHttpClient) =>\n HttpClient.make((request, url, signal, fiber) => {\n const edgeClient = getClient();\n const context = fiber.getFiberRef(FiberRef.currentContext);\n const options: RequestInit = context.unsafeMap.get(requestInitTagKey) ?? {};\n const headers = options.headers\n ? Headers.merge(Headers.fromInput(options.headers), request.headers)\n : request.headers;\n\n const carriedByok = !!headers[BYOK_HEADER.toLowerCase()];\n\n const send = (body: BodyInit | undefined) =>\n Effect.tryPromise({\n try: () =>\n edgeClient.anthropicAiRequest(\n new Request(url, {\n ...options,\n method: request.method,\n headers,\n body: patchAnthropicMessagesRequestBody(body),\n signal,\n }),\n ),\n catch: (cause) => {\n log.error('Failed to fetch', { cause });\n return new HttpClientError.RequestError({\n request,\n reason: 'Transport',\n cause,\n });\n },\n }).pipe(\n Effect.flatMap((response) => {\n const httpResponse = HttpClientResponse.fromWeb(request, response);\n // A 401/403 on a BYOK-carrying request means the user's upstream key was rejected.\n // Wrap as a typed ResponseError with `cause: ByokError` so it survives AiError's\n // `fromRequestError` mapping; callers walk the cause chain to render a useful message.\n if (carriedByok && (response.status === 401 || response.status === 403)) {\n return Effect.tryPromise({\n try: () => response.clone().json() as Promise<{ error?: { message?: string } } | undefined>,\n catch: () => undefined,\n }).pipe(\n Effect.orElseSucceed(() => undefined),\n Effect.flatMap((body) =>\n Effect.fail(\n new HttpClientError.ResponseError({\n request,\n response: httpResponse,\n reason: 'StatusCode',\n cause: new ByokError({\n status: response.status,\n provider: 'anthropic.com',\n message: body?.error?.message ?? 'Authentication failed',\n }),\n }),\n ),\n ),\n );\n }\n // Platform quota (not BYOK): reserve/commit rejected the request before upstream AI.\n if (!carriedByok && response.status === 429) {\n return Effect.tryPromise({\n try: () => response.clone().json() as Promise<{ error?: { message?: string } } | undefined>,\n catch: () => undefined,\n }).pipe(\n Effect.orElseSucceed(() => undefined),\n Effect.flatMap((body) =>\n Effect.fail(\n new HttpClientError.ResponseError({\n request,\n response: httpResponse,\n reason: 'StatusCode',\n cause: new UsageQuotaExceededError({\n message: body?.error?.message,\n }),\n }),\n ),\n ),\n );\n }\n return Effect.succeed(httpResponse);\n }),\n );\n\n switch (request.body._tag) {\n case 'Raw':\n case 'Uint8Array':\n return send(request.body.body as any);\n case 'FormData':\n return send(request.body.formData);\n case 'Stream':\n return Stream.toReadableStreamEffect(request.body.stream).pipe(\n Effect.flatMap((readable) => readStreamBody(readable)),\n Effect.flatMap((text) => send(text)),\n );\n }\n\n return send(undefined);\n });\n\n static layer = (getClient: GetEdgeHttpClient) =>\n Layer.succeed(HttpClient.HttpClient, EdgeAiHttpClient.make(getClient));\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as FetchHttpClient from '@effect/platform/FetchHttpClient';\nimport * as HttpClient from '@effect/platform/HttpClient';\nimport * as HttpClientRequest from '@effect/platform/HttpClientRequest';\nimport * as Effect from 'effect/Effect';\nimport * as Function from 'effect/Function';\n\nimport { type Context } from '@dxos/context';\nimport { EffectEx } from '@dxos/effect';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey, type SpaceId } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport {\n type CompleteOAuthRegistrationRequest,\n type CompleteOAuthRegistrationResponse,\n type CreateAgentRequestBody,\n type CreateAgentResponseBody,\n type CreateSpaceRequest,\n type CreateSpaceResponseBody,\n EDGE_CLIENT_TAG_HEADER,\n type EdgeStatus,\n type ExecuteWorkflowResponseBody,\n type ExportBundleRequest,\n type ExportBundleResponse,\n type FeedProtocol,\n type GetAgentStatusResponseBody,\n type GetNotarizationResponseBody,\n type GetPluginsResponseBody,\n type ImportBundleRequest,\n type InitiateOAuthFlowRequest,\n type InitiateOAuthFlowResponse,\n type JoinSpaceRequest,\n type JoinSpaceResponseBody,\n type ObjectId,\n type PostNotarizationRequestBody,\n type RecoverIdentityRequest,\n type RecoverIdentityResponseBody,\n type UploadFunctionRequest,\n type UploadFunctionResponseBody,\n} from '@dxos/protocols';\nimport {\n type QueryRequest as QueryRequestProto,\n type QueryResponse as QueryResponseProto,\n} from '@dxos/protocols/proto/dxos/echo/query';\nimport { createUrl } from '@dxos/util';\n\nimport { BaseHttpClient, type BaseHttpClientOptions, type EdgeHttpCallArgs } from './base-http-client';\nimport { proxyFetchLegacy } from './cors-proxy';\nimport { HttpConfig, withLogging, withRetryConfig } from './http-client';\n\nexport type { EdgeHttpCallArgs, RetryConfig } from './base-http-client';\n\n/**\n * HTTP wire shape returned by `/queue/.../query`.\n */\nexport type EdgeQueryQueueResponse = {\n objects?: unknown[];\n nextCursor?: string;\n prevCursor?: string;\n};\n\nexport type UploadPluginBundleRequest = {\n slug: string;\n version: string;\n files: { path: string; content: string }[];\n};\n\nexport type TriggersDispatcherStatus = {\n isActive: boolean;\n nextCronTaskRunTimestamp?: number;\n registeredTriggers: string[];\n stopAfterTimestamp?: number;\n remainingMs?: number;\n nextAlarmTimestamp?: number;\n};\n\nexport type GetCronTriggersResponse = {\n cronIds: string[];\n};\n\nexport type EdgeHttpClientOptions = BaseHttpClientOptions;\n\n/**\n * HTTP client for the edge worker API (spaces, queues, functions, agents, etc.).\n *\n * Hub-service API (accounts, invitations) lives in {@link HubHttpClient} — the two\n * services run at different URLs and are never both available from the same base URL.\n */\nexport class EdgeHttpClient extends BaseHttpClient {\n constructor(baseUrl: string, options?: EdgeHttpClientOptions) {\n super(baseUrl, options);\n log('created', { url: this.baseUrl });\n }\n\n //\n // Status\n //\n\n public async getStatus(ctx: Context, args?: EdgeHttpCallArgs): Promise<EdgeStatus> {\n return this._call(ctx, new URL('/status', this.baseUrl), { ...args, method: 'GET', auth: true });\n }\n\n //\n // Agents\n //\n\n public createAgent(\n ctx: Context,\n body: CreateAgentRequestBody,\n args?: EdgeHttpCallArgs,\n ): Promise<CreateAgentResponseBody> {\n return this._call(ctx, new URL('/agents/create', this.baseUrl), { ...args, method: 'POST', body });\n }\n\n public getAgentStatus(\n ctx: Context,\n request: { ownerIdentityKey: PublicKey },\n args?: EdgeHttpCallArgs,\n ): Promise<GetAgentStatusResponseBody> {\n return this._call(ctx, new URL(`/users/${request.ownerIdentityKey.toHex()}/agent/status`, this.baseUrl), {\n ...args,\n method: 'GET',\n });\n }\n\n //\n // Credentials\n //\n\n public getCredentialsForNotarization(\n ctx: Context,\n spaceId: SpaceId,\n args?: EdgeHttpCallArgs,\n ): Promise<GetNotarizationResponseBody> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async notarizeCredentials(\n ctx: Context,\n spaceId: SpaceId,\n body: PostNotarizationRequestBody,\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n await this._call(ctx, new URL(`/spaces/${spaceId}/notarization`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Identity\n //\n\n public async recoverIdentity(\n ctx: Context,\n body: RecoverIdentityRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<RecoverIdentityResponseBody> {\n return this._call(ctx, new URL('/identity/recover', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Invitations (space join)\n //\n\n public async joinSpaceByInvitation(\n ctx: Context,\n spaceId: SpaceId,\n body: JoinSpaceRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<JoinSpaceResponseBody> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/join`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // OAuth\n //\n\n public async initiateOAuthFlow(\n ctx: Context,\n body: InitiateOAuthFlowRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<InitiateOAuthFlowResponse> {\n return this._call(ctx, new URL('/oauth/initiate', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n public async completeOAuthRegistration(\n ctx: Context,\n body: CompleteOAuthRegistrationRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<CompleteOAuthRegistrationResponse> {\n return this._call(ctx, new URL('/oauth/registration/complete', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Spaces\n //\n\n async createSpace(ctx: Context, body: CreateSpaceRequest, args?: EdgeHttpCallArgs): Promise<CreateSpaceResponseBody> {\n return this._call(ctx, new URL('/spaces/create', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Queues\n //\n\n public async queryQueue(\n ctx: Context,\n subspaceTag: string,\n spaceId: SpaceId,\n query: FeedProtocol.QueueQuery,\n args?: EdgeHttpCallArgs,\n ): Promise<EdgeQueryQueueResponse> {\n const queueId = query.queueIds?.[0];\n invariant(queueId, 'queueId required');\n return this._call(\n ctx,\n createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}/query`, this.baseUrl), {\n after: query.after,\n before: query.before,\n limit: query.limit,\n reverse: query.reverse,\n objectIds: query.objectIds?.join(','),\n }),\n { ...args, method: 'GET' },\n );\n }\n\n public async insertIntoQueue(\n ctx: Context,\n subspaceTag: string,\n spaceId: SpaceId,\n queueId: ObjectId,\n objects: unknown[],\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n return this._call(ctx, new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {\n ...args,\n body: { objects },\n method: 'POST',\n });\n }\n\n public async deleteFromQueue(\n ctx: Context,\n subspaceTag: string,\n spaceId: SpaceId,\n queueId: ObjectId,\n objectIds: ObjectId[],\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n return this._call(\n ctx,\n createUrl(new URL(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, this.baseUrl), {\n ids: objectIds.join(','),\n }),\n { ...args, method: 'DELETE' },\n );\n }\n\n //\n // Functions\n //\n\n public async uploadFunction(\n ctx: Context,\n pathParts: { functionId?: string },\n body: UploadFunctionRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<UploadFunctionResponseBody> {\n const formData = new FormData();\n formData.append('name', body.name ?? '');\n formData.append('version', body.version);\n formData.append('ownerPublicKey', body.ownerPublicKey);\n formData.append('entryPoint', body.entryPoint);\n body.runtime && formData.append('runtime', body.runtime);\n for (const [filename, content] of Object.entries(body.assets)) {\n formData.append(\n 'assets',\n new Blob([content as Uint8Array<ArrayBuffer>], { type: getFileMimeType(filename) }),\n filename,\n );\n }\n const path = ['functions', ...(pathParts.functionId ? [pathParts.functionId] : [])].join('/');\n return this._call(ctx, new URL(path, this.baseUrl), { ...args, body: formData, method: 'PUT', json: false });\n }\n\n public async listFunctions(ctx: Context, args?: EdgeHttpCallArgs): Promise<any> {\n return this._call(ctx, new URL('/functions', this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async invokeFunction(\n ctx: Context,\n params: {\n functionId: string;\n version?: string;\n spaceId?: SpaceId;\n cpuTimeLimit?: number;\n subrequestsLimit?: number;\n },\n input: unknown,\n args?: EdgeHttpCallArgs,\n ): Promise<any> {\n const url = new URL(`/functions/${params.functionId}`, this.baseUrl);\n if (params.version) {\n url.searchParams.set('version', params.version);\n }\n if (params.spaceId) {\n url.searchParams.set('spaceId', params.spaceId.toString());\n }\n if (params.cpuTimeLimit) {\n url.searchParams.set('cpuTimeLimit', params.cpuTimeLimit.toString());\n }\n if (params.subrequestsLimit) {\n url.searchParams.set('subrequestsLimit', params.subrequestsLimit.toString());\n }\n return this._call(ctx, url, { ...args, body: input, method: 'POST' });\n }\n\n //\n // Workflows\n //\n\n public async executeWorkflow(\n ctx: Context,\n spaceId: SpaceId,\n graphId: ObjectId,\n input: any,\n args?: EdgeHttpCallArgs,\n ): Promise<ExecuteWorkflowResponseBody> {\n return this._call(ctx, new URL(`/workflows/${spaceId}/${graphId}`, this.baseUrl), {\n ...args,\n body: input,\n method: 'POST',\n });\n }\n\n //\n // Triggers\n //\n\n public async getCronTriggers(ctx: Context, spaceId: SpaceId): Promise<GetCronTriggersResponse> {\n return this._call<GetCronTriggersResponse>(ctx, new URL(`/functions/${spaceId}/triggers/crons`, this.baseUrl), {\n method: 'GET',\n });\n }\n\n public async getTriggersDispatcherStatus(\n ctx: Context,\n spaceId: SpaceId,\n args?: EdgeHttpCallArgs,\n ): Promise<TriggersDispatcherStatus> {\n return this._call<TriggersDispatcherStatus>(ctx, new URL(`/triggers/${spaceId}/status`, this.baseUrl), {\n ...args,\n method: 'GET',\n auth: true,\n });\n }\n\n public async forceRunCronTrigger(ctx: Context, spaceId: SpaceId, triggerId: ObjectId) {\n return this._call(ctx, new URL(`/functions/${spaceId}/triggers/crons/${triggerId}/run`, this.baseUrl), {\n method: 'POST',\n });\n }\n\n //\n // Query\n //\n\n public async execQuery(\n ctx: Context,\n spaceId: SpaceId,\n body: QueryRequestProto,\n args?: EdgeHttpCallArgs,\n ): Promise<QueryResponseProto> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/exec-query`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Registry\n //\n\n public async getRegistryPlugins(ctx: Context, args?: EdgeHttpCallArgs): Promise<GetPluginsResponseBody> {\n return this._call(ctx, new URL('/registry/plugins', this.baseUrl), { ...args, method: 'GET' });\n }\n\n /**\n * Uploads a built plugin bundle to the registry's R2-backed hosting. Authenticated\n * with the caller's hub identity (verifiable presentation) — `setIdentity` must\n * have been called. Returns the canonical `moduleUrl` (the hosted `manifest.json`).\n */\n public async uploadPluginBundle(\n ctx: Context,\n request: UploadPluginBundleRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<{ moduleUrl: string }> {\n return this._call(ctx, new URL('/registry/upload', this.baseUrl), {\n body: request,\n method: 'POST',\n auth: true,\n ...args,\n });\n }\n\n //\n // Import/Export\n //\n\n public async importBundle(\n ctx: Context,\n spaceId: SpaceId,\n body: ImportBundleRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<void> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/import`, this.baseUrl), { ...args, body, method: 'PUT' });\n }\n\n public async exportBundle(\n ctx: Context,\n spaceId: SpaceId,\n body: ExportBundleRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<ExportBundleResponse> {\n return this._call(ctx, new URL(`/spaces/${spaceId}/export`, this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Proxy\n //\n\n /**\n * Fetch through the edge proxy for third-party REST APIs.\n * TEMPORARY: currently routes through legacy open proxy. See https://github.com/dxos/edge/pull/576.\n */\n public async proxyFetch(target: URL, init: RequestInit = {}): Promise<Response> {\n return proxyFetchLegacy(target, init, this._clientTag);\n }\n\n //\n // AI service.\n //\n\n /**\n * Issue an authenticated request to the EDGE AI route (`/ai/generate/anthropic/*`), which\n * proxies to the AI service. Used as the backend HTTP client for the Anthropic AI provider\n * (see {@link EdgeAiHttpClient}).\n *\n * Returns the raw `Response` so streaming bodies are forwarded unchanged to `@effect/ai`.\n * Requires an identity to have been set via {@link setIdentity}.\n */\n // TODO(mykola): Merge into `BaseHttpClient._call` once it can return a streaming/raw `Response`;\n // the auth/retry loop below duplicates the one in `_call`.\n public async anthropicAiRequest(request: Request): Promise<Response> {\n const incoming = new URL(request.url);\n const base = this.baseUrl.replace(/\\/$/, '');\n const target = new URL(`${base}/ai/generate/anthropic${incoming.pathname}${incoming.search}`);\n\n const method = request.method;\n const body = method === 'GET' || method === 'HEAD' ? undefined : await request.arrayBuffer();\n\n let handledAuth = false;\n while (true) {\n if (!this._authHeader) {\n const authResponse = await fetch(new URL('/auth', this.baseUrl));\n if (authResponse.status === 401) {\n this._authHeader = await this._handleUnauthorized(authResponse);\n }\n }\n\n const headers = new Headers(request.headers);\n if (this._authHeader) {\n headers.set('Authorization', this._authHeader);\n }\n if (this._clientTag) {\n headers.set(EDGE_CLIENT_TAG_HEADER, this._clientTag);\n }\n\n const response = await fetch(target, { method, headers, body, signal: request.signal });\n // Only retry edge auth when the 401 came from edge's own auth layer. Edge always sets\n // `WWW-Authenticate` on its own 401s; upstream-forwarded 401s (e.g. invalid BYOK rejected\n // by Anthropic) lack it and must be surfaced verbatim.\n if (response.status === 401 && response.headers.get('WWW-Authenticate') !== null && !handledAuth) {\n this._authHeader = await this._handleUnauthorized(response);\n handledAuth = true;\n continue;\n }\n\n return response;\n }\n }\n\n //\n // Internal (Effect-based, used by tests)\n //\n\n public async _fetch<T>(url: URL, _args: { method: string }): Promise<T> {\n return Function.pipe(\n HttpClient.execute(HttpClientRequest.make(_args.method as any)(url.toString())),\n withLogging,\n withRetryConfig,\n Effect.provide(FetchHttpClient.layer),\n Effect.provide(HttpConfig.default),\n Effect.withSpan('EdgeHttpClient'),\n EffectEx.runAndForwardErrors,\n ) as T;\n }\n}\n\nconst getFileMimeType = (filename: string) =>\n ['.js', '.mjs'].some((ext) => filename.endsWith(ext))\n ? 'application/javascript+module'\n : filename.endsWith('.wasm')\n ? 'application/wasm'\n : 'application/octet-stream';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Context } from '@dxos/context';\nimport {\n type CheckEmailExistsResponse,\n type GetAccountResponse,\n type IssueInvitationResponse,\n type ListAccountInvitationsResponse,\n type LoginRequest,\n type LoginResponse,\n type RedeemInvitationCodeRequest,\n type RedeemInvitationCodeResponse,\n type RequestAccessRequest,\n type RequestAccessResponse,\n type GetProfileUsageResponse,\n type ResendVerificationEmailResponse,\n type ValidateInvitationCodeResponse,\n} from '@dxos/protocols';\nimport { createUrl } from '@dxos/util';\n\nimport { BaseHttpClient, type BaseHttpClientOptions, type EdgeHttpCallArgs } from './base-http-client';\n\n/**\n * HTTP client for the hub-service API (accounts, invitations, email verification).\n *\n * Hub-service and the edge worker are separate Cloudflare Workers deployed at different\n * URLs (`DX_HUB_URL` vs `DX_EDGE_URL`). This client is never used to talk to the edge\n * worker, and vice versa — keep them separate.\n *\n * NOTE: Do NOT set `auth: true` on any call here. Hub-service has no `/auth` VP-challenge\n * endpoint (it has an admin login page that 302s and is not CORS-enabled). Auth is handled\n * via the regular request → 401 → WWW-Authenticate challenge → retry path.\n */\nexport class HubHttpClient extends BaseHttpClient {\n constructor(hubUrl: string, options?: BaseHttpClientOptions) {\n super(hubUrl, options);\n }\n\n //\n // Public (unauthenticated) endpoints\n //\n\n public async checkEmailExists(\n ctx: Context,\n body: { email: string },\n args?: EdgeHttpCallArgs,\n ): Promise<CheckEmailExistsResponse> {\n return this._call(ctx, new URL('/account/email/exists', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n public async validateInvitationCode(\n ctx: Context,\n body: { code: string },\n args?: EdgeHttpCallArgs,\n ): Promise<ValidateInvitationCodeResponse> {\n return this._call(ctx, new URL('/account/invitation-code/validate', this.baseUrl), {\n ...args,\n body,\n method: 'POST',\n });\n }\n\n public async redeemInvitationCode(\n ctx: Context,\n body: RedeemInvitationCodeRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<RedeemInvitationCodeResponse> {\n return this._call(ctx, new URL('/account/invitation-code/redeem', this.baseUrl), {\n ...args,\n body,\n method: 'POST',\n });\n }\n\n /**\n * Existing-account email login. Server inlines `token` for test emails; regular\n * emails are delivered out-of-band. Response is identical for unknown emails\n * (enumeration-safe).\n */\n public async login(ctx: Context, body: LoginRequest, args?: EdgeHttpCallArgs): Promise<LoginResponse> {\n return this._call(ctx, new URL('/account/login', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n public async requestAccess(\n ctx: Context,\n body: RequestAccessRequest,\n args?: EdgeHttpCallArgs,\n ): Promise<RequestAccessResponse> {\n return this._call(ctx, new URL('/account/request-access', this.baseUrl), { ...args, body, method: 'POST' });\n }\n\n //\n // Authenticated (VP) endpoints\n //\n\n public async getAccount(ctx: Context, args?: EdgeHttpCallArgs): Promise<GetAccountResponse> {\n return this._call(ctx, new URL('/account/me', this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async deleteAccount(ctx: Context, args?: EdgeHttpCallArgs): Promise<{ deleted: boolean }> {\n return this._call(ctx, new URL('/account/me', this.baseUrl), { ...args, method: 'DELETE' });\n }\n\n public async listAccountInvitations(ctx: Context, args?: EdgeHttpCallArgs): Promise<ListAccountInvitationsResponse> {\n return this._call(ctx, new URL('/account/invitation', this.baseUrl), { ...args, method: 'GET' });\n }\n\n public async issueAccountInvitation(ctx: Context, args?: EdgeHttpCallArgs): Promise<IssueInvitationResponse> {\n return this._call(ctx, new URL('/account/invitation/issue', this.baseUrl), { ...args, method: 'POST' });\n }\n\n public async resendVerificationEmail(\n ctx: Context,\n args?: EdgeHttpCallArgs,\n ): Promise<ResendVerificationEmailResponse> {\n return this._call(ctx, new URL('/account/email/resend-verification', this.baseUrl), { ...args, method: 'POST' });\n }\n\n /**\n * Rolling-window usage and effective limits for the authenticated identity.\n * Served from the per-user metering DO; optional `windowSeconds` defaults to the largest limit window.\n */\n public async getProfileUsage(\n ctx: Context,\n query?: { windowSeconds?: number },\n args?: EdgeHttpCallArgs,\n ): Promise<GetProfileUsageResponse> {\n return this._call(\n ctx,\n createUrl(new URL('/api/metering/profile/usage', this.baseUrl), {\n windowSeconds: query?.windowSeconds,\n }),\n { ...args, method: 'GET' },\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["createCredential", "signPresentation", "invariant", "Keyring", "PublicKey", "identityKey", "peerKey", "presentCredentials", "presentation", "issuer", "key", "subject", "signer", "signerKey", "nonce", "chain", "signingKey", "challenge", "credentialsToSign", "createDeviceEdgeIdentity", "assertion", "deviceKey", "Error", "TRACE_SPAN_ATTRIBUTE", "scheduleTaskInterval", "Resource", "log", "EdgeStatus", "protocol", "invariant", "schema", "__dxlog_file", "handleAuthChallenge", "headerValue", "failedResponse", "headers", "startsWith", "challenge", "slice", "presentation", "identity", "presentCredentials", "Buffer", "getCodecForType", "Context", "Resource", "invariant", "log", "EdgeWebsocketProtocol", "buf", "MessageSchema", "protocol", "SIGNAL_KEEPALIVE_TIMEOUT", "EdgeWsConnection", "_inactivityTimeoutCtx", "_ws", "_wsMuxer", "_lastReceivedMessageTimestamp", "_openTimestamp", "_rtt", "_downloadRate", "_rateWindow", "_rateUpdateInterval", "_bytesSamples", "_messagesSent", "_messagesReceived", "_identity", "_connectionInfo", "open", "identity", "device", "peerKey", "_uploadRate", "send", "invariant", "__dxlog_file", "log", "payload", "protocol", "getPayloadType", "binary", "toBinary", "MessageSchema", "message", "length", "CLOUDFLARE_MESSAGE_MAX_BYTES", "error", "byteLength", "serviceId", "_recordBytes", "e", "baseProtocols", "EdgeWebsocketProtocol", "headers", "undefined", "muxer", "isOpen", "Date", "_callbacks", "onConnected", "_scheduleHeartbeats", "_scheduleRateCalculation", "currentIdentity", "warn", "code", "reason", "event", "onRestartRequired", "info", "verbose", "_pingTimestamp", "from", "err", "scheduleTaskInterval", "_ctx", "SIGNAL_KEEPALIVE_INTERVAL", "now", "_rescheduleHeartbeatTimeout", "Context", "scheduleTask", "lastReceivedMessageTimestamp", "existingSample", "find", "sent", "received", "timestamp", "_calculateRates", "cutoff", "totalReceived", "oldestTimestamp", "timeSpan", "sample", "totalSent", "Math", "round", "EdgeConnectionClosedError", "Error", "EdgeIdentityChangedError", "getEdgeUrlWithProtocol", "baseUrl", "protocol", "isSecure", "startsWith", "url", "URL", "toString", "statusChanged", "_persistentLifecycle", "_connect", "stop", "state", "_disconnect", "_messageListeners", "_reconnectListeners", "Set", "_baseWsUrl", "_baseHttpUrl", "_currentConnection", "_ready", "Trigger", "_identity", "getEdgeUrlWithProtocol", "_config", "socketEndpoint", "open", "status", "identity", "device", "peerKey", "uptime", "rtt", "rateBytesUp", "rateBytesDown", "downloadRate", "messagesSent", "messagesReceived", "setIdentity", "identityKey", "log", "oldIdentity", "_closeCurrentConnection", "scheduleRestart", "__dxlog_file", "timeout", "EdgeConnectionClosedError", "EdgeIdentityChangedError", "traceCtx", "message", "traceContext", "$typeName", "traceparent", "tracestate", "onMessage", "delete", "onReconnected", "TriggerState", "has", "listener", "error", "catch", "info", "err", "STATUS_REFRESH_INTERVAL", "undefined", "path", "protocolHeader", "disableAuth", "url", "connection", "EdgeWsConnection", "headers", "_isActive", "wake", "_notifyReconnected", "onRestartRequired", "restartRequired", "_notifyMessageReceived", "from", "type", "payload", "then", "wait", "close", "reset", "URL", "httpUrl", "response", "method", "encodePresentationWsAuthHeader", "statusText", "encodedToken", "sleep", "TRACE_SPAN_ATTRIBUTE", "invariant", "log", "EDGE_CLIENT_TAG_HEADER", "EdgeAuthChallengeError", "EdgeCallFailedError", "Context", "Duration", "Effect", "Layer", "Schedule", "log", "__dxlog_file", "timeout", "retryTimes", "retryBaseDelay", "millis", "status", "fail", "toString", "retry", "schedule", "exponential", "times", "withRetry", "effect", "config", "withLogging", "pipe", "__dxlog_file", "DEFAULT_RETRY_TIMEOUT", "DEFAULT_MAX_RETRIES_COUNT", "WARNING_BODY_SIZE", "BaseHttpClient", "_baseUrl", "_clientTag", "_edgeIdentity", "getEdgeUrlWithProtocol", "options", "log", "url", "baseUrl", "setIdentity", "identity", "_authHeader", "undefined", "hasBody", "args", "bodySize", "traceHeaders", "getTraceHeaders", "ctx", "handledAuth", "tryCount", "processingError", "response", "_handleUnauthorized", "authHeader", "fetch", "ok", "contentType", "headers", "get", "body", "success", "status", "invariant", "data", "challenge", "EdgeAuthChallengeError", "EdgeCallFailedError", "fromUnsuccessfulResponse", "isRetryable", "shouldRetry", "handleAuthChallenge", "json", "requestBody", "clientTag", "traceCtx", "tracestate", "retry", "retries", "baseTimeout", "jitter", "DEFAULT_RETRY_JITTER", "retryAfter", "maxRetries", "timeout", "Headers", "HttpClient", "HttpClientError", "HttpClientResponse", "Effect", "FiberRef", "Layer", "Stream", "BaseError", "log", "BYOK_HEADER", "__dxlog_file", "context", "provider", "options", "body", "decodeBody", "undefined", "text", "payload", "tools", "eager_input_streaming", "tool", "patched", "response", "getClient", "getFiberRef", "currentContext", "unsafeMap", "headers", "merge", "fromInput", "carriedByok", "send", "edgeClient", "anthropicAiRequest", "Request", "method", "request", "patchAnthropicMessagesRequestBody", "signal", "cause", "reason", "clone", "pipe", "orElseSucceed", "httpResponse", "status", "message", "error", "_tag", "formData", "toReadableStreamEffect", "layer", "FetchHttpClient", "HttpClient", "HttpClientRequest", "Effect", "Function", "EffectEx", "invariant", "log", "EDGE_CLIENT_TAG_HEADER", "createUrl", "__dxlog_file", "baseUrl", "options", "url", "log", "method", "auth", "args", "body", "getAgentStatus", "invariant", "queueId", "_call", "ctx", "after", "before", "query", "limit", "reverse", "objectIds", "formData", "append", "ownerPublicKey", "entryPoint", "runtime", "filename", "Object", "entries", "content", "type", "path", "pathParts", "json", "version", "searchParams", "params", "cpuTimeLimit", "subrequestsLimit", "input", "request", "replace", "target", "URL", "undefined", "arrayBuffer", "handledAuth", "_authHeader", "authResponse", "status", "_handleUnauthorized", "headers", "_clientTag", "response", "signal", "some", "createUrl", "HubHttpClient", "BaseHttpClient", "hubUrl", "options", "checkEmailExists", "ctx", "body", "args", "_call", "URL", "baseUrl", "method", "validateInvitationCode", "redeemInvitationCode", "login", "requestAccess", "getAccount", "deleteAccount", "listAccountInvitations", "issueAccountInvitation", "resendVerificationEmail", "getProfileUsage", "query", "createUrl", "windowSeconds"]
7
7
  }