-
Notifications
You must be signed in to change notification settings - Fork 157
Expand file tree
/
Copy pathconfig.toml.example
More file actions
262 lines (236 loc) · 13.2 KB
/
Copy pathconfig.toml.example
File metadata and controls
262 lines (236 loc) · 13.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# Enable one or more adapters. At least one [discord] or [slack] section is required.
[discord]
bot_token = "${DISCORD_BOT_TOKEN}"
# allow_all_channels = true # true = allow all channels; false = only allowed_channels
# # omitted = auto-detect from list (non-empty → false, empty → true)
allowed_channels = ["1234567890"] # ↑ omitted + non-empty list → auto-detected as false
# allow_all_users = true # true = any user; false = only allowed_users
# # omitted = auto-detect from list (non-empty → false, empty → true)
# allowed_users = ["<YOUR_DISCORD_USER_ID>"] # ↑ omitted + empty/absent list → auto-detected as true
# allow_bot_messages = "off" # "off" (default) | "mentions" | "all"
# "mentions" is recommended for multi-agent collaboration
# trusted_bot_ids = [] # empty = any bot (mode permitting); set to restrict
# allowed_role_ids = [] # role IDs that trigger the bot (same as direct @mention)
# note: if multiple bots share the same role, all will respond simultaneously
# allow_user_messages = "multibot-mentions" # "multibot-mentions" (default) | "involved" | "mentions"
# "involved" = reply in threads bot owns or has participated in
# "mentions" = always require @mention
# allow_dm = false # true = respond to Discord DMs; false (default) = ignore DMs
# allowed_users still applies in DMs
# [slack]
# bot_token = "${SLACK_BOT_TOKEN}" # Bot User OAuth Token (xoxb-...)
# app_token = "${SLACK_APP_TOKEN}" # App-Level Token (xapp-...) for Socket Mode
# allow_all_channels = true # true (default) = allow all channels; false = only allowed_channels
# allowed_channels = ["C0123456789"] # only checked when allow_all_channels = false
# allow_all_users = true # true (default) = any user; false = only allowed_users
# allowed_users = ["U0123456789"] # only checked when allow_all_users = false
# allow_bot_messages = "off" # "off" (default) | "mentions" | "all"
# trusted_bot_ids = [] # empty = any bot (mode permitting); set to restrict
# allow_user_messages = "multibot-mentions" # "multibot-mentions" (default) | "involved" | "mentions"
# "involved" = reply in threads bot has participated in
# "mentions" = always require @mention
# "multibot-mentions" = like "involved", but require @mention
# once another bot has posted in the thread
# max_bot_turns = 100 # soft cap on consecutive bot turns per thread (human msg resets)
# assistant_mode = true # default true: native streaming (chat.startStream) +
# # assistant.threads.setStatus status line instead of
# # post+edit + emoji reactions. Requires the Slack app to be
# # an AI app with the `assistant:write` scope (plus chat:write).
# # Set false for non-AI Slack apps to keep emoji reactions.
# streaming = true # default true: stream the reply live (native or post+edit).
# # Set false to always post a single final message (send-once),
# # regardless of assistant_mode — useful in multi-agent threads
# # to avoid streamed-edit states re-firing app_mention.
# # What a send-once message *contains* is controlled by [reactions] narration_display.
# [gateway]
# url = "ws://openab-gateway:8080/ws" # WebSocket URL of the custom gateway
# platform = "line" # "telegram" (default) | "line" | "googlechat"
# token = "${GATEWAY_TOKEN}" # shared token for WebSocket auth (optional but recommended)
# bot_username = "my_bot" # for @mention gating in groups
# allow_all_channels = true # true = allow all channels; false = only allowed_channels
# # omitted = auto-detect from list (non-empty → false, empty → true)
# allowed_channels = ["C1234"] # only checked when allow_all_channels = false
# allow_all_users = true # true = any user; false = only allowed_users
# # omitted = auto-detect from list (non-empty → false, empty → true)
# allowed_users = ["U5678"] # only checked when allow_all_users = false
# streaming = true # enable streaming (typewriter) mode
# streaming_placeholder = false # set false for draft-based platforms (e.g. Telegram Rich Messages)
# --- AgentCore Runtime (alternative to [agent]) ---
# When [agentcore] is set and [agent].command is not explicitly provided,
# OAB auto-spawns the bundled agentcore-acp adapter. No manual wiring needed.
# Region is auto-extracted from the ARN.
# [agentcore]
# runtime_arn = "arn:aws:bedrock-agentcore:us-east-1:123456789012:runtime/my-agent"
# cancel_strategy = "stop" # "stop" (default) or "noop"
[agent]
command = "kiro-cli"
args = ["acp", "--trust-all-tools"]
working_dir = "/home/agent"
# [agent]
# command = "claude-agent-acp"
# args = []
# working_dir = "/home/node"
# # Auth: kubectl exec -it deploy/openab-claude -- claude auth login
# # (credentials persist in HOME PVC across restarts; see docs/claude-code.md)
# ⚠️ SECURITY WARNING: Any env var listed here is accessible to the agent.
# A user could trick the agent into leaking these values via prompt injection.
# All supported backends support OAuth login — prefer that over env var API keys.
# Note: env vars here can override baseline vars (HOME, PATH, USER) if needed.
# env = {}
#
# By default, the agent subprocess only inherits these baseline vars:
# Linux/macOS: HOME, PATH, USER
# Windows: USERPROFILE, USERNAME, PATH, SystemRoot, SystemDrive
#
# To pass additional env vars from the OAB process (e.g. vars injected via K8s envFrom),
# list them in inherit_env. Keys in [agent].env take precedence over inherited ones.
# inherit_env = ["API_BASE_URL", "MODEL_NAME"]
# [agent]
# command = "codex"
# args = ["--acp"]
# working_dir = "/home/node"
# env = { OPENAI_API_KEY = "${OPENAI_API_KEY}" }
# [agent]
# command = "gemini"
# args = ["--acp"]
# working_dir = "/home/node"
# env = { GEMINI_API_KEY = "${GEMINI_API_KEY}" }
# [agent]
# command = "copilot"
# args = ["--acp", "--stdio"]
# working_dir = "/home/node"
# env = {} # Auth via: kubectl exec -it <pod> -- gh auth login -p https -w
# [agent]
# command = "opencode"
# args = ["acp"]
# working_dir = "/home/node"
# # Note: opencode handles tool authorization internally and never emits
# # session/request_permission — all tools run without user confirmation,
# # equivalent to --trust-all-tools on other backends.
# # Run `opencode auth login` once before starting openab.
# [agent]
# command = "mimo"
# args = ["acp"]
# working_dir = "/home/node"
# # MiMo-Code (Xiaomi fork of OpenCode) with persistent memory, subagents,
# # and MiMo Auto (free channel). Same ACP protocol as OpenCode.
# # Install: npm install -g @mimo-ai/cli
# # Auth: kubectl exec -it <pod> -- mimo auth login
# [agent]
# command = "cursor-agent"
# args = ["acp", "--model", "auto", "--workspace", "/home/agent"]
# working_dir = "/home/agent"
# env = {} # Auth via: kubectl exec -it <pod> -- cursor-agent login
# [agent]
# command = "hermes-acp"
# working_dir = "/home/agent"
# # Auth via: kubectl exec -it <pod> -- hermes auth add xai-oauth
# # Supports 30+ providers (xAI Grok OAuth, Anthropic, OpenAI Codex, Gemini, etc.)
# # Provider switching: kubectl exec -it <pod> -- hermes model
# [agent]
# command = "grok"
# args = ["agent", "stdio"]
# working_dir = "/home/agent"
# # Auth options:
# # 1. API key: env = { GROK_CODE_XAI_API_KEY = "${XAI_API_KEY}" }
# # 2. Device-code: kubectl exec -it <pod> -- grok login --device-auth
# # 3. Deployment key: env = { GROK_DEPLOYMENT_KEY = "${GROK_DEPLOYMENT_KEY}" }
# # See docs/grok.md for details.
[pool]
max_sessions = 10
session_ttl_hours = 24
# Hard ceiling (sec) per prompt; see #732. Default: 1800 (30 min).
# prompt_hard_timeout_secs = 1800
# Liveness-check cadence (sec) for the recv loop; see #732. Default: 30.
# liveness_check_secs = 30
[markdown]
tables = "code" # "code" (default) | "bullets" | "off"
# code: wrap tables in fenced code blocks with aligned columns
# bullets: convert each row into bullet points (• Header: Value)
# off: pass through unchanged
# NOTE: ignored on Slack — Slack messages are sent as Block Kit
# `markdown` blocks (and `markdown_text` stream chunks), which
# render Markdown tables (and headings, lists, code fences)
# natively. This setting applies to platforms that cannot render
# tables (Discord and gateway integrations).
[reactions]
enabled = true
remove_after_reply = false
# tool_display = "full" # "full" (default) | "compact" | "none"
# # Controls how tool calls appear in the final message.
# # Applies to both assistant_mode and post+edit mode.
# # Set "none" to hide the tool summary entirely.
# narration_display = false # default false: in send-once mode, deliver ONLY the final
# # answer block (text after the last tool call); inter-tool
# # narration ("let me check… / now reading X") is dropped.
# # Set true to keep the full text. Platform-agnostic (Slack
# # streaming=false, multi-bot threads, gateway). No effect
# # while streaming — streamed text is shown live as produced.
[reactions.emojis]
queued = "👀"
thinking = "🤔"
tool = "🔥"
coding = "👨💻"
web = "⚡"
done = "🆗"
error = "😱"
[reactions.timing]
debounce_ms = 700
stall_soft_ms = 10000
stall_hard_ms = 30000
done_hold_ms = 1500
error_hold_ms = 2500
# --- Emoji reaction mapping ---
# Map emoji reactions to text commands. Reacting with a mapped emoji
# is equivalent to sending the corresponding text message.
# Requires GUILD_MESSAGE_REACTIONS intent enabled in Discord Developer Portal.
# Keys can be unicode emoji or Discord shortcodes (e.g. :thumbsup:).
# [reactions.mapping]
# "👍" = "OK"
# ":thumbsdown:" = "不行"
# ":arrows_counterclockwise:" = "重新 review"
# ":white_check_mark:" = "approve"
# --- Scheduled messages (config-driven cron) ---
# Everything cron-related lives under [cron].
# [cron]
# usercron_enabled = true # enable hot-reload (default: false)
# usercron_path = "cronjob.toml" # relative to $HOME/.openab/, or absolute
# [[cron.jobs]]
# enabled = true # optional, default: true
# schedule = "0 9 * * 1-5" # weekdays at 9:00 AM
# channel = "123456789" # target channel/thread ID
# message = "summarize yesterday's merged PRs" # prompt for the agent
# platform = "discord" # "discord" or "slack"
# sender_name = "DailyOps" # attribution (default: "openab-cron")
# timezone = "America/New_York" # IANA timezone (default: "UTC")
# thread_id = "" # optional: post to existing thread
# [[cron.jobs]]
# schedule = "0 0 * * 0"
# channel = "123456789"
# message = "generate weekly status report"
# Workspace aliases for control directives: [[ws:@alias]]
# Users can specify a workspace when starting a session, e.g.:
# @Bot [[ws:@openab]] help me debug the tests
#
# [workspace.aliases]
# openab = "~/projects/openab"
# infra = "~/projects/infra-cdk"
# web = "~/projects/frontend"
# --- Pre-seed: download & extract S3 zip archives before pre_boot ---
# Seeds the agent environment (configs, tools, memory) before any hook runs.
# Archives are extracted in order — later layers overwrite earlier ones (like container layers).
# Max 5 sources. Only s3:// URIs with .zip format are supported.
# Requires the `pre-seed` feature flag (opt-in).
#
# [hooks.pre_seed]
# sources = [
# "s3://my-bucket/base-env.zip", # Layer 1: base tools & configs
# "s3://my-bucket/shared-memory.zip", # Layer 2: shared team memory
# "s3://my-bucket/agent-specific.zip", # Layer 3: agent-specific overrides
# ]
# target = "/home/agent" # extraction target (default: $HOME)
# max_bytes = 104857600 # max compressed zip size (default: 100 MiB)
# timeout_seconds = 300 # per-source timeout (default: 300)
# on_failure = "abort" # "abort" or "warn" (default: "abort")
# region = "us-west-2" # optional: override AWS region
# endpoint_url = "http://localhost:4566" # optional: LocalStack / VPC endpoint