feat: 重命名项目为Boardware Genius并添加运行时环境同步功能
- 将项目品牌从nanobot重命名为Boardware Genius,更新所有相关文档、注释和日志输出 - 在web服务器中添加运行时环境变量同步功能,支持授权和后端身份配置 - 更新create-instance脚本以生成运行时环境文件 - 添加实例后端绑定功能到部署控制服务 - 修改入口脚本以加载运行时环境变量 - 更新前端和认证门户的相关描述文本
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
# nanobot-backend
|
||||
# Boardware Genius Backend
|
||||
|
||||
基于 `nanobot` 的后端服务仓库,当前重点不是上游通用介绍,而是这套实际可运行的后端能力:
|
||||
这是 `Boardware Genius` 的后端服务仓库;当前技术命令和包名仍沿用 `nanobot`,但产品品牌按 `Boardware Genius` 表述:
|
||||
|
||||
- `nanobot web`:单用户 FastAPI 后端,供独立前端或 `/docs` 调试使用
|
||||
- `nanobot gateway`:常驻 worker,负责渠道接入、cron、heartbeat
|
||||
@ -183,7 +183,7 @@ pip install -e .
|
||||
bw-outlook-mcp --help
|
||||
```
|
||||
|
||||
这样 nanobot 就会直接用 PATH 里的 `bw-outlook-mcp`,不依赖额外挂载路径。
|
||||
这样 Boardware Genius 就会直接用 PATH 里的 `bw-outlook-mcp`,不依赖额外挂载路径。
|
||||
|
||||
#### 方案 B:把 `BW_Outlook_Mcp` 作为外部目录挂进来
|
||||
|
||||
@ -204,7 +204,7 @@ python3 -m venv .venv
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
然后给 nanobot 设置:
|
||||
然后给 Boardware Genius 设置:
|
||||
|
||||
```bash
|
||||
export NANOBOT_OUTLOOK_MCP_ROOT=/srv/BW_Outlook_Mcp
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability in nanobot, please report it by:
|
||||
If you discover a security vulnerability in Boardware Genius, please report it by:
|
||||
|
||||
1. **DO NOT** open a public GitHub issue
|
||||
2. Create a private security advisory on GitHub or contact the repository maintainers (xubinrencs@gmail.com)
|
||||
@ -67,7 +67,7 @@ The `exec` tool can execute shell commands. While dangerous command patterns are
|
||||
- ✅ Review all tool usage in agent logs
|
||||
- ✅ Understand what commands the agent is running
|
||||
- ✅ Use a dedicated user account with limited privileges
|
||||
- ✅ Never run nanobot as root
|
||||
- ✅ Never run Boardware Genius as root
|
||||
- ❌ Don't disable security checks
|
||||
- ❌ Don't run on systems with sensitive data without careful review
|
||||
|
||||
@ -82,7 +82,7 @@ The `exec` tool can execute shell commands. While dangerous command patterns are
|
||||
|
||||
File operations have path traversal protection, but:
|
||||
|
||||
- ✅ Run nanobot with a dedicated user account
|
||||
- ✅ Run Boardware Genius with a dedicated user account
|
||||
- ✅ Use filesystem permissions to protect sensitive directories
|
||||
- ✅ Regularly audit file operations in logs
|
||||
- ❌ Don't give unrestricted access to sensitive files
|
||||
@ -123,7 +123,7 @@ npm audit fix
|
||||
- Keep `litellm` updated to the latest version for security fixes
|
||||
- We've updated `ws` to `>=8.17.1` to fix DoS vulnerability
|
||||
- Run `pip-audit` or `npm audit` regularly
|
||||
- Subscribe to security advisories for nanobot and its dependencies
|
||||
- Subscribe to security advisories for Boardware Genius and its dependencies
|
||||
|
||||
### 7. Production Deployment
|
||||
|
||||
@ -238,7 +238,7 @@ If you suspect a security breach:
|
||||
|
||||
## Security Checklist
|
||||
|
||||
Before deploying nanobot:
|
||||
Before deploying Boardware Genius:
|
||||
|
||||
- [ ] API keys stored securely (not in code)
|
||||
- [ ] Config file permissions set to 0600
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "nanobot-whatsapp-bridge",
|
||||
"version": "0.1.0",
|
||||
"description": "WhatsApp bridge for nanobot using Baileys",
|
||||
"description": "WhatsApp bridge for Boardware Genius using Baileys",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* nanobot WhatsApp Bridge
|
||||
* Boardware Genius WhatsApp Bridge
|
||||
*
|
||||
* This bridge connects WhatsApp Web to nanobot's Python backend
|
||||
* This bridge connects WhatsApp Web to the Boardware Genius Python backend
|
||||
* via WebSocket. It handles authentication, message forwarding,
|
||||
* and reconnection logic.
|
||||
*
|
||||
@ -27,7 +27,7 @@ const PORT = parseInt(process.env.BRIDGE_PORT || '3001', 10);
|
||||
const AUTH_DIR = process.env.AUTH_DIR || join(homedir(), '.nanobot', 'whatsapp-auth');
|
||||
const TOKEN = process.env.BRIDGE_TOKEN || undefined;
|
||||
|
||||
console.log('🐈 nanobot WhatsApp Bridge');
|
||||
console.log('Boardware Genius WhatsApp Bridge');
|
||||
console.log('========================\n');
|
||||
|
||||
const server = new BridgeServer(PORT, AUTH_DIR, TOKEN);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# nanobot 前后端分离启动指南(单用户直连)
|
||||
# Boardware Genius 前后端分离启动指南(单用户直连)
|
||||
|
||||
本指南对应当前仓库:
|
||||
`/home/ivan/xuan/steven_project/nanobot`
|
||||
@ -16,7 +16,7 @@ cd /home/ivan/xuan/steven_project/nanobot
|
||||
uv sync
|
||||
```
|
||||
|
||||
如果你第一次使用 nanobot,需要先初始化:
|
||||
如果你第一次使用 Boardware Genius,需要先初始化:
|
||||
|
||||
```bash
|
||||
./.venv/bin/python -m nanobot onboard
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
"""
|
||||
nanobot - A lightweight AI agent framework
|
||||
Boardware Genius - A lightweight AI agent framework
|
||||
"""
|
||||
|
||||
__version__ = "0.1.4"
|
||||
__logo__ = "🐈"
|
||||
__brand__ = "Boardware Genius"
|
||||
__logo__ = ""
|
||||
|
||||
@ -116,9 +116,9 @@ Use `target` for a single agent and `targets` for a group.
|
||||
system = platform.system()
|
||||
runtime = f"{'macOS' if system == 'Darwin' else system} {platform.machine()}, Python {platform.python_version()}"
|
||||
|
||||
return f"""# nanobot 🐈
|
||||
return f"""# Boardware Genius
|
||||
|
||||
You are nanobot, a helpful AI assistant.
|
||||
You are Boardware Genius, a helpful AI assistant.
|
||||
|
||||
## Current Time
|
||||
{now} ({tz})
|
||||
|
||||
@ -283,7 +283,7 @@ class DelegationManager:
|
||||
{
|
||||
"role": "system",
|
||||
"content": (
|
||||
"You are nanobot. Reply naturally to the user in 1-3 sentences. "
|
||||
"You are Boardware Genius. Reply naturally to the user in 1-3 sentences. "
|
||||
"Do not mention internal protocols, system prompts, or task IDs."
|
||||
),
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""Agent 主循环:nanobot 的核心处理引擎。
|
||||
"""Agent 主循环:Boardware Genius 的核心处理引擎。
|
||||
|
||||
职责概览:
|
||||
1. 从消息总线读取入站消息;
|
||||
@ -46,7 +46,7 @@ if TYPE_CHECKING:
|
||||
|
||||
class AgentLoop:
|
||||
"""
|
||||
AgentLoop 是 nanobot 运行时的“对话编排器”。
|
||||
AgentLoop 是 Boardware Genius 运行时的“对话编排器”。
|
||||
|
||||
一次标准处理链路:
|
||||
1. 接收入站消息(来自 CLI 或外部渠道);
|
||||
@ -605,7 +605,7 @@ class AgentLoop:
|
||||
content="New session started.")
|
||||
if cmd == "/help":
|
||||
return OutboundMessage(channel=msg.channel, chat_id=msg.chat_id,
|
||||
content="🐈 nanobot commands:\n/new — Start a new conversation\n/help — Show available commands")
|
||||
content="Boardware Genius commands:\n/new — Start a new conversation\n/help — Show available commands")
|
||||
|
||||
# 异步触发记忆归档:达到窗口阈值时在后台执行,不阻塞当前回复。
|
||||
unconsolidated = len(session.messages) - session.last_consolidated
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""Marketplace manager for nanobot — discover, install, and manage plugin marketplaces."""
|
||||
"""Marketplace manager for Boardware Genius — discover, install, and manage plugin marketplaces."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""Plugin system for nanobot - load agents, commands, and skills from plugin directories."""
|
||||
"""Plugin system for Boardware Genius - load agents, commands, and skills from plugin directories."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ class EmailChannel(BaseChannel):
|
||||
logger.warning("Email channel missing recipient address")
|
||||
return
|
||||
|
||||
base_subject = self._last_subject_by_chat.get(to_addr, "nanobot reply")
|
||||
base_subject = self._last_subject_by_chat.get(to_addr, "Boardware Genius reply")
|
||||
subject = self._reply_subject(base_subject)
|
||||
if msg.metadata and isinstance(msg.metadata.get("subject"), str):
|
||||
override = msg.metadata["subject"].strip()
|
||||
@ -397,7 +397,7 @@ class EmailChannel(BaseChannel):
|
||||
return html.unescape(text)
|
||||
|
||||
def _reply_subject(self, base_subject: str) -> str:
|
||||
subject = (base_subject or "").strip() or "nanobot reply"
|
||||
subject = (base_subject or "").strip() or "Boardware Genius reply"
|
||||
prefix = self.config.subject_prefix or "Re: "
|
||||
if subject.lower().startswith("re:"):
|
||||
return subject
|
||||
|
||||
@ -287,7 +287,7 @@ class TelegramChannel(BaseChannel):
|
||||
|
||||
user = update.effective_user
|
||||
await update.message.reply_text(
|
||||
f"👋 Hi {user.first_name}! I'm nanobot.\n\n"
|
||||
f"👋 Hi {user.first_name}! I'm Boardware Genius.\n\n"
|
||||
"Send me a message and I'll respond!\n"
|
||||
"Type /help to see available commands."
|
||||
)
|
||||
@ -297,7 +297,7 @@ class TelegramChannel(BaseChannel):
|
||||
if not update.message:
|
||||
return
|
||||
await update.message.reply_text(
|
||||
"🐈 nanobot commands:\n"
|
||||
"Boardware Genius commands:\n"
|
||||
"/new — Start a new conversation\n"
|
||||
"/help — Show available commands"
|
||||
)
|
||||
|
||||
@ -1 +1 @@
|
||||
"""CLI module for nanobot."""
|
||||
"""CLI module for Boardware Genius."""
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""nanobot 命令行入口。
|
||||
"""Boardware Genius 命令行入口。
|
||||
|
||||
本文件职责:
|
||||
1. 定义所有 CLI 命令(onboard / agent / gateway / cron / channels / provider)
|
||||
@ -29,12 +29,12 @@ from prompt_toolkit.formatted_text import HTML
|
||||
from prompt_toolkit.history import FileHistory
|
||||
from prompt_toolkit.patch_stdout import patch_stdout
|
||||
|
||||
from nanobot import __version__, __logo__
|
||||
from nanobot import __brand__, __version__
|
||||
from nanobot.config.schema import Config
|
||||
|
||||
app = typer.Typer(
|
||||
name="nanobot",
|
||||
help=f"{__logo__} nanobot - Personal AI Assistant",
|
||||
help=f"{__brand__} - Personal AI Assistant",
|
||||
no_args_is_help=True,
|
||||
)
|
||||
|
||||
@ -122,7 +122,7 @@ def _print_agent_response(response: str, render_markdown: bool) -> None:
|
||||
content = response or ""
|
||||
body = Markdown(content) if render_markdown else Text(content)
|
||||
console.print()
|
||||
console.print(f"[cyan]{__logo__} nanobot[/cyan]")
|
||||
console.print(f"[cyan]{__brand__}[/cyan]")
|
||||
console.print(body)
|
||||
console.print()
|
||||
|
||||
@ -158,7 +158,7 @@ async def _read_interactive_input_async() -> str:
|
||||
def version_callback(value: bool):
|
||||
"""处理 --version/-v 选项并立即退出。"""
|
||||
if value:
|
||||
console.print(f"{__logo__} nanobot v{__version__}")
|
||||
console.print(f"{__brand__} v{__version__}")
|
||||
raise typer.Exit()
|
||||
|
||||
|
||||
@ -168,7 +168,7 @@ def main(
|
||||
None, "--version", "-v", callback=version_callback, is_eager=True
|
||||
),
|
||||
):
|
||||
"""nanobot - Personal AI Assistant."""
|
||||
"""Boardware Genius - Personal AI Assistant."""
|
||||
pass
|
||||
|
||||
|
||||
@ -179,7 +179,7 @@ def main(
|
||||
|
||||
@app.command()
|
||||
def onboard():
|
||||
"""Initialize nanobot configuration and workspace."""
|
||||
"""Initialize Boardware Genius configuration and workspace."""
|
||||
from nanobot.config.loader import get_config_path, load_config, save_config
|
||||
from nanobot.config.schema import Config
|
||||
from nanobot.utils.helpers import get_workspace_path
|
||||
@ -225,11 +225,11 @@ def onboard():
|
||||
_create_workspace_templates(workspace)
|
||||
|
||||
# 第 5 步:输出下一步操作提示,指导用户继续配置 API Key 并开始对话。
|
||||
console.print(f"\n{__logo__} nanobot is ready!")
|
||||
console.print(f"\n{__brand__} is ready!")
|
||||
console.print("\nNext steps:")
|
||||
console.print(" 1. Add your API key to [cyan]~/.nanobot/config.json[/cyan]")
|
||||
console.print(" Get one at: https://openrouter.ai/keys")
|
||||
console.print(" 2. Chat: [cyan]nanobot agent -m \"Hello!\"[/cyan]")
|
||||
console.print(" 2. Chat with Boardware Genius: [cyan]nanobot agent -m \"Hello!\"[/cyan]")
|
||||
console.print("\n[dim]Want Telegram/WhatsApp? See: https://github.com/HKUDS/nanobot#-chat-apps[/dim]")
|
||||
|
||||
|
||||
@ -324,7 +324,7 @@ def gateway(
|
||||
port: int = typer.Option(18790, "--port", "-p", help="Gateway port"),
|
||||
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
|
||||
):
|
||||
"""启动 nanobot 网关常驻服务。
|
||||
"""启动 Boardware Genius 网关常驻服务。
|
||||
|
||||
这是“生产运行入口”之一,主要职责:
|
||||
1. 初始化配置、总线、模型提供方、会话管理、Agent 主循环;
|
||||
@ -352,7 +352,7 @@ def gateway(
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
console.print(f"{__logo__} Starting nanobot gateway on port {port}...")
|
||||
console.print(f"{__brand__}: starting gateway on port {port}...")
|
||||
|
||||
# 运行时核心对象初始化顺序:
|
||||
# config -> bus -> provider -> sessions -> cron -> agent -> channels -> heartbeat
|
||||
@ -525,7 +525,7 @@ def web(
|
||||
config = load_config()
|
||||
_create_workspace_templates(config.workspace_path)
|
||||
|
||||
console.print(f"{__logo__} Starting nanobot web backend on {host}:{port}...")
|
||||
console.print(f"{__brand__}: starting web backend on {host}:{port}...")
|
||||
web_app = create_app(config=config)
|
||||
uvicorn.run(web_app, host=host, port=port)
|
||||
|
||||
@ -541,7 +541,7 @@ def agent(
|
||||
message: str = typer.Option(None, "--message", "-m", help="Message to send to the agent"),
|
||||
session_id: str = typer.Option("cli:direct", "--session", "-s", help="Session ID"),
|
||||
markdown: bool = typer.Option(True, "--markdown/--no-markdown", help="Render assistant output as Markdown"),
|
||||
logs: bool = typer.Option(False, "--logs/--no-logs", help="Show nanobot runtime logs during chat"),
|
||||
logs: bool = typer.Option(False, "--logs/--no-logs", help="Show Boardware Genius runtime logs during chat"),
|
||||
):
|
||||
"""直接与 agent 交互(单轮模式或交互模式)。
|
||||
|
||||
@ -614,7 +614,7 @@ def agent(
|
||||
# 空上下文:进入/退出都不做事,仅用于统一 with 接口。
|
||||
return nullcontext()
|
||||
# 非日志模式下启用转圈动画,提升等待期间的交互感知。
|
||||
return console.status("[dim]nanobot is thinking...[/dim]", spinner="dots")
|
||||
return console.status(f"[dim]{__brand__} is thinking...[/dim]", spinner="dots")
|
||||
|
||||
async def _cli_progress(content: str, *, tool_hint: bool = False) -> None:
|
||||
"""CLI 进度回调:按 channels 配置过滤后渲染中间态输出。"""
|
||||
@ -643,7 +643,7 @@ def agent(
|
||||
# 初始化 prompt_toolkit 会话(历史记录、编辑能力、粘贴兼容等)。
|
||||
_init_prompt_session()
|
||||
# 打印一次交互模式提示,告知退出方式。
|
||||
console.print(f"{__logo__} Interactive mode (type [bold]exit[/bold] or [bold]Ctrl+C[/bold] to quit)\n")
|
||||
console.print(f"{__brand__} interactive mode (type [bold]exit[/bold] or [bold]Ctrl+C[/bold] to quit)\n")
|
||||
|
||||
# session_id 解析规则:
|
||||
# 1) 传入 "channel:chat_id" 时,显式使用对应渠道与会话;
|
||||
@ -945,7 +945,7 @@ def _get_bridge_dir() -> Path:
|
||||
console.print("Try reinstalling: pip install --force-reinstall nanobot")
|
||||
raise typer.Exit(1)
|
||||
|
||||
console.print(f"{__logo__} Setting up bridge...")
|
||||
console.print(f"{__brand__}: setting up bridge...")
|
||||
|
||||
# 重新复制并构建,确保 bridge 资源与当前版本同步。
|
||||
user_bridge.parent.mkdir(parents=True, exist_ok=True)
|
||||
@ -980,7 +980,7 @@ def channels_login():
|
||||
config = load_config()
|
||||
bridge_dir = _get_bridge_dir()
|
||||
|
||||
console.print(f"{__logo__} Starting bridge...")
|
||||
console.print(f"{__brand__}: starting bridge...")
|
||||
console.print("Scan the QR code to connect.\n")
|
||||
|
||||
# 可选注入 BRIDGE_TOKEN 做 bridge 鉴权。
|
||||
@ -1259,14 +1259,14 @@ def cron_run(
|
||||
|
||||
@app.command()
|
||||
def status():
|
||||
"""展示 nanobot 运行配置与 provider 状态概览。"""
|
||||
"""展示 Boardware Genius 运行配置与 provider 状态概览。"""
|
||||
from nanobot.config.loader import load_config, get_config_path
|
||||
|
||||
config_path = get_config_path()
|
||||
config = load_config()
|
||||
workspace = config.workspace_path
|
||||
|
||||
console.print(f"{__logo__} nanobot Status\n")
|
||||
console.print(f"{__brand__} Status\n")
|
||||
|
||||
console.print(f"Config: {config_path} {'[green]✓[/green]' if config_path.exists() else '[red]✗[/red]'}")
|
||||
console.print(f"Workspace: {workspace} {'[green]✓[/green]' if workspace.exists() else '[red]✗[/red]'}")
|
||||
@ -1346,7 +1346,7 @@ def provider_login(
|
||||
console.print(f"[red]Login not implemented for {spec.label}[/red]")
|
||||
raise typer.Exit(1)
|
||||
|
||||
console.print(f"{__logo__} OAuth Login - {spec.label}\n")
|
||||
console.print(f"{__brand__} OAuth Login - {spec.label}\n")
|
||||
handler()
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""Configuration module for nanobot."""
|
||||
"""Configuration module for Boardware Genius."""
|
||||
|
||||
from nanobot.config.loader import load_config, get_config_path
|
||||
from nanobot.config.schema import Config
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Heartbeat Tasks
|
||||
|
||||
This file is checked every 30 minutes by your nanobot agent.
|
||||
This file is checked every 30 minutes by your Boardware Genius agent.
|
||||
Add tasks below that you want the agent to work on periodically.
|
||||
|
||||
If this file has no tasks (only headers and comments), the agent will skip the heartbeat.
|
||||
@ -13,4 +13,3 @@ If this file has no tasks (only headers and comments), the agent will skip the h
|
||||
## Completed
|
||||
|
||||
<!-- Move completed tasks here or delete them -->
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Soul
|
||||
|
||||
I am nanobot 🐈, a personal AI assistant.
|
||||
I am Boardware Genius, a personal AI assistant.
|
||||
|
||||
## Personality
|
||||
|
||||
|
||||
@ -46,4 +46,4 @@ Information about the user to help personalize interactions.
|
||||
|
||||
---
|
||||
|
||||
*Edit this file to customize nanobot's behavior for your needs.*
|
||||
*Edit this file to customize Boardware Genius behavior for your needs.*
|
||||
|
||||
@ -20,4 +20,4 @@ This file stores important information that should persist across sessions.
|
||||
|
||||
---
|
||||
|
||||
*This file is automatically updated by nanobot when important information should be remembered.*
|
||||
*This file is automatically updated by Boardware Genius when important information should be remembered.*
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""Utility functions for nanobot."""
|
||||
"""Utility functions for Boardware Genius."""
|
||||
|
||||
from nanobot.utils.helpers import (
|
||||
ensure_dir,
|
||||
|
||||
@ -1 +1 @@
|
||||
"""Web interface for nanobot."""
|
||||
"""Web interface for Boardware Genius."""
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""FastAPI web server for nanobot frontend."""
|
||||
"""FastAPI web server for the Boardware Genius frontend."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@ -8,6 +8,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
import secrets
|
||||
import shlex
|
||||
import shutil
|
||||
import time
|
||||
import zipfile
|
||||
@ -676,6 +677,8 @@ def create_app(
|
||||
|
||||
app.state.config = config
|
||||
app.state.config_path = get_config_path()
|
||||
app.state.runtime_env_path = _get_runtime_env_file_path(app.state.config_path)
|
||||
_sync_authz_runtime_env(app.state.config, app.state.runtime_env_path)
|
||||
app.state.session_manager = session_manager
|
||||
app.state.cron_service = cron_service
|
||||
app.state.bus = bus
|
||||
@ -766,6 +769,60 @@ def _get_auth_file_path() -> Path:
|
||||
return Path(__file__).resolve().parents[2] / "web_auth_users.json"
|
||||
|
||||
|
||||
_AUTHZ_RUNTIME_ENV_KEYS = (
|
||||
"NANOBOT_AUTHZ__ENABLED",
|
||||
"NANOBOT_AUTHZ__BASE_URL",
|
||||
"NANOBOT_AUTHZ__OUTLOOK_MCP_URL",
|
||||
"NANOBOT_BACKEND_IDENTITY__BACKEND_ID",
|
||||
"NANOBOT_BACKEND_IDENTITY__CLIENT_ID",
|
||||
"NANOBOT_BACKEND_IDENTITY__CLIENT_SECRET",
|
||||
"NANOBOT_BACKEND_IDENTITY__NAME",
|
||||
"NANOBOT_BACKEND_IDENTITY__PUBLIC_BASE_URL",
|
||||
)
|
||||
|
||||
|
||||
def _get_runtime_env_file_path(config_path: Path | None = None) -> Path:
|
||||
env = os.getenv("NANOBOT_RUNTIME_ENV_FILE", "").strip()
|
||||
if env:
|
||||
return Path(env).expanduser()
|
||||
base_path = config_path or get_config_path()
|
||||
return base_path.parent / "runtime.env"
|
||||
|
||||
|
||||
def _authz_runtime_env_values(config: Config) -> dict[str, str]:
|
||||
return {
|
||||
"NANOBOT_AUTHZ__ENABLED": "1" if config.authz.enabled and config.authz.base_url.strip() else "0",
|
||||
"NANOBOT_AUTHZ__BASE_URL": config.authz.base_url.strip(),
|
||||
"NANOBOT_AUTHZ__OUTLOOK_MCP_URL": config.authz.outlook_mcp_url.strip(),
|
||||
"NANOBOT_BACKEND_IDENTITY__BACKEND_ID": config.backend_identity.backend_id.strip(),
|
||||
"NANOBOT_BACKEND_IDENTITY__CLIENT_ID": config.backend_identity.client_id.strip(),
|
||||
"NANOBOT_BACKEND_IDENTITY__CLIENT_SECRET": config.backend_identity.client_secret.strip(),
|
||||
"NANOBOT_BACKEND_IDENTITY__NAME": config.backend_identity.name.strip(),
|
||||
"NANOBOT_BACKEND_IDENTITY__PUBLIC_BASE_URL": config.backend_identity.public_base_url.strip(),
|
||||
}
|
||||
|
||||
|
||||
def _sync_authz_runtime_env(config: Config, target_path: Path) -> None:
|
||||
values = _authz_runtime_env_values(config)
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
lines: list[str] = []
|
||||
for key in _AUTHZ_RUNTIME_ENV_KEYS:
|
||||
value = values.get(key, "")
|
||||
if value:
|
||||
os.environ[key] = value
|
||||
lines.append(f"export {key}={shlex.quote(value)}")
|
||||
continue
|
||||
if key == "NANOBOT_AUTHZ__ENABLED":
|
||||
os.environ[key] = "0"
|
||||
lines.append("export NANOBOT_AUTHZ__ENABLED=0")
|
||||
continue
|
||||
os.environ.pop(key, None)
|
||||
lines.append(f"unset {key}")
|
||||
|
||||
target_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def _load_auth_users(path: Path) -> dict[str, str]:
|
||||
"""Load users from local JSON file.
|
||||
|
||||
@ -1129,6 +1186,7 @@ def _register_routes(app: FastAPI) -> None:
|
||||
if authz_enabled:
|
||||
config.authz.enabled = True
|
||||
_save_app_config(config)
|
||||
_sync_authz_runtime_env(config, app.state.runtime_env_path)
|
||||
return _local_backend_view(config)
|
||||
|
||||
def _authz_client(config: Config):
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# nanobot Workflow
|
||||
# Boardware Genius Workflow
|
||||
|
||||
本文按当前仓库代码,整理 nanobot 的主要运行链路,重点说明:
|
||||
本文按当前仓库代码,整理 Boardware Genius 的主要运行链路。下文的技术命令名仍沿用 `nanobot`,重点说明:
|
||||
|
||||
1. 用户执行 `nanobot agent -m "你好"` 时,CLI 单轮模式到底走了什么路径。
|
||||
2. `nanobot gateway` 常驻模式下,外部渠道、cron、heartbeat 如何进入同一套工作流。
|
||||
@ -106,7 +106,7 @@
|
||||
│ │ └─ NO -> return OutboundMessage(final_content)
|
||||
│
|
||||
├─ process_direct() 拿到 OutboundMessage.content
|
||||
├─ console.print("🐈 ...")
|
||||
├─ console.print("Boardware Genius ...")
|
||||
└─ await agent_loop.close_mcp() -> 程序退出
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user