Gajae Code

Documentation

Building applications on the SDK

Use Gajae-Code as the agent runtime for your own product — mobile apps, desktop apps, custom web frontends, and vertical AI applications. Delete your agentic loop; keep your product.

Built with bundled adapters

The bundled Telegram, Discord, and Slack adapters use the SDK surface described here. They demonstrate how an integration can render questions on a phone, route replies to a session, and stream turn summaries without relying on private hooks.

Why build on it

Delete the agentic loop

Tools, retries, compaction, session persistence, model fallback chains, streaming — one createAgentSession() call instead of a bespoke backend every vertical AI team rebuilds.

Remote-ready sessions

Each top-level session can expose a loopback WebSocket endpoint. Configure the bundled adapters or your own client to receive notifications, resolve remote asks, automate CLI flows, or coordinate through MCP.

Many subscribers

The event stream supports multiple simultaneous subscribers: your app UI, a remote notifier, and an audit logger can all watch one session.

Not just coding

Tools, skills, rules, and the system prompt are injectable. The same runtime powers legal assistants, research agents, and data-analysis products.

Two surfaces

Embedding SDK (in-process)WebSocket SDK (out-of-process)
What it isImport @gajae-code/coding-agent as a libraryConnect to a running session's loopback endpoint
LanguageTypeScript / BunAny language (JSON frames)
TelemetryFull: token deltas, tool events, session eventsCurated: ask/action frames, summarized turn stream, queries
TrustYou are the hostToken-authenticated client; the token crosses the loopback handshake and must never be logged or exposed

A common production shape uses both: your product UI subscribes in-process for full-fidelity streaming while remote channels attach over WebSocket for notifications and approvals.

Embed the runtime

bun add @gajae-code/coding-agent
import { createAgentSession } from "@gajae-code/coding-agent";

const { session } = await createAgentSession();

session.subscribe((event) => {
  if (event.type === "message_update" &&
      event.assistantMessageEvent.type === "text_delta") {
    process.stdout.write(event.assistantMessageEvent.delta);
  }
});

await session.prompt("Summarize this repository in 3 bullets.");
await session.dispose();

Provide to override, omit to discover: with no options it auto-discovers auth, models, settings, tools, context files, and a file-backed session store. Everything is overridable.

Customize for your vertical

All of these are createAgentSession() options:

  • Restrict or drop toolstoolNames allowlist, bashAllowedPrefixes, plus runtime setActiveToolsByName().
  • Add custom toolscustomTools (your domain tools) or mcpConfigPath (tools from an MCP server you own).
  • Inject skills, rules, identityskills, rules, contextFiles, promptTemplates, and systemPrompt (replace or transform the default blocks).
  • Isolate stateSessionManager.inMemory() and Settings.isolated() for request-scoped agents.
  • Structured subagentsoutputSchema, requireYieldTool, taskDepth for orchestrators.
  • Observability — opt-in OpenTelemetry GenAI spans via telemetry.

Attach from outside

Any running top-level session writes a discovery file at <repo>/.gjc/state/sdk/<sessionId>.json containing its url and token. The token crosses the loopback handshake, so treat it as a credential: never log or expose it. Connect with any WebSocket client, or bun add @gajae-code/bridge-client and use SdkClient.

A minimal client handles three server frames — action_needed, action_resolved, reply_rejected — and sends one: reply. Optional threaded frames add turn_stream, context_update, activity, and image_attachment. Typed control operations (turn.prompt, turn.steer, model.set, session.fork, …) and read queries (transcript.*, diff.*, usage.get, …) cover nearly everything the TUI can do.

Sessions can be created programmatically with no pre-existing session: the SDK broker starts on demand (gjc daemon session, broker global session.create/fork/resume/close/delete), and multi-session controllers can use the Coordinator MCP.

Recipes

Vertical AI app

Embed with toolNames + customTools + skills + a domain system prompt. Your UI streams token deltas in-process; bundled adapters can provide phone approvals when configured for the session.

Custom web app

Run top-level sessions under the broker; your backend attaches over WebSocket, renders turn_stream, answers asks with reply, and reads history via transcript.*.

Mobile / desktop companion

Use the same SDK surface as a bundled adapter: discover a top-level session endpoint, render action_needed, and send reply.

Fleet orchestrator

Coordinator MCP or broker globals to create and supervise many worktree-scoped sessions.

Deliberate boundaries

The WebSocket surface is loopback-only. Its session token crosses the loopback handshake and must never be logged or exposed; other secrets do not cross the interface (config.patch rejects secret fields, and endpoint credentials are prohibited through chat adapters). The surface streams summarized turn text (no thinking tokens; redaction-gated) and fails closed on stale action identity. Full-fidelity token streaming is an in-process embedding capability by design — the boundary is trust, not capability.