- Go 99.6%
- Shell 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| agent-browser@7e1dbf8932 | ||
| agent-core-system@b8c3b05d50 | ||
| agent-exec@00ef49a2c3 | ||
| agent-filesystem@5b723c9e7a | ||
| agent-keyring@1a3abf9643 | ||
| agent-llm@d9abff834a | ||
| agent-memory@fdd4831932 | ||
| agent-network@362cc3308f | ||
| agent-provider-bundle-contracts@fd70198bae | ||
| agent-telegram@2ff0cb1356 | ||
| cmd/agent-system | ||
| docs | ||
| rpc-plugin-system@e94a13a57f | ||
| scripts | ||
| .gitignore | ||
| .gitmodules | ||
| go.mod | ||
| go.sum | ||
| README.md | ||
agent-system
Meta-repository for the agent runtime system.
System map: docs/system-map.md.
This repository does not vendor component source. Components are tracked as git submodules so each provider/runtime repo keeps its own history, review gates, and release boundary.
Components
agent-browser— browser provider runtimeagent-core-system— core host/supervisor and routing surfaceagent-exec— process execution provideragent-filesystem— filesystem provideragent-keyring— credential/key authority provideragent-llm— LLM/model provideragent-memory— memory provideragent-network— network provideragent-provider-bundle-contracts— shared provider contract docs/templatesagent-telegram— Telegram providerrpc-plugin-system— substrate plugin runtime
Clone
git clone --recurse-submodules <agent-system-url>
If already cloned:
git submodule update --init --recursive
Configure local bootstrap state
Use the local tcell configure wizard for OpenClaw-style setup:
scripts/agent-system configure
The wizard is a terminal UI. Controls:
↑/↓ or j/k move between fields
Enter edit the selected field
Esc cancel field edit, or exit from the main screen
Ctrl-S save local config/secrets
q quit from the main screen
It writes non-secret settings to local/config/system.env and bootstrap/import secrets to local/secrets/bootstrap.env. Both paths are ignored by git. Secret fields are masked in the TUI; do not pass tokens on argv.
The current wizard fields are:
OpenAI-compatible base URL -> OPENAI_COMPATIBLE_BASE_URL
OpenAI-compatible model -> OPENAI_COMPATIBLE_MODEL
OAuth authorization URL -> OPENAI_OAUTH_AUTH_URL
OAuth token URL -> OPENAI_OAUTH_TOKEN_URL
OAuth client id -> OPENAI_OAUTH_CLIENT_ID
OAuth scopes -> OPENAI_OAUTH_SCOPES
OAuth loopback port -> OPENAI_OAUTH_REDIRECT_PORT
Browser backend -> AGENT_BROWSER_BACKEND
Chromium executable -> AGENT_BROWSER_CHROMIUM_EXECUTABLE
OpenAI API/provider token -> OPENAI_COMPATIBLE_API_KEY
OpenAI OAuth access token -> OPENAI_OAUTH_ACCESS_TOKEN
OpenAI OAuth refresh token -> OPENAI_OAUTH_REFRESH_TOKEN
Telegram bot username -> TELEGRAM_BOT_USERNAME
Telegram bot id -> TELEGRAM_BOT_ID
Telegram bootstrap chat id -> TELEGRAM_BOOTSTRAP_CHAT_ID
Telegram bootstrap sender id -> TELEGRAM_BOOTSTRAP_SENDER_ID
Telegram bot token -> TELEGRAM_BOT_TOKEN
Telegram webhook secret -> TELEGRAM_WEBHOOK_SECRET
You can also set non-secret values directly:
scripts/agent-system config set openai.base_url https://api.openai.com/v1
scripts/agent-system config set openai.model gpt-4.1
scripts/agent-system secret set OPENAI_COMPATIBLE_API_KEY
scripts/agent-system secret set OPENAI_OAUTH_ACCESS_TOKEN
scripts/agent-system secret set OPENAI_OAUTH_REFRESH_TOKEN
scripts/agent-system show
For providers that support OAuth authorization-code + PKCE with a loopback redirect, configure the OAuth endpoints and client id, then run:
scripts/agent-system config set openai.oauth.auth_url https://provider.example/oauth/authorize
scripts/agent-system config set openai.oauth.token_url https://provider.example/oauth/token
scripts/agent-system config set openai.oauth.client_id public-client-id
scripts/agent-system config set openai.oauth.scopes "scope1 scope2"
scripts/agent-system oauth login openai
The login command prints the verification/authorization URL, listens on http://127.0.0.1:<port>/oauth/callback, validates the callback state, exchanges the authorization code with the PKCE verifier, and stores returned tokens in local/secrets/bootstrap.env as OPENAI_OAUTH_ACCESS_TOKEN and, when returned, OPENAI_OAUTH_REFRESH_TOKEN. It does not log token material.
Telegram has no OAuth PKCE flow for bot tokens. For Telegram, run:
scripts/agent-system telegram login
The command prompts for the bot token if one is not already in local bootstrap storage, verifies it with getMe, prints a one-time challenge and a https://t.me/<bot>?start=<challenge> URL, then polls getUpdates until the bot receives that exact challenge. On success it stores the bot token in local/secrets/bootstrap.env and records non-secret bootstrap metadata in local/config/system.env (TELEGRAM_BOT_USERNAME, TELEGRAM_BOT_ID, TELEGRAM_BOOTSTRAP_CHAT_ID, TELEGRAM_BOOTSTRAP_SENDER_ID). It does not print token material.
This is still bootstrap/import storage, not provider authority. agent-keyring and core admission remain the steady-state authority path.
Start and run the local system
These commands build the substrate daemon, admin CLI, core host, and provider binaries into ignored local state. Provider executable filenames are the plugin ids. Do not put random executables in the plugin directory; agent-core-host -plugin-dir treats every directly executable file there as a desired provider.
ROOT="$(pwd)"
RUN="$ROOT/local/run"
BIN="$RUN/bin"
PLUGINS="$RUN/plugins"
RUNTIME="$RUN/runtime"
rm -rf "$RUN"
mkdir -p "$BIN" "$PLUGINS" "$RUNTIME"
(cd "$ROOT/rpc-plugin-system/src" && \
go build -buildvcs=false -o "$BIN/rpcplugind" ./cmd/rpcplugind && \
go build -buildvcs=false -o "$BIN/rpcpluginctl" ./cmd/rpcpluginctl)
(cd "$ROOT/agent-core-system" && \
go build -buildvcs=false -o "$BIN/agent-core-host" ./src/cmd/agent-core-host)
(cd "$ROOT/agent-browser" && go build -buildvcs=false -o "$PLUGINS/browser" ./src/cmd/agent-browser)
(cd "$ROOT/agent-exec" && go build -buildvcs=false -o "$PLUGINS/exec" ./src/cmd/agent-exec)
(cd "$ROOT/agent-filesystem" && go build -buildvcs=false -o "$PLUGINS/filesystem" ./src/cmd/agent-filesystem)
(cd "$ROOT/agent-keyring" && go build -buildvcs=false -o "$PLUGINS/keyring" ./cmd/agent-keyring)
(cd "$ROOT/agent-llm" && go build -buildvcs=false -o "$PLUGINS/llm" ./src/cmd/agent-llm)
(cd "$ROOT/agent-memory" && go build -buildvcs=false -o "$PLUGINS/memory" ./src/cmd/agent-memory)
(cd "$ROOT/agent-network" && go build -buildvcs=false -o "$PLUGINS/network" ./cmd/agent-network)
(cd "$ROOT/agent-telegram" && go build -buildvcs=false -o "$PLUGINS/telegram" ./src/cmd/agent-telegram)
find "$PLUGINS" -maxdepth 1 -type f -perm -111 -printf '%f\n' | sort
Run a one-shot smoke test. This starts the system, prints one JSON status snapshot, and stops the owned substrate daemon:
AGENT_BROWSER_BACKEND=chromedp \
AGENT_BROWSER_CHROMIUM_EXECUTABLE=/usr/bin/chromium \
"$BIN/agent-core-host" \
-rpcplugind "$BIN/rpcplugind" \
-runtime-dir "$RUNTIME" \
-plugin-dir "$PLUGINS" \
-startup-timeout 30s \
-dial-timeout 3s \
-once
Run it continuously by omitting -once:
AGENT_BROWSER_BACKEND=chromedp \
AGENT_BROWSER_CHROMIUM_EXECUTABLE=/usr/bin/chromium \
"$BIN/agent-core-host" \
-rpcplugind "$BIN/rpcplugind" \
-runtime-dir "$RUNTIME" \
-plugin-dir "$PLUGINS" \
-startup-timeout 30s \
-dial-timeout 3s
Inspect the live system from another terminal:
"$BIN/rpcpluginctl" -runtime-dir "$RUNTIME" status
"$BIN/rpcpluginctl" -runtime-dir "$RUNTIME" routes
"$BIN/rpcpluginctl" -runtime-dir "$RUNTIME" capabilities
"$BIN/rpcpluginctl" -runtime-dir "$RUNTIME" heartbeat -plugin-id browser
"$BIN/rpcpluginctl" -runtime-dir "$RUNTIME" heartbeat -plugin-id llm
Stop the foreground agent-core-host with Ctrl-C. It should stop the owned rpcplugind process. If a crash leaves children behind during development, inspect and terminate only that run's PIDs; do not kill unrelated system OpenClaw processes.
Tokens and provider credentials
Do not commit live tokens here. Do not put Telegram bot tokens, Telegram webhook secrets, OpenAI-compatible API keys, OAuth tokens, bearer strings, or provider-native session handles in this repo, .gitmodules, provider config, prompts, logs, workflow evidence, or README examples.
The current component boundary is:
agent-keyringowns credential records, rotation, revocation, leases, and redacted inspection.agent-core-systemowns admission and executable envelopes.agent-telegramandagent-llmconsume only admitted mediated authority-use facts; they must not read raw live tokens from ambient environment as steady-state authority.
For local development, keep bootstrap/import material in ignored local files only. Prefer the wizard:
scripts/agent-system configure
If scripting, keep non-secrets and secrets separate:
scripts/agent-system config set openai.base_url https://api.openai.com/v1
scripts/agent-system config set openai.model replace-with-model
scripts/agent-system secret set OPENAI_COMPATIBLE_API_KEY
When keyring enrollment/import tooling is available, import those values into agent-keyring as credential records, then delete or rotate the bootstrap file. The intended mappings are:
TELEGRAM_BOT_TOKEN -> credential/provider_token, use_kind=telegram_bot_api_request
TELEGRAM_WEBHOOK_SECRET -> credential/webhook_secret, use_kind=telegram_webhook_secret_verify
OPENAI_COMPATIBLE_API_KEY -> credential/api_key or provider_token, use_kind=llm_api_key
OPENAI_OAUTH_ACCESS_TOKEN -> credential/access_token, use_kind=llm_oauth_token
OPENAI_OAUTH_REFRESH_TOKEN -> credential/refresh_token, use_kind=token_refresh
OPENAI_COMPATIBLE_BASE_URL -> non-secret provider/account metadata
OPENAI_COMPATIBLE_MODEL -> non-secret model selection metadata
The LLM credential authority contract now admits mediated llm_api_key, llm_oauth_token, and token_refresh facts for llm.plan; agent-llm routes refresh-token facts through the credential mediator as refresh actions. Bootstrap/import tooling is still separate. Until a local secret has been imported and admitted by core/keyring, live Telegram/LLM provider calls should fail closed or use deterministic fake providers. That is correct. Do not bypass it by teaching providers to scrape raw environment variables.
Notes
- Do not treat this repo as authority to bypass component review gates.
- Component commits are pinned by submodule SHA.
- Update a component by updating that component repo, verifying it, then committing the new submodule pointer here.