diff --git a/Makefile b/Makefile index 6dd8713e..02534761 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ # Agent-System-Dev 顶层编排 -# 用法:make sync && make build && make test -# 部署约束:非容器化;默认产物为单二进制(见 modules/backend)。 +# 部署约束:非容器化;默认产物为单二进制(modules/backend,内嵌前端与嵌入式存储)。 SHELL := /bin/bash CORE := modules/core @@ -8,14 +7,16 @@ BACKEND := modules/backend FRONTEND := modules/frontend BIN := bin/agent-system EMBED_DIR := $(BACKEND)/web/dist +PLUGINS := plugins -.PHONY: help sync status build frontend test test-backend test-frontend test-core dev release clean +.PHONY: help sync status build frontend test test-backend test-frontend test-core dev pin clean help: @echo "make sync 物化全部 submodule(递归)" - @echo "make build 构建单二进制 bin/agent-system(前端 embed + 静态链接)" + @echo "make build 构建单二进制 bin/agent-system(契约同步→前端构建→embed→静态链接)" @echo "make test 全量测试(core + backend + frontend)" @echo "make dev 开发模式说明(前后端分离热更新)" + @echo "make pin 推进 submodule 指针到各仓远端 main(提交前须 make test 通过)" @echo "make status submodule 状态" sync: @@ -24,12 +25,19 @@ sync: status: @git submodule status -frontend: +# 契约同步:Core 的 TS 类型镜像到前端(Core 为权威,单一来源)。 +contracts: + cp $(CORE)/ts/types.ts $(FRONTEND)/src/contracts.ts.tmp + { echo "// 从 Agent-System-Core ts/types.ts 同步(make contracts 生成;Core 为权威)。"; cat $(FRONTEND)/src/contracts.ts.tmp; } > $(FRONTEND)/src/contracts.ts + rm $(FRONTEND)/src/contracts.ts.tmp + +frontend: contracts cd $(FRONTEND) && npm ci --no-fund --no-audit && npm run build rm -rf $(EMBED_DIR) && mkdir -p $(EMBED_DIR) && cp -r $(FRONTEND)/dist/* $(EMBED_DIR)/ build: frontend cd $(BACKEND) && CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o ../../$(BIN) ./cmd/agent-system + @echo "OK: $(BIN)(单二进制;随附插件目录 $(PLUGINS)/)" test-core: cd $(CORE) && go test ./... @@ -37,17 +45,29 @@ test-core: test-backend: cd $(BACKEND) && go test ./... -test-frontend: - cd $(FRONTEND) && npm ci --no-fund --no-audit && npm test -- --run +test-frontend: contracts + cd $(FRONTEND) && npm ci --no-fund --no-audit && npx vitest run test: test-core test-backend test-frontend +# 运行演示(mock 模式):单二进制 + 示例插件 + 嵌入式存储,浏览器 http://127.0.0.1:8787 +demo: build + $(BIN) serve --addr 127.0.0.1:8787 --data ./data --plugins $(PLUGINS) --mock + dev: @echo "开发模式(原生,非容器):" - @echo " 1. make sync" - @echo " 2. 终端 A:cd $(BACKEND) && go run ./cmd/agent-system serve --addr 127.0.0.1:8787 --data ./data" + @echo " 1. make sync && make contracts" + @echo " 2. 终端 A:cd $(BACKEND) && go run ./cmd/agent-system serve --addr 127.0.0.1:8787 --data ./data --plugins ../$(PLUGINS)" @echo " 3. 终端 B:cd $(FRONTEND) && npm ci && npm run dev # Vite 代理到 8787" - @echo " 4. 浏览器打开 Vite 提示的地址;mock 对话不需要模型密钥。" + @echo " 4. mock 演示:设置→运行时→演示模式;或终端 A 加 --mock" + +# 推进指针(多仓纪律:先验证后固定)。 +pin: + @for m in modules/core modules/backend modules/frontend modules/documents deps/agent-native deps/agent-squad deps/agent-intent deps/error-code-system deps/logging-system deps/development-guidelines; do \ + (git -C $$m fetch -q origin && git -C $$m checkout -q origin/main) || echo "skip $$m"; \ + done + @cd $(BACKEND)/deps/agent-system-core && git fetch -q origin && git checkout -q origin/main || true + @echo "submodule 指针已推进;请 make test 后 git add .gitmodules modules deps && git commit" clean: - rm -rf $(BIN) $(FRONTEND)/dist $(FRONTEND)/node_modules + rm -rf $(BIN) $(FRONTEND)/dist $(FRONTEND)/node_modules data diff --git a/modules/backend b/modules/backend index 6832b7f0..964e4fb5 160000 --- a/modules/backend +++ b/modules/backend @@ -1 +1 @@ -Subproject commit 6832b7f0da76225f4c8aaf9ef713d2b8f5689bc1 +Subproject commit 964e4fb545a18d7aad31c28377839f405a020363 diff --git a/modules/core b/modules/core index f2fcc2f6..3cf6bac4 160000 --- a/modules/core +++ b/modules/core @@ -1 +1 @@ -Subproject commit f2fcc2f62e148839e61c4b78bec7d95c6a424de8 +Subproject commit 3cf6bac4561b6fed1bfc06cbe7596280164319a6 diff --git a/modules/frontend b/modules/frontend index a80fae7d..fd3c3dbe 160000 --- a/modules/frontend +++ b/modules/frontend @@ -1 +1 @@ -Subproject commit a80fae7dc6df0e1a5552715efc9ef1084726efed +Subproject commit fd3c3dbe322fa954cd714802c65fe672a661b6b8 diff --git a/plugins/example/cards/note.json b/plugins/example/cards/note.json new file mode 100644 index 00000000..1caa2d00 --- /dev/null +++ b/plugins/example/cards/note.json @@ -0,0 +1 @@ +{ "kind": "note", "data": [ { "type": "markdown", "markdown": "**插件卡片模板**(kind=note)——卡片类型同样走 UI schema 词汇。" } ] } diff --git a/plugins/example/intents/demo.json b/plugins/example/intents/demo.json new file mode 100644 index 00000000..6b8b4e03 --- /dev/null +++ b/plugins/example/intents/demo.json @@ -0,0 +1,3 @@ +[ + { "id": "demo_intent", "domain": "demo", "description": "示例意图:命中『示例/演示』关键词", "includes_any": ["示例", "演示"], "slots": [] } +] diff --git a/plugins/example/panels/demo.json b/plugins/example/panels/demo.json new file mode 100644 index 00000000..42c96914 --- /dev/null +++ b/plugins/example/panels/demo.json @@ -0,0 +1,9 @@ +{ + "id": "demo", + "title": "示例面板", + "body": [ + { "type": "markdown", "markdown": "## 示例插件面板\n\n本面板由插件声明(UI schema),前端通用渲染器渲染——插件未注入任何 React 组件。" }, + { "type": "kv", "title": "能力清单", "kv": [["工具", "http_echo(声明式 HTTP)"], ["意图", "demo_intent"], ["卡片", "note"], ["提示词", "assistant.md"]] }, + { "type": "list", "title": "装卸语义", "items": ["目录移除插件后热重载即卸载", "内置工具不受影响(核心零回归)", "坏资产整批拒绝(fail-closed)"] } + ] +} diff --git a/plugins/example/plugin.json b/plugins/example/plugin.json new file mode 100644 index 00000000..b9967652 --- /dev/null +++ b/plugins/example/plugin.json @@ -0,0 +1,15 @@ +{ + "id": "example", + "name": "示例插件", + "version": "0.1.0", + "apiVersion": "1.0", + "requires": { "network": ["api.example.com"] }, + "provides": { + "tools": ["http_echo"], + "intents": ["demo"], + "panels": ["demo"], + "cards": ["note"], + "prompts": ["assistant"], + "settings": ["greeting"] + } +} diff --git a/plugins/example/prompts/assistant.md b/plugins/example/prompts/assistant.md new file mode 100644 index 00000000..328ecb69 --- /dev/null +++ b/plugins/example/prompts/assistant.md @@ -0,0 +1 @@ +你是示例插件附带的助手画像模板。可复制为本用户画像后微调。 diff --git a/plugins/example/settings.json b/plugins/example/settings.json new file mode 100644 index 00000000..d119866e --- /dev/null +++ b/plugins/example/settings.json @@ -0,0 +1,3 @@ +[ + { "key": "greeting", "group": "plugin:example", "label": "问候语", "type": "string", "default": "你好", "effect": "hot" } +] diff --git a/plugins/example/tools/http_echo.json b/plugins/example/tools/http_echo.json new file mode 100644 index 00000000..c16f73e5 --- /dev/null +++ b/plugins/example/tools/http_echo.json @@ -0,0 +1,6 @@ +{ + "name": "http_echo", + "description": "调用示例端点回显文本(声明式 HTTP 工具演示:修改 URL 指向你的服务即可复用)", + "parameters": { "type": "object", "properties": { "text": { "type": "string", "description": "要回显的文本" } }, "required": ["text"] }, + "http": { "method": "POST", "url": "https://api.example.com/echo", "bodyTemplate": "{\"q\":\"{{param.text}}\"}", "resultPath": "echo", "timeoutMs": 10000 } +}