1+ import { INTERNAL_COMMANDS } from '@agent-device/command-registry/catalog' ;
12import type { DaemonWireRequest } from '@agent-device/contracts/command' ;
23import type { DaemonResponse } from '@agent-device/kernel/contracts' ;
34import type { RequestProgressSink } from '@agent-device/contracts/progress' ;
45import net from 'node:net' ;
56import { AppError , createRequestCanceledError } from '@agent-device/kernel/errors' ;
67import { loadNodeHttpRequester , readNodeHttpResponseBody } from '@agent-device/host-kit/transport' ;
78import { emitDiagnostic } from '@agent-device/host-kit/diagnostics' ;
8- import type {
9- DaemonPaths ,
10- DaemonTransportPreference ,
9+ import {
10+ readDaemonCapabilities ,
11+ type DaemonCapability ,
12+ type DaemonPaths ,
13+ type DaemonTransportPreference ,
1114} from '@agent-device/daemon-contracts/daemon-resolution' ;
1215import {
1316 readDaemonHttpProgressResponse ,
@@ -18,6 +21,8 @@ import {
1821 buildDaemonHttpAuthHeaders ,
1922 buildDaemonHttpUrl ,
2023 DAEMON_HTTP_INSTANCE_HEADER ,
24+ DAEMON_HTTP_NETWORK_ACCESS_HEADER ,
25+ DAEMON_HTTP_PUBLIC_NETWORK_ACCESS ,
2126 DAEMON_HTTP_INSTANCE_MISMATCH_HEADER ,
2227 DAEMON_HTTP_UPSTREAM_INSTANCE_HEADER ,
2328 DAEMON_RPC_PROTOCOL_VERSION ,
@@ -106,7 +111,6 @@ const NO_REQUEST_GUARD: RequestGuard = {
106111 refuseIfAborted : ( ) => { } ,
107112 guard : async < T > ( send : ( ) => Promise < T > ) => await send ( ) ,
108113} ;
109-
110114export function createRequestGuard ( params : {
111115 signal : AbortSignal | undefined ;
112116 requestId ?: string ;
@@ -143,7 +147,6 @@ export function createRequestGuard(params: {
143147const LOCAL_DAEMON_HEALTHCHECK_TIMEOUT_MS = 500 ;
144148const REMOTE_DAEMON_HEALTHCHECK_TIMEOUT_MS = 3000 ;
145149const DAEMON_ENDPOINT_UNAVAILABLE_REASON = 'daemon_endpoint_unavailable' ;
146-
147150export function isDaemonTransportUnavailableError ( error : unknown ) : boolean {
148151 return (
149152 error instanceof AppError &&
@@ -161,7 +164,6 @@ function daemonEndpointUnavailableError(transport: ResolvedDaemonTransport): App
161164 { reason : DAEMON_ENDPOINT_UNAVAILABLE_REASON , transport } ,
162165 ) ;
163166}
164-
165167export type RemoteDaemonHealth = {
166168 reachable : boolean ;
167169 statusCode ?: number ;
@@ -170,7 +172,7 @@ export type RemoteDaemonHealth = {
170172 rpcProtocolVersion ?: number ;
171173 instanceId ?: string ;
172174 hostArch ?: string ;
173- activeScriptArtifacts ?: boolean ;
175+ capabilities ?: readonly DaemonCapability [ ] ;
174176 /** The daemon behind a proxy, as the proxy's health reported it. */
175177 upstream ?: RemoteDaemonHealthLink ;
176178 /** The probe ran out of its time budget before an answer, rather than failing outright. */
@@ -179,9 +181,8 @@ export type RemoteDaemonHealth = {
179181
180182type RemoteDaemonHealthLink = Pick <
181183 RemoteDaemonHealth ,
182- 'service' | 'version' | 'rpcProtocolVersion' | 'instanceId' | 'hostArch' | 'activeScriptArtifacts '
184+ 'service' | 'version' | 'rpcProtocolVersion' | 'instanceId' | 'hostArch' | 'capabilities '
183185> ;
184-
185186export async function canConnect (
186187 info : DaemonInfo ,
187188 preference : DaemonTransportPreference ,
@@ -197,7 +198,6 @@ export async function canConnect(
197198 Date . now ( ) < deadline
198199 : false ;
199200}
200-
201201async function canConnectWithTransport (
202202 info : DaemonInfo ,
203203 transport : ResolvedDaemonTransport ,
@@ -207,7 +207,6 @@ async function canConnectWithTransport(
207207 ? await canConnectHttp ( info , timeoutMs )
208208 : await canConnectSocket ( info . port , timeoutMs ) ;
209209}
210-
211210export function canConnectSocket (
212211 port : number | undefined ,
213212 timeoutMs = LOCAL_DAEMON_HEALTHCHECK_TIMEOUT_MS ,
@@ -237,7 +236,6 @@ export function canConnectSocket(
237236function canConnectHttp ( info : DaemonInfo , timeoutMs : number ) : Promise < boolean > {
238237 return readDaemonHttpHealth ( info , timeoutMs ) . then ( ( health ) => health . reachable ) ;
239238}
240-
241239export async function readRemoteDaemonHealth (
242240 info : DaemonInfo ,
243241 probeTimeoutMs ?: number ,
@@ -277,7 +275,6 @@ function daemonHttpEndpoint(info: DaemonInfo, route: 'health' | 'rpc'): string |
277275 ? `http://127.0.0.1:${ info . httpPort } /${ route } `
278276 : null ;
279277}
280-
281278async function readDaemonHttpHealth (
282279 info : DaemonInfo ,
283280 probeTimeoutMs ?: number ,
@@ -378,10 +375,9 @@ function readHealthLink(parsed: Record<string, unknown>): RemoteDaemonHealthLink
378375 typeof parsed . rpcProtocolVersion === 'number' ? parsed . rpcProtocolVersion : undefined ,
379376 ...( typeof parsed . instanceId === 'string' ? { instanceId : parsed . instanceId } : { } ) ,
380377 ...( typeof parsed . hostArch === 'string' ? { hostArch : parsed . hostArch } : { } ) ,
381- ... ( parsed . activeScriptArtifacts === true ? { activeScriptArtifacts : true } : { } ) ,
378+ capabilities : readDaemonCapabilities ( parsed . capabilities ) ,
382379 } ;
383380}
384-
385381export async function sendRequest (
386382 info : DaemonInfo ,
387383 req : DaemonWireRequest ,
@@ -401,7 +397,6 @@ export async function sendRequest(
401397 throw discloseRequestFailure ( transport . failure , req , transport . sent ) ;
402398 }
403399}
404-
405400async function recoverFromTimeout (
406401 error : unknown ,
407402 info : DaemonInfo ,
@@ -443,7 +438,6 @@ function classifyTransportFailure(
443438 return undefined ;
444439 }
445440}
446-
447441async function sendRequestWithFallback (
448442 info : DaemonInfo ,
449443 req : DaemonWireRequest ,
@@ -477,7 +471,6 @@ async function sendRequestWithFallback(
477471 return await sendRequestWithTransport ( info , req , statePaths , timeoutMs , fallback , options ) ;
478472 }
479473}
480-
481474async function retryAfterRemoteInstanceMismatch (
482475 info : DaemonInfo ,
483476 req : DaemonWireRequest ,
@@ -502,7 +495,7 @@ async function retryAfterRemoteInstanceMismatch(
502495 daemonBaseUrl : info . baseUrl ,
503496 } ) ;
504497 }
505- info . remoteActiveScriptArtifacts = ( health . upstream ?? health ) . activeScriptArtifacts === true ;
498+ info . capabilities = ( health . upstream ?? health ) . capabilities ;
506499 info . remoteInstanceId = health . instanceId ;
507500 info . remoteUpstreamInstanceId = health . upstream ?. instanceId ;
508501 cacheRemoteDaemonHealth ( info , health ) ;
@@ -543,7 +536,6 @@ function isRemoteTransportFailure(error: unknown): boolean {
543536 error . details ?. reason === 'daemon_response_read_failure' )
544537 ) ;
545538}
546-
547539async function sendRequestWithTransport (
548540 info : DaemonInfo ,
549541 req : DaemonWireRequest ,
@@ -649,7 +641,6 @@ function handleTransportError(
649641 err instanceof Error ? err : undefined ,
650642 ) ;
651643}
652-
653644async function sendSocketRequest (
654645 info : DaemonInfo ,
655646 req : DaemonWireRequest ,
@@ -788,7 +779,6 @@ function isRemoteInstanceMismatchResponse(
788779) : boolean {
789780 return statusCode === 409 && headers [ DAEMON_HTTP_INSTANCE_MISMATCH_HEADER ] === 'true' ;
790781}
791-
792782async function sendHttpRequest (
793783 info : DaemonInfo ,
794784 req : DaemonWireRequest ,
@@ -807,6 +797,9 @@ async function sendHttpRequest(
807797 } ;
808798 if ( info . baseUrl ) {
809799 Object . assign ( headers , buildDaemonHttpAuthHeaders ( info . token ) ) ;
800+ if ( req . flags ?. saveScript || req . command === INTERNAL_COMMANDS . sessionSaveScript ) {
801+ headers [ DAEMON_HTTP_NETWORK_ACCESS_HEADER ] = DAEMON_HTTP_PUBLIC_NETWORK_ACCESS ;
802+ }
810803 Object . assign ( headers , buildRemoteInstancePreconditionHeaders ( info ) ) ;
811804 }
812805 const transport = await loadNodeHttpRequester ( rpcUrl . protocol ) ;
@@ -970,7 +963,6 @@ function invalidateRemoteDaemonHealth(info: DaemonInfo): void {
970963 remoteHealthCache = undefined ;
971964 }
972965}
973-
974966export async function cachedRemoteDaemonHealth ( info : DaemonInfo ) : Promise < RemoteDaemonHealth > {
975967 if ( remoteHealthCache && matchesRemoteIdentity ( remoteHealthCache , info ) ) {
976968 return await remoteHealthCache . health ;
0 commit comments