@infimind-next/ai-hive-mcp 0.3.3 → 0.4.1

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 (42) hide show
  1. package/README.md +78 -12
  2. package/dist/api-client.d.ts +15 -0
  3. package/dist/api-client.js +89 -9
  4. package/dist/cli.d.ts +4 -0
  5. package/dist/cli.js +34 -0
  6. package/dist/config.d.ts +19 -1
  7. package/dist/config.js +104 -7
  8. package/dist/index.js +9 -1
  9. package/dist/managed-config.d.ts +75 -0
  10. package/dist/managed-config.js +71 -0
  11. package/dist/managed-download.d.ts +13 -0
  12. package/dist/managed-download.js +138 -0
  13. package/dist/managed-files.d.ts +35 -0
  14. package/dist/managed-files.js +240 -0
  15. package/dist/managed-images.d.ts +70 -0
  16. package/dist/managed-images.js +449 -0
  17. package/dist/managed-server.d.ts +15 -0
  18. package/dist/managed-server.js +195 -0
  19. package/dist/managed-token-provider.d.ts +11 -0
  20. package/dist/managed-token-provider.js +31 -0
  21. package/dist/rest-commands.d.ts +14 -0
  22. package/dist/rest-commands.js +164 -0
  23. package/dist/schemas.d.ts +118 -10
  24. package/dist/schemas.js +79 -0
  25. package/dist/server.d.ts +4 -3
  26. package/dist/server.js +116 -34
  27. package/dist/setup/detect.d.ts +9 -0
  28. package/dist/setup/detect.js +34 -0
  29. package/dist/setup/merge.d.ts +5 -0
  30. package/dist/setup/merge.js +142 -0
  31. package/dist/setup/run-setup.d.ts +20 -0
  32. package/dist/setup/run-setup.js +332 -0
  33. package/dist/setup/skills.d.ts +8 -0
  34. package/dist/setup/skills.js +35 -0
  35. package/dist/setup/targets.d.ts +14 -0
  36. package/dist/setup/targets.js +46 -0
  37. package/package.json +11 -9
  38. package/skills/ai-hive-billing/SKILL.md +33 -0
  39. package/skills/ai-hive-image-video-generation/SKILL.md +41 -0
  40. package/skills/ai-hive-media-upload/SKILL.md +33 -0
  41. package/skills/ai-hive-model-selection/SKILL.md +50 -0
  42. package/skills/ai-hive-text-generation/SKILL.md +39 -0
