antitone 1.1.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.
- package/LICENSE +21 -0
- package/README.md +219 -0
- package/SKILL.md +114 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +371 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +108 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +412 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +117 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +53 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +224 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +74 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +283 -0
- package/dist/output.js.map +1 -0
- package/dist/tools/astock.d.ts +5 -0
- package/dist/tools/astock.d.ts.map +1 -0
- package/dist/tools/astock.js +30 -0
- package/dist/tools/astock.js.map +1 -0
- package/dist/tools/backtest.d.ts +5 -0
- package/dist/tools/backtest.d.ts.map +1 -0
- package/dist/tools/backtest.js +36 -0
- package/dist/tools/backtest.js.map +1 -0
- package/dist/tools/briefing.d.ts +5 -0
- package/dist/tools/briefing.d.ts.map +1 -0
- package/dist/tools/briefing.js +28 -0
- package/dist/tools/briefing.js.map +1 -0
- package/dist/tools/calendar.d.ts +5 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +35 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/entity.d.ts +5 -0
- package/dist/tools/entity.d.ts.map +1 -0
- package/dist/tools/entity.js +41 -0
- package/dist/tools/entity.js.map +1 -0
- package/dist/tools/index.d.ts +28 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +58 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/kit.d.ts +82 -0
- package/dist/tools/kit.d.ts.map +1 -0
- package/dist/tools/kit.js +146 -0
- package/dist/tools/kit.js.map +1 -0
- package/dist/tools/market.d.ts +5 -0
- package/dist/tools/market.d.ts.map +1 -0
- package/dist/tools/market.js +194 -0
- package/dist/tools/market.js.map +1 -0
- package/dist/tools/news.d.ts +5 -0
- package/dist/tools/news.d.ts.map +1 -0
- package/dist/tools/news.js +101 -0
- package/dist/tools/news.js.map +1 -0
- package/dist/tools/usage.d.ts +13 -0
- package/dist/tools/usage.d.ts.map +1 -0
- package/dist/tools/usage.js +50 -0
- package/dist/tools/usage.js.map +1 -0
- package/package.json +66 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antitone HTTP 客户端:只做三件事 —— 拼请求(含鉴权头与计费头)、解析计费回执、规范化错误。
|
|
3
|
+
*
|
|
4
|
+
* 鉴权:Authorization: Bearer <nhk_xxx.yyy>
|
|
5
|
+
* User-Agent: antitone-mcp/0.1.0
|
|
6
|
+
* X-Request-Id: <随机>
|
|
7
|
+
* X-Antitone-Billing-Detail: 1 → 服务端在 body 追加 _billing 明细
|
|
8
|
+
* 注意:API Key 通道免 X-NS-SIG 签名(签名只用于桌面端 session_key 通道)。
|
|
9
|
+
*/
|
|
10
|
+
import { randomUUID } from "node:crypto";
|
|
11
|
+
import { USER_AGENT } from "./config.js";
|
|
12
|
+
import { fromResponse, normalizeAnyThrown, toInteger } from "./errors.js";
|
|
13
|
+
/** 数据时刻候选字段(按优先级)。 */
|
|
14
|
+
const AS_OF_KEYS = [
|
|
15
|
+
"as_of",
|
|
16
|
+
"asOf",
|
|
17
|
+
"data_as_of",
|
|
18
|
+
"dataAsOf",
|
|
19
|
+
"server_time",
|
|
20
|
+
"updated_at",
|
|
21
|
+
"update_time",
|
|
22
|
+
"generated_at",
|
|
23
|
+
"quote_time",
|
|
24
|
+
"trade_time",
|
|
25
|
+
"snapshot_at",
|
|
26
|
+
"ts",
|
|
27
|
+
"timestamp",
|
|
28
|
+
"time",
|
|
29
|
+
"date",
|
|
30
|
+
"trade_date",
|
|
31
|
+
];
|
|
32
|
+
/** 服务端显式 freshness 标记(若存在则优先于时间差推断)。 */
|
|
33
|
+
const STALE_KEYS = ["stale", "is_stale"];
|
|
34
|
+
function isRecord(value) {
|
|
35
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36
|
+
}
|
|
37
|
+
function toIso(value) {
|
|
38
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
39
|
+
const ms = value > 1e12 ? value : value > 1e9 ? value * 1000 : NaN;
|
|
40
|
+
if (Number.isFinite(ms))
|
|
41
|
+
return new Date(ms).toISOString();
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
45
|
+
const raw = value.trim();
|
|
46
|
+
const numeric = Number(raw);
|
|
47
|
+
if (Number.isFinite(numeric) && raw.length >= 10)
|
|
48
|
+
return toIso(numeric);
|
|
49
|
+
const parsed = Date.parse(raw);
|
|
50
|
+
if (Number.isFinite(parsed))
|
|
51
|
+
return new Date(parsed).toISOString();
|
|
52
|
+
// 仅日期:YYYY-MM-DD → 视为当日 00:00 UTC
|
|
53
|
+
const dateOnly = /^\d{4}-\d{2}-\d{2}$/.exec(raw);
|
|
54
|
+
if (dateOnly) {
|
|
55
|
+
const parsedDate = Date.parse(`${raw}T00:00:00Z`);
|
|
56
|
+
if (Number.isFinite(parsedDate))
|
|
57
|
+
return new Date(parsedDate).toISOString();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
/** 从 payload 中挖掘数据时刻;挖不到就用响应头 Date,再退到请求时刻。 */
|
|
63
|
+
export function extractAsOf(data, headerDate, now = Date.now()) {
|
|
64
|
+
const containers = [];
|
|
65
|
+
if (isRecord(data)) {
|
|
66
|
+
containers.push(["payload", data]);
|
|
67
|
+
for (const key of ["data", "meta", "result"]) {
|
|
68
|
+
const nested = data[key];
|
|
69
|
+
if (isRecord(nested))
|
|
70
|
+
containers.push([`payload.${key}`, nested]);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
for (const [scope, container] of containers) {
|
|
74
|
+
for (const key of AS_OF_KEYS) {
|
|
75
|
+
const iso = toIso(container[key]);
|
|
76
|
+
if (iso)
|
|
77
|
+
return { asOf: iso, asOfSource: `${scope}.${key}` };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const headerIso = toIso(headerDate ?? undefined);
|
|
81
|
+
if (headerIso)
|
|
82
|
+
return { asOf: headerIso, asOfSource: "header.date" };
|
|
83
|
+
return { asOf: new Date(now).toISOString(), asOfSource: "request_time" };
|
|
84
|
+
}
|
|
85
|
+
/** 显式 stale 标记(服务端说 stale 时不能反着报 false)。 */
|
|
86
|
+
export function extractExplicitStale(data) {
|
|
87
|
+
if (!isRecord(data))
|
|
88
|
+
return undefined;
|
|
89
|
+
for (const scope of [data, isRecord(data["meta"]) ? data["meta"] : undefined]) {
|
|
90
|
+
if (!scope)
|
|
91
|
+
continue;
|
|
92
|
+
for (const key of STALE_KEYS) {
|
|
93
|
+
const value = scope[key];
|
|
94
|
+
if (typeof value === "boolean")
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
/** body `_billing` + 响应头 X-Antitone-* → Billing。body 优先(含 breakdown)。 */
|
|
101
|
+
export function parseBilling(body, headers) {
|
|
102
|
+
const billing = {};
|
|
103
|
+
let found = false;
|
|
104
|
+
if (isRecord(body) && isRecord(body["_billing"])) {
|
|
105
|
+
const detail = body["_billing"];
|
|
106
|
+
const credits = toInteger(detail["credits"]);
|
|
107
|
+
const balance = toInteger(detail["balance"]);
|
|
108
|
+
if (credits !== undefined) {
|
|
109
|
+
billing.credits = credits;
|
|
110
|
+
billing.credits_from = "body";
|
|
111
|
+
found = true;
|
|
112
|
+
}
|
|
113
|
+
if (balance !== undefined) {
|
|
114
|
+
billing.balance = balance;
|
|
115
|
+
found = true;
|
|
116
|
+
}
|
|
117
|
+
if (isRecord(detail["free_daily"])) {
|
|
118
|
+
const f = detail["free_daily"];
|
|
119
|
+
const limit = toInteger(f["limit"]) ?? 0;
|
|
120
|
+
const used = toInteger(f["used"]) ?? 0;
|
|
121
|
+
const remaining = toInteger(f["remaining"]) ?? Math.max(0, limit - used);
|
|
122
|
+
billing.free_daily = {
|
|
123
|
+
limit,
|
|
124
|
+
used,
|
|
125
|
+
remaining,
|
|
126
|
+
...(typeof f["cny_remaining"] === "number" ? { cny_remaining: f["cny_remaining"] } : {}),
|
|
127
|
+
...(typeof f["resets"] === "string" ? { resets: f["resets"] } : {}),
|
|
128
|
+
};
|
|
129
|
+
found = true;
|
|
130
|
+
}
|
|
131
|
+
if (typeof detail["settled"] === "boolean")
|
|
132
|
+
billing.settled = detail["settled"];
|
|
133
|
+
const pricingVersion = toInteger(detail["pricing_version"]);
|
|
134
|
+
if (pricingVersion !== undefined)
|
|
135
|
+
billing.pricing_version = pricingVersion;
|
|
136
|
+
if (detail["breakdown"] !== undefined)
|
|
137
|
+
billing.breakdown = detail["breakdown"];
|
|
138
|
+
if (typeof detail["source"] === "string")
|
|
139
|
+
billing.source = detail["source"];
|
|
140
|
+
}
|
|
141
|
+
const headerCredits = toInteger(headers.get("x-antitone-credits"));
|
|
142
|
+
if (headerCredits !== undefined) {
|
|
143
|
+
found = true;
|
|
144
|
+
if (billing.credits === undefined) {
|
|
145
|
+
billing.credits = headerCredits;
|
|
146
|
+
billing.credits_from = "header";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const headerBalance = toInteger(headers.get("x-antitone-balance"));
|
|
150
|
+
if (headerBalance !== undefined) {
|
|
151
|
+
found = true;
|
|
152
|
+
if (billing.balance === undefined)
|
|
153
|
+
billing.balance = headerBalance;
|
|
154
|
+
}
|
|
155
|
+
const headerFreeRemaining = toInteger(headers.get("x-antitone-free-remaining"));
|
|
156
|
+
const headerFreeLimit = toInteger(headers.get("x-antitone-free-limit"));
|
|
157
|
+
if (headerFreeLimit !== undefined || headerFreeRemaining !== undefined) {
|
|
158
|
+
found = true;
|
|
159
|
+
if (billing.free_daily === undefined) {
|
|
160
|
+
const limit = headerFreeLimit ?? 0;
|
|
161
|
+
const remaining = headerFreeRemaining ?? 0;
|
|
162
|
+
billing.free_daily = { limit, remaining, used: Math.max(0, limit - remaining) };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const headerSource = headers.get("x-antitone-credits-source");
|
|
166
|
+
if (headerSource && billing.source === undefined)
|
|
167
|
+
billing.source = headerSource;
|
|
168
|
+
const headerPricing = toInteger(headers.get("x-antitone-pricing-version"));
|
|
169
|
+
if (headerPricing !== undefined && billing.pricing_version === undefined)
|
|
170
|
+
billing.pricing_version = headerPricing;
|
|
171
|
+
return found ? billing : undefined;
|
|
172
|
+
}
|
|
173
|
+
/** 去掉 body 里的 _billing(已提升到 billing 字段,避免重复占预算)。 */
|
|
174
|
+
export function stripBilling(body) {
|
|
175
|
+
if (!isRecord(body) || !("_billing" in body))
|
|
176
|
+
return body;
|
|
177
|
+
const clone = { ...body };
|
|
178
|
+
delete clone["_billing"];
|
|
179
|
+
return clone;
|
|
180
|
+
}
|
|
181
|
+
export function buildQuery(query) {
|
|
182
|
+
if (!query)
|
|
183
|
+
return "";
|
|
184
|
+
const params = new URLSearchParams();
|
|
185
|
+
for (const [key, value] of Object.entries(query)) {
|
|
186
|
+
if (value === undefined || value === null)
|
|
187
|
+
continue;
|
|
188
|
+
if (typeof value === "boolean") {
|
|
189
|
+
params.append(key, value ? "1" : "0");
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (Array.isArray(value)) {
|
|
193
|
+
if (value.length === 0)
|
|
194
|
+
continue;
|
|
195
|
+
params.append(key, value.map((item) => String(item)).join(","));
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const text = String(value);
|
|
199
|
+
if (text === "")
|
|
200
|
+
continue;
|
|
201
|
+
params.append(key, text);
|
|
202
|
+
}
|
|
203
|
+
const qs = params.toString();
|
|
204
|
+
return qs ? `?${qs}` : "";
|
|
205
|
+
}
|
|
206
|
+
export class AntitoneClient {
|
|
207
|
+
config;
|
|
208
|
+
fetchImpl;
|
|
209
|
+
constructor(config, fetchImpl) {
|
|
210
|
+
this.config = config;
|
|
211
|
+
this.fetchImpl = fetchImpl ?? globalThis.fetch;
|
|
212
|
+
}
|
|
213
|
+
get baseUrl() {
|
|
214
|
+
return this.config.baseUrl;
|
|
215
|
+
}
|
|
216
|
+
get timeoutMs() {
|
|
217
|
+
return this.config.timeoutMs;
|
|
218
|
+
}
|
|
219
|
+
async get(path, options) {
|
|
220
|
+
return this.request("GET", path, options);
|
|
221
|
+
}
|
|
222
|
+
async post(path, options) {
|
|
223
|
+
return this.request("POST", path, options);
|
|
224
|
+
}
|
|
225
|
+
async request(method, path, options) {
|
|
226
|
+
const url = `${this.config.baseUrl}${path}${buildQuery(options.query)}`;
|
|
227
|
+
const requestId = randomUUID();
|
|
228
|
+
const headers = {
|
|
229
|
+
authorization: `Bearer ${this.config.apiKey}`,
|
|
230
|
+
"user-agent": USER_AGENT,
|
|
231
|
+
"x-request-id": requestId,
|
|
232
|
+
// 让服务端在 body 追加 _billing 明细(docs §7.5)
|
|
233
|
+
"x-antitone-billing-detail": "1",
|
|
234
|
+
accept: "application/json",
|
|
235
|
+
};
|
|
236
|
+
const init = { method, headers };
|
|
237
|
+
if (options.body !== undefined) {
|
|
238
|
+
headers["content-type"] = "application/json";
|
|
239
|
+
init.body = JSON.stringify(options.body);
|
|
240
|
+
}
|
|
241
|
+
const controller = new AbortController();
|
|
242
|
+
let timedOut = false;
|
|
243
|
+
const timer = setTimeout(() => {
|
|
244
|
+
timedOut = true;
|
|
245
|
+
controller.abort();
|
|
246
|
+
}, this.config.timeoutMs);
|
|
247
|
+
const upstreamSignal = options.signal;
|
|
248
|
+
const onAbort = () => controller.abort();
|
|
249
|
+
if (upstreamSignal) {
|
|
250
|
+
if (upstreamSignal.aborted)
|
|
251
|
+
controller.abort();
|
|
252
|
+
else
|
|
253
|
+
upstreamSignal.addEventListener("abort", onAbort, { once: true });
|
|
254
|
+
}
|
|
255
|
+
init.signal = controller.signal;
|
|
256
|
+
const startedAt = Date.now();
|
|
257
|
+
let response;
|
|
258
|
+
try {
|
|
259
|
+
response = await this.fetchImpl(url, init);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
throw normalizeAnyThrown(error, {
|
|
263
|
+
timedOut,
|
|
264
|
+
timeoutMs: this.config.timeoutMs,
|
|
265
|
+
url,
|
|
266
|
+
signalAborted: upstreamSignal?.aborted ?? false,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
clearTimeout(timer);
|
|
271
|
+
if (upstreamSignal)
|
|
272
|
+
upstreamSignal.removeEventListener("abort", onAbort);
|
|
273
|
+
}
|
|
274
|
+
const durationMs = Date.now() - startedAt;
|
|
275
|
+
const rawText = await response.text();
|
|
276
|
+
let body;
|
|
277
|
+
if (rawText.trim() === "") {
|
|
278
|
+
body = undefined;
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
try {
|
|
282
|
+
body = JSON.parse(rawText);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
body = rawText;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const billing = parseBilling(body, response.headers);
|
|
289
|
+
if (!response.ok) {
|
|
290
|
+
throw fromResponse({
|
|
291
|
+
status: response.status,
|
|
292
|
+
body,
|
|
293
|
+
retryAfterHeader: response.headers.get("retry-after"),
|
|
294
|
+
...(billing ? { billing } : {}),
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
const data = stripBilling(body);
|
|
298
|
+
const { asOf, asOfSource } = extractAsOf(data, response.headers.get("date"));
|
|
299
|
+
const explicitStale = extractExplicitStale(data);
|
|
300
|
+
const ageMs = Date.now() - Date.parse(asOf);
|
|
301
|
+
const stale = explicitStale ?? (Number.isFinite(ageMs) ? ageMs > options.staleAfterMs : false);
|
|
302
|
+
const envelope = {
|
|
303
|
+
data,
|
|
304
|
+
asOf,
|
|
305
|
+
asOfSource,
|
|
306
|
+
stale,
|
|
307
|
+
staleAfterMs: options.staleAfterMs,
|
|
308
|
+
requestId: response.headers.get("x-request-id") ?? requestId,
|
|
309
|
+
httpStatus: response.status,
|
|
310
|
+
durationMs,
|
|
311
|
+
endpoint: path,
|
|
312
|
+
};
|
|
313
|
+
if (billing)
|
|
314
|
+
envelope.billing = billing;
|
|
315
|
+
return envelope;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* 合并多个端点的结果(market_overview / get_usage / get_entity?include_financials)。
|
|
320
|
+
* 计费取各次之和;as_of 取最早(对 stale 判定最保守);stale 取或。
|
|
321
|
+
*/
|
|
322
|
+
export function mergeEnvelopes(entries) {
|
|
323
|
+
const data = {};
|
|
324
|
+
let credits = 0;
|
|
325
|
+
let hasCredits = false;
|
|
326
|
+
let balance;
|
|
327
|
+
let source;
|
|
328
|
+
let pricingVersion;
|
|
329
|
+
let settled;
|
|
330
|
+
let freeDaily;
|
|
331
|
+
let creditsFrom;
|
|
332
|
+
const perEndpoint = [];
|
|
333
|
+
let asOf = new Date().toISOString();
|
|
334
|
+
let asOfSource = "request_time";
|
|
335
|
+
let stale = false;
|
|
336
|
+
let staleAfterMs = Number.POSITIVE_INFINITY;
|
|
337
|
+
let requestId = "";
|
|
338
|
+
let httpStatus = 200;
|
|
339
|
+
let durationMs = 0;
|
|
340
|
+
for (const [key, envelope] of entries) {
|
|
341
|
+
data[key] = envelope.data;
|
|
342
|
+
perEndpoint.push({ endpoint: envelope.endpoint, credits: envelope.billing?.credits ?? null, ms: envelope.durationMs });
|
|
343
|
+
if (envelope.billing?.credits !== undefined) {
|
|
344
|
+
credits += envelope.billing.credits;
|
|
345
|
+
hasCredits = true;
|
|
346
|
+
// 来源标记:只要有一路来自 body 的 _billing,就按 body 记(信息量更大)
|
|
347
|
+
if (envelope.billing.credits_from === "body")
|
|
348
|
+
creditsFrom = "body";
|
|
349
|
+
else if (creditsFrom === undefined)
|
|
350
|
+
creditsFrom = envelope.billing.credits_from ?? "header";
|
|
351
|
+
}
|
|
352
|
+
if (envelope.billing?.balance !== undefined)
|
|
353
|
+
balance = envelope.billing.balance;
|
|
354
|
+
if (envelope.billing?.source !== undefined)
|
|
355
|
+
source = envelope.billing.source;
|
|
356
|
+
if (envelope.billing?.pricing_version !== undefined)
|
|
357
|
+
pricingVersion = envelope.billing.pricing_version;
|
|
358
|
+
if (envelope.billing?.settled !== undefined)
|
|
359
|
+
settled = envelope.billing.settled;
|
|
360
|
+
const f = envelope.billing?.free_daily;
|
|
361
|
+
if (f)
|
|
362
|
+
freeDaily = !freeDaily || f.remaining < freeDaily.remaining ? f : freeDaily;
|
|
363
|
+
if (Date.parse(envelope.asOf) < Date.parse(asOf)) {
|
|
364
|
+
asOf = envelope.asOf;
|
|
365
|
+
asOfSource = envelope.asOfSource;
|
|
366
|
+
}
|
|
367
|
+
stale = stale || envelope.stale;
|
|
368
|
+
staleAfterMs = Math.min(staleAfterMs, envelope.staleAfterMs);
|
|
369
|
+
if (!requestId)
|
|
370
|
+
requestId = envelope.requestId;
|
|
371
|
+
httpStatus = Math.max(httpStatus, envelope.httpStatus);
|
|
372
|
+
durationMs += envelope.durationMs;
|
|
373
|
+
}
|
|
374
|
+
const billing = {};
|
|
375
|
+
if (hasCredits) {
|
|
376
|
+
billing.credits = credits;
|
|
377
|
+
billing.credits_from = creditsFrom ?? "header";
|
|
378
|
+
}
|
|
379
|
+
if (balance !== undefined)
|
|
380
|
+
billing.balance = balance;
|
|
381
|
+
if (source !== undefined)
|
|
382
|
+
billing.source = source;
|
|
383
|
+
if (pricingVersion !== undefined)
|
|
384
|
+
billing.pricing_version = pricingVersion;
|
|
385
|
+
if (settled !== undefined)
|
|
386
|
+
billing.settled = settled;
|
|
387
|
+
if (freeDaily !== undefined) {
|
|
388
|
+
billing.free_daily = freeDaily;
|
|
389
|
+
// 余额 0 但还有免费额度 —— 明确告诉模型"能继续用",这是实测踩出来的坑:
|
|
390
|
+
// 只给 balance: 0,Agent 会自行放弃调用付费端点。
|
|
391
|
+
if ((balance ?? 0) <= 0 && freeDaily.remaining > 0) {
|
|
392
|
+
billing.note = `余额为 0,但今日免费额度还剩 ${freeDaily.remaining} 积分(约 ¥${(freeDaily.cny_remaining ?? freeDaily.remaining * 0.005).toFixed(2)}),本次由免费额度覆盖,可继续调用。`;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (perEndpoint.length > 1)
|
|
396
|
+
billing.breakdown = { calls: perEndpoint };
|
|
397
|
+
const merged = {
|
|
398
|
+
data,
|
|
399
|
+
asOf,
|
|
400
|
+
asOfSource,
|
|
401
|
+
stale,
|
|
402
|
+
staleAfterMs: Number.isFinite(staleAfterMs) ? staleAfterMs : 0,
|
|
403
|
+
requestId,
|
|
404
|
+
httpStatus,
|
|
405
|
+
durationMs,
|
|
406
|
+
endpoints: entries.map(([, envelope]) => envelope.endpoint),
|
|
407
|
+
};
|
|
408
|
+
if (Object.keys(billing).length > 0)
|
|
409
|
+
merged.billing = billing;
|
|
410
|
+
return merged;
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 运行时配置:全部来自环境变量,缺省值见 docs/api-platform-master-plan.md §9。
|
|
3
|
+
*
|
|
4
|
+
* ANTITONE_API_KEY 必填,形如 nhk_xxx.yyy
|
|
5
|
+
* ANTITONE_BASE_URL 选填,默认 https://api.desicterminal.com:8443
|
|
6
|
+
* ANTITONE_TIMEOUT_MS 选填,默认 20000
|
|
7
|
+
* ANTITONE_MAX_BYTES 选填,单次返回预算,默认 32768(32 KB,规范硬上限)
|
|
8
|
+
*/
|
|
9
|
+
export declare const PACKAGE_NAME = "antitone-mcp";
|
|
10
|
+
export declare const PACKAGE_VERSION: string;
|
|
11
|
+
export declare const USER_AGENT: string;
|
|
12
|
+
export declare const DEFAULT_BASE_URL = "https://api.desicterminal.com:8443";
|
|
13
|
+
export declare const DEFAULT_TIMEOUT_MS = 20000;
|
|
14
|
+
export declare const DEFAULT_LIMIT = 20;
|
|
15
|
+
/** 单次工具返回的序列化预算:32 KB(文档 §9 输出规范)。 */
|
|
16
|
+
export declare const MAX_RESULT_BYTES: number;
|
|
17
|
+
/** API Key 形状:`nhk_<id>.<secret>`(secret 段允许缺省以便兼容早期 key)。 */
|
|
18
|
+
export declare const API_KEY_PATTERN: RegExp;
|
|
19
|
+
export interface AntitoneConfig {
|
|
20
|
+
apiKey: string;
|
|
21
|
+
baseUrl: string;
|
|
22
|
+
timeoutMs: number;
|
|
23
|
+
maxResultBytes: number;
|
|
24
|
+
defaultLimit: number;
|
|
25
|
+
}
|
|
26
|
+
/** 配置错误(缺少 key / URL 不合法)。启动阶段直接以退出码 1 结束,并打印可读中文提示。 */
|
|
27
|
+
export declare class ConfigError extends Error {
|
|
28
|
+
readonly hint: string;
|
|
29
|
+
constructor(message: string, hint: string);
|
|
30
|
+
}
|
|
31
|
+
export declare function normalizeBaseUrl(raw: string): string;
|
|
32
|
+
export interface LoadConfigOptions {
|
|
33
|
+
/** 默认 process.env;测试可注入。 */
|
|
34
|
+
env?: Record<string, string | undefined>;
|
|
35
|
+
/** 配置告警输出(默认 stderr,绝不写 stdout,stdout 是 MCP 的 JSON-RPC 通道)。 */
|
|
36
|
+
onWarn?: (message: string) => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function loadConfig(options?: LoadConfigOptions): AntitoneConfig;
|
|
39
|
+
/** 打印用:key 只留前 8 位。 */
|
|
40
|
+
export declare function maskApiKey(apiKey: string): string;
|
|
41
|
+
export declare function describeConfig(config: AntitoneConfig): string;
|
|
42
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAoB3C,eAAO,MAAM,eAAe,QAAuB,CAAC;AACpD,eAAO,MAAM,UAAU,QAAuC,CAAC;AAE/D,eAAO,MAAM,gBAAgB,uCAAuC,CAAC;AACrE,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,sCAAsC;AACtC,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAE1C,8DAA8D;AAC9D,eAAO,MAAM,eAAe,QAA4C,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wDAAwD;AACxD,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAK1C;AASD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBpD;AAED,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,cAAc,CAqC1E;AAED,uBAAuB;AACvB,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAS7D"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 运行时配置:全部来自环境变量,缺省值见 docs/api-platform-master-plan.md §9。
|
|
3
|
+
*
|
|
4
|
+
* ANTITONE_API_KEY 必填,形如 nhk_xxx.yyy
|
|
5
|
+
* ANTITONE_BASE_URL 选填,默认 https://api.desicterminal.com:8443
|
|
6
|
+
* ANTITONE_TIMEOUT_MS 选填,默认 20000
|
|
7
|
+
* ANTITONE_MAX_BYTES 选填,单次返回预算,默认 32768(32 KB,规范硬上限)
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync } from "node:fs";
|
|
10
|
+
import { dirname, join } from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
export const PACKAGE_NAME = "antitone-mcp";
|
|
13
|
+
/**
|
|
14
|
+
* 版本号:**运行时从 package.json 读**,不再手写常量。
|
|
15
|
+
*
|
|
16
|
+
* 2026-09-16 修复:此前写死 "0.1.0",发到 0.1.1 后启动横幅与 User-Agent
|
|
17
|
+
* 仍自称 0.1.0(服务端日志里看到的客户端版本永远是错的,排查问题时极具误导性)。
|
|
18
|
+
* dist/config.js → ../package.json 即包根,npm 发布时 package.json 一定在。
|
|
19
|
+
*/
|
|
20
|
+
function readPackageVersion() {
|
|
21
|
+
try {
|
|
22
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const raw = readFileSync(join(here, "..", "package.json"), "utf8");
|
|
24
|
+
const v = JSON.parse(raw)?.version;
|
|
25
|
+
return typeof v === "string" && v ? v : "0.0.0";
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return "0.0.0";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export const PACKAGE_VERSION = readPackageVersion();
|
|
32
|
+
export const USER_AGENT = `${PACKAGE_NAME}/${PACKAGE_VERSION}`;
|
|
33
|
+
export const DEFAULT_BASE_URL = "https://api.desicterminal.com:8443";
|
|
34
|
+
export const DEFAULT_TIMEOUT_MS = 20_000;
|
|
35
|
+
export const DEFAULT_LIMIT = 20;
|
|
36
|
+
/** 单次工具返回的序列化预算:32 KB(文档 §9 输出规范)。 */
|
|
37
|
+
export const MAX_RESULT_BYTES = 32 * 1024;
|
|
38
|
+
/** API Key 形状:`nhk_<id>.<secret>`(secret 段允许缺省以便兼容早期 key)。 */
|
|
39
|
+
export const API_KEY_PATTERN = /^nhk_[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)?$/;
|
|
40
|
+
/** 配置错误(缺少 key / URL 不合法)。启动阶段直接以退出码 1 结束,并打印可读中文提示。 */
|
|
41
|
+
export class ConfigError extends Error {
|
|
42
|
+
hint;
|
|
43
|
+
constructor(message, hint) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = "ConfigError";
|
|
46
|
+
this.hint = hint;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function parsePositiveInt(raw, fallback, min, max) {
|
|
50
|
+
if (raw === undefined || raw.trim() === "")
|
|
51
|
+
return fallback;
|
|
52
|
+
const n = Number(raw);
|
|
53
|
+
if (!Number.isFinite(n))
|
|
54
|
+
return fallback;
|
|
55
|
+
return Math.min(max, Math.max(min, Math.floor(n)));
|
|
56
|
+
}
|
|
57
|
+
export function normalizeBaseUrl(raw) {
|
|
58
|
+
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = new URL(trimmed);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw new ConfigError(`ANTITONE_BASE_URL 不是合法的 URL:${raw}`, `示例:https://api.desicterminal.com:8443(注意保留 :8443 端口)`);
|
|
65
|
+
}
|
|
66
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
67
|
+
throw new ConfigError(`ANTITONE_BASE_URL 仅支持 http/https:${raw}`, `示例:https://api.desicterminal.com:8443`);
|
|
68
|
+
}
|
|
69
|
+
return trimmed;
|
|
70
|
+
}
|
|
71
|
+
export function loadConfig(options = {}) {
|
|
72
|
+
const env = options.env ?? process.env;
|
|
73
|
+
const warn = options.onWarn ?? ((message) => process.stderr.write(`${message}\n`));
|
|
74
|
+
const apiKey = (env.ANTITONE_API_KEY ?? "").trim();
|
|
75
|
+
if (!apiKey) {
|
|
76
|
+
throw new ConfigError("缺少环境变量 ANTITONE_API_KEY。", [
|
|
77
|
+
"先到 Antitone 个人中心创建 API Key(只显示一次,形如 nhk_xxx.yyy),再把它写进 MCP 客户端配置:",
|
|
78
|
+
'{',
|
|
79
|
+
' "mcpServers": {',
|
|
80
|
+
' "antitone": {',
|
|
81
|
+
' "command": "npx",',
|
|
82
|
+
' "args": ["-y", "antitone-mcp"],',
|
|
83
|
+
' "env": { "ANTITONE_API_KEY": "nhk_xxx.yyy" }',
|
|
84
|
+
" }",
|
|
85
|
+
" }",
|
|
86
|
+
"}",
|
|
87
|
+
].join("\n"));
|
|
88
|
+
}
|
|
89
|
+
if (!API_KEY_PATTERN.test(apiKey)) {
|
|
90
|
+
warn(`[antitone-mcp] 警告:ANTITONE_API_KEY 形如 nhk_xxx.yyy,当前值前缀/形状不匹配(已按原值继续,若被 401 请优先检查此处)。`);
|
|
91
|
+
}
|
|
92
|
+
const baseUrl = normalizeBaseUrl(env.ANTITONE_BASE_URL ?? DEFAULT_BASE_URL);
|
|
93
|
+
return {
|
|
94
|
+
apiKey,
|
|
95
|
+
baseUrl,
|
|
96
|
+
timeoutMs: parsePositiveInt(env.ANTITONE_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, 1_000, 300_000),
|
|
97
|
+
maxResultBytes: parsePositiveInt(env.ANTITONE_MAX_BYTES, MAX_RESULT_BYTES, 4 * 1024, 4 * 1024 * 1024),
|
|
98
|
+
defaultLimit: DEFAULT_LIMIT,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** 打印用:key 只留前 8 位。 */
|
|
102
|
+
export function maskApiKey(apiKey) {
|
|
103
|
+
if (apiKey.length <= 10)
|
|
104
|
+
return `${apiKey.slice(0, 4)}****`;
|
|
105
|
+
return `${apiKey.slice(0, 10)}…${apiKey.slice(-4)}`;
|
|
106
|
+
}
|
|
107
|
+
export function describeConfig(config) {
|
|
108
|
+
return [
|
|
109
|
+
`${PACKAGE_NAME} v${PACKAGE_VERSION} (stdio)`,
|
|
110
|
+
` base_url = ${config.baseUrl}`,
|
|
111
|
+
` api_key = ${maskApiKey(config.apiKey)}`,
|
|
112
|
+
` timeout = ${config.timeoutMs} ms`,
|
|
113
|
+
` max_bytes = ${config.maxResultBytes} B`,
|
|
114
|
+
` auth = Authorization: Bearer <key>(API Key 通道免 X-NS-SIG 签名)`,
|
|
115
|
+
].join("\n");
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 错误规范化:把 HTTP 状态码 / 网络异常翻译成 agent 可读的中文语义,
|
|
3
|
+
* 并保留 402 / 403 / 429 的结构化字段(need_credits / required_scope / Retry-After)。
|
|
4
|
+
*
|
|
5
|
+
* 依据:docs/api-platform-master-plan.md §7.4 错误语义、§7.5 计费回执。
|
|
6
|
+
*/
|
|
7
|
+
import type { Billing } from "./client.js";
|
|
8
|
+
export type ErrorKind = "config" | "invalid_key" | "insufficient_credits" | "missing_scope" | "rate_limited" | "bad_request" | "not_found" | "timeout" | "network" | "server_error" | "bad_response" | "cancelled" | "unknown";
|
|
9
|
+
export interface NormalizedError {
|
|
10
|
+
kind: ErrorKind;
|
|
11
|
+
message: string;
|
|
12
|
+
hint?: string;
|
|
13
|
+
status?: number;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
retry_after_ms?: number;
|
|
16
|
+
retry_after_s?: number;
|
|
17
|
+
need_credits?: number;
|
|
18
|
+
balance?: number;
|
|
19
|
+
required_scope?: string;
|
|
20
|
+
topup_url?: string;
|
|
21
|
+
server_error?: string;
|
|
22
|
+
detail?: unknown;
|
|
23
|
+
}
|
|
24
|
+
export declare function toInteger(value: unknown): number | undefined;
|
|
25
|
+
/** 解析 Retry-After:支持秒数或 HTTP-date。 */
|
|
26
|
+
export declare function parseRetryAfter(raw: string | null | undefined, now?: number): number | undefined;
|
|
27
|
+
export declare function humanizeRetryAfter(ms: number | undefined): string;
|
|
28
|
+
export declare class AntitoneError extends Error {
|
|
29
|
+
readonly normalized: NormalizedError;
|
|
30
|
+
readonly billing?: Billing;
|
|
31
|
+
constructor(normalized: NormalizedError, billing?: Billing);
|
|
32
|
+
get kind(): ErrorKind;
|
|
33
|
+
get retryable(): boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface ResponseErrorContext {
|
|
36
|
+
status: number;
|
|
37
|
+
body: unknown;
|
|
38
|
+
retryAfterHeader?: string | null;
|
|
39
|
+
billing?: Billing;
|
|
40
|
+
}
|
|
41
|
+
/** 把一次失败的 HTTP 响应规范化。体里若带 error/limit/required_scope 等字段则直通。 */
|
|
42
|
+
export declare function fromResponse(ctx: ResponseErrorContext): AntitoneError;
|
|
43
|
+
export interface ThrownErrorContext {
|
|
44
|
+
timedOut?: boolean;
|
|
45
|
+
timeoutMs?: number;
|
|
46
|
+
url?: string;
|
|
47
|
+
signalAborted?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** 把 fetch 抛出的异常(超时 / DNS / 连接重置 / 用户取消)规范化。 */
|
|
50
|
+
export declare function normalizeThrown(error: unknown, ctx?: ThrownErrorContext): AntitoneError;
|
|
51
|
+
/** 统一出口:把任意异常转成 AntitoneError(工具层绝不让异常冒泡打断 MCP 连接)。 */
|
|
52
|
+
export declare function normalizeAnyThrown(error: unknown, ctx?: ThrownErrorContext): AntitoneError;
|
|
53
|
+
//# sourceMappingURL=errors.d.ts.map
|