scoutline 0.1.0 → 0.2.0

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 (206) hide show
  1. package/README.md +170 -5
  2. package/bin/scoutline.js +36 -15
  3. package/dist/capabilities/diagnostics.d.ts +97 -0
  4. package/dist/capabilities/diagnostics.d.ts.map +1 -0
  5. package/dist/capabilities/diagnostics.js +88 -0
  6. package/dist/capabilities/diagnostics.js.map +1 -0
  7. package/dist/capabilities/quota.d.ts +99 -0
  8. package/dist/capabilities/quota.d.ts.map +1 -0
  9. package/dist/capabilities/quota.js +129 -0
  10. package/dist/capabilities/quota.js.map +1 -0
  11. package/dist/capabilities/search.d.ts +110 -0
  12. package/dist/capabilities/search.d.ts.map +1 -0
  13. package/dist/capabilities/search.js +21 -0
  14. package/dist/capabilities/search.js.map +1 -0
  15. package/dist/capabilities/vision.d.ts +156 -0
  16. package/dist/capabilities/vision.d.ts.map +1 -0
  17. package/dist/capabilities/vision.js +111 -0
  18. package/dist/capabilities/vision.js.map +1 -0
  19. package/dist/command-invocation.d.ts +58 -0
  20. package/dist/command-invocation.d.ts.map +1 -0
  21. package/dist/command-invocation.js +95 -0
  22. package/dist/command-invocation.js.map +1 -0
  23. package/dist/commands/code.d.ts +11 -4
  24. package/dist/commands/code.d.ts.map +1 -1
  25. package/dist/commands/code.js +16 -42
  26. package/dist/commands/code.js.map +1 -1
  27. package/dist/commands/doctor.d.ts +58 -3
  28. package/dist/commands/doctor.d.ts.map +1 -1
  29. package/dist/commands/doctor.js +154 -52
  30. package/dist/commands/doctor.js.map +1 -1
  31. package/dist/commands/quota.d.ts +45 -3
  32. package/dist/commands/quota.d.ts.map +1 -1
  33. package/dist/commands/quota.js +116 -60
  34. package/dist/commands/quota.js.map +1 -1
  35. package/dist/commands/read.d.ts +15 -1
  36. package/dist/commands/read.d.ts.map +1 -1
  37. package/dist/commands/read.js +53 -54
  38. package/dist/commands/read.js.map +1 -1
  39. package/dist/commands/repo.d.ts +8 -3
  40. package/dist/commands/repo.d.ts.map +1 -1
  41. package/dist/commands/repo.js +40 -78
  42. package/dist/commands/repo.js.map +1 -1
  43. package/dist/commands/search.d.ts +27 -2
  44. package/dist/commands/search.d.ts.map +1 -1
  45. package/dist/commands/search.js +95 -103
  46. package/dist/commands/search.js.map +1 -1
  47. package/dist/commands/tools.d.ts +9 -3
  48. package/dist/commands/tools.d.ts.map +1 -1
  49. package/dist/commands/tools.js +29 -59
  50. package/dist/commands/tools.js.map +1 -1
  51. package/dist/commands/vision.d.ts +35 -9
  52. package/dist/commands/vision.d.ts.map +1 -1
  53. package/dist/commands/vision.js +184 -131
  54. package/dist/commands/vision.js.map +1 -1
  55. package/dist/index.d.ts +42 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +389 -207
  58. package/dist/index.js.map +1 -1
  59. package/dist/lib/cache.d.ts +61 -0
  60. package/dist/lib/cache.d.ts.map +1 -1
  61. package/dist/lib/cache.js +74 -11
  62. package/dist/lib/cache.js.map +1 -1
  63. package/dist/lib/code-mode.d.ts +13 -0
  64. package/dist/lib/code-mode.d.ts.map +1 -1
  65. package/dist/lib/code-mode.js +26 -6
  66. package/dist/lib/code-mode.js.map +1 -1
  67. package/dist/lib/config.d.ts.map +1 -1
  68. package/dist/lib/config.js +15 -18
  69. package/dist/lib/config.js.map +1 -1
  70. package/dist/lib/errors.d.ts +65 -10
  71. package/dist/lib/errors.d.ts.map +1 -1
  72. package/dist/lib/errors.js +135 -19
  73. package/dist/lib/errors.js.map +1 -1
  74. package/dist/lib/execution.d.ts +76 -0
  75. package/dist/lib/execution.d.ts.map +1 -0
  76. package/dist/lib/execution.js +177 -0
  77. package/dist/lib/execution.js.map +1 -0
  78. package/dist/lib/index.d.ts +10 -2
  79. package/dist/lib/index.d.ts.map +1 -1
  80. package/dist/lib/index.js +10 -2
  81. package/dist/lib/index.js.map +1 -1
  82. package/dist/lib/mcp-client.d.ts +46 -11
  83. package/dist/lib/mcp-client.d.ts.map +1 -1
  84. package/dist/lib/mcp-client.js +92 -27
  85. package/dist/lib/mcp-client.js.map +1 -1
  86. package/dist/lib/mcp-config.d.ts +17 -0
  87. package/dist/lib/mcp-config.d.ts.map +1 -1
  88. package/dist/lib/mcp-config.js +29 -0
  89. package/dist/lib/mcp-config.js.map +1 -1
  90. package/dist/lib/monitor-client.d.ts +17 -3
  91. package/dist/lib/monitor-client.d.ts.map +1 -1
  92. package/dist/lib/monitor-client.js +23 -69
  93. package/dist/lib/monitor-client.js.map +1 -1
  94. package/dist/lib/output.d.ts +53 -7
  95. package/dist/lib/output.d.ts.map +1 -1
  96. package/dist/lib/output.js +126 -39
  97. package/dist/lib/output.js.map +1 -1
  98. package/dist/lib/redact.d.ts +62 -3
  99. package/dist/lib/redact.d.ts.map +1 -1
  100. package/dist/lib/redact.js +165 -31
  101. package/dist/lib/redact.js.map +1 -1
  102. package/dist/lib/tty.d.ts +7 -20
  103. package/dist/lib/tty.d.ts.map +1 -1
  104. package/dist/lib/tty.js +51 -30
  105. package/dist/lib/tty.js.map +1 -1
  106. package/dist/node-command-invocation-adapter.d.ts +28 -0
  107. package/dist/node-command-invocation-adapter.d.ts.map +1 -0
  108. package/dist/node-command-invocation-adapter.js +88 -0
  109. package/dist/node-command-invocation-adapter.js.map +1 -0
  110. package/dist/providers/minimax/adapter.d.ts +47 -0
  111. package/dist/providers/minimax/adapter.d.ts.map +1 -0
  112. package/dist/providers/minimax/adapter.js +443 -0
  113. package/dist/providers/minimax/adapter.js.map +1 -0
  114. package/dist/providers/minimax/config.d.ts +32 -0
  115. package/dist/providers/minimax/config.d.ts.map +1 -0
  116. package/dist/providers/minimax/config.js +84 -0
  117. package/dist/providers/minimax/config.js.map +1 -0
  118. package/dist/providers/minimax/media.d.ts +34 -0
  119. package/dist/providers/minimax/media.d.ts.map +1 -0
  120. package/dist/providers/minimax/media.js +92 -0
  121. package/dist/providers/minimax/media.js.map +1 -0
  122. package/dist/providers/minimax/quota-client.d.ts +37 -0
  123. package/dist/providers/minimax/quota-client.d.ts.map +1 -0
  124. package/dist/providers/minimax/quota-client.js +78 -0
  125. package/dist/providers/minimax/quota-client.js.map +1 -0
  126. package/dist/providers/minimax/quota.d.ts +48 -0
  127. package/dist/providers/minimax/quota.d.ts.map +1 -0
  128. package/dist/providers/minimax/quota.js +120 -0
  129. package/dist/providers/minimax/quota.js.map +1 -0
  130. package/dist/providers/minimax/sdk-client.d.ts +29 -0
  131. package/dist/providers/minimax/sdk-client.d.ts.map +1 -0
  132. package/dist/providers/minimax/sdk-client.js +50 -0
  133. package/dist/providers/minimax/sdk-client.js.map +1 -0
  134. package/dist/providers/minimax/vision-attestations.d.ts +29 -0
  135. package/dist/providers/minimax/vision-attestations.d.ts.map +1 -0
  136. package/dist/providers/minimax/vision-attestations.js +54 -0
  137. package/dist/providers/minimax/vision-attestations.js.map +1 -0
  138. package/dist/providers/minimax/vision-conformance.d.ts +184 -0
  139. package/dist/providers/minimax/vision-conformance.d.ts.map +1 -0
  140. package/dist/providers/minimax/vision-conformance.js +369 -0
  141. package/dist/providers/minimax/vision-conformance.js.map +1 -0
  142. package/dist/providers/minimax/vision-mappings/chart.d.ts +35 -0
  143. package/dist/providers/minimax/vision-mappings/chart.d.ts.map +1 -0
  144. package/dist/providers/minimax/vision-mappings/chart.js +55 -0
  145. package/dist/providers/minimax/vision-mappings/chart.js.map +1 -0
  146. package/dist/providers/minimax/vision-mappings/common.d.ts +60 -0
  147. package/dist/providers/minimax/vision-mappings/common.d.ts.map +1 -0
  148. package/dist/providers/minimax/vision-mappings/common.js +75 -0
  149. package/dist/providers/minimax/vision-mappings/common.js.map +1 -0
  150. package/dist/providers/minimax/vision-mappings/diagnose-error.d.ts +35 -0
  151. package/dist/providers/minimax/vision-mappings/diagnose-error.d.ts.map +1 -0
  152. package/dist/providers/minimax/vision-mappings/diagnose-error.js +55 -0
  153. package/dist/providers/minimax/vision-mappings/diagnose-error.js.map +1 -0
  154. package/dist/providers/minimax/vision-mappings/diagram.d.ts +35 -0
  155. package/dist/providers/minimax/vision-mappings/diagram.d.ts.map +1 -0
  156. package/dist/providers/minimax/vision-mappings/diagram.js +55 -0
  157. package/dist/providers/minimax/vision-mappings/diagram.js.map +1 -0
  158. package/dist/providers/minimax/vision-mappings/extract-text.d.ts +35 -0
  159. package/dist/providers/minimax/vision-mappings/extract-text.d.ts.map +1 -0
  160. package/dist/providers/minimax/vision-mappings/extract-text.js +55 -0
  161. package/dist/providers/minimax/vision-mappings/extract-text.js.map +1 -0
  162. package/dist/providers/minimax/vision-mappings/ui-artifact.d.ts +35 -0
  163. package/dist/providers/minimax/vision-mappings/ui-artifact.d.ts.map +1 -0
  164. package/dist/providers/minimax/vision-mappings/ui-artifact.js +69 -0
  165. package/dist/providers/minimax/vision-mappings/ui-artifact.js.map +1 -0
  166. package/dist/providers/minimax/vision-mappings.generated.d.ts +29 -0
  167. package/dist/providers/minimax/vision-mappings.generated.d.ts.map +1 -0
  168. package/dist/providers/minimax/vision-mappings.generated.js +29 -0
  169. package/dist/providers/minimax/vision-mappings.generated.js.map +1 -0
  170. package/dist/providers/minimax/vision-revisions.d.ts +22 -0
  171. package/dist/providers/minimax/vision-revisions.d.ts.map +1 -0
  172. package/dist/providers/minimax/vision-revisions.js +27 -0
  173. package/dist/providers/minimax/vision-revisions.js.map +1 -0
  174. package/dist/providers/registry.d.ts +36 -0
  175. package/dist/providers/registry.d.ts.map +1 -0
  176. package/dist/providers/registry.js +45 -0
  177. package/dist/providers/registry.js.map +1 -0
  178. package/dist/providers/selection.d.ts +44 -0
  179. package/dist/providers/selection.d.ts.map +1 -0
  180. package/dist/providers/selection.js +85 -0
  181. package/dist/providers/selection.js.map +1 -0
  182. package/dist/providers/types.d.ts +247 -0
  183. package/dist/providers/types.d.ts.map +1 -0
  184. package/dist/providers/types.js +127 -0
  185. package/dist/providers/types.js.map +1 -0
  186. package/dist/providers/zai/adapter.d.ts +35 -0
  187. package/dist/providers/zai/adapter.d.ts.map +1 -0
  188. package/dist/providers/zai/adapter.js +619 -0
  189. package/dist/providers/zai/adapter.js.map +1 -0
  190. package/dist/providers/zai/credentials.d.ts +38 -0
  191. package/dist/providers/zai/credentials.d.ts.map +1 -0
  192. package/dist/providers/zai/credentials.js +60 -0
  193. package/dist/providers/zai/credentials.js.map +1 -0
  194. package/dist/providers/zai/media.d.ts +38 -0
  195. package/dist/providers/zai/media.d.ts.map +1 -0
  196. package/dist/providers/zai/media.js +107 -0
  197. package/dist/providers/zai/media.js.map +1 -0
  198. package/dist/providers/zai/monitor-client.d.ts +53 -0
  199. package/dist/providers/zai/monitor-client.d.ts.map +1 -0
  200. package/dist/providers/zai/monitor-client.js +117 -0
  201. package/dist/providers/zai/monitor-client.js.map +1 -0
  202. package/dist/providers/zai/quota.d.ts +47 -0
  203. package/dist/providers/zai/quota.d.ts.map +1 -0
  204. package/dist/providers/zai/quota.js +127 -0
  205. package/dist/providers/zai/quota.js.map +1 -0
  206. package/package.json +10 -5
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Z.AI credential resolution (DESIGN.md §6, P0-02 — Fixup A — B4, B7).
3
+ *
4
+ * Single source of truth for the Z.AI API key. The primary
5
+ * `Z_AI_API_KEY` is accepted alongside the characterized `ZAI_API_KEY`
6
+ * alias; `Z_AI_API_KEY` takes precedence when both are set. Whitespace-
7
+ * only values are treated as absent, matching the descriptor's
8
+ * `isConfigured` contract.
9
+ *
10
+ * Boundary rules (ARCHITECTURE.md §2):
11
+ * - May import the normalized-error contract only.
12
+ * - Must NOT import transport, command presentation, or another
13
+ * Provider's Adapter.
14
+ *
15
+ * Missing credentials are surfaced as {@link ConfigurationError}
16
+ * (exit 3), distinct from {@link AuthError} (exit 1) which means the
17
+ * Provider REJECTED a presented credential. This mirrors `lib/config.ts`
18
+ * (`loadConfig`/`getApiKey`) so every Z.AI entry point agrees on the
19
+ * missing-credential exit code.
20
+ */
21
+ /**
22
+ * Resolve the Z.AI API key without throwing. `Z_AI_API_KEY` takes
23
+ * precedence over the `ZAI_API_KEY` alias. Returns `undefined` when no
24
+ * non-blank value is present.
25
+ */
26
+ export declare function resolveZaiApiKey(env: NodeJS.ProcessEnv): string | undefined;
27
+ /**
28
+ * Resolve the Z.AI API key or throw {@link ConfigurationError} (exit 3)
29
+ * when it is missing. Call this at every capability invocation gate.
30
+ */
31
+ export declare function requireZaiApiKey(env: NodeJS.ProcessEnv): string;
32
+ /**
33
+ * True when a non-blank Z.AI API key (primary or alias) is configured.
34
+ * Metadata-only: performs no transport construction and reads no other
35
+ * Provider's credentials.
36
+ */
37
+ export declare function isZaiConfigured(env: NodeJS.ProcessEnv): boolean;
38
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/providers/zai/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAgBH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,GAAG,SAAS,CAE3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAM/D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAE/D"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Z.AI credential resolution (DESIGN.md §6, P0-02 — Fixup A — B4, B7).
3
+ *
4
+ * Single source of truth for the Z.AI API key. The primary
5
+ * `Z_AI_API_KEY` is accepted alongside the characterized `ZAI_API_KEY`
6
+ * alias; `Z_AI_API_KEY` takes precedence when both are set. Whitespace-
7
+ * only values are treated as absent, matching the descriptor's
8
+ * `isConfigured` contract.
9
+ *
10
+ * Boundary rules (ARCHITECTURE.md §2):
11
+ * - May import the normalized-error contract only.
12
+ * - Must NOT import transport, command presentation, or another
13
+ * Provider's Adapter.
14
+ *
15
+ * Missing credentials are surfaced as {@link ConfigurationError}
16
+ * (exit 3), distinct from {@link AuthError} (exit 1) which means the
17
+ * Provider REJECTED a presented credential. This mirrors `lib/config.ts`
18
+ * (`loadConfig`/`getApiKey`) so every Z.AI entry point agrees on the
19
+ * missing-credential exit code.
20
+ */
21
+ import { ConfigurationError } from "../../lib/errors.js";
22
+ const MISSING_KEY_HELP = 'export Z_AI_API_KEY="your-api-key"';
23
+ /**
24
+ * Pick a non-blank raw value from the environment. Returns the original
25
+ * (untrimmed) string when it contains at least one non-whitespace
26
+ * character, otherwise `undefined`.
27
+ */
28
+ function pickNonBlank(raw) {
29
+ if (typeof raw !== "string")
30
+ return undefined;
31
+ return raw.trim().length > 0 ? raw : undefined;
32
+ }
33
+ /**
34
+ * Resolve the Z.AI API key without throwing. `Z_AI_API_KEY` takes
35
+ * precedence over the `ZAI_API_KEY` alias. Returns `undefined` when no
36
+ * non-blank value is present.
37
+ */
38
+ export function resolveZaiApiKey(env) {
39
+ return pickNonBlank(env.Z_AI_API_KEY) ?? pickNonBlank(env.ZAI_API_KEY);
40
+ }
41
+ /**
42
+ * Resolve the Z.AI API key or throw {@link ConfigurationError} (exit 3)
43
+ * when it is missing. Call this at every capability invocation gate.
44
+ */
45
+ export function requireZaiApiKey(env) {
46
+ const key = resolveZaiApiKey(env);
47
+ if (key === undefined) {
48
+ throw new ConfigurationError("Z_AI_API_KEY environment variable is required", MISSING_KEY_HELP);
49
+ }
50
+ return key;
51
+ }
52
+ /**
53
+ * True when a non-blank Z.AI API key (primary or alias) is configured.
54
+ * Metadata-only: performs no transport construction and reads no other
55
+ * Provider's credentials.
56
+ */
57
+ export function isZaiConfigured(env) {
58
+ return resolveZaiApiKey(env) !== undefined;
59
+ }
60
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/providers/zai/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,gBAAgB,GAAG,oCAAoC,CAAC;AAE9D;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9C,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAsB;IACrD,OAAO,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAsB;IACrD,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,kBAAkB,CAAC,+CAA+C,EAAE,gBAAgB,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAsB;IACpD,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Z.AI Provider Media Module (DESIGN.md §9 — P3-02).
3
+ *
4
+ * Owns Z.AI-local media facts: accepted image and video extensions, size
5
+ * limits, existence checks, and absolute-path resolution. Commands pass
6
+ * raw path-or-URL strings; this module is the single owner of every
7
+ * Provider-specific media decision for Z.AI.
8
+ *
9
+ * Boundary rules (ARCHITECTURE.md §2):
10
+ * - May import normalized errors from `lib/errors.ts`.
11
+ * - Must NOT read file content. The Z.AI MCP receives the validated
12
+ * absolute path; it never receives a data URI or file bytes from
13
+ * this module. Only `stat` (existence + size) is performed.
14
+ *
15
+ * Media rules (DESIGN.md §9 Z.AI):
16
+ * - Local image: JPG, JPEG, PNG (case-insensitive), at most 5 MiB.
17
+ * - Local video: preserve the Phase 0 extension set and 8 MiB limit.
18
+ * - Local source becomes an absolute path after validation.
19
+ * - HTTP(S) source passes through without local filesystem access.
20
+ * - Missing local file rejects with `FILE_ERROR`.
21
+ * - Non-HTTP URL-like strings and unsupported extensions reject with
22
+ * `VALIDATION_ERROR` and Provider-specific supported-format help.
23
+ */
24
+ /**
25
+ * Resolve a Z.AI image source into the value the Z.AI MCP consumes. For a
26
+ * local file, validates existence, size (≤ 5 MiB), and extension
27
+ * (JPG/JPEG/PNG) and returns the absolute path. For an HTTP(S) URL,
28
+ * returns the URL unchanged without touching the local filesystem.
29
+ */
30
+ export declare function resolveImageSource(source: string): string;
31
+ /**
32
+ * Resolve a Z.AI video source into the value the Z.AI MCP consumes. For a
33
+ * local file, validates existence, size (≤ 8 MiB), and extension (the
34
+ * Phase 0 set) and returns the absolute path. For an HTTP(S) URL, returns
35
+ * the URL unchanged.
36
+ */
37
+ export declare function resolveVideoSource(source: string): string;
38
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../src/providers/zai/media.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AA8EH;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAezD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAezD"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Z.AI Provider Media Module (DESIGN.md §9 — P3-02).
3
+ *
4
+ * Owns Z.AI-local media facts: accepted image and video extensions, size
5
+ * limits, existence checks, and absolute-path resolution. Commands pass
6
+ * raw path-or-URL strings; this module is the single owner of every
7
+ * Provider-specific media decision for Z.AI.
8
+ *
9
+ * Boundary rules (ARCHITECTURE.md §2):
10
+ * - May import normalized errors from `lib/errors.ts`.
11
+ * - Must NOT read file content. The Z.AI MCP receives the validated
12
+ * absolute path; it never receives a data URI or file bytes from
13
+ * this module. Only `stat` (existence + size) is performed.
14
+ *
15
+ * Media rules (DESIGN.md §9 Z.AI):
16
+ * - Local image: JPG, JPEG, PNG (case-insensitive), at most 5 MiB.
17
+ * - Local video: preserve the Phase 0 extension set and 8 MiB limit.
18
+ * - Local source becomes an absolute path after validation.
19
+ * - HTTP(S) source passes through without local filesystem access.
20
+ * - Missing local file rejects with `FILE_ERROR`.
21
+ * - Non-HTTP URL-like strings and unsupported extensions reject with
22
+ * `VALIDATION_ERROR` and Provider-specific supported-format help.
23
+ */
24
+ import * as fs from "node:fs";
25
+ import * as path from "node:path";
26
+ import { FileError, ValidationError } from "../../lib/errors.js";
27
+ // ---------------------------------------------------------------------------
28
+ // Z.AI media limits (DESIGN.md §9)
29
+ // ---------------------------------------------------------------------------
30
+ const ZAI_IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png"];
31
+ const ZAI_VIDEO_EXTENSIONS = [".mp4", ".mov", ".m4v", ".avi", ".webm", ".wmv"];
32
+ const ZAI_MAX_IMAGE_BYTES = 5 * 1024 * 1024; // 5 MiB
33
+ const ZAI_MAX_VIDEO_BYTES = 8 * 1024 * 1024; // 8 MiB
34
+ const ZAI_IMAGE_FORMAT_HELP = "Supported Z.AI image formats: JPG, JPEG, PNG (max 5 MiB)";
35
+ const ZAI_VIDEO_FORMAT_HELP = "Supported Z.AI video formats: MP4, MOV, M4V, AVI, WebM, WMV (max 8 MiB)";
36
+ // ---------------------------------------------------------------------------
37
+ // Source classification
38
+ // ---------------------------------------------------------------------------
39
+ /**
40
+ * A leading `<scheme>://` that is NOT `http(s)://` (e.g. `ftp://`, `file://`)
41
+ * is a URL-like string Z.AI cannot consume. It is rejected up front with
42
+ * `VALIDATION_ERROR` rather than falling through to a misleading local-file
43
+ * `FILE_ERROR`.
44
+ */
45
+ const URL_SCHEME_PATTERN = /^[a-z][a-z0-9+.-]*:\/\//i;
46
+ function classifySource(source) {
47
+ if (source.startsWith("http://") || source.startsWith("https://")) {
48
+ return "http";
49
+ }
50
+ if (URL_SCHEME_PATTERN.test(source)) {
51
+ return "unsupported-url";
52
+ }
53
+ return "local";
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // Local media validation (existence + size + extension; never reads content)
57
+ // ---------------------------------------------------------------------------
58
+ function validateLocalMedia(source, allowedExtensions, maxBytes, formatHelp) {
59
+ const resolved = path.resolve(source);
60
+ if (!fs.existsSync(resolved)) {
61
+ throw new FileError(`File not found: ${source}`, "Check the file path is correct");
62
+ }
63
+ const stats = fs.statSync(resolved);
64
+ if (stats.size > maxBytes) {
65
+ throw new ValidationError(`File exceeds the ${(maxBytes / 1024 / 1024).toFixed(0)} MiB limit ` +
66
+ `(${(stats.size / 1024 / 1024).toFixed(2)} MiB)`, formatHelp);
67
+ }
68
+ const ext = path.extname(resolved).toLowerCase();
69
+ if (!allowedExtensions.includes(ext)) {
70
+ throw new ValidationError(`Unsupported media format: ${ext || "(no extension)"}`, formatHelp);
71
+ }
72
+ return resolved;
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Public resolvers
76
+ // ---------------------------------------------------------------------------
77
+ /**
78
+ * Resolve a Z.AI image source into the value the Z.AI MCP consumes. For a
79
+ * local file, validates existence, size (≤ 5 MiB), and extension
80
+ * (JPG/JPEG/PNG) and returns the absolute path. For an HTTP(S) URL,
81
+ * returns the URL unchanged without touching the local filesystem.
82
+ */
83
+ export function resolveImageSource(source) {
84
+ const kind = classifySource(source);
85
+ if (kind === "http")
86
+ return source;
87
+ if (kind === "unsupported-url") {
88
+ throw new ValidationError(`Unsupported source scheme for Z.AI vision`, "Use an HTTP(S) URL or a local file path");
89
+ }
90
+ return validateLocalMedia(source, ZAI_IMAGE_EXTENSIONS, ZAI_MAX_IMAGE_BYTES, ZAI_IMAGE_FORMAT_HELP);
91
+ }
92
+ /**
93
+ * Resolve a Z.AI video source into the value the Z.AI MCP consumes. For a
94
+ * local file, validates existence, size (≤ 8 MiB), and extension (the
95
+ * Phase 0 set) and returns the absolute path. For an HTTP(S) URL, returns
96
+ * the URL unchanged.
97
+ */
98
+ export function resolveVideoSource(source) {
99
+ const kind = classifySource(source);
100
+ if (kind === "http")
101
+ return source;
102
+ if (kind === "unsupported-url") {
103
+ throw new ValidationError(`Unsupported source scheme for Z.AI vision`, "Use an HTTP(S) URL or a local file path");
104
+ }
105
+ return validateLocalMedia(source, ZAI_VIDEO_EXTENSIONS, ZAI_MAX_VIDEO_BYTES, ZAI_VIDEO_FORMAT_HELP);
106
+ }
107
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../../../src/providers/zai/media.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEjE,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAE9E,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACvD,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAE/E,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AACrD,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAErD,MAAM,qBAAqB,GAAG,0DAA0D,CAAC;AACzF,MAAM,qBAAqB,GACzB,yEAAyE,CAAC;AAE5E,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAItD,SAAS,cAAc,CAAC,MAAc;IACpC,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAE9E,SAAS,kBAAkB,CACzB,MAAc,EACd,iBAAoC,EACpC,QAAgB,EAChB,UAAkB;IAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,SAAS,CAAC,mBAAmB,MAAM,EAAE,EAAE,gCAAgC,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,eAAe,CACvB,oBAAoB,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa;YAClE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAClD,UAAU,CACX,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,eAAe,CAAC,6BAA6B,GAAG,IAAI,gBAAgB,EAAE,EAAE,UAAU,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,eAAe,CACvB,2CAA2C,EAC3C,yCAAyC,CAC1C,CAAC;IACJ,CAAC;IACD,OAAO,kBAAkB,CACvB,MAAM,EACN,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,CACtB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,eAAe,CACvB,2CAA2C,EAC3C,yCAAyC,CAC1C,CAAC;IACJ,CAAC;IACD,OAAO,kBAAkB,CACvB,MAAM,EACN,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,CACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Z.AI Monitor API client — Provider-local transport (DESIGN.md §13, P4-02).
3
+ *
4
+ * This Module owns the Z.AI monitor endpoint fetch mechanics moved here
5
+ * from `lib/monitor-client.ts`. It performs direct HTTP against
6
+ * `https://api.z.ai` (overridable via `ZAI_MONITOR_BASE_URL`) with an
7
+ * auth quirk: try the raw key first, and on 401 retry the same request
8
+ * with a `Bearer` prefix. Every transport dependency (fetch, timer,
9
+ * environment) is injectable so tests drive auth fallback and timeout
10
+ * deterministically without touching globals.
11
+ *
12
+ * Boundary rules (ARCHITECTURE.md §2):
13
+ * - May import Provider identity types, normalized errors.
14
+ * - Must NOT import command presentation or another Provider's Adapter.
15
+ *
16
+ * Raw response text NEVER enters public errors. A non-2xx response is
17
+ * mapped to a stable normalized error (`AuthError` for 401/403, `ApiError`
18
+ * otherwise) whose message carries no response body. Transport failures
19
+ * map to `TimeoutError`/`NetworkError`.
20
+ *
21
+ * This transport performs ONE logical attempt (including the auth-scheme
22
+ * fallback). Shared execution owns retry policy.
23
+ */
24
+ import type { ProviderQuotaFetch } from "../types.js";
25
+ /** Injectable fetch signature (shared duck-typed port). */
26
+ export type ZaiMonitorFetch = ProviderQuotaFetch;
27
+ /** Fetch response shape this transport consumes. */
28
+ export type ZaiMonitorFetchResponse = Awaited<ReturnType<ZaiMonitorFetch>>;
29
+ /** Injectable transport dependencies. */
30
+ export interface ZaiMonitorDeps {
31
+ readonly fetch?: ZaiMonitorFetch;
32
+ readonly setTimeout?: typeof setTimeout;
33
+ readonly clearTimeout?: typeof clearTimeout;
34
+ readonly env?: NodeJS.ProcessEnv;
35
+ }
36
+ /** Raw Z.AI quota-limit response shape (monitor endpoint). */
37
+ export interface ZaiRawQuotaLimit {
38
+ level?: string;
39
+ limits?: unknown[];
40
+ }
41
+ /**
42
+ * Perform one authenticated GET against the monitor API with the raw-key
43
+ * then Bearer auth fallback. Returns the unwrapped `data` payload (or the
44
+ * whole body when no `data` envelope is present).
45
+ *
46
+ * `path` is appended to the monitor base; `params` become query params.
47
+ */
48
+ export declare function fetchZaiMonitorPath(apiKey: string, path: string, params: Record<string, string> | undefined, deps?: ZaiMonitorDeps): Promise<unknown>;
49
+ /**
50
+ * Fetch the Z.AI quota-limit payload (one attempt, auth-scheme fallback).
51
+ */
52
+ export declare function fetchZaiQuotaLimit(apiKey: string, deps?: ZaiMonitorDeps): Promise<ZaiRawQuotaLimit>;
53
+ //# sourceMappingURL=monitor-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor-client.d.ts","sourceRoot":"","sources":["../../../src/providers/zai/monitor-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKtD,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAEjD,oDAAoD;AACpD,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;AAE3E,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,YAAY,CAAC;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC;AAED,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAsCD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC1C,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,OAAO,CAAC,CAgDlB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAO3B"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Z.AI Monitor API client — Provider-local transport (DESIGN.md §13, P4-02).
3
+ *
4
+ * This Module owns the Z.AI monitor endpoint fetch mechanics moved here
5
+ * from `lib/monitor-client.ts`. It performs direct HTTP against
6
+ * `https://api.z.ai` (overridable via `ZAI_MONITOR_BASE_URL`) with an
7
+ * auth quirk: try the raw key first, and on 401 retry the same request
8
+ * with a `Bearer` prefix. Every transport dependency (fetch, timer,
9
+ * environment) is injectable so tests drive auth fallback and timeout
10
+ * deterministically without touching globals.
11
+ *
12
+ * Boundary rules (ARCHITECTURE.md §2):
13
+ * - May import Provider identity types, normalized errors.
14
+ * - Must NOT import command presentation or another Provider's Adapter.
15
+ *
16
+ * Raw response text NEVER enters public errors. A non-2xx response is
17
+ * mapped to a stable normalized error (`AuthError` for 401/403, `ApiError`
18
+ * otherwise) whose message carries no response body. Transport failures
19
+ * map to `TimeoutError`/`NetworkError`.
20
+ *
21
+ * This transport performs ONE logical attempt (including the auth-scheme
22
+ * fallback). Shared execution owns retry policy.
23
+ */
24
+ import { ApiError, AuthError, NetworkError, TimeoutError } from "../../lib/errors.js";
25
+ const DEFAULT_MONITOR_BASE = "https://api.z.ai";
26
+ const DEFAULT_TIMEOUT_MS = 30000;
27
+ function resolveBase(env) {
28
+ return env.ZAI_MONITOR_BASE_URL || DEFAULT_MONITOR_BASE;
29
+ }
30
+ function resolveTimeoutMs(env) {
31
+ const raw = parseInt(env.Z_AI_TIMEOUT || String(DEFAULT_TIMEOUT_MS), 10);
32
+ return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_TIMEOUT_MS;
33
+ }
34
+ function mapStatusError(status) {
35
+ if (status === 401 || status === 403) {
36
+ return new AuthError("Z.AI monitor API authentication failed");
37
+ }
38
+ return new ApiError("Z.AI monitor API request failed", status);
39
+ }
40
+ function normalizeTransportError(err, timeoutMs) {
41
+ if (err instanceof AuthError || err instanceof ApiError)
42
+ return err;
43
+ if (err instanceof Error) {
44
+ if (err.name === "AbortError") {
45
+ return new TimeoutError(timeoutMs);
46
+ }
47
+ const lower = err.message.toLowerCase();
48
+ if (lower.includes("fetch") ||
49
+ lower.includes("econnrefused") ||
50
+ lower.includes("econnreset") ||
51
+ lower.includes("enotfound") ||
52
+ lower.includes("network")) {
53
+ return new NetworkError("Z.AI monitor network error");
54
+ }
55
+ }
56
+ return new ApiError("Z.AI monitor request failed", 500);
57
+ }
58
+ /**
59
+ * Perform one authenticated GET against the monitor API with the raw-key
60
+ * then Bearer auth fallback. Returns the unwrapped `data` payload (or the
61
+ * whole body when no `data` envelope is present).
62
+ *
63
+ * `path` is appended to the monitor base; `params` become query params.
64
+ */
65
+ export async function fetchZaiMonitorPath(apiKey, path, params, deps = {}) {
66
+ const f = deps.fetch ?? fetch;
67
+ const setT = deps.setTimeout ?? setTimeout;
68
+ const clearT = deps.clearTimeout ?? clearTimeout;
69
+ const env = deps.env ?? process.env;
70
+ const base = resolveBase(env);
71
+ const timeoutMs = resolveTimeoutMs(env);
72
+ const url = new URL(base + path);
73
+ if (params) {
74
+ for (const [k, v] of Object.entries(params))
75
+ url.searchParams.set(k, v);
76
+ }
77
+ for (const authValue of [apiKey, `Bearer ${apiKey}`]) {
78
+ const controller = new AbortController();
79
+ const timeoutId = setT(() => controller.abort(), timeoutMs);
80
+ try {
81
+ const res = await f(url, {
82
+ method: "GET",
83
+ headers: {
84
+ Authorization: authValue,
85
+ "Accept-Language": "en-US,en",
86
+ "Content-Type": "application/json",
87
+ },
88
+ signal: controller.signal,
89
+ });
90
+ clearT(timeoutId);
91
+ if (res.status === 401 && authValue === apiKey) {
92
+ // Auth-scheme fallback: retry the same request with Bearer.
93
+ continue;
94
+ }
95
+ if (!res.ok) {
96
+ // Drain the body so the connection can be reused, but NEVER let
97
+ // the raw text reach a public error message.
98
+ await res.text().catch(() => { });
99
+ throw mapStatusError(res.status);
100
+ }
101
+ const body = (await res.json());
102
+ return body.data ?? body;
103
+ }
104
+ catch (err) {
105
+ clearT(timeoutId);
106
+ throw normalizeTransportError(err, timeoutMs);
107
+ }
108
+ }
109
+ throw new AuthError("Z.AI monitor API rejected both auth schemes");
110
+ }
111
+ /**
112
+ * Fetch the Z.AI quota-limit payload (one attempt, auth-scheme fallback).
113
+ */
114
+ export async function fetchZaiQuotaLimit(apiKey, deps = {}) {
115
+ return (await fetchZaiMonitorPath(apiKey, "/api/monitor/usage/quota/limit", undefined, deps));
116
+ }
117
+ //# sourceMappingURL=monitor-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor-client.js","sourceRoot":"","sources":["../../../src/providers/zai/monitor-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Z.AI Quota Capability (DESIGN.md §13, P4-02).
3
+ *
4
+ * Maps the Z.AI monitor quota-limit response into the normalized
5
+ * Provider-quota Interface. The normalizer is pure; the capability
6
+ * factory owns credential resolution, the single monitor transport
7
+ * attempt, and failure normalization. Shared execution owns retry.
8
+ *
9
+ * Z.AI mapping (DESIGN.md §13):
10
+ * - `level` -> `plan`.
11
+ * - Rolling `TIME_LIMIT` -> `requests` category with current counts,
12
+ * duration in seconds, derived remaining percent, and ISO reset.
13
+ * - `TOKENS_LIMIT` -> `tokens` category; convert the Provider's used
14
+ * percentage to a remaining percentage.
15
+ * - Categories are named `requests` then `tokens` when present.
16
+ * - Per-tool breakdown (`usageDetails`) is omitted — no field in
17
+ * ADR-0001.
18
+ *
19
+ * Boundary rules (ARCHITECTURE.md §2):
20
+ * - May import the quota capability contract, Provider-local monitor
21
+ * transport, and normalized errors.
22
+ * - Must NOT import command presentation or another Provider's Adapter.
23
+ */
24
+ import type { ProviderQuotaSuccess, QuotaCapability } from "../../capabilities/quota.js";
25
+ import { type ZaiMonitorDeps } from "./monitor-client.js";
26
+ /**
27
+ * Normalize a raw Z.AI quota-limit payload into the shared Interface.
28
+ * Throws `QUOTA_ERROR` (via {@link buildQuotaWindow}) when a present
29
+ * limit entry has neither a valid percentage nor valid counts.
30
+ */
31
+ export declare function normalizeZaiQuota(raw: unknown): ProviderQuotaSuccess;
32
+ /**
33
+ * Options for the Z.AI QuotaCapability. `env` resolves the API key and
34
+ * monitor base/timeout. The transport dependencies (`fetch`, timer) are
35
+ * injectable for deterministic tests.
36
+ */
37
+ export interface ZaiQuotaCapabilityOptions extends ZaiMonitorDeps {
38
+ readonly env: NodeJS.ProcessEnv;
39
+ }
40
+ /**
41
+ * Build the Z.AI QuotaCapability. `invoke` resolves the credential,
42
+ * performs one monitor transport attempt (auth-scheme fallback inside),
43
+ * and normalizes the response. Shared execution wraps this in the retry
44
+ * policy; quota never uses the response cache.
45
+ */
46
+ export declare function createZaiQuotaCapability(options: ZaiQuotaCapabilityOptions): QuotaCapability;
47
+ //# sourceMappingURL=quota.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../../../src/providers/zai/quota.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EAEhB,MAAM,6BAA6B,CAAC;AASrC,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,qBAAqB,CAAC;AAsD7B;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAiDpE;AAmBD;;;;GAIG;AACH,MAAM,WAAW,yBAA0B,SAAQ,cAAc;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,eAAe,CAgB5F"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Z.AI Quota Capability (DESIGN.md §13, P4-02).
3
+ *
4
+ * Maps the Z.AI monitor quota-limit response into the normalized
5
+ * Provider-quota Interface. The normalizer is pure; the capability
6
+ * factory owns credential resolution, the single monitor transport
7
+ * attempt, and failure normalization. Shared execution owns retry.
8
+ *
9
+ * Z.AI mapping (DESIGN.md §13):
10
+ * - `level` -> `plan`.
11
+ * - Rolling `TIME_LIMIT` -> `requests` category with current counts,
12
+ * duration in seconds, derived remaining percent, and ISO reset.
13
+ * - `TOKENS_LIMIT` -> `tokens` category; convert the Provider's used
14
+ * percentage to a remaining percentage.
15
+ * - Categories are named `requests` then `tokens` when present.
16
+ * - Per-tool breakdown (`usageDetails`) is omitted — no field in
17
+ * ADR-0001.
18
+ *
19
+ * Boundary rules (ARCHITECTURE.md §2):
20
+ * - May import the quota capability contract, Provider-local monitor
21
+ * transport, and normalized errors.
22
+ * - Must NOT import command presentation or another Provider's Adapter.
23
+ */
24
+ import { buildQuotaWindow } from "../../capabilities/quota.js";
25
+ import { ApiError, AuthError, ConfigurationError, NetworkError, TimeoutError, } from "../../lib/errors.js";
26
+ import { fetchZaiQuotaLimit, } from "./monitor-client.js";
27
+ import { requireZaiApiKey } from "./credentials.js";
28
+ function isTimeLimit(value) {
29
+ return (!!value && typeof value === "object" && value.type === "TIME_LIMIT");
30
+ }
31
+ function isTokensLimit(value) {
32
+ return (!!value && typeof value === "object" && value.type === "TOKENS_LIMIT");
33
+ }
34
+ function readNumber(value) {
35
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Normalizer
39
+ // ---------------------------------------------------------------------------
40
+ /**
41
+ * Normalize a raw Z.AI quota-limit payload into the shared Interface.
42
+ * Throws `QUOTA_ERROR` (via {@link buildQuotaWindow}) when a present
43
+ * limit entry has neither a valid percentage nor valid counts.
44
+ */
45
+ export function normalizeZaiQuota(raw) {
46
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
47
+ throw new ApiError("Z.AI quota returned a malformed response", 500);
48
+ }
49
+ const data = raw;
50
+ const categories = [];
51
+ const limits = Array.isArray(data.limits) ? data.limits : [];
52
+ const timeLimit = limits.find(isTimeLimit);
53
+ if (timeLimit) {
54
+ const durationSeconds = typeof timeLimit.unit === "number" && Number.isFinite(timeLimit.unit)
55
+ ? timeLimit.unit * 3600
56
+ : undefined;
57
+ categories.push({
58
+ name: "requests",
59
+ unit: "requests",
60
+ current: buildQuotaWindow({
61
+ used: readNumber(timeLimit.currentValue),
62
+ limit: readNumber(timeLimit.usage),
63
+ durationSeconds,
64
+ resetsAtEpochMs: readNumber(timeLimit.nextResetTime),
65
+ // Z.AI `percentage` is a USED percentage — do NOT treat it as an
66
+ // explicit remaining percentage. Derive from counts instead.
67
+ }),
68
+ });
69
+ }
70
+ const tokensLimit = limits.find(isTokensLimit);
71
+ if (tokensLimit) {
72
+ const usedPercent = readNumber(tokensLimit.percentage);
73
+ const remainingPercent = usedPercent !== undefined ? 100 - usedPercent : undefined;
74
+ categories.push({
75
+ name: "tokens",
76
+ unit: "tokens",
77
+ current: buildQuotaWindow({
78
+ explicitRemainingPercent: remainingPercent,
79
+ resetsAtEpochMs: readNumber(tokensLimit.nextResetTime),
80
+ }),
81
+ });
82
+ }
83
+ return {
84
+ provider: "zai",
85
+ status: "ok",
86
+ plan: typeof data.level === "string" && data.level.length > 0 ? data.level : undefined,
87
+ categories,
88
+ };
89
+ }
90
+ // ---------------------------------------------------------------------------
91
+ // Capability factory
92
+ // ---------------------------------------------------------------------------
93
+ function normalizeZaiQuotaError(error) {
94
+ if (error instanceof AuthError ||
95
+ error instanceof ApiError ||
96
+ error instanceof NetworkError ||
97
+ error instanceof TimeoutError ||
98
+ error instanceof ConfigurationError) {
99
+ return error;
100
+ }
101
+ return new ApiError("Z.AI quota request failed", 500);
102
+ }
103
+ /**
104
+ * Build the Z.AI QuotaCapability. `invoke` resolves the credential,
105
+ * performs one monitor transport attempt (auth-scheme fallback inside),
106
+ * and normalizes the response. Shared execution wraps this in the retry
107
+ * policy; quota never uses the response cache.
108
+ */
109
+ export function createZaiQuotaCapability(options) {
110
+ const { env, ...transportDeps } = options;
111
+ return {
112
+ async invoke() {
113
+ // Shared credential resolver (Fixup A — B4/B7): honours the
114
+ // ZAI_API_KEY alias and treats a missing key as a configuration
115
+ // failure (ConfigurationError, exit 3).
116
+ const apiKey = requireZaiApiKey(env);
117
+ try {
118
+ const raw = await fetchZaiQuotaLimit(apiKey, transportDeps);
119
+ return normalizeZaiQuota(raw);
120
+ }
121
+ catch (error) {
122
+ throw normalizeZaiQuotaError(error);
123
+ }
124
+ },
125
+ };
126
+ }
127
+ //# sourceMappingURL=quota.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota.js","sourceRoot":"","sources":["../../../src/providers/zai/quota.ts"],"names":[],"mappings":"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"}