@@ -0,0 +1,31 @@
1
+ import { execFile } from "node:child_process";
2
+ export const MANAGED_AUTH_ERROR = "登录已失效,请回到 AI-HIVE 启动器重新登录";
3
+ export class ManagedBearerTokenProvider {
4
+ helper;
5
+ constructor(helper) {
6
+ this.helper = helper;
7
+ }
8
+ async getToken() {
9
+ return new Promise((resolve, reject) => {
10
+ execFile(this.helper.command, this.helper.args, {
11
+ encoding: "utf8",
12
+ timeout: 10_000,
13
+ maxBuffer: 16_384,
14
+ windowsHide: true,
15
+ env: Object.fromEntries(Object.entries(process.env).filter(([name]) => !/KEY|TOKEN|SECRET|^(ELECTRON_RUN_AS_NODE|NODE_OPTIONS|NODE_PATH)$/i.test(name))),
16
+ }, (error, stdout) => {
17
+ const token = stdout.trim();
18
+ if (error ||
19
+ !/^[A-Za-z0-9._~+/-]+={0,2}$/.test(token) ||
20
+ token.length > 8_192) {
21
+ reject(new Error(MANAGED_AUTH_ERROR));
22
+ return;
23
+ }
24
+ resolve(token);
25
+ });
26
+ });
27
+ }
28
+ async refreshAfterUnauthorized() {
29
+ return this.getToken();
30
+ }
31
+ }
@@ -0,0 +1,14 @@
1
+ import { AiHiveApiClient } from "./api-client.js";
2
+ import type { McpClientConfig } from "./config.js";
3
+ export type RestCommandDependencies = {
4
+ stdout(line: string): void;
5
+ stderr(line: string): void;
6
+ createClient(input: {
7
+ endpoint: string;
8
+ key: string;
9
+ timeoutMs: number;
10
+ }): AiHiveApiClient;
11
+ newClientRequestId(): string;
12
+ };
13
+ export declare function runRestCommand(config: McpClientConfig, dependencies: RestCommandDependencies): Promise<number>;
14
+ export declare const defaultRestCommandDependencies: RestCommandDependencies;
@@ -0,0 +1,164 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { AiHiveApiClient, AiHiveApiError } from "./api-client.js";
3
+ import { StaticBearerTokenProvider } from "./auth-token-provider.js";
4
+ import { SERVER_VERSION } from "./server.js";
5
+ // 这些命令让没有 MCP 宿主的 Agent(纯 shell)也能完成选型、试跑和查账;
6
+ // 走的是同一个 /mcp 门面, 因此 MCP 密钥即可用, 不需要再申请 API 密钥.
7
+ export async function runRestCommand(config, dependencies) {
8
+ if (!config.key) {
9
+ dependencies.stderr("缺少 MCP 密钥。请在控制台创建后传入 --key,或设置环境变量 AI_HIVE_MCP_KEY。");
10
+ return 1;
11
+ }
12
+ const client = dependencies.createClient({
13
+ endpoint: config.endpoint,
14
+ key: config.key,
15
+ timeoutMs: config.timeoutMs,
16
+ });
17
+ try {
18
+ switch (config.command) {
19
+ case "models":
20
+ return await runModels(config, client, dependencies);
21
+ case "model":
22
+ return await runModel(config, client, dependencies);
23
+ case "usage":
24
+ return await runUsage(client, dependencies);
25
+ case "run":
26
+ return await runPrompt(config, client, dependencies);
27
+ default:
28
+ return 1;
29
+ }
30
+ }
31
+ catch (error) {
32
+ dependencies.stderr(safeErrorMessage(error));
33
+ return 1;
34
+ }
35
+ }
36
+ async function runModels(config, client, dependencies) {
37
+ const result = await client.listModels({
38
+ ...(config.modelType ? { modelType: config.modelType } : {}),
39
+ detail: config.detail ?? "lite",
40
+ });
41
+ if (config.json) {
42
+ dependencies.stdout(JSON.stringify(result, null, 2));
43
+ return 0;
44
+ }
45
+ const models = Array.isArray(result) ? result : [];
46
+ if (models.length === 0) {
47
+ dependencies.stderr("没有可用的模型,请到控制台确认模型状态。");
48
+ return 1;
49
+ }
50
+ dependencies.stdout("模型 ID\t名称\t类型\t线路");
51
+ for (const model of models) {
52
+ dependencies.stdout([
53
+ text(model.publicModelId),
54
+ text(model.displayName),
55
+ text(model.modelType),
56
+ Array.isArray(model.routingModes)
57
+ ? model.routingModes
58
+ .filter((mode) => typeof mode === "string")
59
+ .join(",")
60
+ : "",
61
+ ].join("\t"));
62
+ }
63
+ dependencies.stdout("价格与参数用 models --json 或 model <模型 ID> 查看。");
64
+ return 0;
65
+ }
66
+ async function runModel(config, client, dependencies) {
67
+ if (!config.modelId) {
68
+ dependencies.stderr("请提供模型 ID,例如:ai-hive-mcp model doubao-seed-1-6");
69
+ return 1;
70
+ }
71
+ const result = await client.getModel(config.modelId, config.routingMode, {
72
+ announcements: false,
73
+ });
74
+ dependencies.stdout(JSON.stringify(result, null, 2));
75
+ return 0;
76
+ }
77
+ async function runUsage(client, dependencies) {
78
+ const result = await client.getBillingSummary({});
79
+ dependencies.stdout(JSON.stringify(result, null, 2));
80
+ return 0;
81
+ }
82
+ async function runPrompt(config, client, dependencies) {
83
+ if (!config.modelId || !config.prompt) {
84
+ dependencies.stderr('请提供模型 ID 和提示词,例如:ai-hive-mcp run doubao-seed-1-6 "写一句欢迎语"');
85
+ return 1;
86
+ }
87
+ const routingMode = config.routingMode ?? "COST_FIRST";
88
+ // /mcp/chat/text 的严格入参要求 pricingSnapshot, CLI 没有宿主代为补全, 必须自己取一次.
89
+ const model = (await client.getModel(config.modelId, routingMode, {
90
+ announcements: false,
91
+ }));
92
+ const pricingSnapshot = Array.isArray(model.pricingSnapshot)
93
+ ? model.pricingSnapshot.find((snapshot) => typeof snapshot === "object" &&
94
+ snapshot !== null &&
95
+ snapshot.routingMode === routingMode)
96
+ : undefined;
97
+ if (pricingSnapshot === undefined) {
98
+ dependencies.stderr("该模型当前没有所选线路的报价,请先用 model 命令确认可用线路。");
99
+ return 1;
100
+ }
101
+ const result = (await client.chatText({
102
+ publicModelId: config.modelId,
103
+ routingMode,
104
+ messages: [{ role: "user", content: config.prompt }],
105
+ pricingSnapshot,
106
+ clientRequestId: dependencies.newClientRequestId(),
107
+ }));
108
+ if (config.json) {
109
+ dependencies.stdout(JSON.stringify(result, null, 2));
110
+ return 0;
111
+ }
112
+ if (typeof result.content === "string") {
113
+ dependencies.stdout(result.content);
114
+ }
115
+ else {
116
+ dependencies.stdout(JSON.stringify(result, null, 2));
117
+ }
118
+ if (typeof result.chargeMicros === "string") {
119
+ dependencies.stdout(`本次消费:${formatHoneyMicros(result.chargeMicros)} 蜂蜜`);
120
+ }
121
+ return 0;
122
+ }
123
+ // 钱包与公开报价都以蜂蜜计价, 只有充值实付金额才是元.
124
+ function formatHoneyMicros(value) {
125
+ if (!/^-?\d+$/.test(value)) {
126
+ return value;
127
+ }
128
+ const micros = BigInt(value);
129
+ const negative = micros < 0n;
130
+ const magnitude = negative ? -micros : micros;
131
+ const whole = (magnitude / 1000000n).toString();
132
+ const fraction = (magnitude % 1000000n)
133
+ .toString()
134
+ .padStart(6, "0")
135
+ .replace(/0+$/, "");
136
+ return `${negative ? "-" : ""}${whole}${fraction ? `.${fraction}` : ""}`;
137
+ }
138
+ function text(value) {
139
+ return typeof value === "string" ? value : "";
140
+ }
141
+ function safeErrorMessage(error) {
142
+ if (error instanceof AiHiveApiError) {
143
+ return error.message;
144
+ }
145
+ if (error instanceof Error && error.message.length > 0) {
146
+ return error.message;
147
+ }
148
+ return "命令执行失败,请稍后重试。";
149
+ }
150
+ export const defaultRestCommandDependencies = {
151
+ stdout: (line) => console.log(line),
152
+ stderr: (line) => console.error(line),
153
+ createClient: ({ endpoint, key, timeoutMs }) => new AiHiveApiClient({
154
+ endpoint,
155
+ tokenProvider: new StaticBearerTokenProvider(key),
156
+ timeoutMs,
157
+ // 命令行调用没有 MCP 宿主可以代报身份, 自己声明来源, 后台才能区分 CLI 与裸 MCP.
158
+ clientInfoProvider: () => ({
159
+ name: "ai-hive-mcp-cli",
160
+ version: SERVER_VERSION,
161
+ }),
162
+ }),
163
+ newClientRequestId: () => randomUUID(),
164
+ };
package/dist/schemas.d.ts CHANGED
@@ -9,37 +9,37 @@ export declare const mcpCreateMediaUploadOutputSchema: z.ZodObject<{
9
9
  method: z.ZodLiteral<"PUT">;
10
10
  headers: z.ZodRecord<z.ZodString, z.ZodString>;
11
11
  }, "strict", z.ZodTypeAny, {
12
- method: "PUT";
13
12
  url: string;
13
+ method: "PUT";
14
14
  headers: Record<string, string>;
15
15
  }, {
16
- method: "PUT";
17
16
  url: string;
17
+ method: "PUT";
18
18
  headers: Record<string, string>;
19
19
  }>;
