diff --git a/cmd/skills_test.go b/cmd/skills_test.go index 027b5c8..99b8ae8 100644 --- a/cmd/skills_test.go +++ b/cmd/skills_test.go @@ -22,6 +22,7 @@ import ( "bytes" "os" "regexp" + "strings" "testing/fstest" json "github.com/goccy/go-json" @@ -96,6 +97,84 @@ description: 共享规则 } }) + DescribeTable("keeps AIDev examples actionable in CLI help and the usage skill", func(name string) { + content, err := os.ReadFile("../skills/bk-cli-aidev/SKILL.md") + Expect(err).NotTo(HaveOccurred()) + root := newRootCmd() + bodyPattern := regexp.MustCompile(`--body '([^']+)'`) + action, _, findErr := root.Find([]string{"aidev", name}) + Expect(findErr).NotTo(HaveOccurred()) + _, section, found := strings.Cut(string(content), "#### `"+name+"`") + Expect(found).To(BeTrue()) + section, _, _ = strings.Cut(section, "\n#### ") + for source, example := range map[string]string{"help": action.Example, "skill": section} { + bodies := bodyPattern.FindAllStringSubmatch(example, -1) + Expect(bodies).NotTo(BeEmpty(), "%s %s needs a body example", source, name) + for _, match := range bodies { + var body map[string]any + Expect(json.Unmarshal([]byte(match[1]), &body)).To(Succeed()) + Expect(body["space_id"]).To(Equal("demo-space"), "%s %s", source, name) + switch name { + case "create_mcp": + Expect(body["url"]).To(MatchRegexp(`^https?://[^/]+`)) + if body["credential_type"] == "custom" { + Expect(body["credential_id"]).To(BeNumerically(">", 0)) + } + case "create_knowledge": + Expect(body["file_path"]).To(Equal(body["file_name"])) + Expect(body["url"]).To(BeAssignableToTypeOf("")) + Expect(body["url"]).NotTo(BeEmpty()) + case "import_knowledge_archive": + Expect(body["anchor_path"]).To(MatchRegexp(`^/[0-9]+(/.*)?$`)) + case "upsert_collection": + messages, ok := body["content"].([]any) + Expect(ok).To(BeTrue()) + Expect(messages).NotTo(BeEmpty()) + Expect(messages[0]).To(HaveKeyWithValue("role", "system")) + Expect(messages[0]).To(HaveKeyWithValue("content", Not(BeEmpty()))) + case "reclean_knowledge", "trigger_knowledge_update": + Expect(body["id"]).To(BeNumerically(">", 0)) + case "append_agent_admins": + Expect(body["admins"]).NotTo(BeEmpty()) + case "get_upload_url": + Expect(body["module"]).To(Equal("skill")) + case "create_credential", "update_credential": + Expect(body["credential_detail"]).To(HaveKeyWithValue("key", Not(BeEmpty()))) + Expect(body["credential_detail"]).To(HaveKeyWithValue("value", Not(BeEmpty()))) + case "batch_delete_credentials": + Expect(body["credential_ids"]).NotTo(BeEmpty()) + case "batch_create_knowledges", "batch_update_knowledges": + Expect(body["items"]).NotTo(BeEmpty()) + case "batch_delete_knowledges": + Expect(body["ids"]).NotTo(BeEmpty()) + case "apply_cross_space_resources": + Expect(body["resource_ids"]).NotTo(BeEmpty()) + } + } + } + }, + Entry("archive_skill", "archive_skill"), + Entry("archive_agent", "archive_agent"), + Entry("delete_knowledgebase", "delete_knowledgebase"), + Entry("delete_knowledge", "delete_knowledge"), + Entry("delete_credential", "delete_credential"), + Entry("create_mcp", "create_mcp"), + Entry("create_knowledge", "create_knowledge"), + Entry("import_knowledge_archive", "import_knowledge_archive"), + Entry("upsert_collection", "upsert_collection"), + Entry("reclean_knowledge", "reclean_knowledge"), + Entry("trigger_knowledge_update", "trigger_knowledge_update"), + Entry("append_agent_admins", "append_agent_admins"), + Entry("get_upload_url", "get_upload_url"), + Entry("create_credential", "create_credential"), + Entry("update_credential", "update_credential"), + Entry("batch_delete_credentials", "batch_delete_credentials"), + Entry("batch_create_knowledges", "batch_create_knowledges"), + Entry("batch_update_knowledges", "batch_update_knowledges"), + Entry("batch_delete_knowledges", "batch_delete_knowledges"), + Entry("apply_cross_space_resources", "apply_cross_space_resources"), + ) + It("lists embedded skills as structured JSON without machine-only files", func() { cmd := newRootCmd() out := &bytes.Buffer{} diff --git a/cmd/system/aidev/actions.yaml b/cmd/system/aidev/actions.yaml index 77a7f43..9af4cf6 100644 --- a/cmd/system/aidev/actions.yaml +++ b/cmd/system/aidev/actions.yaml @@ -204,6 +204,21 @@ actions: description: "归档指定 Skill。先核对目标 ID、版本和 Agent 引用,再执行。" method: DELETE path: "/openapi/aidev/private/v1/skills/{skill_id}/" + body_required: true + body_schema: | + { + "type": "object", + "required": [ + "space_id" + ], + "properties": { + "space_id": { + "type": "string", + "minLength": 1, + "description": "真实空间 ID,必须显式传递,不支持 all" + } + } + } authConfig: appVerifiedRequired: true userVerifiedRequired: true @@ -215,7 +230,7 @@ actions: description: "Skill ID" required: true examples: - - "bk-cli aidev archive_skill --skill_id 1" + - "bk-cli aidev archive_skill --skill_id 1 --body '{\"space_id\":\"demo-space\"}'" - name: get_skill_download_url description: "获取指定 Skill 文件的临时下载链接。适用于核对或下载已有制品;链接有时效,不用于上传新版本。" @@ -472,7 +487,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev create_mcp --body '{\"space_id\":\"demo-space\",\"mcp_name\":\"Demo MCP\",\"mcp_code\":\"demo-mcp\",\"url\":\"bkrepo://demo.zip\",\"protocol\":\"stdio\",\"credential_type\":\"custom\",\"description\":\"demo description\"}'" + - "bk-cli aidev create_mcp --body '{\"space_id\":\"demo-space\",\"mcp_name\":\"Demo MCP\",\"mcp_code\":\"demo-mcp\",\"url\":\"https://mcp.example.com/mcp\",\"protocol\":\"streamable_http\",\"credential_type\":\"custom\",\"description\":\"demo description\",\"credential_id\":1}'" - name: get_mcp description: "按类型和 ID 读取 MCP 详情。适用于已取得准确 ID 后核对资源型或 APIGW MCP 配置。" @@ -1453,6 +1468,21 @@ actions: description: "归档指定智能体;已发布的插件应用可能异步下架。适用于明确要移除智能体时,先核对目标 ID 和资源引用。" method: DELETE path: "/openapi/aidev/private/v1/agents/{agent_id}/" + body_required: true + body_schema: | + { + "type": "object", + "required": [ + "space_id" + ], + "properties": { + "space_id": { + "type": "string", + "minLength": 1, + "description": "真实空间 ID,必须显式传递,不支持 all" + } + } + } authConfig: appVerifiedRequired: true userVerifiedRequired: true @@ -1464,7 +1494,7 @@ actions: description: "Agent ID" required: true examples: - - "bk-cli aidev archive_agent --agent_id 1" + - "bk-cli aidev archive_agent --agent_id 1 --body '{\"space_id\":\"demo-space\"}'" - name: publish_agent description: "提交指定智能体的发布请求并返回版本与状态。建议不传 version,由平台自动生成:首次为 1.0.0,后续递增末位;仅在确需指定版本号时传入。pending 或 running 表示后台处理中,不等于发布或部署完成。" @@ -2552,6 +2582,21 @@ actions: description: "删除指定知识库。先确认其中知识、Agent 引用及删除影响,再执行。" method: DELETE path: "/openapi/aidev/private/v1/knowledgebase/{id}/" + body_required: true + body_schema: | + { + "type": "object", + "required": [ + "space_id" + ], + "properties": { + "space_id": { + "type": "string", + "minLength": 1, + "description": "真实空间 ID,必须显式传递,不支持 all" + } + } + } authConfig: appVerifiedRequired: true userVerifiedRequired: true @@ -2562,7 +2607,7 @@ actions: type: int required: true examples: - - "bk-cli aidev delete_knowledgebase --id 1" + - "bk-cli aidev delete_knowledgebase --id 1 --body '{\"space_id\":\"demo-space\"}'" - name: update_knowledgebase description: "更新已有知识库的配置。适用于查到 ID 且完成配置差异核对后;不会单独完成知识文档 ZIP 导入。" @@ -2777,7 +2822,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev create_knowledge --body '{\"space_id\":\"demo-space\",\"knowledge_base_id\":1,\"knowledge_name\":\"Demo Knowledge\",\"file_name\":\"demo.md\",\"file_path\":\"bkrepo://demo.md\"}'" + - "bk-cli aidev create_knowledge --body '{\"space_id\":\"demo-space\",\"knowledge_base_id\":1,\"knowledge_name\":\"Demo Knowledge\",\"file_name\":\"demo.md\",\"file_path\":\"demo.md\",\"url\":\"bkrepo://demo.md\"}'" - name: batch_create_knowledges description: "一次创建多条知识文档。适用于已确认同一批输入的多篇新增;整目录 ZIP 同步使用 archive/import。" @@ -2815,7 +2860,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev batch_create_knowledges --body '{\"space_id\":\"demo-space\",\"items\":[]}'" + - "bk-cli aidev batch_create_knowledges --body '{\"space_id\":\"demo-space\",\"items\":[{\"knowledge_base_id\":1,\"knowledge_name\":\"Demo Knowledge\",\"file_name\":\"demo.md\",\"file_path\":\"demo.md\",\"url\":\"bkrepo://demo.md\"}]}'" - name: batch_delete_knowledges description: "一次删除多条知识文档。适用于已逐项核对目标 ID 和删除影响的批量清理。" @@ -2852,7 +2897,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev batch_delete_knowledges --body '{\"space_id\":\"demo-space\",\"ids\":[]}'" + - "bk-cli aidev batch_delete_knowledges --body '{\"space_id\":\"demo-space\",\"ids\":[1]}'" - name: batch_update_knowledges description: "一次更新多条已有知识文档。适用于每条目标 ID 和修改内容均已确认的批量操作。" @@ -2890,7 +2935,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev batch_update_knowledges --body '{\"space_id\":\"demo-space\",\"items\":[]}'" + - "bk-cli aidev batch_update_knowledges --body '{\"space_id\":\"demo-space\",\"items\":[{\"id\":1,\"knowledge_name\":\"Updated Knowledge\"}]}'" - name: list_knowledges description: "列出指定知识库或目录内的知识文档;这是只读查询,虽然使用 POST。适用于确认导入后的文档范围或定位文档 ID。" @@ -3158,7 +3203,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev trigger_knowledge_update --body '{\"space_id\":\"demo-space\"}'" + - "bk-cli aidev trigger_knowledge_update --body '{\"space_id\":\"demo-space\",\"id\":1}'" - name: list_knowledge_update_frequencies description: "列出知识文档支持的更新频率选项,供创建或更新配置时选择;不触发更新。" @@ -3219,6 +3264,21 @@ actions: description: "删除指定知识文档。适用于明确移除单篇文档时,先确认 ID 和影响。" method: DELETE path: "/openapi/aidev/private/v1/knowledges/{id}/" + body_required: true + body_schema: | + { + "type": "object", + "required": [ + "space_id" + ], + "properties": { + "space_id": { + "type": "string", + "minLength": 1, + "description": "真实空间 ID,必须显式传递,不支持 all" + } + } + } authConfig: appVerifiedRequired: true userVerifiedRequired: true @@ -3229,7 +3289,7 @@ actions: type: int required: true examples: - - "bk-cli aidev delete_knowledge --id 1" + - "bk-cli aidev delete_knowledge --id 1 --body '{\"space_id\":\"demo-space\"}'" - name: get_knowledge_index_info description: "读取指定知识文档的索引配置。适用于核对切分、清洗和检索设置;不返回文档正文。" @@ -3532,7 +3592,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev create_credential --body '{\"credential_name\":\"demo-credential\",\"credential_type\":\"custom\",\"credential_detail\":{\"key\":\"demo-value\"},\"space_id\":\"demo-space\"}'" + - "bk-cli aidev create_credential --body '{\"credential_name\":\"demo-credential\",\"credential_type\":\"custom\",\"credential_detail\":{\"key\":\"demo-key\",\"value\":\"demo-value\"},\"space_id\":\"demo-space\"}'" - name: batch_delete_credentials description: "批量删除指定凭证;先逐项确认 ID 与引用关系。适用于一次清理多个已确认不再使用的凭证。" @@ -3571,7 +3631,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev batch_delete_credentials --body '{\"space_id\":\"demo-space\",\"credential_ids\":[]}'" + - "bk-cli aidev batch_delete_credentials --body '{\"space_id\":\"demo-space\",\"credential_ids\":[1]}'" - name: bind_credential description: "将已有凭证绑定到目标资源。适用于凭证和资源均已确定时;会改变目标资源的凭证关联。" @@ -3685,6 +3745,21 @@ actions: description: "删除指定凭证。先查询引用并确认解绑或影响范围,再执行删除。" method: DELETE path: "/openapi/aidev/private/v1/credentials/{credential_id}/" + body_required: true + body_schema: | + { + "type": "object", + "required": [ + "space_id" + ], + "properties": { + "space_id": { + "type": "string", + "minLength": 1, + "description": "真实空间 ID,必须显式传递,不支持 all" + } + } + } authConfig: appVerifiedRequired: true userVerifiedRequired: true @@ -3696,7 +3771,7 @@ actions: description: "凭证 ID" required: true examples: - - "bk-cli aidev delete_credential --credential_id 1" + - "bk-cli aidev delete_credential --credential_id 1 --body '{\"space_id\":\"demo-space\"}'" - name: list_credential_references description: "查询指定凭证被哪些资源引用。适用于更新、解绑或删除前评估影响。" @@ -3809,7 +3884,7 @@ actions: description: "凭证 ID" required: true examples: - - "bk-cli aidev update_credential --credential_id 1 --body '{\"credential_name\":\"demo-credential\",\"credential_type\":\"custom\",\"credential_detail\":{\"key\":\"demo-value\"},\"space_id\":\"demo-space\",\"credential_id\":1}'" + - "bk-cli aidev update_credential --credential_id 1 --body '{\"credential_name\":\"demo-credential\",\"credential_type\":\"custom\",\"credential_detail\":{\"key\":\"demo-key\",\"value\":\"demo-value\"},\"space_id\":\"demo-space\",\"credential_id\":1}'" - name: reclean_knowledge description: "按当前或指定导入链路重新清洗并重建知识产物。适用于确认现有产物需重建时;会触发后台处理。" @@ -3867,7 +3942,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev reclean_knowledge --body '{\"space_id\":\"demo-space\"}'" + - "bk-cli aidev reclean_knowledge --body '{\"space_id\":\"demo-space\",\"id\":1}'" - name: list_resource_references description: "查询哪些 Agent 引用了指定类型和 ID 的资源。适用于删除或变更 Skill、MCP、知识库等资源前评估影响。" @@ -4038,7 +4113,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev upsert_collection --body '{\"space_id\":\"demo-space\",\"collection_code\":\"demo-collection\",\"collection_name\":\"Demo Collection\",\"content\":[]}'" + - "bk-cli aidev upsert_collection --body '{\"space_id\":\"demo-space\",\"collection_code\":\"demo-collection\",\"collection_name\":\"Demo Collection\",\"content\":[{\"role\":\"system\",\"content\":\"你是示例角色\"}]}'" - name: get_collection description: "读取指定角色 Prompt Collection 的消息内容及配置。适用于同步前比对,或确认 Agent 引用的现有 Collection。" @@ -4147,7 +4222,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev import_knowledge_archive --body '{\"space_id\":\"demo-space\",\"url\":\"bkrepo://demo.zip\",\"file_name\":\"demo\",\"file_type\":\"zip\",\"anchor_path\":\"/\"}'" + - "bk-cli aidev import_knowledge_archive --body '{\"space_id\":\"demo-space\",\"url\":\"bkrepo://demo.zip\",\"file_name\":\"demo\",\"file_type\":\"zip\",\"anchor_path\":\"/1\"}'" - name: get_mcp_by_code description: "按 mcp_type 和 mcp_code 精确解析 MCP 的 ID、类型及可用范围。适用于 Agent 配置引用 MCP 时;传 agent_code 可按目标 Agent 的关联场景检查 APIGW MCP。" @@ -4267,7 +4342,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev apply_cross_space_resources --body '{\"space_id\":\"demo-space\",\"resource_type\":\"skill\",\"resource_ids\":[]}'" + - "bk-cli aidev apply_cross_space_resources --body '{\"space_id\":\"demo-space\",\"resource_type\":\"skill\",\"resource_ids\":[1]}'" - name: check_upload_status description: "查询并校验直传文件是否存在、大小范围和 SHA256 格式,返回实际文件大小与摘要。调用方仍需与本地文件比对;适用于上传后或超时后确认结果,不会重新上传。" @@ -4348,7 +4423,7 @@ actions: userVerifiedRequired: true resourcePermissionRequired: true examples: - - "bk-cli aidev get_upload_url --body '{\"space_id\":\"demo-space\",\"file_name\":\"demo.md\"}'" + - "bk-cli aidev get_upload_url --body '{\"space_id\":\"demo-space\",\"file_name\":\"demo.zip\",\"module\":\"skill\"}'" - name: append_agent_admins description: "向智能体对应的开发者中心插件追加管理员,保留原有成员;不修改 Agent 使用者或空间权限。适用于 Agent 创建后补充管理员。" @@ -4397,7 +4472,7 @@ actions: description: "智能体 ID" required: true examples: - - "bk-cli aidev append_agent_admins --agent_id 1 --body '{\"space_id\":\"demo-space\",\"agent_id\":1}'" + - "bk-cli aidev append_agent_admins --agent_id 1 --body '{\"space_id\":\"demo-space\",\"agent_id\":1,\"admins\":[\"username\"]}'" - name: list_tags description: "获取当前租户指定范围的全量标签树,供智能体配置时选择标签;无需指定空间或智能体。" @@ -4413,4 +4488,5 @@ actions: type: string description: "标签范围,默认使用智能体标签范围;未识别的范围沿用 meta 回退到通用默认范围" examples: - - "bk-cli aidev list_tags --scope_name agent" + - "bk-cli aidev list_tags" + - "bk-cli aidev list_tags --scope_name BUSINESS" diff --git a/cmd/system/register_test.go b/cmd/system/register_test.go index 189c4c5..babd033 100644 --- a/cmd/system/register_test.go +++ b/cmd/system/register_test.go @@ -22,6 +22,8 @@ import ( "bytes" "io" "io/fs" + "net/http" + "net/http/httptest" "os" "strings" "testing/fstest" @@ -31,6 +33,7 @@ import ( . "github.com/onsi/gomega" "github.com/spf13/cobra" + systemtest "github.com/TencentBlueKing/bk-cli/cmd/system/testutil" "github.com/TencentBlueKing/bk-cli/internal/output" syslib "github.com/TencentBlueKing/bk-cli/internal/system" systemcmd "github.com/TencentBlueKing/bk-cli/internal/systemcmd" @@ -1189,7 +1192,7 @@ actions: }, "create_credential": { `"credential_type":"custom"`, - `"credential_detail":{"key":"demo-value"}`, + `"credential_detail":{"key":"demo-key","value":"demo-value"}`, }, "bind_credential": { `"resource_type":"mcp"`, @@ -1199,7 +1202,7 @@ actions: }, "update_credential": { `"credential_type":"custom"`, - `"credential_detail":{"key":"demo-value"}`, + `"credential_detail":{"key":"demo-key","value":"demo-value"}`, }, } for actionName, expectedFragments := range expectedHelpExamples { @@ -1292,6 +1295,69 @@ actions: Expect(upload.Short).To(ContainSubstring("返回上传成功不等于资源已同步")) }) + DescribeTable("requires an AIDev DELETE body before resolving credentials", func(name, flag string) { + GinkgoT().Setenv("BK_CLI_CONFIG_DIR", GinkgoT().TempDir()) + root := &cobra.Command{Use: "bk-cli", SilenceUsage: true, SilenceErrors: true} + Expect(registerSystemSpecs(root, systemCatalog(), testBuildDeps(nil), actionsFS)).To(Succeed()) + root.SetArgs([]string{"aidev", name, "--" + flag, "1"}) + err := root.Execute() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("required parameter --body is missing")) + }, + Entry("archive_skill", "archive_skill", "skill_id"), + Entry("archive_agent", "archive_agent", "agent_id"), + Entry("delete_knowledgebase", "delete_knowledgebase", "id"), + Entry("delete_knowledge", "delete_knowledge", "id"), + Entry("delete_credential", "delete_credential", "credential_id"), + ) + + DescribeTable("sends space_id in the AIDev DELETE JSON body", func(name, flag, path string) { + GinkgoT().Setenv("BK_CLI_CONFIG_DIR", GinkgoT().TempDir()) + var received bool + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer GinkgoRecover() + received = true + Expect(r.Method).To(Equal(http.MethodDelete)) + Expect(r.URL.Path).To(Equal("/bk-aidev/prod/openapi/aidev/private/v1/" + path + "/1/")) + Expect(r.URL.RawQuery).To(BeEmpty()) + Expect(r.Header.Get("Content-Type")).To(Equal("application/json")) + var body map[string]any + Expect(json.NewDecoder(r.Body).Decode(&body)).To(Succeed()) + Expect(body).To(Equal(map[string]any{"space_id": "demo-space"})) + _, _ = w.Write([]byte(`{"deleted":true}`)) + })) + DeferCleanup(server.Close) + Expect(systemtest.SetupTestContext(server.URL)).To(Succeed()) + root := &cobra.Command{Use: "bk-cli"} + Expect(registerSystemSpecs(root, systemCatalog(), testBuildDeps(nil), actionsFS)).To(Succeed()) + root.SetArgs([]string{"aidev", name, "--" + flag, "1", "--body", `{"space_id":"demo-space"}`}) + _, err := systemtest.CaptureCommandStdout(root.Execute) + Expect(err).NotTo(HaveOccurred()) + Expect(received).To(BeTrue()) + action, _, err := root.Find([]string{"aidev", name}) + Expect(err).NotTo(HaveOccurred()) + Expect(action.Flag("body").Usage).To(ContainSubstring("[Required]")) + var out bytes.Buffer + action.SetOut(&out) + root.SetArgs([]string{"aidev", name, "-h", "--body-schema"}) + Expect(root.Execute()).To(Succeed()) + var schema struct { + Required []string `json:"required"` + } + Expect( + json.Unmarshal([]byte(strings.TrimPrefix(out.String(), "Request body schema:\n")), &schema), + ).To( + Succeed(), + ) + Expect(schema.Required).To(ContainElement("space_id")) + }, + Entry("archive_skill", "archive_skill", "skill_id", "skills"), + Entry("archive_agent", "archive_agent", "agent_id", "agents"), + Entry("delete_knowledgebase", "delete_knowledgebase", "id", "knowledgebase"), + Entry("delete_knowledge", "delete_knowledge", "id", "knowledges"), + Entry("delete_credential", "delete_credential", "credential_id", "credentials"), + ) + It("shows the updated AIDev knowledge request schema", func() { root := &cobra.Command{Use: "bk-cli"} Expect(registerSystemSpecs(root, systemCatalog(), testBuildDeps(nil), actionsFS)).To(Succeed()) diff --git a/docs/user-guide.md b/docs/user-guide.md index fa334a9..bd7f114 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -282,27 +282,16 @@ bk-cli api bk-demo POST /api/v2/resources/ \ ``` bk-cli apigateway list_gateways --name bk-iam --fuzzy -bk-cli aidev list_spaces --keyword demo -bk-cli aidev list_tags --scope_name agent bk-cli cmdb search_business --bk_biz_id 2 bk-cli paas create_cloud_native_app -h --body-schema ``` -AIDev action 名称与最新资源配置中的操作 ID 一致,例如 `list_skills`、`get_skill`、`upsert_skill` 和 `upload_file`。文件上传示例: - -``` -bk-cli aidev upload_file --file ./artifact.zip --space_id demo-space -``` - -文件必须存在且为可读的常规文件,上传时流式读取内容。使用 `--dry-run` 时仍会检查本地文件,预览 body 中的 `size` 表示文件大小(字节),不会读取或上传文件内容。 - -支持 Bearer 鉴权的部署可使用 `auth login --personal_token` 登录后上传。`--dry-run` 会隐藏认证头的 token,同时保留 multipart 类型和文件元数据。 +各 system 的详细用法和示例请查看对应的 [skills](../skills/)。 如果你不知道参数怎么写,最稳妥的方式就是: ``` bk-cli apigateway list_gateways --help -bk-cli aidev upsert_skill -h --body-schema bk-cli cmdb search_business --help ``` diff --git a/skills/bk-cli-aidev/SKILL.md b/skills/bk-cli-aidev/SKILL.md index 1deeedd..78240d3 100644 --- a/skills/bk-cli-aidev/SKILL.md +++ b/skills/bk-cli-aidev/SKILL.md @@ -19,7 +19,7 @@ CRITICAL — 开始前 MUST 先读取 `../bk-cli-shared/SKILL.md`。共享 skill - 调用 AIDev 前,按共享 skill 配置当前 context 的登录凭据,并确保身份具有对应空间和 API 权限。支持 Bearer 鉴权的部署可使用个人 token;使用应用与用户凭据时,需要同时提供两种身份并申请对应 API 权限。 - CLI flag 名保持上游 OpenAPI 参数名不变,例如 `space_id`、`skill_id`、`mcp_type`、`agent_code`、`page_size`。 -- 列表类命令的 `space_id` 通常可省略或传 `all`,表示查询当前租户内所有有权限空间;传具体 ID 时只查询该空间。 +- `list_skills`、`list_agents` 等 GET 列表的 `space_id` 可省略或传 `all`,表示查询当前租户内所有有权限空间;`list_knowledges` 必须在 body 中传真实空间 ID,不支持 `all`。 - 带复杂 request body 的 action 统一通过共享 `--body ''` 传入;执行时要求请求体的 action 会在本地校验 `--body` 非空。 - 查看请求体结构时使用 `bk-cli aidev -h --body-schema`。 - `upload_file` 是文件上传命令,使用 `--file`、`--space_id` 和可选 `--module` 发送 `multipart/form-data`,不使用 `--body`。 @@ -84,11 +84,11 @@ bk-cli aidev get_skill --skill_id 1 --space_id demo-space --version v1.0.0 #### `archive_skill` ```bash -bk-cli aidev archive_skill --skill_id 1 +bk-cli aidev archive_skill --skill_id 1 --body '{"space_id":"demo-space"}' ``` - 归档指定 Skill。先核对目标 ID、版本和 Agent 引用,再执行。 -- 必填:`skill_id`。 +- 必填:`skill_id` 和包含真实 `space_id` 的 DELETE 请求体;通过 `--body` 显式传入空间 ID,不支持 `all`。 #### `get_skill_download_url` @@ -125,10 +125,11 @@ bk-cli aidev list_mcps --space_id all --fuzzy demo --page 1 --page_size 20 ```bash bk-cli aidev create_mcp \ - --body '{"space_id":"demo-space","mcp_name":"Demo MCP","mcp_code":"demo-mcp","url":"bkrepo://demo.zip","protocol":"stdio","credential_type":"custom","description":"demo description"}' + --body '{"space_id":"demo-space","mcp_name":"Demo MCP","mcp_code":"demo-mcp","url":"https://mcp.example.com/mcp","protocol":"streamable_http","credential_type":"custom","description":"demo description","credential_id":1}' ``` - 在指定空间创建 MCP 配置。适用于确需新建 MCP 时;Agent 引用已有 MCP 应先使用 by-code 精确查询。 +- `url` 必须是 HTTP(S) MCP 服务地址,不能使用上传制品地址。`credential_type` 为 `custom` 时必须同时传 `credential_id`;`null` 不需要凭证 ID,`blueapps` 还要求蓝鲸网关 URL。 - 请求体结构以 `bk-cli aidev create_mcp -h --body-schema` 为准。 #### `get_mcp` @@ -236,11 +237,11 @@ bk-cli aidev get_agent --agent_id 1 --space_id demo-space --version v1.0.0 #### `archive_agent` ```bash -bk-cli aidev archive_agent --agent_id 1 +bk-cli aidev archive_agent --agent_id 1 --body '{"space_id":"demo-space"}' ``` - 归档指定智能体;已发布的插件应用可能异步下架。适用于明确要移除智能体时,先核对目标 ID 和资源引用。 -- 必填:`agent_id`。 +- 必填:`agent_id` 和包含真实 `space_id` 的 DELETE 请求体;通过 `--body` 显式传入空间 ID,不支持 `all`。 #### `publish_agent` @@ -269,11 +270,11 @@ bk-cli aidev update_agent \ ```bash bk-cli aidev append_agent_admins \ --agent_id 1 \ - --body '{"space_id":"demo-space","agent_id":1}' + --body '{"space_id":"demo-space","agent_id":1,"admins":["username"]}' ``` - 向智能体对应的开发者中心插件追加管理员,保留原有成员;不修改 Agent 使用者或空间权限。适用于 Agent 创建后补充管理员。 -- 必填:`agent_id` 和请求体;调用方需要空间访问和智能体管理权限。 +- 必填:`agent_id` 和请求体;`admins` 必须包含要追加的用户名,省略、`null` 或 `[]` 不会追加任何人。调用方需要空间访问和智能体管理权限。 ### 知识库 @@ -307,11 +308,11 @@ bk-cli aidev list_knowledgebases #### `delete_knowledgebase` ```bash -bk-cli aidev delete_knowledgebase --id 1 +bk-cli aidev delete_knowledgebase --id 1 --body '{"space_id":"demo-space"}' ``` - 删除指定知识库。先确认其中知识、Agent 引用及删除影响,再执行。 -- 必填:`id`。 +- 必填:`id` 和包含真实 `space_id` 的 DELETE 请求体;通过 `--body` 显式传入空间 ID,不支持 `all`。 #### `update_knowledgebase` @@ -339,16 +340,17 @@ bk-cli aidev query_knowledgebase --body '{"space_id":"demo-space","query":"hello ```bash bk-cli aidev create_knowledge \ - --body '{"space_id":"demo-space","knowledge_base_id":1,"knowledge_name":"Demo Knowledge","file_name":"demo.md","file_path":"bkrepo://demo.md"}' + --body '{"space_id":"demo-space","knowledge_base_id":1,"knowledge_name":"Demo Knowledge","file_name":"demo.md","file_path":"demo.md","url":"bkrepo://demo.md"}' ``` - 在指定知识库中创建一条知识文档。适用于单篇新增;批量或整目录 ZIP 同步应选择相应接口。 +- 上传结果放在 `url`;`file_path` 是知识库内相对路径,文件名必须和 `file_name` 一致,例如 `demo.md`。 - 请求体结构以 `bk-cli aidev create_knowledge -h --body-schema` 为准。 #### `batch_create_knowledges` ```bash -bk-cli aidev batch_create_knowledges --body '{"space_id":"demo-space","items":[]}' +bk-cli aidev batch_create_knowledges --body '{"space_id":"demo-space","items":[{"knowledge_base_id":1,"knowledge_name":"Demo Knowledge","file_name":"demo.md","file_path":"demo.md","url":"bkrepo://demo.md"}]}' ``` - 一次创建多条知识文档。适用于已确认同一批输入的多篇新增;整目录 ZIP 同步使用 archive/import。 @@ -357,7 +359,7 @@ bk-cli aidev batch_create_knowledges --body '{"space_id":"demo-space","items":[] #### `batch_update_knowledges` ```bash -bk-cli aidev batch_update_knowledges --body '{"space_id":"demo-space","items":[]}' +bk-cli aidev batch_update_knowledges --body '{"space_id":"demo-space","items":[{"id":1,"knowledge_name":"Updated Knowledge"}]}' ``` - 一次更新多条已有知识文档。适用于每条目标 ID 和修改内容均已确认的批量操作。 @@ -366,7 +368,7 @@ bk-cli aidev batch_update_knowledges --body '{"space_id":"demo-space","items":[] #### `batch_delete_knowledges` ```bash -bk-cli aidev batch_delete_knowledges --body '{"space_id":"demo-space","ids":[]}' +bk-cli aidev batch_delete_knowledges --body '{"space_id":"demo-space","ids":[1]}' ``` - 一次删除多条知识文档。适用于已逐项核对目标 ID 和删除影响的批量清理。 @@ -379,7 +381,7 @@ bk-cli aidev list_knowledges --body '{"space_id":"demo-space"}' ``` - 列出指定知识库或目录内的知识文档;这是只读查询,虽然使用 POST。适用于确认导入后的文档范围或定位文档 ID。 -- 该列表接口通过 body 传查询条件。 +- 该列表接口通过 body 传查询条件,`space_id` 必须是真实空间 ID,不能省略或传 `all`。 #### `preview_knowledge_link` @@ -421,7 +423,7 @@ bk-cli aidev preview_knowledge --id 1 --space_id demo-space ```bash bk-cli aidev get_knowledge_status --space_id demo-space -bk-cli aidev get_knowledge_status --space_id demo-space --anchor_path / --group_type document +bk-cli aidev get_knowledge_status --space_id demo-space --anchor_path /1 --group_type document ``` - 按空间和 anchor_path 查询知识处理状态统计及可见的 ZIP 导入任务。适用于导入前检查是否已有任务,或提交后查询进度;不触发重试。 @@ -430,10 +432,11 @@ bk-cli aidev get_knowledge_status --space_id demo-space --anchor_path / --group_ #### `trigger_knowledge_update` ```bash -bk-cli aidev trigger_knowledge_update --body '{"space_id":"demo-space"}' +bk-cli aidev trigger_knowledge_update --body '{"space_id":"demo-space","id":1}' ``` - 触发已有知识文档的更新任务。适用于明确需要重新抓取或更新时;可能产生后台处理。 +- 不传 `anchor_path` 时必须提供文档 `id`;示例更新知识文档 1。 - 要求 `--body`,结构以 `bk-cli aidev trigger_knowledge_update -h --body-schema` 为准。 #### `list_knowledge_update_frequencies` @@ -456,20 +459,21 @@ bk-cli aidev get_knowledge_index_info --id 1 --space_id demo-space #### `reclean_knowledge` ```bash -bk-cli aidev reclean_knowledge --body '{"space_id":"demo-space"}' +bk-cli aidev reclean_knowledge --body '{"space_id":"demo-space","id":1}' ``` - 按当前或指定导入链路重新清洗并重建知识产物。适用于确认现有产物需重建时;会触发后台处理。 +- 请求体中 `id` 或非空 `ids` 至少提供一个,选定待重新清洗的文档。 - 要求 `--body`,结构以 `bk-cli aidev reclean_knowledge -h --body-schema` 为准。 #### `delete_knowledge` ```bash -bk-cli aidev delete_knowledge --id 1 +bk-cli aidev delete_knowledge --id 1 --body '{"space_id":"demo-space"}' ``` - 删除指定知识文档。适用于明确移除单篇文档时,先确认 ID 和影响。 -- 必填:`id`。 +- 必填:`id` 和包含真实 `space_id` 的 DELETE 请求体;通过 `--body` 显式传入空间 ID,不支持 `all`。 #### `update_knowledge` @@ -486,10 +490,11 @@ bk-cli aidev update_knowledge \ ```bash bk-cli aidev import_knowledge_archive \ - --body '{"space_id":"demo-space","url":"bkrepo://demo.zip","file_name":"demo","file_type":"zip","anchor_path":"/"}' + --body '{"space_id":"demo-space","url":"bkrepo://demo.zip","file_name":"demo","file_type":"zip","anchor_path":"/1"}' ``` - 将已上传或远程 ZIP 异步导入指定 anchor_path,并覆盖目标目录内容。适用于目录化文档同步;返回任务 ID 后用相同 anchor_path 查询 status_info,不应把提交成功当作处理完成。 +- `anchor_path` 必须为 `/<知识库ID>` 或 `/<知识库ID>/<目录>`,不能只传 `/`;示例 `/1` 指知识库 1。 - 导入进度可用相同 `anchor_path` 调用 `get_knowledge_status` 查询。 ### 凭证 @@ -516,10 +521,11 @@ bk-cli aidev list_credentials --space_id all --credential_name demo --credential ```bash bk-cli aidev create_credential \ - --body '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-value"},"space_id":"demo-space"}' + --body '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-key","value":"demo-value"},"space_id":"demo-space"}' ``` - 在指定空间创建凭证配置,返回凭证 ID。仅在明确需要新凭证且字段已确认时调用;凭证生命周期与绑定关系分开管理。 +- 先用 `list_credential_types` 确认类型字段;`custom` 的 `credential_detail` 需要 `key` 和 `value`。 - 请求体结构以 `bk-cli aidev create_credential -h --body-schema` 为准。 #### `update_credential` @@ -527,7 +533,7 @@ bk-cli aidev create_credential \ ```bash bk-cli aidev update_credential \ --credential_id 1 \ - --body '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-value"},"space_id":"demo-space","credential_id":1}' + --body '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-key","value":"demo-value"},"space_id":"demo-space","credential_id":1}' ``` - 更新指定凭证的配置。适用于已核对凭证 ID、需要变更字段时;可能影响已绑定该凭证的资源。 @@ -536,7 +542,7 @@ bk-cli aidev update_credential \ #### `batch_delete_credentials` ```bash -bk-cli aidev batch_delete_credentials --body '{"space_id":"demo-space","credential_ids":[]}' +bk-cli aidev batch_delete_credentials --body '{"space_id":"demo-space","credential_ids":[1]}' ``` - 批量删除指定凭证;先逐项确认 ID 与引用关系。适用于一次清理多个已确认不再使用的凭证。 @@ -545,11 +551,11 @@ bk-cli aidev batch_delete_credentials --body '{"space_id":"demo-space","credenti #### `delete_credential` ```bash -bk-cli aidev delete_credential --credential_id 1 +bk-cli aidev delete_credential --credential_id 1 --body '{"space_id":"demo-space"}' ``` - 删除指定凭证。先查询引用并确认解绑或影响范围,再执行删除。 -- 必填:`credential_id`。 +- 必填:`credential_id` 和包含真实 `space_id` 的 DELETE 请求体;通过 `--body` 显式传入空间 ID,不支持 `all`。 #### `bind_credential` @@ -583,11 +589,12 @@ bk-cli aidev list_credential_references --credential_id 1 --space_id demo-space #### `list_tags` ```bash -bk-cli aidev list_tags --scope_name agent +bk-cli aidev list_tags +bk-cli aidev list_tags --scope_name BUSINESS ``` - 获取当前租户指定范围的全量标签树,供智能体配置时选择标签;无需指定空间或智能体。 -- 可选:`scope_name`,例如 `agent`;省略时使用默认标签范围。 +- 可选:`scope_name`。省略时使用部署配置的智能体标签范围(默认 `default`),业务范围为 `BUSINESS`。`agent` 不是范围名;未识别的值会回退到通用默认范围。 ### 资源引用与资源集合 @@ -614,10 +621,11 @@ bk-cli aidev list_collections --space_id all --collection_code demo-collection ```bash bk-cli aidev upsert_collection \ - --body '{"space_id":"demo-space","collection_code":"demo-collection","collection_name":"Demo Collection","content":[]}' + --body '{"space_id":"demo-space","collection_code":"demo-collection","collection_name":"Demo Collection","content":[{"role":"system","content":"你是示例角色"}]}' ``` - 按 collection_code 创建或更新角色 Prompt Collection,并返回 collection_id。适用于同步 Agent 所引用的角色指令;已有编码会更新线上内容。 +- `content` 至少包含一条消息,第一条 `role` 必须为 `system`,消息 `content` 不能为空。 - 请求体结构以 `bk-cli aidev upsert_collection -h --body-schema` 为准。 #### `get_collection` @@ -633,7 +641,7 @@ bk-cli aidev get_collection --collection_id 1 --space_id demo-space ```bash bk-cli aidev apply_cross_space_resources \ - --body '{"space_id":"demo-space","resource_type":"skill","resource_ids":[]}' + --body '{"space_id":"demo-space","resource_type":"skill","resource_ids":[1]}' ``` - 为指定资源发起跨空间使用申请,返回请求 ID 和审批工单信息。适用于目标空间尚无资源使用权限时;提交申请不等于授权已生效。 @@ -655,11 +663,12 @@ bk-cli aidev upload_file --file ./knowledge.zip --space_id demo-space --module k #### `get_upload_url` ```bash -bk-cli aidev get_upload_url --body '{"space_id":"demo-space","file_name":"demo.md"}' +bk-cli aidev get_upload_url --body '{"space_id":"demo-space","file_name":"demo.zip","module":"skill"}' ``` - 为 Skill 或知识 ZIP 申请限时、一次性的直传地址。适用于大文件直传;取得地址后仍需上传文件并校验状态。 -- 文件直传后再分别调用知识 ZIP 导入或 Skill upsert。 +- `module` 默认 `knowledge`,Skill 直传必须显式指定 `"module":"skill"`;知识 ZIP 使用 `"module":"knowledge"`。 +- 返回的 `upload_url` 只用于一次性上传;上传成功后,用返回的 `url` 调用 Skill upsert、知识 ZIP 导入或 `check_upload_status`。 #### `check_upload_status` diff --git a/tests/integration/cases/system/aidev/AIDEV-006-aidev-archive_skill.yaml b/tests/integration/cases/system/aidev/AIDEV-006-aidev-archive_skill.yaml index 21c46e1..af530ca 100644 --- a/tests/integration/cases/system/aidev/AIDEV-006-aidev-archive_skill.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-006-aidev-archive_skill.yaml @@ -15,6 +15,17 @@ steps: checks: - path: ok equals: true +- name: reject missing DELETE body before login + command: + - aidev + - archive_skill + - --skill_id + - '1' + expect: + exit_code: 1 + checks: + - path: error.code + equals: missing_param - name: login command: - auth @@ -32,6 +43,8 @@ steps: - archive_skill - --skill_id - '1' + - --body + - '{"space_id":"demo-space"}' expect: exit_code: 0 checks: @@ -41,3 +54,5 @@ steps: equals: DELETE - path: data.path contains: /bk-aidev/prod/openapi/aidev/private/v1/skills/1/ + - path: data.body.space_id + equals: demo-space diff --git a/tests/integration/cases/system/aidev/AIDEV-010-aidev-create_mcp.yaml b/tests/integration/cases/system/aidev/AIDEV-010-aidev-create_mcp.yaml index 00a1436..c256d95 100644 --- a/tests/integration/cases/system/aidev/AIDEV-010-aidev-create_mcp.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-010-aidev-create_mcp.yaml @@ -31,8 +31,7 @@ steps: - aidev - create_mcp - --body - - '{"space_id":"demo-space","mcp_name":"demo-mcp_name","mcp_code":"demo-mcp","url":"bkrepo://demo.zip","protocol":"stdio","credential_type":"custom","description":"demo - description"}' + - '{"space_id":"demo-space","mcp_name":"Demo MCP","mcp_code":"demo-mcp","url":"https://mcp.example.com/mcp","protocol":"streamable_http","credential_type":"custom","description":"demo description","credential_id":1}' expect: exit_code: 0 checks: @@ -44,3 +43,7 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/mcps/ - path: data.body.space_id equals: demo-space + - path: data.body.url + equals: "https://mcp.example.com/mcp" + - path: data.body.credential_id + equals: 1 diff --git a/tests/integration/cases/system/aidev/AIDEV-020-aidev-archive_agent.yaml b/tests/integration/cases/system/aidev/AIDEV-020-aidev-archive_agent.yaml index 6c3c9ad..1a3dbb0 100644 --- a/tests/integration/cases/system/aidev/AIDEV-020-aidev-archive_agent.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-020-aidev-archive_agent.yaml @@ -15,6 +15,17 @@ steps: checks: - path: ok equals: true +- name: reject missing DELETE body before login + command: + - aidev + - archive_agent + - --agent_id + - '1' + expect: + exit_code: 1 + checks: + - path: error.code + equals: missing_param - name: login command: - auth @@ -32,6 +43,8 @@ steps: - archive_agent - --agent_id - '1' + - --body + - '{"space_id":"demo-space"}' expect: exit_code: 0 checks: @@ -41,3 +54,5 @@ steps: equals: DELETE - path: data.path contains: /bk-aidev/prod/openapi/aidev/private/v1/agents/1/ + - path: data.body.space_id + equals: "demo-space" diff --git a/tests/integration/cases/system/aidev/AIDEV-026-aidev-delete_knowledgebase.yaml b/tests/integration/cases/system/aidev/AIDEV-026-aidev-delete_knowledgebase.yaml index f093c87..98d3df4 100644 --- a/tests/integration/cases/system/aidev/AIDEV-026-aidev-delete_knowledgebase.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-026-aidev-delete_knowledgebase.yaml @@ -15,6 +15,17 @@ steps: checks: - path: ok equals: true +- name: reject missing DELETE body before login + command: + - aidev + - delete_knowledgebase + - --id + - '1' + expect: + exit_code: 1 + checks: + - path: error.code + equals: missing_param - name: login command: - auth @@ -32,6 +43,8 @@ steps: - delete_knowledgebase - --id - '1' + - --body + - '{"space_id":"demo-space"}' expect: exit_code: 0 checks: @@ -41,3 +54,5 @@ steps: equals: DELETE - path: data.path contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledgebase/1/ + - path: data.body.space_id + equals: "demo-space" diff --git a/tests/integration/cases/system/aidev/AIDEV-028-aidev-create_knowledge.yaml b/tests/integration/cases/system/aidev/AIDEV-028-aidev-create_knowledge.yaml index 98401ba..11d8ebc 100644 --- a/tests/integration/cases/system/aidev/AIDEV-028-aidev-create_knowledge.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-028-aidev-create_knowledge.yaml @@ -31,7 +31,7 @@ steps: - aidev - create_knowledge - --body - - '{"space_id":"demo-space","knowledge_base_id":1,"knowledge_name":"Demo Knowledge","file_name":"demo.md","file_path":"bkrepo://demo.md"}' + - '{"space_id":"demo-space","knowledge_base_id":1,"knowledge_name":"Demo Knowledge","file_name":"demo.md","file_path":"demo.md","url":"bkrepo://demo.md"}' expect: exit_code: 0 checks: @@ -43,3 +43,7 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/ - path: data.body.space_id equals: demo-space + - path: data.body.file_path + equals: "demo.md" + - path: data.body.url + equals: "bkrepo://demo.md" diff --git a/tests/integration/cases/system/aidev/AIDEV-029-aidev-batch_create_knowledges.yaml b/tests/integration/cases/system/aidev/AIDEV-029-aidev-batch_create_knowledges.yaml index 68f2380..d2bea0f 100644 --- a/tests/integration/cases/system/aidev/AIDEV-029-aidev-batch_create_knowledges.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-029-aidev-batch_create_knowledges.yaml @@ -31,7 +31,7 @@ steps: - aidev - batch_create_knowledges - --body - - '{"space_id":"demo-space","items":[]}' + - '{"space_id":"demo-space","items":[{"knowledge_base_id":1,"knowledge_name":"Demo Knowledge","file_name":"demo.md","file_path":"demo.md","url":"bkrepo://demo.md"}]}' expect: exit_code: 0 checks: @@ -43,3 +43,7 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/batch/create/ - path: data.body.space_id equals: demo-space + - path: data.body.items.0.file_path + equals: "demo.md" + - path: data.body.items.0.url + equals: "bkrepo://demo.md" diff --git a/tests/integration/cases/system/aidev/AIDEV-030-aidev-batch_delete_knowledges.yaml b/tests/integration/cases/system/aidev/AIDEV-030-aidev-batch_delete_knowledges.yaml index 3ca7583..05fe0c1 100644 --- a/tests/integration/cases/system/aidev/AIDEV-030-aidev-batch_delete_knowledges.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-030-aidev-batch_delete_knowledges.yaml @@ -31,7 +31,7 @@ steps: - aidev - batch_delete_knowledges - --body - - '{"space_id":"demo-space","ids":[]}' + - '{"space_id":"demo-space","ids":[1]}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/batch/delete/ - path: data.body.space_id equals: demo-space + - path: data.body.ids.0 + equals: 1 diff --git a/tests/integration/cases/system/aidev/AIDEV-031-aidev-batch_update_knowledges.yaml b/tests/integration/cases/system/aidev/AIDEV-031-aidev-batch_update_knowledges.yaml index 53578be..7016fa2 100644 --- a/tests/integration/cases/system/aidev/AIDEV-031-aidev-batch_update_knowledges.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-031-aidev-batch_update_knowledges.yaml @@ -31,7 +31,7 @@ steps: - aidev - batch_update_knowledges - --body - - '{"space_id":"demo-space","items":[]}' + - '{"space_id":"demo-space","items":[{"id":1,"knowledge_name":"Updated Knowledge"}]}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/batch/update/ - path: data.body.space_id equals: demo-space + - path: data.body.items.0.id + equals: 1 diff --git a/tests/integration/cases/system/aidev/AIDEV-036-aidev-trigger_knowledge_update.yaml b/tests/integration/cases/system/aidev/AIDEV-036-aidev-trigger_knowledge_update.yaml index e61aa2b..0ce9e0e 100644 --- a/tests/integration/cases/system/aidev/AIDEV-036-aidev-trigger_knowledge_update.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-036-aidev-trigger_knowledge_update.yaml @@ -31,7 +31,7 @@ steps: - aidev - trigger_knowledge_update - --body - - '{"space_id":"demo-space"}' + - '{"space_id":"demo-space","id":1}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/trigger/ - path: data.body.space_id equals: demo-space + - path: data.body.id + equals: 1 diff --git a/tests/integration/cases/system/aidev/AIDEV-039-aidev-delete_knowledge.yaml b/tests/integration/cases/system/aidev/AIDEV-039-aidev-delete_knowledge.yaml index 8bcf528..69f6c16 100644 --- a/tests/integration/cases/system/aidev/AIDEV-039-aidev-delete_knowledge.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-039-aidev-delete_knowledge.yaml @@ -15,6 +15,17 @@ steps: checks: - path: ok equals: true +- name: reject missing DELETE body before login + command: + - aidev + - delete_knowledge + - --id + - '1' + expect: + exit_code: 1 + checks: + - path: error.code + equals: missing_param - name: login command: - auth @@ -32,6 +43,8 @@ steps: - delete_knowledge - --id - '1' + - --body + - '{"space_id":"demo-space"}' expect: exit_code: 0 checks: @@ -41,3 +54,5 @@ steps: equals: DELETE - path: data.path contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/1/ + - path: data.body.space_id + equals: "demo-space" diff --git a/tests/integration/cases/system/aidev/AIDEV-045-aidev-create_credential.yaml b/tests/integration/cases/system/aidev/AIDEV-045-aidev-create_credential.yaml index 8d32505..5a95bb8 100644 --- a/tests/integration/cases/system/aidev/AIDEV-045-aidev-create_credential.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-045-aidev-create_credential.yaml @@ -31,7 +31,7 @@ steps: - aidev - create_credential - --body - - '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-value"},"space_id":"demo-space"}' + - '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-key","value":"demo-value"},"space_id":"demo-space"}' expect: exit_code: 0 checks: @@ -43,3 +43,7 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/credentials/ - path: data.body.credential_name equals: demo-credential + - path: data.body.credential_detail.key + equals: "demo-key" + - path: data.body.credential_detail.value + equals: "demo-value" diff --git a/tests/integration/cases/system/aidev/AIDEV-046-aidev-batch_delete_credentials.yaml b/tests/integration/cases/system/aidev/AIDEV-046-aidev-batch_delete_credentials.yaml index 9f60777..fd528fe 100644 --- a/tests/integration/cases/system/aidev/AIDEV-046-aidev-batch_delete_credentials.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-046-aidev-batch_delete_credentials.yaml @@ -31,7 +31,7 @@ steps: - aidev - batch_delete_credentials - --body - - '{"space_id":"demo-space","credential_ids":[]}' + - '{"space_id":"demo-space","credential_ids":[1]}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/credentials/batch_delete/ - path: data.body.space_id equals: demo-space + - path: data.body.credential_ids.0 + equals: 1 diff --git a/tests/integration/cases/system/aidev/AIDEV-049-aidev-delete_credential.yaml b/tests/integration/cases/system/aidev/AIDEV-049-aidev-delete_credential.yaml index d8a498e..70565d8 100644 --- a/tests/integration/cases/system/aidev/AIDEV-049-aidev-delete_credential.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-049-aidev-delete_credential.yaml @@ -15,6 +15,17 @@ steps: checks: - path: ok equals: true +- name: reject missing DELETE body before login + command: + - aidev + - delete_credential + - --credential_id + - '1' + expect: + exit_code: 1 + checks: + - path: error.code + equals: missing_param - name: login command: - auth @@ -32,6 +43,8 @@ steps: - delete_credential - --credential_id - '1' + - --body + - '{"space_id":"demo-space"}' expect: exit_code: 0 checks: @@ -41,3 +54,5 @@ steps: equals: DELETE - path: data.path contains: /bk-aidev/prod/openapi/aidev/private/v1/credentials/1/ + - path: data.body.space_id + equals: "demo-space" diff --git a/tests/integration/cases/system/aidev/AIDEV-051-aidev-update_credential.yaml b/tests/integration/cases/system/aidev/AIDEV-051-aidev-update_credential.yaml index 4312d63..7c5b91b 100644 --- a/tests/integration/cases/system/aidev/AIDEV-051-aidev-update_credential.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-051-aidev-update_credential.yaml @@ -33,7 +33,7 @@ steps: - --credential_id - '1' - --body - - '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-value"},"space_id":"demo-space","credential_id":1}' + - '{"credential_name":"demo-credential","credential_type":"custom","credential_detail":{"key":"demo-key","value":"demo-value"},"space_id":"demo-space","credential_id":1}' expect: exit_code: 0 checks: @@ -45,3 +45,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/credentials/1/update/ - path: data.body.credential_name equals: demo-credential + - path: data.body.credential_detail.value + equals: "demo-value" diff --git a/tests/integration/cases/system/aidev/AIDEV-052-aidev-reclean_knowledge.yaml b/tests/integration/cases/system/aidev/AIDEV-052-aidev-reclean_knowledge.yaml index f3e16d8..080450d 100644 --- a/tests/integration/cases/system/aidev/AIDEV-052-aidev-reclean_knowledge.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-052-aidev-reclean_knowledge.yaml @@ -31,7 +31,7 @@ steps: - aidev - reclean_knowledge - --body - - '{"space_id":"demo-space"}' + - '{"space_id":"demo-space","id":1}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/reclean/ - path: data.body.space_id equals: demo-space + - path: data.body.id + equals: 1 diff --git a/tests/integration/cases/system/aidev/AIDEV-055-aidev-upsert_collection.yaml b/tests/integration/cases/system/aidev/AIDEV-055-aidev-upsert_collection.yaml index 6f56f11..cfc5743 100644 --- a/tests/integration/cases/system/aidev/AIDEV-055-aidev-upsert_collection.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-055-aidev-upsert_collection.yaml @@ -31,8 +31,7 @@ steps: - aidev - upsert_collection - --body - - '{"space_id":"demo-space","collection_code":"demo-collection","collection_name":"demo - collection","content":[]}' + - '{"space_id":"demo-space","collection_code":"demo-collection","collection_name":"Demo Collection","content":[{"role":"system","content":"你是示例角色"}]}' expect: exit_code: 0 checks: @@ -44,3 +43,7 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/collections/upsert/ - path: data.body.space_id equals: demo-space + - path: data.body.content.0.role + equals: "system" + - path: data.body.content.0.content + equals: "你是示例角色" diff --git a/tests/integration/cases/system/aidev/AIDEV-057-aidev-import_knowledge_archive.yaml b/tests/integration/cases/system/aidev/AIDEV-057-aidev-import_knowledge_archive.yaml index 672b5cf..7a1aa63 100644 --- a/tests/integration/cases/system/aidev/AIDEV-057-aidev-import_knowledge_archive.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-057-aidev-import_knowledge_archive.yaml @@ -31,7 +31,7 @@ steps: - aidev - import_knowledge_archive - --body - - '{"space_id":"demo-space","url":"bkrepo://demo.zip","file_name":"demo","file_type":"zip","anchor_path":"/"}' + - '{"space_id":"demo-space","url":"bkrepo://demo.zip","file_name":"demo","file_type":"zip","anchor_path":"/1"}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/knowledges/archive/import/ - path: data.body.space_id equals: demo-space + - path: data.body.anchor_path + equals: "/1" diff --git a/tests/integration/cases/system/aidev/AIDEV-060-aidev-apply_cross_space_resources.yaml b/tests/integration/cases/system/aidev/AIDEV-060-aidev-apply_cross_space_resources.yaml index a5d24c3..2a4b6fe 100644 --- a/tests/integration/cases/system/aidev/AIDEV-060-aidev-apply_cross_space_resources.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-060-aidev-apply_cross_space_resources.yaml @@ -31,7 +31,7 @@ steps: - aidev - apply_cross_space_resources - --body - - '{"space_id":"demo-space","resource_type":"skill","resource_ids":[]}' + - '{"space_id":"demo-space","resource_type":"skill","resource_ids":[1]}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/space_manage/apply_resources/ - path: data.body.space_id equals: demo-space + - path: data.body.resource_ids.0 + equals: 1 diff --git a/tests/integration/cases/system/aidev/AIDEV-062-aidev-get_upload_url.yaml b/tests/integration/cases/system/aidev/AIDEV-062-aidev-get_upload_url.yaml index e1bd751..6ece8ce 100644 --- a/tests/integration/cases/system/aidev/AIDEV-062-aidev-get_upload_url.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-062-aidev-get_upload_url.yaml @@ -31,7 +31,7 @@ steps: - aidev - get_upload_url - --body - - '{"space_id":"demo-space","file_name":"demo.md"}' + - '{"space_id":"demo-space","file_name":"demo.zip","module":"skill"}' expect: exit_code: 0 checks: @@ -43,3 +43,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/upload/url/ - path: data.body.space_id equals: demo-space + - path: data.body.module + equals: "skill" diff --git a/tests/integration/cases/system/aidev/AIDEV-063-aidev-append_agent_admins.yaml b/tests/integration/cases/system/aidev/AIDEV-063-aidev-append_agent_admins.yaml index 72ec8cb..5406930 100644 --- a/tests/integration/cases/system/aidev/AIDEV-063-aidev-append_agent_admins.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-063-aidev-append_agent_admins.yaml @@ -33,7 +33,7 @@ steps: - --agent_id - '1' - --body - - '{"space_id":"demo-space","agent_id":1}' + - '{"space_id":"demo-space","agent_id":1,"admins":["username"]}' expect: exit_code: 0 checks: @@ -45,3 +45,5 @@ steps: contains: /bk-aidev/prod/openapi/aidev/private/v1/agents/1/admins/ - path: data.body.space_id equals: demo-space + - path: data.body.admins.0 + equals: "username" diff --git a/tests/integration/cases/system/aidev/AIDEV-065-aidev-list_tags.yaml b/tests/integration/cases/system/aidev/AIDEV-065-aidev-list_tags.yaml index 47f8b46..e39e85a 100644 --- a/tests/integration/cases/system/aidev/AIDEV-065-aidev-list_tags.yaml +++ b/tests/integration/cases/system/aidev/AIDEV-065-aidev-list_tags.yaml @@ -31,7 +31,7 @@ steps: - aidev - list_tags - --scope_name - - agent + - BUSINESS expect: exit_code: 0 checks: @@ -42,4 +42,4 @@ steps: - path: data.path contains: /bk-aidev/prod/openapi/aidev/private/v1/tags/ - path: data.query.scope_name - equals: agent + equals: BUSINESS