gaoding-cli 1.0.0-alpha.13 → 1.0.0-alpha.14

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 (39) hide show
  1. package/README.md +3 -2
  2. package/contracts/operations/agent.send/input.schema.json +4 -0
  3. package/contracts/operations/model.get/output.schema.json +1 -0
  4. package/dist/bin/gd-cli.js +3 -1
  5. package/dist/src/bootstrap/create-cli.js +36 -3
  6. package/dist/src/bootstrap/create-runtime.js +32 -7
  7. package/dist/src/cli/action-binding.js +43 -9
  8. package/dist/src/cli/agent-commands.js +13 -3
  9. package/dist/src/cli/auth-commands.js +21 -13
  10. package/dist/src/cli/dam-commands.js +35 -20
  11. package/dist/src/cli/errors.js +19 -1
  12. package/dist/src/cli/model-commands.js +41 -11
  13. package/dist/src/cli/org-commands.js +18 -12
  14. package/dist/src/cli/presenter.js +11 -1
  15. package/dist/src/cli/tool-commands.js +19 -7
  16. package/dist/src/cli/update-command.js +6 -4
  17. package/dist/src/features/agent/creative-agent-adapter.js +19 -14
  18. package/dist/src/features/agent/creative-protocol.js +7 -3
  19. package/dist/src/features/agent/use-cases.js +63 -54
  20. package/dist/src/features/auth/use-cases.js +82 -65
  21. package/dist/src/features/dam/asset-projection.js +22 -14
  22. package/dist/src/features/dam/dam-api-adapter.js +19 -4
  23. package/dist/src/features/dam/object-storage.js +2 -0
  24. package/dist/src/features/dam/registered-uploader.js +58 -35
  25. package/dist/src/features/dam/use-cases.js +39 -32
  26. package/dist/src/features/org/use-cases.js +27 -11
  27. package/dist/src/features/tool/catalog.js +7 -3
  28. package/dist/src/features/tool/dynamic-schema.js +19 -9
  29. package/dist/src/features/tool/mns-catalog-adapter.js +7 -4
  30. package/dist/src/features/tool/tool-api-adapter.js +35 -33
  31. package/dist/src/features/tool/use-cases.js +68 -36
  32. package/dist/src/features/update/update-service.js +28 -22
  33. package/dist/src/platform/json-input.js +3 -0
  34. package/dist/src/platform/remote-protocol.js +6 -0
  35. package/dist/src/telemetry/invocation.js +128 -0
  36. package/dist/src/telemetry/sls-sink.js +31 -0
  37. package/package.json +1 -1
  38. package/skills/gd-cli/references/creation.md +4 -2
  39. package/skills/gd-cli/references/errors.md +3 -1