20
20
  expiresAt: z.ZodString;
21
21
  }, "strict", z.ZodTypeAny, {
22
- mimeType: string;
23
- expiresAt: string;
24
22
  mediaId: string;
25
23
  mediaType: "IMAGE" | "VIDEO" | "AUDIO" | "DOCUMENT";
24
+ mimeType: string;
26
25
  sizeBytes: number;
27
26
  upload: {
28
- method: "PUT";
29
27
  url: string;
28
+ method: "PUT";
30
29
  headers: Record<string, string>;
31
30
  };
32
- }, {
33
- mimeType: string;
34
31
  expiresAt: string;
32
+ }, {
35
33
  mediaId: string;
36
34
  mediaType: "IMAGE" | "VIDEO" | "AUDIO" | "DOCUMENT";
35
+ mimeType: string;
37
36
  sizeBytes: number;
38
37
  upload: {
39
- method: "PUT";
40
38
  url: string;
39
+ method: "PUT";
41
40
  headers: Record<string, string>;
42
41
  };
42
+ expiresAt: string;
43
43
  }>;
44
44
  export declare const mcpUploadMediaFromPathInputSchema: z.ZodObject<{
45
45
  path: z.ZodEffects<z.ZodString, string, string>;
@@ -70,12 +70,12 @@ export declare const chatTextShape: {
70
70
  content: z.ZodEffects<z.ZodString, string, string>;
71
71
  mediaIds: z.ZodDefault<z.ZodEffects<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodNull]>, string[], string[] | null>>;
72
72
  }, "strict", z.ZodTypeAny, {
73
+ role: "system" | "user" | "assistant";
73
74
  content: string;
74
- role: "user" | "assistant" | "system";
75
75
  mediaIds: string[];
76
76
  }, {
77
+ role: "system" | "user" | "assistant";
77
78
  content: string;
78
- role: "user" | "assistant" | "system";
79
79
  mediaIds?: string[] | null | undefined;
80
80
  }>, "many">;
