dong-ai 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. dong_ai-0.1.0/LICENSE +21 -0
  2. dong_ai-0.1.0/PKG-INFO +145 -0
  3. dong_ai-0.1.0/README.md +124 -0
  4. dong_ai-0.1.0/pyproject.toml +34 -0
  5. dong_ai-0.1.0/setup.cfg +4 -0
  6. dong_ai-0.1.0/src/dong_ai/__init__.py +34 -0
  7. dong_ai-0.1.0/src/dong_ai/api.py +255 -0
  8. dong_ai-0.1.0/src/dong_ai/browser_tool.py +99 -0
  9. dong_ai-0.1.0/src/dong_ai/ceo.py +416 -0
  10. dong_ai-0.1.0/src/dong_ai/ceo_memory.py +279 -0
  11. dong_ai-0.1.0/src/dong_ai/cli.py +370 -0
  12. dong_ai-0.1.0/src/dong_ai/codegraph_bridge.py +78 -0
  13. dong_ai-0.1.0/src/dong_ai/cron.py +141 -0
  14. dong_ai-0.1.0/src/dong_ai/datastore.py +376 -0
  15. dong_ai-0.1.0/src/dong_ai/design_engine.py +133 -0
  16. dong_ai-0.1.0/src/dong_ai/display.py +135 -0
  17. dong_ai-0.1.0/src/dong_ai/llm.py +145 -0
  18. dong_ai-0.1.0/src/dong_ai/logger.py +79 -0
  19. dong_ai-0.1.0/src/dong_ai/mcp_client.py +182 -0
  20. dong_ai-0.1.0/src/dong_ai/memory.py +364 -0
  21. dong_ai-0.1.0/src/dong_ai/model_pool.py +336 -0
  22. dong_ai-0.1.0/src/dong_ai/tool_executor.py +148 -0
  23. dong_ai-0.1.0/src/dong_ai/tui.py +390 -0
  24. dong_ai-0.1.0/src/dong_ai/web_search.py +35 -0
  25. dong_ai-0.1.0/src/dong_ai/worker.py +520 -0
  26. dong_ai-0.1.0/src/dong_ai.egg-info/PKG-INFO +145 -0
  27. dong_ai-0.1.0/src/dong_ai.egg-info/SOURCES.txt +33 -0
  28. dong_ai-0.1.0/src/dong_ai.egg-info/dependency_links.txt +1 -0
  29. dong_ai-0.1.0/src/dong_ai.egg-info/entry_points.txt +2 -0
  30. dong_ai-0.1.0/src/dong_ai.egg-info/requires.txt +9 -0
  31. dong_ai-0.1.0/src/dong_ai.egg-info/top_level.txt +1 -0
  32. dong_ai-0.1.0/tests/test_ceo_memory.py +234 -0
  33. dong_ai-0.1.0/tests/test_harness.py +395 -0
  34. dong_ai-0.1.0/tests/test_model_pool.py +351 -0
  35. dong_ai-0.1.0/tests/test_worker.py +330 -0
