Questa pagina è tradotta dalla documentazione inglese. Comandi, identificatori ed esempi restano invariati. Runtime 7.24.4 · SDK 2.6.7. Testo inglese
Trasporto gRPC e SDK nativo
Stato: attivo Ambito: contratto di trasporto nativo per desktop Ultima revisione: 2026-09-02 Responsabile: SDK di ax-code
AX Code espone ora un contratto di trasporto facoltativo a forma gRPC per app desktop e GUI native. Il contratto è volutamente più stretto dell’albero completo delle route HTTP/OpenAPI: si concentra sulle capacità del runtime headless di cui una GUI ha bisogno per risultare nativa, mantenendo HTTP/OpenAPI disponibile internamente per compatibilità, diagnostica e client generati.
Raccomandazione
Usa il trasporto gRPC/nativo come confine preferito per le app desktop di prima parte. Tieni HTTP/SSE abilitato come ripiego e superficie di debug.
| Esigenza | Percorso consigliato | Motivo |
|---|---|---|
| GUI desktop di prima parte | @defai-digital/ax-code-sdk/grpc |
Contratto stabile di comandi ed eventi, pronto allo streaming, metadati e scadenze adatti al nativo |
| Automazione TypeScript nello stesso processo | @defai-digital/ax-code-sdk con createAgent() |
Minimo overhead e supporto a strumenti personalizzati |
| Browser, ripiego WebView o diagnostica facile | HTTP/SSE con @defai-digital/ax-code-sdk/headless |
Funziona con fetch, curl, gli strumenti di sviluppo del browser e i controlli di autenticazione attuali del server |
| Integrazioni esterne non JS | proto gRPC o client generato da OpenAPI | Ampio supporto di strumenti senza manutenzione di un SDK HTTP di prima parte |
| Incorporazione di un host Rust | servizio gRPC/nativo o ponte a sottoprocesso | Evita di esporre l’intero albero delle route HTTP alla shell dell’app |
Perché non rimuovere HTTP
Rimuovere HTTP/OpenAPI dal runtime toglierebbe il percorso di compatibilità più ispezionabile e portabile. L’SDK JavaScript non deve esporre i sottopercorsi client/server HTTP come superfici di supporto di prima parte, ma il ponte HTTP interno resta utile per diagnostica, avvio esistente del backend headless e flussi di client generati. I controlli attuali del server HTTP includono il vincolo di binding solo loopback, credenziali Basic Auth generate negli helper di backend gestiti dall’SDK, controlli di origine sulle richieste mutanti del browser, validazione delle directory, limiti di frequenza delle richieste e documentazione OpenAPI live solo loopback.
Il trasporto non è la fonte dominante di latenza per i turni normali dell’agente. Le chiamate LLM, i comandi di shell, l’IO dei file, l’indicizzazione, l’avvio LSP e l’esecuzione degli strumenti sono di solito più costosi del JSON su localhost. gRPC resta utile per una GUI desktop perché offre un contratto API nativo più pulito, scadenze, metadati, streaming del server e un percorso verso trasporti su socket Unix o named pipe senza trascinare un’API orientata al browser nella shell dell’app.
Forma del contratto
Il contratto neutrale rispetto al linguaggio sta in packages/sdk/proto/ax_code/v1/headless.proto. Il pacchetto JSR contiene anche quel proto come asset. Gli host TypeScript lo localizzano con resolveAxCodeGrpcProtoUrl(); i generatori non JavaScript devono usare il contratto canonico del repository.
La facciata TypeScript sta in @defai-digital/ax-code-sdk/grpc e copre:
- salute e prontezza del ciclo di vita
- ingestione dei log dell’app e controlli di dispose/riavvio dell’istanza per la gestione del ciclo di vita dell’host nativo
- creazione della sessione
- prompt, comando, shell, interruzione, risposta ai permessi e risposta alle domande
- istantanee di bootstrap della GUI per provider, sessioni, permessi, domande, percorso, VCS, LSP, MCP, formattatore e stato dei comandi
- elenco sessioni, dettaglio, cronologia dei messaggi, dettaglio del messaggio, figli, obiettivo, todo, diff, fork, condivisione e operazioni di riepilogo
- scoperta GUI e navigazione dello spazio di lavoro per agenti, skill, progetti, percorso, VCS, comandi, albero, contenuto e stato dei file, ricerca di testo, file e simboli e schemi degli strumenti
- contesto di progetto, modelli di contesto, aggiornamento e pulizia della memoria in cache e diagnostica del piano in attesa del motore di debug
- operazioni di elenco, risposta e rifiuto di permessi e domande in attesa per i flussi GUI supervisionati
- impostazioni di provider, configurazione, autenticazione con chiave API e OAuth del provider per le schermate delle impostazioni GUI
- controlli delle impostazioni di runtime per modalità autonoma, modalità di isolamento e instradamento LLM intelligente
- stato MCP, scoperta delle risorse, gestione dinamica dei server, OAuth, connessione e disconnessione
- stato di LSP e formattatore per diagnostica e schermate delle impostazioni
- gestione del terminale PTY e streaming bidirezionale del terminale
- prove di sessione per l’interfaccia di revisione e debug
- operazioni della coda dei compiti
- operazioni dei compiti pianificati
- modelli di flusso di lavoro, esecuzioni di flusso, riepiloghi della dashboard, casi di eval, routine di flusso e artefatti di esecuzione
- eventi di runtime in streaming dal server
Il proto usa payload JSON strutturati per i corpi dei comandi e i payload di flusso e compito. Questo mantiene stabile il trasporto mentre gli schemi del runtime di AX Code continuano a evolvere in fretta.
@defai-digital/ax-code-sdk/grpc esporta anche AX_CODE_GRPC_METHOD_DESCRIPTORS, listAxCodeGrpcMethods(), getAxCodeGrpcMethodDescriptor(), assertAxCodeGrpcMethodSupported(), listMissingAxCodeGrpcNativeHandlers() e assertAxCodeGrpcNativeHandlers(). Gli host nativi devono usare questi descrittori e i controlli di copertura come catalogo canonico dei metodi quando costruiscono mappe di handler, binder di servizi gRPC, elenchi consentiti del preload o cancelli di avvio. Ogni descrittore include il nome del metodo, il percorso del metodo pienamente qualificato, il tipo di stream, i nomi dei messaggi proto di richiesta e risposta, il dominio GUI, la disponibilità del ponte HTTP e la stabilità corrente. Questo mantiene esplicito il confine di trasporto nativo senza esporre o rispecchiare l’intero albero delle route HTTP.
Uso di TypeScript
Usa il backend headless gRPC gestito dall’SDK quando l’host ha ancora bisogno internamente del runtime HTTP esistente. Tiene il ponte HTTP dentro il processo host e restituisce solo il client gRPC più l’handle del ciclo di vita:
import {
createAxCodeGrpcClientFromNativeBridge,
resolveAxCodeGrpcProtoUrl,
startAxCodeGrpcHeadlessBackend,
} from "@defai-digital/ax-code-sdk/grpc"
const backend = await startAxCodeGrpcHeadlessBackend({ directory: "/workspace/app" })
try {
const client = backend.client
const session = await client.createSession({ title: "GUI session" })
const messages = await client.session.messages((session as { id: string }).id, { limit: 50 })
const skills = await client.app.skills()
const readme = await client.file.read("README.md")
const authMethods = await client.provider.auth()
const bootstrap = await client.bootstrap.load({
include: { sessions: true, providers: true, providerList: true, path: true, vcs: true },
})
const terminal = (await client.pty.create({ title: "GUI shell" })) as { id: string }
const protoUrl = resolveAxCodeGrpcProtoUrl()
await client.sendPrompt((session as { id: string }).id, {
parts: [{ type: "text", text: "Review this workspace" }],
})
for await (const event of client.subscribeEvents({ sessionID: (session as { id: string }).id })) {
if (event.type === "server.heartbeat") continue
// Project event into GUI state.
}
} finally {
await backend.close()
}
Usa un ponte IPC nativo quando l’host desktop possiede il confine privilegiato del runtime tramite preload di Electron, comandi Tauri o un altro confine structured-clone. Le chiamate IPC omettono di proposito AbortSignal e tengono il flusso di input bidirezionale fuori dal payload della chiamata, così l’oggetto della chiamata può attraversare in modo pulito i confini renderer/host:
const client = createAxCodeGrpcClientFromNativeIpc({
unary(call) {
return window.axCodeNative.unary(call)
},
serverStream(call) {
return window.axCodeNative.serverStream(call)
},
bidiStream(call, input) {
return window.axCodeNative.bidiStream(call, input)
},
})
Usa createAxCodeGrpcClientFromNativeBridge() solo quando entrambi i lati sono nello stesso realm JavaScript e possono passare in sicurezza AbortSignal e iterabili asincroni direttamente nell’oggetto della chiamata.
Se l’host espone sottoscrizioni in stile push, usa createAxCodeGrpcNativeIpcBridgeFromChannels() o createAxCodeGrpcNativeIpcStream() per adattare le callback dell’host nei flussi AsyncIterable attesi dall’SDK gRPC. Quegli helper sono utili per i listener di eventi Tauri, le callback del preload Electron e altri sistemi IPC che restituiscono una funzione di disiscrizione invece di un generatore asincrono JavaScript.
Gli host nativi possono anche esporre una mappa di handler invece di scrivere a mano uno switch di metodi. È utile per comandi Rust/Tauri, API di preload Electron o un vero server gRPC locale che vuole legare le operazioni del runtime di AX Code metodo per metodo. Usa i descrittori dei metodi per validare che ogni dominio atteso sia coperto prima di consegnare il ponte al codice del renderer:
import {
AX_CODE_GRPC_METHOD,
assertAxCodeGrpcNativeHandlers,
createAxCodeGrpcNativeBridgeFromHandlers,
listAxCodeGrpcMethods,
} from "@defai-digital/ax-code-sdk/grpc"
const handlers = {
unary: {
[AX_CODE_GRPC_METHOD.GetSession](request, options) {
return runtime.getSession(request.sessionID, options)
},
},
serverStream: {
[AX_CODE_GRPC_METHOD.SubscribeEvents](_request, options) {
return runtime.events(options)
},
},
bidiStream: {
[AX_CODE_GRPC_METHOD.ConnectPty](request, input, options) {
return runtime.connectPty(request.id, input, options)
},
},
}
const mcpMethods = listAxCodeGrpcMethods({ domain: "mcp" })
const streamingMethods = listAxCodeGrpcMethods({ kind: "serverStream" })
const ptyDescriptor = listAxCodeGrpcMethods({ kind: "bidiStream" })[0]
// ptyDescriptor.requestType === "PtyClientEvent"
// ptyDescriptor.responseType === "PtyServerEvent"
assertAxCodeGrpcNativeHandlers(handlers, {
methods: [AX_CODE_GRPC_METHOD.GetSession, AX_CODE_GRPC_METHOD.SubscribeEvents, AX_CODE_GRPC_METHOD.ConnectPty],
})
const bridge = createAxCodeGrpcNativeBridgeFromHandlers(handlers, {
requireHandlers: {
methods: [AX_CODE_GRPC_METHOD.GetSession, AX_CODE_GRPC_METHOD.SubscribeEvents, AX_CODE_GRPC_METHOD.ConnectPty],
},
})
bootstrap.load() è di proposito un’istantanea orientata alla GUI, non una copia uno a uno di ogni route HTTP. Usa include per richiedere solo lo stato necessario alla vista corrente. Le sottorichieste fallite sono segnalate in errors mentre i campi riusciti vengono comunque restituiti, così un sottosistema facoltativo mancante non impedisce l’apertura della shell desktop.
Lo streaming degli eventi accetta filtri facoltativi types e sessionID. I trasporti nativi devono applicare quei filtri lato server. Il ponte di compatibilità HTTP applica gli stessi filtri lato client sulla route SSE esistente, così il codice GUI può mantenere una sola forma di sottoscrizione mentre il server nativo viene implementato.
startAxCodeGrpcHeadlessBackend() è il ripiego temporaneo preferito quando l’host avvia ancora ax-code serve internamente. Non restituisce l’URL HTTP né l’intestazione di autorizzazione, così il codice del renderer può essere scritto contro la facciata gRPC e spostato in seguito su un trasporto gRPC nativo reale senza una riscrittura dell’API pubblica.
Gli host desktop basati su Node.js possono esporre un vero endpoint gRPC HTTP/2 dallo stesso ponte nativo con @defai-digital/ax-code-sdk/grpc/node. Questo è per i processi host privilegiati, non per il codice del renderer:
import { createAxCodeGrpcNativeBridgeFromHandlers, AX_CODE_GRPC_METHOD } from "@defai-digital/ax-code-sdk/grpc"
import { startAxCodeGrpcNodeHttp2Server } from "@defai-digital/ax-code-sdk/grpc/node"
const bridge = createAxCodeGrpcNativeBridgeFromHandlers({
unary: {
[AX_CODE_GRPC_METHOD.Health]() {
return { status: "SERVING" }
},
},
serverStream: {
[AX_CODE_GRPC_METHOD.SubscribeEvents](request) {
return runtime.subscribeEvents(request)
},
},
})
const server = await startAxCodeGrpcNodeHttp2Server({ bridge, host: "127.0.0.1" })
try {
// Native clients can generate from ax_code/v1/headless.proto and connect to server.url.
} finally {
await server.close()
}
Lo streaming PTY è modellato come uno stream bidirezionale gRPC. Il ponte HTTP adatta quello stream alla route WebSocket esistente per compatibilità; gli host GUI nativi devono implementarlo sul proprio trasporto gRPC locale, socket Unix o named pipe invece di esporre la route WebSocket al codice del renderer.
Quando un trasporto gRPC reale è disponibile, forniscilo a createAxCodeGrpcClient({ transport }). Il client di alto livello resta lo stesso.
Postura di sicurezza
Per le app desktop, preferisci questo ordine:
- SDK in-process quando la GUI è TypeScript e può caricare il runtime in sicurezza.
- Trasporto gRPC/nativo locale su loopback, socket Unix o named pipe.
- Ponte headless HTTP/SSE con credenziali Basic Auth monouso generate.
- Non esporre AX Code su HTTP di rete.
Il ponte di compatibilità gRPC HTTP e gli helper di backend HTTP gestiti dall’SDK accettano solo endpoint loopback letterali. Le opzioni legacy allowRemoteHttpBridge e allowNetworkBind sono conservate per la compatibilità del sorgente ma non aggirano la policy solo locale. Tieni /doc limitato al server loopback.
Il ponte di compatibilità HTTP rifiuta per impostazione predefinita gli upgrade WebSocket cross-origin. Aggiungi un’origine all’elenco CORS esplicito del server solo quando quell’origine del browser fa parte della shell dell’app fidata.
Non esporre l’API HTTP completa, il WebSocket PTY o la documentazione OpenAPI a WebView arbitrarie. Se si usa una WebView, tienila come renderer e instrada le operazioni privilegiate attraverso l’host nativo usando la facciata gRPC/nativa.