81
81
  thinkingEnabled: z.ZodOptional<z.ZodBoolean>;
@@ -109,7 +109,115 @@ export declare const generateVideoShape: {
109
109
  clientRequestId: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
110
110
  pricingSnapshot: z.ZodOptional<z.ZodUnion<[z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>, z.ZodArray<z.ZodNullable<z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>, "many">, z.ZodString, z.ZodNull]>>;
111
111
  };
112
+ export declare const listGenerationTasksShape: {
113
+ publicModelId: z.ZodOptional<z.ZodString>;
114
+ page: z.ZodDefault<z.ZodNumber>;
115
+ pageSize: z.ZodDefault<z.ZodNumber>;
116
+ };
112
117
  export declare const getGenerationTaskShape: {
113
118
  taskId: z.ZodString;
114
119
  };
115
120
  export type McpUploadMediaFromPathInput = z.infer<typeof mcpUploadMediaFromPathInputSchema>;
121
+ export declare const billingQueryShape: {
122
+ from: z.ZodOptional<z.ZodString>;
123
+ to: z.ZodOptional<z.ZodString>;
124
+ taskIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
125
+ publicModelId: z.ZodOptional<z.ZodString>;
126
+ invocationSource: z.ZodOptional<z.ZodEnum<["UNKNOWN", "WEB", "MCP", "WORKBUDDY", "QWENWORK", "DOUBAO_WORK", "MIAOSHOU", "OPENAPI"]>>;
127
+ };
128
+ export declare const listBillingRecordsShape: {
129
+ pageSize: z.ZodDefault<z.ZodNumber>;
130
+ cursor: z.ZodOptional<z.ZodString>;
131
+ from: z.ZodOptional<z.ZodString>;
132
+ to: z.ZodOptional<z.ZodString>;
133
+ taskIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
134
+ publicModelId: z.ZodOptional<z.ZodString>;
135
+ invocationSource: z.ZodOptional<z.ZodEnum<["UNKNOWN", "WEB", "MCP", "WORKBUDDY", "QWENWORK", "DOUBAO_WORK", "MIAOSHOU", "OPENAPI"]>>;
136
+ };
137
+ export declare const getBillingRecordShape: {
138
+ recordId: z.ZodString;
139
+ };
140
+ export type BillingQueryInput = z.infer<z.ZodObject<typeof billingQueryShape>>;
141
+ export type ListBillingRecordsInput = BillingQueryInput & {
142
+ pageSize?: number;
143
+ cursor?: string;
144
+ };
145
+ export declare const billingQueryInputSchema: z.ZodEffects<z.ZodObject<{
146
+ from: z.ZodOptional<z.ZodString>;
147
+ to: z.ZodOptional<z.ZodString>;
148
+ taskIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
149
+ publicModelId: z.ZodOptional<z.ZodString>;
150
+ invocationSource: z.ZodOptional<z.ZodEnum<["UNKNOWN", "WEB", "MCP", "WORKBUDDY", "QWENWORK", "DOUBAO_WORK", "MIAOSHOU", "OPENAPI"]>>;
151
+ }, "strict", z.ZodTypeAny, {
152
+ publicModelId?: string | undefined;
153
+ from?: string | undefined;
154
+ to?: string | undefined;
155
+ taskIds?: string[] | undefined;
156
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
157
+ }, {
158
+ publicModelId?: string | undefined;
159
+ from?: string | undefined;
160
+ to?: string | undefined;
161
+ taskIds?: string[] | undefined;
162
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
163
+ }>, {
164
+ publicModelId?: string | undefined;
165
+ from?: string | undefined;
166
+ to?: string | undefined;
167
+ taskIds?: string[] | undefined;
168
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
169
+ }, {
170
+ publicModelId?: string | undefined;
171
+ from?: string | undefined;
172
+ to?: string | undefined;
173
+ taskIds?: string[] | undefined;
174
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
175
+ }>;
176
+ export declare const listBillingRecordsInputSchema: z.ZodEffects<z.ZodObject<{
177
+ pageSize: z.ZodDefault<z.ZodNumber>;
178
+ cursor: z.ZodOptional<z.ZodString>;
179
+ from: z.ZodOptional<z.ZodString>;
180
+ to: z.ZodOptional<z.ZodString>;
181
+ taskIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
182
+ publicModelId: z.ZodOptional<z.ZodString>;
183
+ invocationSource: z.ZodOptional<z.ZodEnum<["UNKNOWN", "WEB", "MCP", "WORKBUDDY", "QWENWORK", "DOUBAO_WORK", "MIAOSHOU", "OPENAPI"]>>;
184
+ }, "strict", z.ZodTypeAny, {
185
+ pageSize: number;
186
+ publicModelId?: string | undefined;
187
+ from?: string | undefined;
188
+ to?: string | undefined;
189
+ taskIds?: string[] | undefined;
190
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
191
+ cursor?: string | undefined;
192
+ }, {
193
+ publicModelId?: string | undefined;
194
+ pageSize?: number | undefined;
195
+ from?: string | undefined;
196
+ to?: string | undefined;
197
+ taskIds?: string[] | undefined;
198
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
199
+ cursor?: string | undefined;
200
+ }>, {
201
+ pageSize: number;
202
+ publicModelId?: string | undefined;
203
+ from?: string | undefined;
204
+ to?: string | undefined;
205
+ taskIds?: string[] | undefined;
206
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
207
+ cursor?: string | undefined;
208
+ }, {
209
+ publicModelId?: string | undefined;
210
+ pageSize?: number | undefined;
211
+ from?: string | undefined;
212
+ to?: string | undefined;
213
+ taskIds?: string[] | undefined;
214
+ invocationSource?: "UNKNOWN" | "WEB" | "MCP" | "WORKBUDDY" | "QWENWORK" | "DOUBAO_WORK" | "MIAOSHOU" | "OPENAPI" | undefined;
215
+ cursor?: string | undefined;
216
+ }>;
217
+ export declare const getBillingRecordInputSchema: z.ZodObject<{
218
+ recordId: z.ZodString;
219
+ }, "strict", z.ZodTypeAny, {
220
+ recordId: string;
221
+ }, {
222
+ recordId: string;
223
+ }>;
package/dist/schemas.js CHANGED
@@ -116,6 +116,85 @@ export const generateVideoShape = {
116
116
  clientRequestId: clientRequestIdSchema,
117
117
  pricingSnapshot: pricingSnapshotInputSchema,
118
118
  };