dong_ai-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dong AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
dong_ai-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.4
2
+ Name: dong-ai
3
+ Version: 0.1.0
4
+ Summary: Dong AI Company — 多智能体 AI 公司框架
5
+ Author-email: Dong AI <dong@dong-ai.dev>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/nousresearch/dong-ai
8
+ Project-URL: Source, https://github.com/nousresearch/dong-ai
9
+ Keywords: ai,agent,multi-agent,llm,framework
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Provides-Extra: server
14
+ Requires-Dist: fastapi>=0.110; extra == "server"
15
+ Requires-Dist: uvicorn[standard]>=0.29; extra == "server"
16
+ Provides-Extra: all
17
+ Requires-Dist: fastapi>=0.110; extra == "all"
18
+ Requires-Dist: uvicorn[standard]>=0.29; extra == "all"
19
+ Requires-Dist: ddgs>=0.5; extra == "all"
20
+ Dynamic: license-file
21
+
22
+ # Dong AI Company
23
+
24
+ <div align="center">
25
+
26
+ **您的私人AI公司 — 一个命令拉起一家AI企业**
27
+
28
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://python.org)
29
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
30
+ [![CI](https://img.shields.io/github/actions/workflow/status/Dong04-123/Dong-AI-Company/ci.yml?branch=main&label=CI)](.github/workflows/ci.yml)
31
+ [![Tests](https://img.shields.io/badge/tests-121%20passed-brightgreen)](tests/)
32
+ [![Providers](https://img.shields.io/badge/providers-20%2B-orange)](src/dong_ai/model_pool.py)
33
+ [![Context](https://img.shields.io/badge/context-256K%2B-purple)](#)
34
+
35
+ </div>
36
+
37
+ ```bash
38
+ pip install dong-ai
39
+ dong setup
40
+ ```
41
+
42
+ ---
43
+
44
+ ## 为什么是 AI 公司?
45
+
46
+ 现有 AI Agent 是"工具"——你问它答,最多帮你写代码。
47
+ Dong AI 是**一家公司**——有红蓝辩论决策、有工人池执行、有董事会评分质量门。
48
+
49
+ ```
50
+ 你: "开发配置系统" 工人池 董事会
51
+ │ │ │
52
+ ├─ 红队: 方案A(安全但慢) ├─ 代码匠 → 写文件 ├─ 评分8.5
53
+ ├─ 蓝队: 方案B(快有风险) ├─ 测试判官 → 测试 ├─ 覆盖检查
54
+ └─ CEO: 采纳方案A └─ 审查 → 通过 └─ 放行下一阶段
55
+ ```
56
+
57
+ ## 特性
58
+
59
+ | 能力 | 说明 |
60
+ |------|------|
61
+ | 🏛️ **治理流水线** | 红蓝辩论 → 依赖拆解 → 工人池(自愈+互审) → 董事会评分 → 需求锁 |
62
+ | 🧠 **图记忆** | 精确符号索引 + 依赖关系,新任务自动注入相关上下文 |
63
+ | 🔌 **开放生态** | Hermes 125+ 技能 / MCP 协议 / OpenAI API 兼容 |
64
+ | 🌐 **20+ Provider** | DeepSeek / OpenAI / Claude / Groq / Together / 本地 / Ollama |
65
+ | ⚙️ **双模式** | API 模式(256K 窗口) / 本地模式(64K 窗口) / 用户自由设置 |
66
+ | 🕐 **定时任务** | `dong cron add --cmd "dong run 审计" --every 1h` |
67
+ | 📡 **Webhook** | `POST /webhook` 触发自动审计 |
68
+ | 🔗 **MCP 客户端** | 发现并调用任何 MCP 服务器工具 |
69
+
70
+ ## 快速开始
71
+
72
+ ```bash
73
+ pip install dong-ai
74
+ pip install 'dong-ai[all]' # 全部依赖(含 API 服务)
75
+
76
+ dong setup # 交互式配置向导
77
+ dong chat # 启动对话
78
+ dong run "配置系统" # 一键项目执行
79
+ dong serve # 启动 API 服务 → http://localhost:8648
80
+ ```
81
+
82
+ ### 命令一览
83
+
84
+ ```
85
+ dong chat 交互式 TUI dong config 配置管理
86
+ dong run "需求" 一键项目执行 dong skill 技能管理
87
+ dong serve API 服务 dong session 会话管理
88
+ dong setup 配置向导 dong mcp MCP 工具发现
89
+ dong detect 模型检测 dong cron 定时任务
90
+ dong version 版本信息 dong webhook Webhook 管理
91
+ ```
92
+
93
+ ## 架构
94
+
95
+ ```
96
+ dong chat / dong run / dong serve
97
+
98
+ ┌────┴────┐
99
+ │ CEO │ ← DesignEngine(红蓝辩论) + WorkerPool(自愈+互审)
100
+ └────┬────┘
101
+
102
+ ┌────┴────┐
103
+ │ ModelPool│ ← 20+ Provider 自动 failover
104
+ └────┬────┘
105
+
106
+ ┌────┴────┐
107
+ │ LLMClient│ ← 统一 HTTP + SSE
108
+ └─────────┘
109
+
110
+ 存储层:
111
+ Datastore (SQLite)
112
+ ├── MemoryRepository 事实 KV
113
+ ├── SessionRepository 会话历史
114
+ ├── ProjectRepository 决策/模块
115
+ ├── LoreRepository 世界观
116
+ └── GraphRepository 代码符号/依赖/需求追溯
117
+ ```
118
+
119
+ ## 双模式配置
120
+
121
+ ```
122
+ 模式 CEO 上下文 工人上下文 适用场景
123
+ ─────────────────────────────────────────────────
124
+ API 256K 128K 云端模型(DeepSeek/GPT/Claude)
125
+ Local 64K 64K 本地模型(Qwen/Llama/Ollama)
126
+ 自定义 任意 任意 dong config set ceo_context=999999
127
+ ```
128
+
129
+ ## 测试
130
+
131
+ ```bash
132
+ pip install pytest
133
+ pytest tests/
134
+ # 121 passed in 1.6s
135
+ ```
136
+
137
+ ## 许可证
138
+
139
+ MIT — 随意使用、修改、商用。
140
+
141
+ ---
142
+
143
+ <p align="center">
144
+ <sub>不是聊天工具——是你的 AI 员工团队</sub>
145
+ </p>
@@ -0,0 +1,124 @@
1
+ # Dong AI Company
2
+
3
+ <div align="center">
4
+
5
+ **您的私人AI公司 — 一个命令拉起一家AI企业**
6
+
7
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://python.org)
8
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
9
+ [![CI](https://img.shields.io/github/actions/workflow/status/Dong04-123/Dong-AI-Company/ci.yml?branch=main&label=CI)](.github/workflows/ci.yml)
10
+ [![Tests](https://img.shields.io/badge/tests-121%20passed-brightgreen)](tests/)
11
+ [![Providers](https://img.shields.io/badge/providers-20%2B-orange)](src/dong_ai/model_pool.py)
12
+ [![Context](https://img.shields.io/badge/context-256K%2B-purple)](#)
13
+
14
+ </div>
15
+
16
+ ```bash
17
+ pip install dong-ai
18
+ dong setup
19
+ ```
20
+
21
+ ---
22
+
23
+ ## 为什么是 AI 公司?
24
+
25
+ 现有 AI Agent 是"工具"——你问它答,最多帮你写代码。
26
+ Dong AI 是**一家公司**——有红蓝辩论决策、有工人池执行、有董事会评分质量门。
27
+
28
+ ```
29
+ 你: "开发配置系统" 工人池 董事会
30
+ │ │ │
31
+ ├─ 红队: 方案A(安全但慢) ├─ 代码匠 → 写文件 ├─ 评分8.5
32
+ ├─ 蓝队: 方案B(快有风险) ├─ 测试判官 → 测试 ├─ 覆盖检查
33
+ └─ CEO: 采纳方案A └─ 审查 → 通过 └─ 放行下一阶段
34
+ ```
35
+
36
+ ## 特性
37
+
38
+ | 能力 | 说明 |
39
+ |------|------|
40
+ | 🏛️ **治理流水线** | 红蓝辩论 → 依赖拆解 → 工人池(自愈+互审) → 董事会评分 → 需求锁 |
41
+ | 🧠 **图记忆** | 精确符号索引 + 依赖关系,新任务自动注入相关上下文 |
42
+ | 🔌 **开放生态** | Hermes 125+ 技能 / MCP 协议 / OpenAI API 兼容 |
43
+ | 🌐 **20+ Provider** | DeepSeek / OpenAI / Claude / Groq / Together / 本地 / Ollama |
44
+ | ⚙️ **双模式** | API 模式(256K 窗口) / 本地模式(64K 窗口) / 用户自由设置 |
45
+ | 🕐 **定时任务** | `dong cron add --cmd "dong run 审计" --every 1h` |
46
+ | 📡 **Webhook** | `POST /webhook` 触发自动审计 |
47
+ | 🔗 **MCP 客户端** | 发现并调用任何 MCP 服务器工具 |
48
+
49
+ ## 快速开始
50
+
51
+ ```bash
52
+ pip install dong-ai
53
+ pip install 'dong-ai[all]' # 全部依赖(含 API 服务)
54
+
55
+ dong setup # 交互式配置向导
56
+ dong chat # 启动对话
57
+ dong run "配置系统" # 一键项目执行
58
+ dong serve # 启动 API 服务 → http://localhost:8648
59
+ ```
60
+
61
+ ### 命令一览
62
+
63
+ ```
64
+ dong chat 交互式 TUI dong config 配置管理
65
+ dong run "需求" 一键项目执行 dong skill 技能管理
66
+ dong serve API 服务 dong session 会话管理
67
+ dong setup 配置向导 dong mcp MCP 工具发现
68
+ dong detect 模型检测 dong cron 定时任务
69
+ dong version 版本信息 dong webhook Webhook 管理
70
+ ```
71
+
72
+ ## 架构
73
+
74
+ ```
75
+ dong chat / dong run / dong serve
76
+
77
+ ┌────┴────┐
78
+ │ CEO │ ← DesignEngine(红蓝辩论) + WorkerPool(自愈+互审)
79
+ └────┬────┘
80
+
81
+ ┌────┴────┐
82
+ │ ModelPool│ ← 20+ Provider 自动 failover
83
+ └────┬────┘
84
+
85
+ ┌────┴────┐
86
+ │ LLMClient│ ← 统一 HTTP + SSE
87
+ └─────────┘
88
+
89
+ 存储层:
90
+ Datastore (SQLite)
91
+ ├── MemoryRepository 事实 KV
92
+ ├── SessionRepository 会话历史
93
+ ├── ProjectRepository 决策/模块
94
+ ├── LoreRepository 世界观
95
+ └── GraphRepository 代码符号/依赖/需求追溯
96
+ ```
97
+
98
+ ## 双模式配置
99
+
100
+ ```
101
+ 模式 CEO 上下文 工人上下文 适用场景
102
+ ─────────────────────────────────────────────────
103
+ API 256K 128K 云端模型(DeepSeek/GPT/Claude)
104
+ Local 64K 64K 本地模型(Qwen/Llama/Ollama)
105
+ 自定义 任意 任意 dong config set ceo_context=999999
106
+ ```
107
+
108
+ ## 测试
109
+
110
+ ```bash
111
+ pip install pytest
112
+ pytest tests/
113
+ # 121 passed in 1.6s
114
+ ```
115
+
116
+ ## 许可证
117
+
118
+ MIT — 随意使用、修改、商用。
119
+
120
+ ---
121
+
122
+ <p align="center">
123
+ <sub>不是聊天工具——是你的 AI 员工团队</sub>
124
+ </p>
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dong-ai"
7
+ version = "0.1.0"
8
+ description = "Dong AI Company — 多智能体 AI 公司框架"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Dong AI", email = "dong@dong-ai.dev"},
14
+ ]
15
+ keywords = ["ai", "agent", "multi-agent", "llm", "framework"]
16
+
17
+ [project.urls]
18
+ Homepage = "https://github.com/nousresearch/dong-ai"
19
+ Source = "https://github.com/nousresearch/dong-ai"
20
+
21
+ [project.optional-dependencies]
22
+ server = ["fastapi>=0.110", "uvicorn[standard]>=0.29"]
23
+ all = [
24
+ "fastapi>=0.110",
25
+ "uvicorn[standard]>=0.29",
26
+ "ddgs>=0.5",
27
+ ]
28
+
29
+ [project.scripts]
30
+ dong = "dong_ai.cli:main"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
34
+ include = ["dong_ai*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,34 @@
1
+ """Dong AI Company — 多智能体 AI 公司框架
2
+
3
+ 一键安装:
4
+ pip install dong-ai
5
+
6
+ 快速开始:
7
+ dong chat # 交互式 TUI
8
+ dong run "需求" # 一键项目执行
9
+ dong serve # API 服务
10
+ dong detect # 检测可用模型
11
+ """
12
+
13
+ __version__ = "0.1.0"
14
+
15
+ from .ceo import CEO
16
+ from .llm import LLMConfig, LLMResponse, OpenAICompatibleClient, create_client
17
+ from .datastore import Datastore, get_repo
18
+ from .design_engine import DesignEngine
19
+ from .display import print_banner, print_assistant, status_line, box_top, box_bottom, sep
20
+ from .tool_executor import ToolExecutor
21
+ from .ceo_memory import CEOMemory
22
+ from .logger import get_logger
23
+ from .model_pool import ModelPool, get_pool, llm_call, PROVIDERS
24
+ from .worker import WorkerPool
25
+ from .web_search import search, search_formatted
26
+
27
+ __all__ = [
28
+ "CEO", "WorkerPool", "ModelPool", "DesignEngine",
29
+ "LLMConfig", "LLMResponse", "OpenAICompatibleClient", "create_client",
30
+ "Datastore", "get_repo", "CEOMemory", "ToolExecutor",
31
+ "print_banner", "print_assistant", "status_line", "box_top", "box_bottom", "sep",
32
+ "get_logger", "get_pool", "llm_call", "PROVIDERS",
33
+ "search", "search_formatted",
34
+ ]
@@ -0,0 +1,255 @@
1
+ """Dong AI — FastAPI API Server
2
+
3
+ OpenAI 兼容 API,任何 OpenAI 客户端可直接连接。
4
+
5
+ 启动:
6
+ dong serve --port 8648
7
+
8
+ 端点:
9
+ GET /v1/models → 可用模型列表
10
+ POST /v1/chat/completions → 聊天(含流式)
11
+ POST /v1/run → CEO 项目执行
12
+ GET /health → 健康检查
13
+ """
14
+
15
+ import json, time, uuid, os
16
+ from typing import Optional
17
+
18
+ try:
19
+ from fastapi import FastAPI, HTTPException, Request
20
+ from fastapi.responses import StreamingResponse, JSONResponse, HTMLResponse
21
+ from fastapi.staticfiles import StaticFiles
22
+ from pathlib import Path
23
+ except ImportError:
24
+ raise ImportError("需要安装 fastapi: pip install 'dong-ai[server]'")
25
+
26
+ from dong_ai.model_pool import ModelPool
27
+
28
+ app = FastAPI(title="Dong AI API", version="0.1.0")
29
+ pool = ModelPool()
30
+
31
+
32
+ # ═══════════════════════════════════════════════════════════
33
+ # Models (OpenAI 兼容)
34
+ # ═══════════════════════════════════════════════════════════
35
+
36
+ @app.get("/v1/models")
37
+ async def list_models():
38
+ """OpenAI 兼容的模型列表"""
39
+ providers = pool.available()
40
+ models = []
41
+ for p in providers:
42
+ for model_id in p["models"]:
43
+ models.append({
44
+ "id": model_id,
45
+ "object": "model",
46
+ "created": int(time.time()),
47
+ "owned_by": p["name"],
48
+ })
49
+ return {"object": "list", "data": models}
50
+
51
+
52
+ # ═══════════════════════════════════════════════════════════
53
+ # Chat Completions (OpenAI 兼容)
54
+ # ═══════════════════════════════════════════════════════════
55
+
56
+ @app.post("/v1/chat/completions")
57
+ async def chat_completions(request: Request):
58
+ """OpenAI 兼容的聊天补全(支持流式)"""
59
+ body = await request.json()
60
+ messages = body.get("messages", [])
61
+ model = body.get("model", "")
62
+ stream = body.get("stream", False)
63
+ max_tokens = body.get("max_tokens", 8192)
64
+ temperature = body.get("temperature", 0.7)
65
+
66
+ # 从 messages 中提取 system prompt
67
+ system = ""
68
+ filtered = []
69
+ for m in messages:
70
+ if m.get("role") == "system":
71
+ system = m["content"]
72
+ else:
73
+ filtered.append(m)
74
+ messages = filtered
75
+
76
+ # 选择 provider(如果指定 model 则匹配,否则用 best)
77
+ providers = pool.available()
78
+ if model:
79
+ target = next((p for p in providers if model in p["models"]), None)
80
+ if not target:
81
+ raise HTTPException(status_code=404, detail=f"Model {model} not found")
82
+ providers = [target]
83
+
84
+ if not providers:
85
+ raise HTTPException(status_code=503, detail="No available model providers")
86
+
87
+ if stream:
88
+ return _stream_response(providers[0], messages, system, max_tokens, temperature, model)
89
+ else:
90
+ return _json_response(providers[0], messages, system, max_tokens, temperature, model)
91
+
92
+
93
+ def _json_response(provider, messages, system, max_tokens, temperature, model_id):
94
+ """非流式响应"""
95
+ from dong_ai.llm import LLMConfig, OpenAICompatibleClient
96
+
97
+ client = OpenAICompatibleClient(LLMConfig(
98
+ model=model_id or provider["models"][0],
99
+ base_url=provider["base_url"],
100
+ api_key=provider.get("api_key", ""),
101
+ max_tokens=max_tokens,
102
+ temperature=temperature,
103
+ ))
104
+
105
+ try:
106
+ resp = client.chat(messages, system=system if system else None)
107
+ except Exception as e:
108
+ raise HTTPException(status_code=502, detail=str(e))
109
+
110
+ return {
111
+ "id": f"chatcmpl-{uuid.uuid4().hex[:12]}",
112
+ "object": "chat.completion",
113
+ "created": int(time.time()),
114
+ "model": model_id or provider["models"][0],
115
+ "choices": [{
116
+ "index": 0,
117
+ "message": {"role": "assistant", "content": resp.text},
118
+ "finish_reason": "stop",
119
+ }],
120
+ "usage": resp.usage,
121
+ }
122
+
123
+
124
+ def _stream_response(provider, messages, system, max_tokens, temperature, model_id):
125
+ """流式 SSE 响应"""
126
+ from dong_ai.llm import LLMConfig, OpenAICompatibleClient
127
+
128
+ client = OpenAICompatibleClient(LLMConfig(
129
+ model=model_id or provider["models"][0],
130
+ base_url=provider["base_url"],
131
+ api_key=provider.get("api_key", ""),
132
+ max_tokens=max_tokens,
133
+ temperature=temperature,
134
+ ))
135
+
136
+ async def generate():
137
+ completion_id = f"chatcmpl-{uuid.uuid4().hex[:12]}"
138
+ yield f"data: {json.dumps({'id': completion_id, 'object': 'chat.completion.chunk', 'created': int(time.time()), 'model': model_id or provider['models'][0], 'choices': [{'index': 0, 'delta': {'role': 'assistant'}, 'finish_reason': None}]})}\n\n"
139
+
140
+ try:
141
+ for token in client.chat_stream(messages, system=system if system else "", max_tokens=max_tokens, temperature=temperature):
142
+ yield f"data: {json.dumps({'id': completion_id, 'object': 'chat.completion.chunk', 'created': int(time.time()), 'model': model_id or provider['models'][0], 'choices': [{'index': 0, 'delta': {'content': token}, 'finish_reason': None}]})}\n\n"
143
+
144
+ yield f"data: {json.dumps({'id': completion_id, 'object': 'chat.completion.chunk', 'created': int(time.time()), 'model': model_id or provider['models'][0], 'choices': [{'index': 0, 'delta': {}, 'finish_reason': 'stop'}]})}\n\n"
145
+ except Exception as e:
146
+ yield f"data: {json.dumps({'error': {'message': str(e)}})}\n\n"
147
+
148
+ yield "data: [DONE]\n\n"
149
+
150
+ return StreamingResponse(generate(), media_type="text/event-stream",
151
+ headers={"Cache-Control": "no-cache", "Connection": "keep-alive"})
152
+
153
+
154
+ # ═══════════════════════════════════════════════════════════
155
+ # CEO 项目执行
156
+ # ═══════════════════════════════════════════════════════════
157
+
158
+ @app.post("/v1/run")
159
+ async def run_project(request: Request):
160
+ """CEO 一键项目执行"""
161
+ body = await request.json()
162
+ request_text = body.get("request", "")
163
+ if not request_text:
164
+ raise HTTPException(status_code=400, detail="request is required")
165
+
166
+ try:
167
+ from dong_ai.ceo import CEO
168
+ import io, sys
169
+ # 捕获 print 输出作为执行日志
170
+ captured = io.StringIO()
171
+ old_stdout = sys.stdout
172
+ sys.stdout = captured
173
+ ceo = CEO()
174
+ ceo.run(request_text)
175
+ sys.stdout = old_stdout
176
+ log = captured.getvalue()
177
+ except Exception as e:
178
+ raise HTTPException(status_code=500, detail=str(e))
179
+
180
+ return {"status": "done", "log": log, "report_path": str(ceo.report_path)}
181
+
182
+
183
+ # ═══════════════════════════════════════════════════════════
184
+ # Health
185
+ # ═══════════════════════════════════════════════════════════
186
+
187
+ @app.get("/health")
188
+ async def health():
189
+ providers = pool.available()
190
+ return {
191
+ "status": "ok",
192
+ "version": "0.1.0",
193
+ "providers": len(providers),
194
+ "models": [p["models"][0] for p in providers[:5]],
195
+ }
196
+
197
+
198
+ # ═══════════════════════════════════════════════════════════
199
+ # Webhook
200
+ # ═══════════════════════════════════════════════════════════
201
+
202
+ WEBHOOK_SECRET = os.environ.get("DONG_WEBHOOK_SECRET", "")
203
+
204
+
205
+ @app.post("/webhook")
206
+ async def webhook(request: Request):
207
+ """通用 webhook 接收器——接收外部事件并触发动作"""
208
+ body = await request.json()
209
+ event = body.get("event", body.get("type", "unknown"))
210
+ payload = body.get("payload", body)
211
+
212
+ # 验证 secret
213
+ token = request.headers.get("X-Webhook-Token", "")
214
+ if WEBHOOK_SECRET and token != WEBHOOK_SECRET:
215
+ raise HTTPException(status_code=401, detail="invalid token")
216
+
217
+ # 记录 webhook
218
+ try:
219
+ from dong_ai.ceo_memory import CEOMemory
220
+ mem = CEOMemory()
221
+ sid = mem.session_start(f"webhook_{int(time.time())}")
222
+ mem.session_save(sid, "system",
223
+ f"Webhook received: {event}\nPayload: {json.dumps(payload, ensure_ascii=False)[:1000]}")
224
+ except Exception:
225
+ pass
226
+
227
+ # 根据事件类型执行动作
228
+ if event == "deploy" or event == "push":
229
+ # 触发 CEO 审计
230
+ try:
231
+ from dong_ai.ceo import CEO
232
+ ceo = CEO()
233
+ # 后台线程执行
234
+ import threading
235
+ threading.Thread(target=ceo.run,
236
+ args=(f"审计最近的代码变更: {json.dumps(payload, ensure_ascii=False)[:200]}",),
237
+ daemon=True).start()
238
+ return {"status": "accepted", "message": "审计已启动"}
239
+ except Exception as e:
240
+ return {"status": "error", "message": str(e)}
241
+
242
+ return {"status": "received", "event": event}
243
+
244
+
245
+ # ═══════════════════════════════════════════════════════════
246
+ # Web UI
247
+ # ═══════════════════════════════════════════════════════════
248
+
249
+ @app.get("/")
250
+ async def chat_ui():
251
+ """Kimi 风格的聊天界面"""
252
+ html_path = Path(__file__).parent / "chat_ui.html"
253
+ if html_path.exists():
254
+ return HTMLResponse(html_path.read_text(encoding="utf-8"))
255
+ return HTMLResponse("<h1>Dong AI Company</h1><p>Chat UI not found</p>")