@antseed/node 0.1.2 → 0.1.4
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/README.md +8 -0
- package/dist/discovery/announcer.d.ts +14 -0
- package/dist/discovery/announcer.d.ts.map +1 -1
- package/dist/discovery/announcer.js +128 -68
- package/dist/discovery/announcer.js.map +1 -1
- package/dist/discovery/index.d.ts +1 -1
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +1 -1
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/metadata-codec.d.ts +7 -0
- package/dist/discovery/metadata-codec.d.ts.map +1 -1
- package/dist/discovery/metadata-codec.js +151 -0
- package/dist/discovery/metadata-codec.js.map +1 -1
- package/dist/discovery/metadata-validator.d.ts +4 -0
- package/dist/discovery/metadata-validator.d.ts.map +1 -1
- package/dist/discovery/metadata-validator.js +142 -1
- package/dist/discovery/metadata-validator.js.map +1 -1
- package/dist/discovery/peer-metadata.d.ts +9 -1
- package/dist/discovery/peer-metadata.d.ts.map +1 -1
- package/dist/discovery/peer-metadata.js +11 -1
- package/dist/discovery/peer-metadata.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/seller-provider.d.ts +5 -0
- package/dist/interfaces/seller-provider.d.ts.map +1 -1
- package/dist/node.d.ts +12 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +175 -59
- package/dist/node.js.map +1 -1
- package/dist/p2p/message-protocol.js +3 -3
- package/dist/p2p/message-protocol.js.map +1 -1
- package/dist/proxy/index.d.ts +1 -0
- package/dist/proxy/index.d.ts.map +1 -1
- package/dist/proxy/index.js +1 -0
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/model-api-adapter.d.ts +20 -0
- package/dist/proxy/model-api-adapter.d.ts.map +1 -0
- package/dist/proxy/model-api-adapter.js +514 -0
- package/dist/proxy/model-api-adapter.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/model-api.d.ts +4 -0
- package/dist/types/model-api.d.ts.map +1 -0
- package/dist/types/model-api.js +10 -0
- package/dist/types/model-api.js.map +1 -0
- package/dist/types/peer.d.ts +11 -0
- package/dist/types/peer.d.ts.map +1 -1
- package/dist/types/peer.js.map +1 -1
- package/dist/types/plugin-config.d.ts +1 -1
- package/dist/types/plugin-config.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './types/index.js';
|
|
|
6
6
|
export { loadOrCreateIdentity } from './p2p/identity.js';
|
|
7
7
|
export { DHTNode, DEFAULT_DHT_CONFIG } from './discovery/dht-node.js';
|
|
8
8
|
export { OFFICIAL_BOOTSTRAP_NODES, mergeBootstrapNodes, toBootstrapConfig } from './discovery/bootstrap.js';
|
|
9
|
+
export { WELL_KNOWN_MODEL_CATEGORIES, WELL_KNOWN_MODEL_API_PROTOCOLS, } from './discovery/peer-metadata.js';
|
|
9
10
|
export { MetadataServer } from './discovery/metadata-server.js';
|
|
10
11
|
export { MeteringStorage } from './metering/storage.js';
|
|
11
12
|
export { BalanceManager } from './payments/balance-manager.js';
|
|
@@ -15,6 +16,7 @@ export { NatTraversal } from './p2p/nat-traversal.js';
|
|
|
15
16
|
export { BuyerPaymentManager } from './payments/buyer-payment-manager.js';
|
|
16
17
|
export { ProxyMux } from './proxy/proxy-mux.js';
|
|
17
18
|
export { resolveProvider } from './proxy/provider-detection.js';
|
|
19
|
+
export { detectRequestModelApiProtocol, inferProviderDefaultModelApiProtocols, selectTargetProtocolForRequest, transformAnthropicMessagesRequestToOpenAIChat, transformOpenAIChatResponseToAnthropicMessage, } from './proxy/model-api-adapter.js';
|
|
18
20
|
export { DefaultRouter } from './routing/default-router.js';
|
|
19
21
|
export { ProfileManager } from './discovery/profile-manager.js';
|
|
20
22
|
// Reputation
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EACL,WAAW,GAMZ,MAAM,WAAW,CAAC;AAInB,+BAA+B;AAC/B,cAAc,kBAAkB,CAAC;AAEjC,uCAAuC;AACvC,OAAO,EAAE,oBAAoB,EAAiB,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EACL,WAAW,GAMZ,MAAM,WAAW,CAAC;AAInB,+BAA+B;AAC/B,cAAc,kBAAkB,CAAC;AAEjC,uCAAuC;AACvC,OAAO,EAAE,oBAAoB,EAAiB,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC5G,OAAO,EACL,2BAA2B,EAC3B,8BAA8B,GAI/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAA6B,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAyB,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAE,YAAY,EAA4C,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE1E,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EACL,6BAA6B,EAC7B,qCAAqC,EACrC,8BAA8B,EAC9B,6CAA6C,EAC7C,6CAA6C,GAG9C,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAA4B,MAAM,6BAA6B,CAAC;AAGtF,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,aAAa;AACb,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAGvF,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,0BAA0B;AAC1B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACnG,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,WAAW,EACX,YAAY,EACZ,oBAAoB,GACrB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACL,gBAAgB,EAChB,cAAc,GAGf,MAAM,2BAA2B,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SerializedHttpRequest, SerializedHttpResponse, SerializedHttpResponseChunk } from '../types/http.js';
|
|
2
2
|
import type { ProviderCapability } from '../types/capability.js';
|
|
3
|
+
import type { ModelApiProtocol } from '../types/model-api.js';
|
|
3
4
|
export interface ProviderTokenPricingUsdPerMillion {
|
|
4
5
|
inputUsdPerMillion: number;
|
|
5
6
|
outputUsdPerMillion: number;
|
|
@@ -22,6 +23,10 @@ export interface Provider {
|
|
|
22
23
|
models: string[];
|
|
23
24
|
/** Seller pricing in USD per 1M tokens (defaults + optional per-model overrides). */
|
|
24
25
|
pricing: ProviderPricing;
|
|
26
|
+
/** Optional model category tags used for discovery metadata. */
|
|
27
|
+
modelCategories?: Record<string, string[]>;
|
|
28
|
+
/** Optional per-model API protocol support advertised via discovery metadata. */
|
|
29
|
+
modelApiProtocols?: Record<string, ModelApiProtocol[]>;
|
|
25
30
|
/** Maximum concurrent requests this provider can handle */
|
|
26
31
|
maxConcurrency: number;
|
|
27
32
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seller-provider.d.ts","sourceRoot":"","sources":["../../src/interfaces/seller-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"seller-provider.d.ts","sourceRoot":"","sources":["../../src/interfaces/seller-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AACnH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,iCAAiC;IAChD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,iCAAiC,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC;CAC5D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IAEb,0GAA0G;IAC1G,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,qFAAqF;IACrF,OAAO,EAAE,eAAe,CAAC;IAEzB,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE3C,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAEvD,2DAA2D;IAC3D,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,mBAAmB,CAAC,CAClB,GAAG,EAAE,qBAAqB,EAC1B,SAAS,EAAE,uBAAuB,GACjC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAEnC,sEAAsE;IACtE,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,2DAA2D;IAC3D,WAAW,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAEhD,2EAA2E;IAC3E,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAEpC,6EAA6E;IAC7E,UAAU,CAAC,CAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAEzD,uCAAuC;IACvC,WAAW,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,uBAAuB;IACtC,eAAe,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC5D,eAAe,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,cAAc,GAAG,OAAO,CAAC;IACvD,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
package/dist/node.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface NodePaymentsConfig {
|
|
|
33
33
|
}
|
|
34
34
|
export interface NodeConfig {
|
|
35
35
|
role: 'seller' | 'buyer';
|
|
36
|
+
displayName?: string;
|
|
36
37
|
dataDir?: string;
|
|
37
38
|
dhtPort?: number;
|
|
38
39
|
signalingPort?: number;
|
|
@@ -41,6 +42,10 @@ export interface NodeConfig {
|
|
|
41
42
|
port: number;
|
|
42
43
|
}>;
|
|
43
44
|
requestTimeoutMs?: number;
|
|
45
|
+
/** Maximum buffered body size (bytes) while reconstructing streaming responses. Default: 16 MiB. */
|
|
46
|
+
maxStreamBufferBytes?: number;
|
|
47
|
+
/** Maximum wall time allowed for a streaming response. Default: 5 minutes. */
|
|
48
|
+
maxStreamDurationMs?: number;
|
|
44
49
|
/** Allow private/loopback IPs in DHT lookups. Default: false. Set true for local testing. */
|
|
45
50
|
allowPrivateIPs?: boolean;
|
|
46
51
|
/** Optional seller-side payment runtime wiring. */
|
|
@@ -69,6 +74,7 @@ export interface RequestStreamCallbacks {
|
|
|
69
74
|
onResponseChunk?: (chunk: SerializedHttpResponseChunk) => void;
|
|
70
75
|
}
|
|
71
76
|
export declare class AntseedNode extends EventEmitter {
|
|
77
|
+
private static readonly _METADATA_REFRESH_DEBOUNCE_MS;
|
|
72
78
|
private _config;
|
|
73
79
|
private _identity;
|
|
74
80
|
private _dht;
|
|
@@ -86,6 +92,8 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
86
92
|
private _balanceManager;
|
|
87
93
|
private _escrowClient;
|
|
88
94
|
private _paymentMuxes;
|
|
95
|
+
private _providerLoadCounts;
|
|
96
|
+
private _metadataRefreshTimer;
|
|
89
97
|
/** Per-buyer session tracking: buyerPeerId → seller session state */
|
|
90
98
|
private _sessions;
|
|
91
99
|
private _settlementTimers;
|
|
@@ -129,6 +137,7 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
129
137
|
private _stripStreamingHeader;
|
|
130
138
|
private _parseJsonBody;
|
|
131
139
|
private _extractRequestedModel;
|
|
140
|
+
private _extractRequestedProvider;
|
|
132
141
|
private _resolveProviderPricing;
|
|
133
142
|
private _getOrCreateSellerSession;
|
|
134
143
|
private _emitSellerSessionUpdated;
|
|
@@ -185,5 +194,8 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
185
194
|
*/
|
|
186
195
|
private _endAllBuyerSessions;
|
|
187
196
|
private _lookupResultToPeerInfo;
|
|
197
|
+
private _adjustProviderLoad;
|
|
198
|
+
private _scheduleMetadataRefresh;
|
|
199
|
+
private _unrefTimer;
|
|
188
200
|
}
|
|
189
201
|
//# sourceMappingURL=node.d.ts.map
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
|
package/dist/node.js
CHANGED
|
@@ -25,6 +25,7 @@ import { debugLog, debugWarn } from "./utils/debug.js";
|
|
|
25
25
|
import { BuyerPaymentManager } from "./payments/buyer-payment-manager.js";
|
|
26
26
|
import { identityToEvmAddress } from "./payments/evm/keypair.js";
|
|
27
27
|
export class AntseedNode extends EventEmitter {
|
|
28
|
+
static _METADATA_REFRESH_DEBOUNCE_MS = 200;
|
|
28
29
|
_config;
|
|
29
30
|
_identity = null;
|
|
30
31
|
_dht = null;
|
|
@@ -42,6 +43,8 @@ export class AntseedNode extends EventEmitter {
|
|
|
42
43
|
_balanceManager = null;
|
|
43
44
|
_escrowClient = null;
|
|
44
45
|
_paymentMuxes = new Map();
|
|
46
|
+
_providerLoadCounts = new Map();
|
|
47
|
+
_metadataRefreshTimer = null;
|
|
45
48
|
/** Per-buyer session tracking: buyerPeerId → seller session state */
|
|
46
49
|
_sessions = new Map();
|
|
47
50
|
_settlementTimers = new Map();
|
|
@@ -147,6 +150,11 @@ export class AntseedNode extends EventEmitter {
|
|
|
147
150
|
clearTimeout(timer);
|
|
148
151
|
}
|
|
149
152
|
this._settlementTimers.clear();
|
|
153
|
+
if (this._metadataRefreshTimer) {
|
|
154
|
+
clearTimeout(this._metadataRefreshTimer);
|
|
155
|
+
this._metadataRefreshTimer = null;
|
|
156
|
+
}
|
|
157
|
+
this._providerLoadCounts.clear();
|
|
150
158
|
// Remove NAT port mappings
|
|
151
159
|
if (this._nat) {
|
|
152
160
|
await this._nat.cleanup();
|
|
@@ -266,12 +274,16 @@ export class AntseedNode extends EventEmitter {
|
|
|
266
274
|
const startTime = Date.now();
|
|
267
275
|
return new Promise((resolve, reject) => {
|
|
268
276
|
const timeoutMs = this._config.requestTimeoutMs ?? 30_000;
|
|
277
|
+
const maxStreamBufferBytes = Math.max(1, this._config.maxStreamBufferBytes ?? 16 * 1024 * 1024);
|
|
278
|
+
const maxStreamDurationMs = Math.max(1, this._config.maxStreamDurationMs ?? 5 * 60_000);
|
|
269
279
|
// Idle timeout for streaming: resets on each chunk so long-running
|
|
270
280
|
// streams (thinking models, large outputs) stay alive as long as
|
|
271
281
|
// data keeps flowing.
|
|
272
282
|
const streamIdleTimeoutMs = Math.max(timeoutMs, 60_000);
|
|
273
283
|
let settled = false;
|
|
274
284
|
let streamStarted = false;
|
|
285
|
+
let streamStartedAtMs = 0;
|
|
286
|
+
let streamBufferedBytes = 0;
|
|
275
287
|
let streamStartResponse = null;
|
|
276
288
|
const streamChunks = [];
|
|
277
289
|
let activeTimeout = null;
|
|
@@ -308,8 +320,12 @@ export class AntseedNode extends EventEmitter {
|
|
|
308
320
|
reject(error);
|
|
309
321
|
};
|
|
310
322
|
mux.sendProxyRequest(req, (response, metadata) => {
|
|
323
|
+
if (settled)
|
|
324
|
+
return;
|
|
311
325
|
if (metadata.streamingStart) {
|
|
312
326
|
streamStarted = true;
|
|
327
|
+
streamStartedAtMs = Date.now();
|
|
328
|
+
streamBufferedBytes = 0;
|
|
313
329
|
streamStartResponse = this._stripStreamingHeader(response);
|
|
314
330
|
// Switch to streaming idle timeout: resets on each chunk.
|
|
315
331
|
resetTimeout(streamIdleTimeoutMs);
|
|
@@ -319,10 +335,26 @@ export class AntseedNode extends EventEmitter {
|
|
|
319
335
|
callbacks?.onResponseStart?.(this._stripStreamingHeader(response), { streaming: false });
|
|
320
336
|
finish(response);
|
|
321
337
|
}, (chunk) => {
|
|
338
|
+
if (settled)
|
|
339
|
+
return;
|
|
322
340
|
if (!streamStarted)
|
|
323
341
|
return;
|
|
324
342
|
// Reset idle timeout on each chunk so streaming stays alive.
|
|
325
343
|
resetTimeout(streamIdleTimeoutMs);
|
|
344
|
+
if (Date.now() - streamStartedAtMs > maxStreamDurationMs) {
|
|
345
|
+
mux.cancelProxyRequest(req.requestId);
|
|
346
|
+
fail(new Error(`Stream ${req.requestId} exceeded max duration (${maxStreamDurationMs}ms)`));
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (chunk.data.length > 0) {
|
|
350
|
+
const nextBufferedBytes = streamBufferedBytes + chunk.data.length;
|
|
351
|
+
if (nextBufferedBytes > maxStreamBufferBytes) {
|
|
352
|
+
mux.cancelProxyRequest(req.requestId);
|
|
353
|
+
fail(new Error(`Stream ${req.requestId} exceeded max buffered size (${maxStreamBufferBytes} bytes)`));
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
streamBufferedBytes = nextBufferedBytes;
|
|
357
|
+
}
|
|
326
358
|
callbacks?.onResponseChunk?.(chunk);
|
|
327
359
|
if (chunk.data.length > 0) {
|
|
328
360
|
streamChunks.push(chunk.data);
|
|
@@ -391,7 +423,16 @@ export class AntseedNode extends EventEmitter {
|
|
|
391
423
|
_wireConnection(conn, peerId) {
|
|
392
424
|
const decoder = new FrameDecoder();
|
|
393
425
|
conn.on("message", (data) => {
|
|
394
|
-
|
|
426
|
+
let frames;
|
|
427
|
+
try {
|
|
428
|
+
frames = decoder.feed(data);
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
432
|
+
debugWarn(`[Node] Failed to decode frame from ${peerId.slice(0, 12)}...: ${message}`);
|
|
433
|
+
conn.fail(err instanceof Error ? err : new Error(message));
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
395
436
|
const proxyMux = this._muxes.get(peerId);
|
|
396
437
|
const paymentMux = this._paymentMuxes.get(peerId);
|
|
397
438
|
for (const frame of frames) {
|
|
@@ -478,8 +519,11 @@ export class AntseedNode extends EventEmitter {
|
|
|
478
519
|
providers: this._providers.map((p) => ({
|
|
479
520
|
provider: p.name,
|
|
480
521
|
models: p.models,
|
|
522
|
+
...(p.modelCategories ? { modelCategories: { ...p.modelCategories } } : {}),
|
|
523
|
+
...(p.modelApiProtocols ? { modelApiProtocols: { ...p.modelApiProtocols } } : {}),
|
|
481
524
|
maxConcurrency: p.maxConcurrency,
|
|
482
525
|
})),
|
|
526
|
+
...(this._config.displayName ? { displayName: this._config.displayName } : {}),
|
|
483
527
|
region: "unknown",
|
|
484
528
|
pricing: new Map(this._providers.map((p) => [
|
|
485
529
|
p.name,
|
|
@@ -574,7 +618,18 @@ export class AntseedNode extends EventEmitter {
|
|
|
574
618
|
});
|
|
575
619
|
return;
|
|
576
620
|
}
|
|
577
|
-
const
|
|
621
|
+
const requestedModel = this._extractRequestedModel(request);
|
|
622
|
+
const requestedProvider = this._extractRequestedProvider(request);
|
|
623
|
+
const matchesModel = (provider) => provider.models.length === 0
|
|
624
|
+
|| (requestedModel !== null && provider.models.includes(requestedModel))
|
|
625
|
+
|| this._providers.length === 1;
|
|
626
|
+
let provider;
|
|
627
|
+
if (requestedProvider) {
|
|
628
|
+
provider = this._providers.find((candidate) => candidate.name.toLowerCase() === requestedProvider && matchesModel(candidate));
|
|
629
|
+
}
|
|
630
|
+
if (!provider) {
|
|
631
|
+
provider = this._providers.find((candidate) => matchesModel(candidate));
|
|
632
|
+
}
|
|
578
633
|
if (!provider) {
|
|
579
634
|
debugWarn(`[Node] No matching provider for ${request.path}`);
|
|
580
635
|
mux.sendProxyResponse({
|
|
@@ -593,60 +648,66 @@ export class AntseedNode extends EventEmitter {
|
|
|
593
648
|
let statusCode = 500;
|
|
594
649
|
let responseBody = new Uint8Array(0);
|
|
595
650
|
let streamedResponseStarted = false;
|
|
651
|
+
this._adjustProviderLoad(provider.name, 1);
|
|
596
652
|
try {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
statusCode = response.statusCode;
|
|
610
|
-
responseBody = response.body;
|
|
611
|
-
debugLog(`[Node] Provider responded: status=${statusCode} (${Date.now() - startTime}ms, ${responseBody.length}b)`);
|
|
612
|
-
if (!streamedResponseStarted) {
|
|
613
|
-
mux.sendProxyResponse(response);
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
catch (err) {
|
|
617
|
-
const message = err instanceof Error ? err.message : "Internal error";
|
|
618
|
-
debugWarn(`[Node] Provider error after ${Date.now() - startTime}ms: ${message}`);
|
|
619
|
-
responseBody = new TextEncoder().encode(message);
|
|
620
|
-
if (streamedResponseStarted) {
|
|
621
|
-
mux.sendProxyChunk({
|
|
622
|
-
requestId: request.requestId,
|
|
623
|
-
data: new TextEncoder().encode(`event: error\ndata: ${message}\n\n`),
|
|
624
|
-
done: false,
|
|
625
|
-
});
|
|
626
|
-
mux.sendProxyChunk({
|
|
627
|
-
requestId: request.requestId,
|
|
628
|
-
data: new Uint8Array(0),
|
|
629
|
-
done: true,
|
|
653
|
+
try {
|
|
654
|
+
const response = await this._executeProviderRequest(provider, request, {
|
|
655
|
+
onResponseStart: (streamResponseStart) => {
|
|
656
|
+
streamedResponseStarted = true;
|
|
657
|
+
statusCode = streamResponseStart.statusCode;
|
|
658
|
+
mux.sendProxyResponse(streamResponseStart);
|
|
659
|
+
},
|
|
660
|
+
onResponseChunk: (chunk) => {
|
|
661
|
+
if (!streamedResponseStarted)
|
|
662
|
+
return;
|
|
663
|
+
mux.sendProxyChunk(chunk);
|
|
664
|
+
},
|
|
630
665
|
});
|
|
666
|
+
statusCode = response.statusCode;
|
|
667
|
+
responseBody = response.body;
|
|
668
|
+
debugLog(`[Node] Provider responded: status=${statusCode} (${Date.now() - startTime}ms, ${responseBody.length}b)`);
|
|
669
|
+
if (!streamedResponseStarted) {
|
|
670
|
+
mux.sendProxyResponse(response);
|
|
671
|
+
}
|
|
631
672
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
673
|
+
catch (err) {
|
|
674
|
+
const message = err instanceof Error ? err.message : "Internal error";
|
|
675
|
+
debugWarn(`[Node] Provider error after ${Date.now() - startTime}ms: ${message}`);
|
|
676
|
+
responseBody = new TextEncoder().encode(message);
|
|
677
|
+
if (streamedResponseStarted) {
|
|
678
|
+
mux.sendProxyChunk({
|
|
679
|
+
requestId: request.requestId,
|
|
680
|
+
data: new TextEncoder().encode(`event: error\ndata: ${message}\n\n`),
|
|
681
|
+
done: false,
|
|
682
|
+
});
|
|
683
|
+
mux.sendProxyChunk({
|
|
684
|
+
requestId: request.requestId,
|
|
685
|
+
data: new Uint8Array(0),
|
|
686
|
+
done: true,
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
statusCode = 500;
|
|
691
|
+
mux.sendProxyResponse({
|
|
692
|
+
requestId: request.requestId,
|
|
693
|
+
statusCode: 500,
|
|
694
|
+
headers: { "content-type": "text/plain" },
|
|
695
|
+
body: responseBody,
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// Record metering
|
|
700
|
+
const latencyMs = Date.now() - startTime;
|
|
701
|
+
const requestPricing = this._resolveProviderPricing(provider, request);
|
|
702
|
+
await this._recordMetering(buyerPeerId, provider.name, requestPricing, request, statusCode, latencyMs, request.body.length, responseBody.length);
|
|
703
|
+
// Generate bilateral receipt after each request if lock committed (Task 3)
|
|
704
|
+
const currentSession = this._sessions.get(buyerPeerId);
|
|
705
|
+
if (currentSession?.lockCommitted) {
|
|
706
|
+
await this._sendBilateralReceipt(buyerPeerId, currentSession, requestPricing, responseBody, paymentMux);
|
|
640
707
|
}
|
|
641
708
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
const requestPricing = this._resolveProviderPricing(provider, request);
|
|
645
|
-
await this._recordMetering(buyerPeerId, provider.name, requestPricing, request, statusCode, latencyMs, request.body.length, responseBody.length);
|
|
646
|
-
// Generate bilateral receipt after each request if lock committed (Task 3)
|
|
647
|
-
const currentSession = this._sessions.get(buyerPeerId);
|
|
648
|
-
if (currentSession?.lockCommitted) {
|
|
649
|
-
await this._sendBilateralReceipt(buyerPeerId, currentSession, requestPricing, responseBody, paymentMux);
|
|
709
|
+
finally {
|
|
710
|
+
this._adjustProviderLoad(provider.name, -1);
|
|
650
711
|
}
|
|
651
712
|
});
|
|
652
713
|
this._muxes.set(buyerPeerId, mux);
|
|
@@ -777,6 +838,13 @@ export class AntseedNode extends EventEmitter {
|
|
|
777
838
|
}
|
|
778
839
|
return model.trim();
|
|
779
840
|
}
|
|
841
|
+
_extractRequestedProvider(request) {
|
|
842
|
+
const providers = Object.entries(request.headers)
|
|
843
|
+
.filter(([header]) => header.toLowerCase() === "x-antseed-provider")
|
|
844
|
+
.map(([, value]) => value.trim().toLowerCase())
|
|
845
|
+
.filter((value) => value.length > 0);
|
|
846
|
+
return providers[0] ?? null;
|
|
847
|
+
}
|
|
780
848
|
_resolveProviderPricing(provider, request) {
|
|
781
849
|
const requestedModel = this._extractRequestedModel(request);
|
|
782
850
|
if (requestedModel) {
|
|
@@ -1407,23 +1475,42 @@ export class AntseedNode extends EventEmitter {
|
|
|
1407
1475
|
_lookupResultToPeerInfo(result) {
|
|
1408
1476
|
const providers = result.metadata.providers.map((p) => p.provider);
|
|
1409
1477
|
const firstProvider = result.metadata.providers[0];
|
|
1410
|
-
const providerPricingEntries =
|
|
1411
|
-
|
|
1412
|
-
|
|
1478
|
+
const providerPricingEntries = {};
|
|
1479
|
+
const providerModelCategoryEntries = {};
|
|
1480
|
+
const providerModelApiProtocolEntries = {};
|
|
1481
|
+
for (const providerAnnouncement of result.metadata.providers) {
|
|
1482
|
+
providerPricingEntries[providerAnnouncement.provider] = {
|
|
1413
1483
|
defaults: {
|
|
1414
|
-
inputUsdPerMillion:
|
|
1415
|
-
outputUsdPerMillion:
|
|
1484
|
+
inputUsdPerMillion: providerAnnouncement.defaultPricing.inputUsdPerMillion,
|
|
1485
|
+
outputUsdPerMillion: providerAnnouncement.defaultPricing.outputUsdPerMillion,
|
|
1416
1486
|
},
|
|
1417
|
-
...(
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1487
|
+
...(providerAnnouncement.modelPricing ? { models: { ...providerAnnouncement.modelPricing } } : {}),
|
|
1488
|
+
};
|
|
1489
|
+
if (providerAnnouncement.modelCategories && Object.keys(providerAnnouncement.modelCategories).length > 0) {
|
|
1490
|
+
providerModelCategoryEntries[providerAnnouncement.provider] = {
|
|
1491
|
+
models: Object.fromEntries(Object.entries(providerAnnouncement.modelCategories)
|
|
1492
|
+
.map(([model, categories]) => [model, [...categories]])),
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
if (providerAnnouncement.modelApiProtocols && Object.keys(providerAnnouncement.modelApiProtocols).length > 0) {
|
|
1496
|
+
providerModelApiProtocolEntries[providerAnnouncement.provider] = {
|
|
1497
|
+
models: Object.fromEntries(Object.entries(providerAnnouncement.modelApiProtocols)
|
|
1498
|
+
.map(([model, protocols]) => [model, [...protocols]])),
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1420
1502
|
const hasProviderPricing = Object.keys(providerPricingEntries).length > 0;
|
|
1503
|
+
const hasProviderModelCategories = Object.keys(providerModelCategoryEntries).length > 0;
|
|
1504
|
+
const hasProviderModelApiProtocols = Object.keys(providerModelApiProtocolEntries).length > 0;
|
|
1421
1505
|
return {
|
|
1422
1506
|
peerId: result.metadata.peerId,
|
|
1507
|
+
displayName: result.metadata.displayName,
|
|
1423
1508
|
lastSeen: result.metadata.timestamp,
|
|
1424
1509
|
providers,
|
|
1425
1510
|
publicAddress: `${result.host}:${result.port}`,
|
|
1426
1511
|
...(hasProviderPricing ? { providerPricing: providerPricingEntries } : {}),
|
|
1512
|
+
...(hasProviderModelCategories ? { providerModelCategories: providerModelCategoryEntries } : {}),
|
|
1513
|
+
...(hasProviderModelApiProtocols ? { providerModelApiProtocols: providerModelApiProtocolEntries } : {}),
|
|
1427
1514
|
defaultInputUsdPerMillion: firstProvider?.defaultPricing.inputUsdPerMillion,
|
|
1428
1515
|
defaultOutputUsdPerMillion: firstProvider?.defaultPricing.outputUsdPerMillion,
|
|
1429
1516
|
maxConcurrency: firstProvider?.maxConcurrency,
|
|
@@ -1435,6 +1522,35 @@ export class AntseedNode extends EventEmitter {
|
|
|
1435
1522
|
trustScore: result.metadata.onChainReputation,
|
|
1436
1523
|
};
|
|
1437
1524
|
}
|
|
1525
|
+
_adjustProviderLoad(providerName, delta) {
|
|
1526
|
+
const nextLoad = Math.max(0, (this._providerLoadCounts.get(providerName) ?? 0) + delta);
|
|
1527
|
+
this._providerLoadCounts.set(providerName, nextLoad);
|
|
1528
|
+
if (!this._announcer)
|
|
1529
|
+
return;
|
|
1530
|
+
this._announcer.updateLoad(providerName, nextLoad);
|
|
1531
|
+
this._scheduleMetadataRefresh();
|
|
1532
|
+
}
|
|
1533
|
+
_scheduleMetadataRefresh() {
|
|
1534
|
+
if (!this._announcer || this._metadataRefreshTimer) {
|
|
1535
|
+
return;
|
|
1536
|
+
}
|
|
1537
|
+
const timer = setTimeout(() => {
|
|
1538
|
+
this._metadataRefreshTimer = null;
|
|
1539
|
+
const announcer = this._announcer;
|
|
1540
|
+
if (!announcer)
|
|
1541
|
+
return;
|
|
1542
|
+
void announcer.refreshMetadata().catch((err) => {
|
|
1543
|
+
debugWarn(`[Node] Failed to refresh metadata snapshot: ${err instanceof Error ? err.message : err}`);
|
|
1544
|
+
});
|
|
1545
|
+
}, AntseedNode._METADATA_REFRESH_DEBOUNCE_MS);
|
|
1546
|
+
this._metadataRefreshTimer = timer;
|
|
1547
|
+
this._unrefTimer(timer);
|
|
1548
|
+
}
|
|
1549
|
+
_unrefTimer(timer) {
|
|
1550
|
+
if (typeof timer.unref === "function") {
|
|
1551
|
+
timer.unref();
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1438
1554
|
}
|
|
1439
1555
|
function concatChunks(chunks) {
|
|
1440
1556
|
if (chunks.length === 0)
|