119
+ export const listGenerationTasksShape = {
120
+ publicModelId: z.string().min(1).optional(),
121
+ page: z.number().int().min(1).default(1),
122
+ pageSize: z.number().int().min(1).max(50).default(20),
123
+ };
119
124
  export const getGenerationTaskShape = {
120
125
  taskId: z.string().min(1),
121
126
  };
127
+ // 独立发布的客户端镜像服务端账单输入, 避免引入 contracts 运行时依赖.
128
+ export const billingQueryShape = {
129
+ from: z
130
+ .string()
131
+ .datetime({ offset: true })
132
+ .optional()
133
+ .describe("开始时间,ISO 8601 含时区;与 to 成对传入,包含此时刻;不填默认北京时间今日"),
134
+ to: z
135
+ .string()
136
+ .datetime({ offset: true })
137
+ .optional()
138
+ .describe("结束时间,ISO 8601 含时区;与 from 成对传入,不包含此时刻"),
139
+ taskIds: z
140
+ .array(z.string().trim().min(1).max(200))
141
+ .min(1)
142
+ .max(100)
143
+ .optional()
144
+ .describe("按生成任务 ID 查询指定批次,最多 100 个;不能用积分差推断批次消费"),
145
+ publicModelId: z.string().trim().min(1).max(200).optional(),
146
+ invocationSource: z
147
+ .enum([
148
+ "UNKNOWN",
149
+ "WEB",
150
+ "MCP",
151
+ "WORKBUDDY",
152
+ "QWENWORK",
153
+ "DOUBAO_WORK",
154
+ "MIAOSHOU",
155
+ "OPENAPI",
156
+ ])
157
+ .optional(),
158
+ };
159
+ export const listBillingRecordsShape = {
160
+ ...billingQueryShape,
161
+ pageSize: z.number().int().min(1).max(100).default(20),
162
+ cursor: z.string().min(1).max(8192).optional(),
163
+ };
164
+ export const getBillingRecordShape = {
165
+ recordId: z
166
+ .string()
167
+ .regex(/^(charge|reservation):[^:]+$/)
168
+ .max(250)
169
+ .describe("列表返回的账单记录 ID,例如 charge:<id> 或 reservation:<id>"),
170
+ };
171
+ function refineBillingRange(value, ctx) {
172
+ if ((value.from === undefined) !== (value.to === undefined)) {
173
+ ctx.addIssue({
174
+ code: z.ZodIssueCode.custom,
175
+ message: "from 和 to 必须同时填写",
176
+ path: [value.from === undefined ? "from" : "to"],
177
+ });
178
+ return;
179
+ }
180
+ if (value.from !== undefined &&
181
+ value.to !== undefined &&
182
+ Date.parse(value.from) >= Date.parse(value.to)) {
183
+ ctx.addIssue({
184
+ code: z.ZodIssueCode.custom,
185
+ message: "结束时间必须晚于开始时间",
186
+ path: ["to"],
187
+ });
188
+ }
189
+ }
190
+ export const billingQueryInputSchema = z
191
+ .object(billingQueryShape)
192
+ .strict()
193
+ .superRefine(refineBillingRange);
194
+ export const listBillingRecordsInputSchema = z
195
+ .object(listBillingRecordsShape)
196
+ .strict()
197
+ .superRefine(refineBillingRange);
198
+ export const getBillingRecordInputSchema = z
199
+ .object(getBillingRecordShape)
200
+ .strict();
package/dist/server.d.ts CHANGED
@@ -5,7 +5,7 @@ import { AiHiveApiClient } from "./api-client.js";
5
5
  import { type BearerTokenProvider } from "./auth-token-provider.js";
