Move construction and document OnOutbox out of server, give HTTP/CLI a shared task use case, and block already-cleared import/event arch rules. Co-authored-by: Cursor <cursoragent@cursor.com>
101 lines
4.3 KiB
Go
101 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"chat-agent-system/internal/app"
|
|
"chat-agent-system/internal/config"
|
|
"chat-agent-system/internal/server"
|
|
)
|
|
|
|
func main() {
|
|
envPath := flag.String("env", ".env", "环境配置文件路径")
|
|
port := flag.Int("port", 0, "HTTP 服务端口 (默认读取配置文件或 8080)")
|
|
host := flag.String("host", "", "HTTP 监听主机 (默认读取配置文件或 127.0.0.1)")
|
|
backend := flag.String("backend", "", "智能体后端调度覆盖 (stub, pi-agent, cursor-cli)")
|
|
flag.Parse()
|
|
|
|
cfg, err := config.Load(*envPath)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "加载配置失败: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if *port > 0 {
|
|
cfg.HTTPPort = *port
|
|
}
|
|
if *host != "" {
|
|
cfg.HTTPHost = *host
|
|
}
|
|
if *backend != "" {
|
|
cfg.AgentBackend = *backend
|
|
}
|
|
|
|
rt, err := app.New(cfg)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "业务服务初始化失败: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
if err := rt.Start(context.Background()); err != nil {
|
|
fmt.Fprintf(os.Stderr, "后台 worker 启动失败: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
srv := server.NewFromRuntime(rt)
|
|
|
|
addr := fmt.Sprintf("%s:%d", cfg.HTTPHost, cfg.HTTPPort)
|
|
fmt.Println("==================================================================")
|
|
fmt.Println(" 🤖 医疗器械商务与研发智能参谋系统 - HTTP / SSE API 守护服务 ")
|
|
fmt.Println("==================================================================")
|
|
fmt.Printf("服务环境: %s | 智能体后端: %s\n", cfg.Env, cfg.AgentBackend)
|
|
fmt.Printf("监听地址: http://%s\n", addr)
|
|
fmt.Println("核心服务路由:")
|
|
fmt.Println(" • [GET] /api/v1/health - 服务健康检查与基础设施状态")
|
|
fmt.Println(" • [GET] /api/v1/projects - 查询项目当前上下文与黑板事实")
|
|
fmt.Println(" • [POST] /api/v1/chat - 标准阻塞式对话协同接口")
|
|
fmt.Println(" • [POST] /api/v1/chat/stream - 核心 SSE 流式长连接对话协议 (分层按需)")
|
|
fmt.Println(" • [GET] /api/v1/chat/stream - SSE 流式长连接对话调试接口 (EventSource)")
|
|
fmt.Println(" • [POST] /api/v1/tasks/run/stream - 独立任务与阶段执行 SSE 监控流 (精简进度与拦截)")
|
|
fmt.Println(" • [GET] /api/v1/context/user - 获取单用户私有上下文与习惯偏好画像")
|
|
fmt.Println(" • [PUT] /api/v1/context/user/preference - 整理或更新用户个性化产出风格")
|
|
fmt.Println(" • [GET] /api/v1/context/project - 获取项目多方协同黑板事实与里程碑决策流")
|
|
fmt.Println(" • [GET] /api/v1/chat/sessions - 分页查询用户/项目历史会话列表")
|
|
fmt.Println(" • [GET] /api/v1/chat/messages - 分页拉取指定会话多轮历史消息记录")
|
|
fmt.Println(" • [GET] /api/v1/context/cases/recommend - 往期受控标杆案例与历史报价语义自推荐")
|
|
fmt.Println(" • [GET] /api/v1/docgov/document - 查询受控文档治理状态看板")
|
|
fmt.Println(" • [POST] /api/v1/docgov/claim - 查阅并认领受控文档 (正式稿方可认领)")
|
|
fmt.Println(" • [POST] /api/v1/docgov/proposal/decide - 编制负责人拍板同意/拒绝变更提案")
|
|
fmt.Println(" • [POST] /api/v1/docgov/submit-review - 编制完成提交审核 (文档正文锁定)")
|
|
fmt.Println(" • [POST] /api/v1/docgov/review-decision - 审核通过或驳回 (驳回必填原因且解锁)")
|
|
fmt.Println(" • [POST] /api/v1/docgov/approver-decision - 最终批准或驳回")
|
|
fmt.Println(" • [GET/POST] /api/v1/docgov/comments - 批注与修改建议管理")
|
|
fmt.Println(" • [GET] /api/v1/docgov/audit-logs - 全生命周期审计轨迹流")
|
|
fmt.Println("==================================================================")
|
|
|
|
stop := make(chan os.Signal, 1)
|
|
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
|
|
|
|
go func() {
|
|
if err := srv.Start(); err != nil && err != http.ErrServerClosed {
|
|
fmt.Fprintf(os.Stderr, "服务启动失败: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}()
|
|
|
|
<-stop
|
|
fmt.Println("\n正在优雅停止服务...")
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
if err := srv.Shutdown(ctx); err != nil {
|
|
fmt.Fprintf(os.Stderr, "服务停止异常: %v\n", err)
|
|
} else {
|
|
fmt.Println("服务已安全退出。")
|
|
}
|
|
}
|