# MAESTRO 設定ファイル (v2 layout) # # このファイルを config.yaml にコピーして編集してください: # cp config.yaml.example config.yaml # # ─── v2 への移行 (v1 → v2) ───────────────────────────────────── # 旧構造 (provider.* / 平置きの worktree_dir 等) は 1 リリース分だけ # 読み取り互換が残っています。手元の config.yaml が旧形式の場合は: # # scripts/migrate-config.sh --dry-run # 変換後を確認 # scripts/migrate-config.sh # in-place で書き換え (.bak を自動保存) # # v3.0 で v1 形式は起動 fatal になる予定です。 # v2 schema バージョン (必須)。 # - 2 : このリリースの正規形 (= 本ファイル) # - 1 / 未指定 : v1 互換読み取り + 起動 warning # - その他 : 起動 fatal (typo / 未来形式の混入防止) config_version: 2 # ─── LLM ───────────────────────────────────────────────────── # ジョブ実行時に LLM 呼び出し先として使う接続群と、retry / timeout / metrics。 llm: timeout_minutes: 10 # 1 リクエスト全体の上限 (分)。default 10 retry: max_attempts: 3 backoff_ms: [2000, 5000, 15000] # 429 / 5xx / 一時的接続失敗時の待機 ms retryable_status: [429, 500, 502, 503, 504] # workers[] — この AAO がジョブ実行時に呼ぶ接続先。 # # connection_type: # direct — Ollama / llama.cpp / vLLM 等の OpenAI 互換 backend に直接接続 # aao_gateway — 別 AAO Gateway 経由で接続 (Gateway Key 必須) # # トップレベル `gateway.*` (この AAO 自身が gateway として動く設定) と # 単語衝突を避けるため、worker 側は `aao_gateway` と prefix 付き。 # # model はワーカーごとに明示。`default_model` は廃止された。 # roles: 用途別 (auto / fast / quality / title / reflection 等) のフィルタ。 # max_concurrency: 1ワーカーが同時実行するジョブ数 (A1スロット方式)。デフォルト1。 # >1 はオプトイン。注意: shutdown drain は粗く、fairness は低下し、 # LLM provider 側の rate limit は別途。browser を使うワーカーで >1 にする場合は # セッション作成は mutex 済みだが本番投入前に dogfooding すること。 # vlm: true で画像入力に対応 (ReadImage は VLM ワーカーを優先)。 workers: - id: local-ollama connection_type: direct endpoint: http://localhost:11434/v1 model: qwen3:32b roles: [auto, fast, quality] max_concurrency: 1 enabled: true vlm: false # 例: 別 AAO Gateway 越しに共有 GPU プールを使う # - id: team-gateway # connection_type: aao_gateway # endpoint: http://gateway.example.com:9876/v1 # api_key: ${TEAM_AAO_GATEWAY_KEY} # gateway 発行の sk-aao-*** virtual key # model: qwen3:32b # roles: [quality] # max_concurrency: 2 # enabled: true # 例: タイトル生成専用ワーカー (chat ジョブは受け付けない) # - id: title-worker # connection_type: direct # endpoint: http://localhost:11434/v1 # model: qwen3:8b # roles: [title] # max_concurrency: 4 # enabled: true # 例: Reflection 専用ワーカー (cheap モデルで memory 更新を回す) # - id: reflector # connection_type: direct # endpoint: http://localhost:11434/v1 # model: qwen3:8b # roles: [reflection] # max_concurrency: 1 # enabled: true # Prometheus exporter (worker side). default で enabled。 # /metrics が bridge HTTP server (PORT, default 9876) に mount される。 # access control: default では localhost (127.0.0.1 / ::1) のみ通る。 # 本番では (a) bearer_token を設定するか、(b) allowed_hosts で前段 IP を許可。 # env: AAO_WORKER_METRICS_BEARER_TOKEN / AAO_WORKER_METRICS_ALLOWED_HOSTS (CSV) でも上書き可。 metrics: enabled: true prefix: aao_worker # /^[a-z][a-z0-9_]*$/ # bearer_token: env:AAO_WORKER_METRICS_BEARER_TOKEN # allowed_hosts: # - 127.0.0.1 # - ::1 # - localhost # # - 0.0.0.0 # 全許可。前段で firewall を必ず使う運用前提 # ─── AAO Gateway Server ────────────────────────────────────── # この AAO 自身を OpenAI 互換 LLM Gateway として公開する設定。 # 有効化すると `/v1/chat/completions` などが同 process で立ち上がる。 # # Virtual Keys (sk-aao-*** 形式) は **admin REST API での発行を推奨**: # POST /api/admin/gateway/keys # config.yaml の virtual_keys[] は bootstrap / backup 用途のみで、 # DB に自動 import される (source='config-import')。rotation は admin API 経由でのみ。 # # 同 process / separate process の deploy 方法は docs/aao-gateway-overview.md を参照。 # UI からは Settings → LLM → Gateway Server で全て編集可能。 # gateway: # enabled: false # true で同 process gateway が即時起動 # # (ConfigManager hot reload 対応、再起動不要) # listen_port: 4000 # separate-deploy 時のみ有効 (default LiteLLM 互換) # request_timeout_sec: 600 # 1 リクエスト全体 (streaming 込み) # upstream_timeout_sec: 30 # 各 upstream fetch の TTFB 上限 # shutdown_graceful_sec: 30 # SIGTERM 後、in-flight SSE の drain 上限秒 # # backends: # # role ベース routing: worker はジョブの role (auto/fast/quality/reflection) # # を routing key として送り、Gateway はその role を担う最も空いている # # backend に振る。異なる model 名の GPU でも同じ role でまとめられる。 # # roles 未指定の backend は全 role を担当 (アップグレード後も従来どおり動く)。 # - id: gpu-a # `x-aao-backend-id` に出る ID # endpoint: http://gpu-a:11434/v1 # model: qwen3:32b # backend が積むモデル (role が無い時の fallback 一致キー) # roles: [quality] # この backend は quality ティア専用 # max_slots: 2 # llama-server -np と合わせる # api_key: ${GPU_A_API_KEY} # backend が bearer 必須な場合のみ # - id: gpu-b # endpoint: http://gpu-b:11434/v1 # model: qwen3:8b # 別 GPU は別モデルでも OK # roles: [fast, auto] # fast/auto ティアを担当 # max_slots: 2 # # # Bootstrap / Backup 専用 virtual_keys (新規発行は admin API 経由を推奨)。 # # virtual_keys: # # - key: ${TEAM_ALPHA_KEY} # 起動時に DB へ idempotent import # # team: alpha # # allowed_models: [qwen3:32b] # # # tokens_budget: 1000000 # 月次 token 上限 (UTC 月初に reset) # # # rate_limit_rpm: 60 # 1 分あたり最大リクエスト数 # # # Prometheus exporter (gateway side)。default enabled。 # # team / key_prefix / backend ラベルが出るので auth 必須運用 (default localhost のみ)。 # # env: AAO_GATEWAY_METRICS_BEARER_TOKEN / AAO_GATEWAY_METRICS_ALLOWED_HOSTS (CSV) で上書き可。 # # metrics: # # enabled: true # # prefix: aao_gateway # # bearer_token: env:AAO_GATEWAY_METRICS_BEARER_TOKEN # # allowed_hosts: # # - 127.0.0.1 # # - ::1 # # # - 0.0.0.0 # 前段 firewall 必須 # ─── Storage / Paths ───────────────────────────────────────── # 旧 worktree_dir / custom_pieces_dir / user_folder_root / # tools.task_upload_max_size_mb / tools.trash_retention_days # は normalizer により storage.* に集約された。 storage: worktree_dir: ./data/workspaces # ジョブ実行時の作業ディレクトリのベース # custom_pieces_dir: ./custom-pieces # リポジトリ内の pieces/ に加えて読みに行く Piece dir (任意) user_folder_root: ./data/users # {root}/{userId}/ 配下に AGENTS.md/scripts/notes 等を保存 task_upload_max_size_mb: 50 # /api/local/tasks と /comments の body 上限 (MB) # base64 で乗るので実ファイル目安は値 × 0.75。範囲 [1, 1000] trash_retention_days: 30 # data/users/{userId}/trash/ の自動 sweep (起動時 + 24h 周期) # 0 で sweep 毎に全削除 # ─── Execution ─────────────────────────────────────────────── # ジョブ全体の並列度・movement 上限・ジョブ retry。 concurrency: 4 # 全 worker 合算の最大並列ジョブ数 (env: CONCURRENCY) max_movements: 200 # 1 ジョブ内の最大 movement 数 (loop 防止) retry: max_attempts: 3 # ジョブ失敗時の最大再試行回数 backoff_seconds: [60, 300, 900] # 各 attempt 間の待機秒 # ASK (ユーザーへの質問) 制御 ask: max_per_job: 2 # 1 Job あたりの ASK 上限 # Subtask 制御 subtasks: max_depth: 2 # SpawnSubTask のネスト最大深度 max_per_parent: 10 # 1 ジョブが生成できるサブタスクの最大数 # ─── Context (LLM コンテキスト管理) ─────────────────────────── # context: # limit_tokens: 128000 # 省略時は Ollama API で自動取得、それも失敗なら 128000 # thresholds: # - ratio: 0.7 # action: warn # - ratio: 0.85 # action: prompt # - ratio: 0.95 # action: force_transition # ─── Safety (エージェント自爆防止) ──────────────────────────── # safety: # max_iterations: 200 # 1 movement 内の最大イテレーション # max_revisits: 3 # 同一 movement の最大再訪問 # max_tool_loop_repeats: 5 # 全く同じツール呼び出し(名前+引数)を連続で繰り返した回数がこの値に達したらループとみなし強制中断 (2以上) # prompt_guard_ratio: 0.8 # コンテキスト上限の何 % まで prompt を許容するか (0.5–0.95) # history_summarization: # 古い turn を構造化要約に置換して粘る (Opencode 方式) # enabled: true # default true # tail_turns: 2 # 末尾何 turn を必ず保護するか # preserve_recent_budget: 8000 # 末尾保護の最大トークン数 # bash_unrestricted: false # true: コマンドホワイトリストを撤廃し任意コマンド実行可。 # # 代わりに bwrap サンドボックスで workspace 単位の # # ファイルシステム隔離を強制 (タスク間の横断アクセス防止)。 # # 前提: コンテナで user namespace が有効 (nesting=1)。 # # 起動時に bwrap の動作確認を行い、失敗時はエラー終了。 # # Bash サンドボックス機構: # # auto (既定) bwrap があれば sandbox、無ければ hardened-whitelist にフォールバック # # always sandbox を強制。bwrap 不在なら起動失敗(本番推奨) # # off bwrap を使わない(env スクラブは維持)。デバッグ用、非推奨 # bash_sandbox: auto # bash_allow_network: false # true: サンドボックスで host network を許可 # # (--unshare-net を外す)。pip/npm install/curl 等が # # 可能になる。⚠ 隔離が弱まり情報漏えい/SSRF のリスク。 # # 既定 false (ネット遮断)。sandboxed 時のみ有効。 # ─── Search Filter (WebSearch の機密情報漏洩防止) ───────────── # search_filter: # blocked_patterns: # カスタムブロックパターン (完全一致で除去) # - secret-project # - internal-codename # auto_block: # 自動検出 (default: 全 true) # private_ip: true # 10.* / 172.16-31.* / 192.168.* / 127.* # internal_domain: true # .local / .internal / .lan / .intranet / .corp / .home # email: true # phone: true # 日本の電話番号 # ─── Browser Runtime (BrowseWeb / BrowserAction) ────────────── # browser: # page_timeout: 60000 # ms # action_timeout: 30000 # ms # display_mode: novnc # 'headless' (default) / 'novnc' # # novnc = Browser タブのライブ表示 / InteractiveBrowse / # # CAPTCHA 解決を有効化 (ホストに Xvfb/x11vnc/websockify 必須)。 # # 旧 'captcha_solve' は自動で display_mode に移行される (非推奨)。 # max_captcha_pages: 5 # CAPTCHA Pool の同時ページ上限 (display_mode: novnc 時のみ) # channel: chrome # 'chromium' (default) / 'chrome' / 'msedge' # executable_path: /usr/bin/google-chrome # channel と排他 # ─── Tools (Web & Search / Media / External / Legacy) ──────── # UI 上は 5 カテゴリに分かれて編集可能 (Web & Search / Browser Runtime / # Media & Documents / External Services / Legacy Knowledge)。YAML は # 互換のため `tools` 1 ブロックで管理。 tools: # Web & Search searxng_url: http://localhost:8080 # WebSearch フォールバック先 (通常は Playwright + Google) webfetch_timeout: 30 # WebFetch / DownloadFile timeout (sec) # websearch_timeout: 15 # webfetch_allowed_hosts: # SSRF 例外 (private IP / .local 等を許可する場合) # - my-internal-host.local # Media & Documents # vision_model: qwen2-vl:8b-instruct # ReadImage 用 VLM (provider と別エンドポイントなら vision_base_url) # vision_base_url: http://localhost:11434/v1 # vision_timeout: 60 # vision_max_tokens: 1024 # ocr_model: glm-ocr # OCR 用モデル (vision_base_url の server に問い合わせる) # office_excel_max_size_mb: 10 # ReadExcel 上限 (default 10) # office_docx_max_size_mb: 10 # ReadDocx 上限 # office_pdf_max_size_mb: 10 # ReadPdf 上限 # office_pptx_max_size_mb: 50 # ReadPPTX 上限 # office_pptx_max_uncompressed_mb: 200 # PPTX ZIP 展開後上限 (zip-bomb 検知) # speech_server_url: http://localhost:8000/v1 # speech_timeout: 300 # speech_language: ja # External Services # x_cli_command: ["twitter"] # twitter-cli 実行コマンド # x_timeout: 90 # x_auth_token: "..." # 任意: auth_token cookie # x_ct0: "..." # 任意: ct0 cookie # x_proxy: http://127.0.0.1:7890 # 任意: twitter-cli 用 proxy # x_chrome_profile: "Profile 2" # Chrome cookie 抽出 profile # x_download_media: auto # 'auto' (default) / 'never' # x_download_video: thumbnail # 'thumbnail' (default) / 'full' / 'never' # x_media_max_mb: 25 # x_media_fetch_timeout_seconds: 15 # google_maps_api_key: "..." # 未設定なら Nominatim / OSRM # maps_timeout: 30 # amazon_affiliate_tag: "your-tag-22" # keepa_api_key: "..." # User scripts (RunUserScript) # user_scripts_enabled: false # true で許可。plain runtime は Node --permission で sandbox 化 # user_scripts_allow_userids: # 未指定 = 全ユーザー許可 (user_scripts_enabled に従う) # - alice-id # - bob-id # Legacy Knowledge (DKS) — 新規 namespace 追加は MCP 経由を推奨 # knowledge_service_url: http://dks-server:8100 # 未設定で knowledge ツール無効 # knowledge_namespaces: # product-a-support: # api_key: "sk-product-a-xxx" # contract-review: # api_key: "sk-contract-yyy" # ── Shared Knowledge Notes ─────────────────────────────────── # data/users/{userId}/notes/ のノートをシステムプロンプトに自動注入する設定。 # notes: # inject: # per_note_max_kb: 8 # 日本語コンテンツは 4 推奨 # total_max_kb: 32 # over_budget_strategy: skip_remaining # truncate_last / skip_remaining (default) / degrade_to_search # ─── 認証 (オプション) ──────────────────────────────────────── # 未設定なら認証なしで動作 (従来互換)。 # auth: # session_secret: "ランダムな文字列を設定してください" # session_max_age: 86400000 # 24h (ms) # secure_cookie: false # HTTPS 環境では true # admin_emails: # - "admin@example.com" # # primary_provider: gitea # 'google' | 'gitea' | 'local'。複数有効時に明示 # providers: # google: # client_id: "" # client_secret: "" # callback_url: "http://localhost:3000/auth/google/callback" # gitea: # client_id: "" # client_secret: "" # base_url: "https://gitea.example.com" # callback_url: "http://localhost:3000/auth/gitea/callback" # # ローカルアカウント (email + password)。OAuth を立てずにパスワード保護したい時。 # # 既存の no-auth デプロイに後付け可: 起動時に bootstrap_admin を id='local' で冪等 seed し、 # # no-auth 時代に 'local' 所有で溜まったデータをそのまま admin が引き継ぐ。 # local: # enabled: true # allow_signup: false # true でセルフ登録 (status=pending → admin 承認) # bootstrap_admin: # 初回 admin (id='local')。seed 後は Settings/CLI で変更 # email: "admin@example.com" # password: "強いパスワードを設定" # 平文保存される。初回ログイン後に変更推奨 # ─── Branding (オプション) ──────────────────────────────────── # config.yaml / data/branding/ は .gitignore 済みで git pull 影響なし。 # Settings → System → Branding で GUI 編集可 (admin)。 # branding: # app_name: "My Team AI" # primary_color: "#2563eb" # login_page_title: "My Team AI" # logo_url: "/branding/logo-abc123.svg" # favicon_url: "/branding/favicon-def456.png" # footer_text: "© 2026 Your Team" # ─── Secrets ───────────────────────────────────────────────── # secrets: # master_key_path: ./data/secrets/master.key # 32-byte key, auto-generated on first start (mode 0600) # ─── Reflection ("Hermes" mode) ────────────────────────────── # default OFF。ON にすると毎ジョブ完了後に user memory を LLM が自動更新する。 # snapshot は data/users/{userId}/.reflection-history/ に残り UI から revert 可。 # reflection: # enabled: false # max_memory_changes_per_job: 3 # piece_edit_cooldown_hours: 24 # snapshot_retention_days: 90 # per_user_daily_budget_tokens: 200000 # ─── MCP (Model Context Protocol) ──────────────────────────── # Individual servers は admin UI (global) または各ユーザー (self-hosted) で管理。 # MCP_ENCRYPTION_KEY env (64 hex chars) が必須。 # mcp: # call_timeout_seconds: 60 # max_binary_size_mb: 20 # max_output_files_per_job: 10 # max_output_size_mb_per_job: 200 # tool_cache_ttl_seconds: 600 # oauth_pending_ttl_minutes: 10 # # allow_private_addresses: false # 自前 MCP server を private 網に置く場合 true # ─── SSH (off by default) ──────────────────────────────────── # 有効化手順は docs/ssh.md / config.yaml.example のコメント (旧版) を参照。 # Operator runbook: docs/ssh.md # Sample piece: pieces/ssh-ops.yaml # # ssh: # enabled: false # # # allow_private_addresses: false # global default。admin は per-connection で grant 可 # # call_timeout_seconds: 30 # # max_output_bytes: 32768 # # max_upload_size_mb: 100 # # max_download_size_mb: 100 # # audit_retention_days: 90 # # admin_bypasses_grants: true # # abuse_window_minutes: 10 # # abuse_failure_threshold: 5 # # abuse_lock_minutes: 30 # # # ── Interactive SSH Console (live PTY-backed shell) ── # console: # enabled: false # true で SshConsole* tools + UI Terminal タブを公開 # idle_timeout_seconds: 1800 # 30min I/O-less = auto close # max_session_duration_seconds: 14400 # 4h hard cap # scrollback_bytes: 524288 # 512KB scrollback / session # max_sessions_per_connection: 3 # max_input_bytes_per_send: 16384 # auto_inject_screen_lines: 24 # default_cols: 120 # default_rows: 32 # ── Browser Notifications V2 (Web Push) ─────────────────────────────── # Requires HTTPS hosting + (for iOS) PWA installation on the client side. # notifications: # push: # enabled: false # true で V2 を有効化 # vapid_subject: "https://maestro.example.com/" # RFC 8292 — operations URL preferred # vapid_current_path: "./data/secrets/vapid.json" # 自動生成 (mode 0600) # vapid_history_dir: "./data/secrets/vapid-history" # payload_max_bytes: 3072 # JSON byte length cap (上限 4096) # queue_concurrency: 8 # per_send_timeout_ms: 10000 # # 起動時に vapid_current_path に鍵が無ければ自動生成、mode 0600 で保存。 # 鍵をローテーションする場合: npm run vapid-rotate