6
6
  import type { McpClientConfig } from "./config.js";
7
7
  import { WorkBuddyCredentialStore } from "./workbuddy-credentials.js";
8
- export declare const SERVER_VERSION = "0.3.3";
8
+ export declare const SERVER_VERSION = "0.4.1";
9
9
  declare function content(value: unknown): {
10
10
  content: {
11
11
  type: "text";
@@ -20,12 +20,13 @@ declare function userInfoContent(value: unknown): {
20
20
  }[];
21
21
  structuredContent: Record<string, unknown>;
22
22
  };
23
- type ApiClientLike = Pick<AiHiveApiClient, "getUserInfo" | "getMaterialMode" | "quoteVideoMaterials" | "listModels" | "getModel" | "createMediaUpload" | "completeMediaUpload" | "chatText" | "generateImage" | "generateVideo" | "getGenerationTask" | "putUpload">;
23
+ type ApiClientLike = Pick<AiHiveApiClient, "getUserInfo" | "getMaterialMode" | "quoteVideoMaterials" | "listModels" | "getModel" | "createMediaUpload" | "completeMediaUpload" | "chatText" | "generateImage" | "generateVideo" | "getGenerationTask" | "listGenerationTasks" | "putUpload"> & Partial<Pick<AiHiveApiClient, "getBillingSummary" | "listBillingRecords" | "getBillingRecord">>;
24
24
  export type ToolDefinition = {
25
25
  name: string;
26
- title?: string;
26
+ title: string;
27
27
  description: string;
28
28
  schema: z.ZodRawShape;
29
+ inputSchema?: z.AnyZodObject;
29
30
  annotations?: ToolAnnotations;
30
31
  handler: (args: Record<string, unknown>) => Promise<ReturnType<typeof content> | ReturnType<typeof userInfoContent>>;
31
32
  };