MCPcopy Index your code
hub / github.com/TanStack/ai / exec

Method exec

packages/ai-sandbox-sprites/src/client.ts:534–733  ·  view source on GitHub ↗
(name: string, options: SpritesExecOptions)

Source from the content-addressed store, hash-verified

532 }
533
534 exec(name: string, options: SpritesExecOptions): SpritesExecStream {
535 const query = new URLSearchParams()
536 for (const arg of options.argv) query.append('cmd', arg)
537 if (options.cwd !== undefined) query.set('dir', options.cwd)
538 if (options.env) {
539 for (const [key, value] of Object.entries(options.env)) {
540 query.append('env', `${key}=${value}`)
541 }
542 }
543
544 const wsBase = this.baseUrl.replace(/^http(s?):\/\//, 'ws$1://')
545 const url = `${wsBase}/v1/sprites/${encodeURIComponent(name)}/exec?${query.toString()}`
546 // The query carries cmd/env (possibly secrets); never surface it in errors.
547 const safeUrl = `${wsBase}/v1/sprites/${encodeURIComponent(name)}/exec`
548
549 const stdoutQ = new AsyncChunkQueue()
550 const stderrQ = new AsyncChunkQueue()
551 const outDecoder = new TextDecoder()
552 const errDecoder = new TextDecoder()
553
554 let sessionId: string | undefined
555 let exitCode: number | undefined
556 let exitObserved = false
557 let killedByCaller = false
558 let opened = false
559 let settled = false
560 let socketError: Error | undefined
561 let onAbort: (() => void) | undefined
562 let resolveClosed!: () => void
563 const closed = new Promise<void>((resolve) => {
564 resolveClosed = resolve
565 })
566 // Resolves when the session id is known (or the socket closes without one),
567 // so kill() can reach the server-side kill endpoint even if it is called
568 // before the `session_info` frame arrives.
569 let resolveSession!: (id: string | undefined) => void
570 const sessionReady = new Promise<string | undefined>((resolve) => {
571 resolveSession = resolve
572 })
573
574 // The global (undici) WebSocket accepts a `headers` constructor option at
575 // runtime, but the WHATWG type only declares `(url, protocols?)`, so the two
576 // constructor signatures don't structurally overlap — bridge via `unknown`.
577 // eslint-disable-next-line no-restricted-syntax -- undici headers option not in the DOM WebSocket type
578 const WebSocketCtor = WebSocket as unknown as WsCtor
579 const ws = new WebSocketCtor(url, { headers: this.headers() })
580 ws.binaryType = 'arraybuffer'
581
582 // Bound the connect phase: if the socket never opens (e.g. the Sprite is
583 // restarting and stalls in CONNECTING), fail instead of hanging wait().
584 const connectTimer: ReturnType<typeof setTimeout> = setTimeout(() => {
585 if (!opened) {
586 socketError ??= new Error(
587 `Sprites exec WebSocket did not connect within ${options.connectTimeoutMs ?? 30_000}ms (${safeUrl}).`,
588 )
589 try {
590 ws.close()
591 } catch {

Callers

nothing calls this directly

Calls 12

headersMethod · 0.95
pushMethod · 0.95
parseControlMessageFunction · 0.85
signalReasonFunction · 0.85
toStringMethod · 0.80
onAbortFunction · 0.70
appendMethod · 0.65
setMethod · 0.65
replaceMethod · 0.65
closeMethod · 0.65
finishFunction · 0.50
addEventListenerMethod · 0.45

Tested by

no test coverage detected