@@ -57,20 +57,22 @@ export function createUpdateService(options) {
57
57
  return {
58
58
  async run(signal) {
59
59
  signal.throwIfAborted();
60
- const latest = await fetchLatest(fetchPackage, signal);
60
+ const latest = await options.telemetry.stage("registry", () => (fetchLatest(fetchPackage, signal)));
61
61
  signal.throwIfAborted();
62
62
  const skillOptions = {
63
63
  env,
64
64
  ...(options.homeDirectory ? { homeDirectory: options.homeDirectory } : {})
65
65
  };
66
66
  if (!gt(latest, options.currentVersion)) {
67
- try {
68
- await syncSkills(options.bundledSkills, skillOptions);
69
- }
70
- catch (error) {
71
- rethrowAbort(signal);
72
- throw new UpdateError("UPDATE_FAILED", `gd-cli ${options.currentVersion} 无需更新,但 Agent Skill 同步失败。`, ["请解决冲突后重新执行 gd-cli update。"]);
73
- }
67
+ await options.telemetry.stage("sync", async () => {
68
+ try {
69
+ await syncSkills(options.bundledSkills, skillOptions);
70
+ }
71
+ catch (error) {
72
+ rethrowAbort(signal);
73
+ throw new UpdateError("UPDATE_FAILED", `gd-cli ${options.currentVersion} 无需更新,但 Agent Skill 同步失败。`, ["请解决冲突后重新执行 gd-cli update。"]);
74
+ }
75
+ });
74
76
  return { version: options.currentVersion, updated: false };
75
77
  }
76
78
  const binaryPath = options.binaryPath ?? process.argv[1] ?? "";
@@ -89,25 +91,29 @@ export function createUpdateService(options) {
89
91
  const args = source.manager === "npm"
90
92
  ? ["install", "--global", "--allow-scripts=gaoding-cli", `gaoding-cli@${latest}`]
91
93
  : ["add", "--global", "--allow-build=gaoding-cli", `gaoding-cli@${latest}`];
92
- try {
93
- await runProcess(command, args, signal);
94
- }
95
- catch (error) {
96
- rethrowAbort(signal);
97
- throw new UpdateError("UPDATE_FAILED", `gd-cli 更新到 ${latest} 失败。`, nextSteps);
98
- }
94
+ await options.telemetry.stage("install", async () => {
95
+ try {
96
+ await runProcess(command, args, signal);
97
+ }
98
+ catch (error) {
99
+ rethrowAbort(signal);
100
+ throw new UpdateError("UPDATE_FAILED", `gd-cli 更新到 ${latest} 失败。`, nextSteps);
101
+ }
102
+ });
99
103
  signal.throwIfAborted();
100
104
  const targetSkills = options.bundledSkills.map((skill) => ({
101
105
  ...skill,
102
106
  version: latest
103
107
  }));
104
- try {
105
- await verifySkills(targetSkills, skillOptions);
106
- }
107
- catch (error) {
108
- rethrowAbort(signal);
109
- throw new UpdateError("UPDATE_PARTIAL", `gd-cli 已更新到 ${latest},但 Agent Skill 验收失败。`, ["请重新执行 gd-cli update。"]);
110
- }
108
+ await options.telemetry.stage("verify", async () => {
109
+ try {
110
+ await verifySkills(targetSkills, skillOptions);
111
+ }
112
+ catch (error) {
113
+ rethrowAbort(signal);
114
+ throw new UpdateError("UPDATE_PARTIAL", `gd-cli 已更新到 ${latest},但 Agent Skill 验收失败。`, ["请重新执行 gd-cli update。"]);
115
+ }
116
+ });
111
117
  return { version: latest, updated: true };
112
118
  }
113
119
  };
@@ -52,6 +52,9 @@ function readStream(stream, signal) {
52
52
  };
53
53
  const onAbort = () => {
54
54
  cleanup();
55
+ const destroy = stream.destroy;
56
+ if (typeof destroy === "function")
57
+ destroy.call(stream);
55
58
  reject(signal.reason);
56
59
  };
57
60
  stream.on("data", onData);
@@ -0,0 +1,6 @@
1
+ export class RemoteProtocolError extends Error {
2
+ constructor() {
3
+ super("稿定服务响应与当前 CLI 不兼容。");
4
+ this.name = "RemoteProtocolError";
5
+ }
6
+ }
@@ -0,0 +1,128 @@
1
+ const detailedStages = {
2
+ "auth.login": new Set(["authorize", "wait", "identity", "bind"]),
3
+ "org.switch": new Set(["list", "bind"]),
4
+ "agent.send:execute": new Set(["upload", "execute", "result"]),
5
+ "tool.call:execute": new Set(["catalog", "upload", "intent", "submit", "wait"]),
6
+ "dam.upload": new Set(["inspect", "repository", "prepare", "upload", "persist", "wait"]),
7
+ update: new Set(["registry", "install", "sync", "verify"])
8
+ };
9
+ export function createTelemetryInvocation(options) {
10
+ const invocationId = options.idFactory();
11
+ const startedAt = options.now();
12
+ let definition;
13
+ const context = {};
14
+ const stages = [];
15
+ return {
16
+ invocationId,
17
+ get selected() {
18
+ return definition !== undefined;
19
+ },
20
+ select(nextDefinition) {
21
+ definition = nextDefinition;
22
+ },
23
+ annotate(annotation) {
24
+ if (annotation.account_id !== undefined)
25
+ context.account_id = annotation.account_id;
26
+ if (annotation.organization_id !== undefined) {
27
+ context.organization_id = annotation.organization_id;
28
+ }
29
+ if (annotation.tool_name !== undefined)
30
+ context.tool_name = annotation.tool_name;
31
+ if (annotation.model_id !== undefined)
32
+ context.model_id = annotation.model_id;
33
+ if (annotation.parameters !== undefined) {
34
+ context.parameters = { ...annotation.parameters };
35
+ }
36
+ },
37
+ async stage(name, run) {
38
+ const stageStartedAt = options.now();
39
+ try {
40
+ const result = await run();
41
+ stages.push({
42
+ name,
43
+ durationMs: elapsed(options.now(), stageStartedAt),
44
+ outcome: "success"
45
+ });
46
+ return result;
47
+ }
48
+ catch (error) {
49
+ const classification = options.classifyError(error);
50
+ stages.push({
51
+ name,
52
+ durationMs: elapsed(options.now(), stageStartedAt),
53
+ outcome: classification.outcome,
54
+ error,
55
+ ...(classification.errorCode === undefined
56
+ ? {}
57
+ : { errorCode: classification.errorCode }),
58
+ ...(classification.httpStatus === undefined
59
+ ? {}
60
+ : { httpStatus: classification.httpStatus })
61
+ });
62
+ throw error;
63
+ }
64
+ },
65
+ finish(completion) {
66
+ if (!definition)
67
+ return [];
68
+ const selectedDefinition = definition;
69
+ const mode = selectedDefinition.mode?.();
70
+ const allowedStages = detailedStages[stageKey(selectedDefinition.operation, mode)];
71
+ const stageEvents = allowedStages
72
+ ? stages
73
+ .filter((stage) => allowedStages.has(stage.name))
74
+ .map((stage) => ({
75
+ schema_version: "1",
76
+ event_name: "stage_finished",
77
+ invocation_id: invocationId,
78
+ operation: selectedDefinition.operation,
79
+ stage: stage.name,
80
+ outcome: stage.outcome,
81
+ duration_ms: stage.durationMs,
82
+ ...(stage.errorCode === undefined ? {} : { error_code: stage.errorCode }),
83
+ ...(stage.httpStatus === undefined ? {} : { http_status: stage.httpStatus })
84
+ }))
85
+ : [];
86
+ const command = {
87
+ schema_version: "1",
88
+ event_name: "command_finished",
89
+ invocation_id: invocationId,
90
+ operation: selectedDefinition.operation,
91
+ ...(mode === undefined ? {} : { mode }),
92
+ outcome: completion.outcome,
93
+ duration_ms: elapsed(options.now(), startedAt),
94
+ cli_version: options.cliVersion,
95
+ os: options.runtime.os,
96
+ arch: options.runtime.arch,
97
+ node_major: options.runtime.nodeMajor,
98
+ ...(context.account_id === undefined ? {} : { account_id: context.account_id }),
99
+ ...(context.organization_id === undefined
100
+ ? {}
101
+ : { organization_id: context.organization_id }),
102
+ ...(context.tool_name === undefined ? {} : { tool_name: context.tool_name }),
103
+ ...(context.model_id === undefined ? {} : { model_id: context.model_id }),
104
+ ...(context.parameters === undefined
105
+ ? {}
106
+ : { parameters: { ...context.parameters } }),
107
+ ...(completion.outcome === "failure"
108
+ ? {
109
+ error_code: completion.errorCode,
110
+ error_message: completion.errorMessage,
111
+ failure_stage: stages.find((stage) => stage.error === completion.error)?.name
112
+ ?? "unknown",
113
+ ...(completion.httpStatus === undefined
114
+ ? {}
115
+ : { http_status: completion.httpStatus })
116
+ }
117
+ : {})
118
+ };
119
+ return [...stageEvents, command];
120
+ }
121
+ };
122
+ }
123
+ function stageKey(operation, mode) {
124
+ return mode === undefined ? operation : `${operation}:${mode}`;
125
+ }
126
+ function elapsed(now, startedAt) {
127
+ return Math.max(0, now - startedAt);
128
+ }
@@ -0,0 +1,31 @@
1
+ const trackingUrl = new URL("https://gaoding-log-ai-gpu.cn-hangzhou.log.aliyuncs.com/logstores/gd-cli/track?APIVersion=0.6.0");
2
+ const TIMEOUT_MS = 2_000;
3
+ export function createSlsTelemetrySink(options) {
4
+ return {
5
+ async send(events) {
6
+ if (events.length === 0)
7
+ return;
8
+ try {
9
+ await options.fetch(trackingUrl, {
10
+ method: "POST",
11
+ headers: { "Content-Type": "application/json" },
12
+ body: JSON.stringify({ __logs__: events.map(wireEvent) }),
13
+ redirect: "error",
14
+ signal: AbortSignal.timeout(TIMEOUT_MS)
15
+ });
16
+ }
17
+ catch {
18
+ // Telemetry must never change command behavior.
19
+ }
20
+ }
21
+ };
22
+ }
23
+ function wireEvent(event) {
24
+ const wire = {};
25
+ for (const [key, value] of Object.entries(event)) {
26
+ if (value === undefined)
27
+ continue;
28
+ wire[key] = key === "parameters" ? JSON.stringify(value) : String(value);
29
+ }
30
+ return wire;
31
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gaoding-cli",
3
- "version": "1.0.0-alpha.13",
3
+ "version": "1.0.0-alpha.14",
4
4
  "description": "Gaoding command-line interface for agents and people.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,11 +25,13 @@ gd-cli agent send --input request.json
25
25
  gd-cli tool list
26
26
  gd-cli model list --tool <tool>
27
27
  gd-cli model get <model>
28
- gd-cli tool call <tool> --schema
28
+ gd-cli model get <model> --schema
29
29
  gd-cli tool call <tool> --input request.json
30
30
  ```
31
31
 
32
- `tool list` 给出可用 Tool;`model list` 和 `model get` 给出当前可用 Model、费用与预估耗时等信息;`tool call --schema` 给出所选 Tool 的实时输入要求。不要把列表值固化在提示或脚本中。
32
+ `tool list` 给出可用 Tool;`model list` 和 `model get` 给出当前可用 Model、说明、费用与预估耗时;`model get --schema` 给出所选 Model 的实时运行时输入 Schema。不要把列表值固化在提示或脚本中。
33
+
34
+ 按所选 Model Schema 构造 JSON:提供全部 required 字段;SELECT 参数使用 `options[].value`;required 字段带 default 且用户未指定时,在输入中显式使用该 default。存在 width、height、resolution 等专用字段时,将用户要求写入对应结构化参数,不要只写在 prompt 中。`tool call <tool> --schema` 返回整个 Tool 下所有 Model 的参数并集,只用于 Tool 级发现,不替代选定 Model 的 Schema。
33
35
 
34
36
  成功结果包含 `content` 和 `usage`。`content` 是文本或资源链接;`usage` 包含所选模型及模型目录公布的稿豆价格区间,不表示实际扣费。
35
37
 
@@ -3,8 +3,10 @@
3
3
  - `stdout` 只承载命令结果;结构化命令的 JSON 可直接解析。
4
4
  - `stderr` 承载警告、授权提示和错误;不要把警告混入结果。
5
5
  - 退出码 `0` 表示成功。
6
- - 退出码 `1` 表示运行、服务或状态失败;读取错误码与“下一步”,处理后再重试。
6
+ - 退出码 `1` 表示运行、服务或状态失败;只执行错误中 `error.details.next_steps` 明确给出的恢复步骤,缺失时停止并报告。
7
7
  - 退出码 `2` 表示命令或参数错误;执行对应命令的 `--help` 后修正调用。
8
8
  - 退出码 `130` 表示用户中断;立即停止,不自动重试。
9
9
 
10
+ Agent 或 Tool 等可能消耗稿豆的请求如果可能已经提交、但完成状态未知,停止并报告,不自动重试原调用。
11
+
10
12
  不要从未知错误中推断内部实现,也不要输出本地凭证、请求签名或带敏感查询参数的 URL。命令失败且没有安全恢复步骤时,保留原始 stderr 的公开错误码并向用户说明。