@axhub/acp
v0.1.13
Published
Experimental sibling project for validating an ACP + [assistant-ui](https://github.com/assistant-ui/assistant-ui) migration path.
Readme
@axhub/acp
Experimental sibling project for validating an ACP + assistant-ui migration path.
This project uses assistant-ui for the chat runtime/UI and routes messages through ACP using the vendored @mcpc-tech/[email protected] baseline in lib/acp2aisdk/vendor/acp-ai-provider, with the Codex ACP provider fixed to @zed-industries/codex-acp.
Getting Started
Runtime requirements
- Node.js 22 or newer is required by AI SDK 7.
- Node.js 24 LTS is recommended for local development, CI, and deployment.
Run from npm
npx -y @axhub/acpCommon options:
npx -y @axhub/acp --port 32124
npx -y @axhub/acp --cors-origin https://client.example.comBy default the CLI allows /api/* CORS requests from http://localhost:53817 and http://127.0.0.1:53817. --cors-origin replaces that default with another allowed browser Origin list. It also supports comma-separated origins and the aliases --cors and --cor.
External Integration
- HTTP Chat API documents
POST /api/chat, including request parameters, stream chunks, response headers, a one-shot command example, and a live message listener example. - Post Message API documents the browser
postMessagebridge overview, with focused pages for embedded host lifecycle, runtime configuration, thread queries, and artifacts/tools. - Host Integration documents generic iframe/child-window embedding, runtime API base configuration, context injection, runtime config injection, postMessage thread queries, HTTP chat execution, image generation, and React component reuse.
- Host Browser Tools And Local Files documents trusted extension frontend tools, MessageChannel execution, the unified workspace-relative file API, screenshot persistence, and Commentary document persistence.
- Component And Runtime API documents package-level
@axhub/acp/ui,@axhub/acp/runtime,@axhub/acp/server,@axhub/acp/react,@axhub/acp/voice, and@axhub/acp/react/styles.cssentries, including the generic embeddable realtime voice surface. - Provider And Model Defaults lists built-in provider keys, startup commands, UI fallback modes, and fallback model options.
- Voice Agent Architecture documents the Doubao speech layer, three selectable brain modes, shared prompt/tools, settings, and screen-permission flow.
Voice credentials, brain provider/model options, task executor, and vision
model are configured in Settings > Voice Agent and persisted server-side.
ACP and task execution use the current app's internal same-origin service, so
their settings expose provider/model choices instead of another URL or API key;
task execution follows the ACP brain unless independently selected.
The packaged acp launcher starts only the Web UI and API. On the first
/api/livekit/*-token request, the server starts the local LiveKit service and
exactly one bundled worker for the selected brain mode; later connections reuse
those processes until ACP exits. Changing brain mode replaces only the worker.
Local on-demand mode requires livekit-server on PATH (or
LIVEKIT_SERVER_BIN). An explicit remote LIVEKIT_URL is reused instead and
must provide matching LIVEKIT_API_KEY and LIVEKIT_API_SECRET; ACP still
starts the selected bundled worker. A failed cold start returns a stable safe
error code and a later request retries without leaving duplicate workers.
The opt-in development LiveKit launcher still reads the saved configuration
before starting its full local stack. It listens on 32124/TCP for the Web UI
and API and on 7880/TCP+UDP for LiveKit. The standalone direct-Doubao latency
demo is only started explicitly with npm run dev:doubao; it is never part of
the default application launcher.
Axhub production and development Chrome extensions are trusted by default. Add
another exact host temporarily to a running service with
npx -y @axhub/acp@latest trusted-host add <origin> and then refresh the
embedded page. Runtime additions are append-only, process-local, and do not
grant CORS access.
1. Configure an ACP Provider
Use a local provider login/session that the selected ACP command can access. Built-in provider recipes cover Codex, Claude, OpenCode, Cursor, Qoder, CodeBuddy, Reasonix, and Grok Build. Qoder, CodeBuddy, Cursor, Reasonix, and Grok Build authentication or project configuration stays in the vendor CLI or inherited process environment. See Provider And Model Defaults for provider keys and default built-in model options.
2. Install Dependencies
npm install
# or
yarn install
# or
pnpm install3. Run the Development Server
npm run dev
# or
yarn dev
# or
pnpm devOpen http://localhost:32124 with your browser. The Web
UI first requires a local project directory; after selection it keeps the
canonical absolute path in the cwd query parameter.
npm run dev uses the local source checkout and runs next dev. It allows the same default host-app origins on port 53817. For a local host app on another origin, pass the CORS option through npm:
npm run dev -- --cors-origin http://localhost:3000For the common local host-app setup, use the host-aware development command. It binds the ACP UI dev server on 0.0.0.0, allows the usual host app origins on port 53817, and also lets Next.js dev assets/HMR accept those origins:
npm run dev:hostDoubao Full-Duplex Voice Demo
The optional development demo connects the existing resident voice control to the Doubao end-to-end realtime dialogue API. It keeps both Doubao credentials and the task API key out of browser code.
Prefer Settings > Voice Agent. Environment variables remain supported for isolated local runs:
DOUBAO_REALTIME_APP_ID=your-app-id
DOUBAO_REALTIME_ACCESS_KEY=your-access-token
ACP_UI_VOICE_BRIDGE_TOKEN=your-dedicated-task-api-keyStart the isolated demo:
npm run dev:doubaoThe home page exposes the same generic LiveKit realtime voice control used by external hosts. Each connection has temporary captions and an ephemeral ACP brain session; it does not create chat history or list/switch ACP conversations. The isolated demos remain available for A/B comparison:
/livekit-voicefor direct Doubao;/livekit-voice-apifor the configured OpenAI-compatible brain;/livekit-voice-codexfor the configured ACP brain.
Normal speech uses the selected brain mode. Development commands, task queries/cancellation, screen inspection, and host-provided tools use the same provider-neutral contract; only the configured brain decides when to call them.
The default demo uses model 1.2.1.1, speaker
zh_female_vv_jupiter_bigtts, 16 kHz PCM16 microphone input, and 24 kHz
PCM16LE output. Optional overrides are:
DOUBAO_REALTIME_MODEL=1.2.1.1
DOUBAO_REALTIME_SPEAKER=zh_female_vv_jupiter_bigtts
DOUBAO_VOICE_GATEWAY_PORT=3102
DOUBAO_DEMO_APP_PORT=32125The browser and gateway continue sending and receiving audio concurrently.
Doubao ASRInfo clears queued playback for barge-in, and a manual UI
interruption maps to ClientInterrupt. This direct Doubao adapter is a voice
quality and latency baseline; it does not measure TEN Framework overhead.
Development
You can start customizing the UI by modifying components in the components/assistant-ui/ directory.
To add more assistant-ui components:
npx assistant-ui addKey Files
app/assistant.tsx- Sets up the runtime providerapp/api/chat/route.ts- ACP Codex chat endpoint with per-thread session reusecomponents/assistant-ui/thread.tsx- Compatibility re-export for the chat thread componentcomponents/assistant-ui/thread/- Split thread UI modules for message list, composer, context chips, empty states, and message rendererspublic-api/- Component/runtime/server facade entries emitted todist/for package-level external reuse
Regression
The recommended local regression flow is documented in docs/regression/test-coverage.zh-CN.md.
npm run regressionThe pipeline runs provider official command smoke first, then provider registry/smoke tests, then the Codex API/CLI P0 regression, and finally the Midscene frontend smoke.
Provider Defaults
Provider startup recipes and UI fallback defaults live in static profiles under
lib/acp2aisdk/providers/. Fallback modes such as Claude
bypassPermissions, Codex agent-full-access, OpenCode build, Cursor
agent, and Qoder/CodeBuddy bypassPermissions are only used for selector
display and capability fallback. They are not automatically sent to
/api/chat; omitting modeId keeps the provider session default. Reasonix has
no fallback mode because its ACP implementation is driven by model and effort
config options. Grok Build also has no fallback mode or thought level in the
tested ACP baseline; it uses the grok-build model exposed by
grok agent stdio.
Grok Build falls back to
npx -y @xai-official/[email protected] agent stdio when the local grok command is
not available. Authentication remains owned by the Grok CLI or inherited
process environment; acp-ui does not store provider credentials.
Default ACP capability snapshots are generated from live ACP provider initSession
responses:
npm run refresh:default-capabilities -- --providers=all
npm run refresh:default-capabilities -- --provider=codexUse ACP_PROVIDER_COMMAND_OVERRIDES or per-provider ACP_<PROVIDER>_COMMAND
environment variables when refreshing defaults for a new or local provider.
Each profile can define command, args, optional fallbackCommands, UI
defaults, fallback capabilities, and compatibility flags without touching the
shared session runtime. Cross-platform PATH/PATHEXT enrichment and Windows npm
shim wrapping are centralized in lib/acp2aisdk/provider-command.ts, so new
providers should only need a profile unless they have protocol differences.
Changes to provider-owned external config files do not invalidate existing ACP
runtime sessions automatically; start a new thread, clear sessions, or restart
acp-ui when you need those changes to take effect.
