@antseed/node 0.1.0 → 0.1.2
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 +674 -0
- package/README.md +7 -5
- package/dist/discovery/http-metadata-resolver.d.ts +6 -0
- package/dist/discovery/http-metadata-resolver.d.ts.map +1 -1
- package/dist/discovery/http-metadata-resolver.js +32 -4
- package/dist/discovery/http-metadata-resolver.js.map +1 -1
- package/dist/discovery/peer-lookup.d.ts +1 -0
- package/dist/discovery/peer-lookup.d.ts.map +1 -1
- package/dist/discovery/peer-lookup.js +10 -25
- package/dist/discovery/peer-lookup.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/seller-provider.d.ts +13 -1
- package/dist/interfaces/seller-provider.d.ts.map +1 -1
- package/dist/node.d.ts +13 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +146 -21
- package/dist/node.js.map +1 -1
- package/dist/proxy/proxy-mux.d.ts +3 -1
- package/dist/proxy/proxy-mux.d.ts.map +1 -1
- package/dist/proxy/proxy-mux.js +9 -5
- package/dist/proxy/proxy-mux.js.map +1 -1
- package/dist/types/http.d.ts +1 -0
- package/dist/types/http.d.ts.map +1 -1
- package/dist/types/http.js +1 -1
- package/dist/types/http.js.map +1 -1
- package/package.json +14 -10
- package/contracts/AntseedEscrow.sol +0 -310
- package/contracts/MockUSDC.sol +0 -64
- package/contracts/README.md +0 -102
- package/src/config/encryption.test.ts +0 -49
- package/src/config/encryption.ts +0 -53
- package/src/config/plugin-config-manager.test.ts +0 -92
- package/src/config/plugin-config-manager.ts +0 -153
- package/src/config/plugin-loader.ts +0 -90
- package/src/discovery/announcer.ts +0 -169
- package/src/discovery/bootstrap.ts +0 -57
- package/src/discovery/default-metadata-resolver.ts +0 -18
- package/src/discovery/dht-health.ts +0 -136
- package/src/discovery/dht-node.ts +0 -191
- package/src/discovery/http-metadata-resolver.ts +0 -47
- package/src/discovery/index.ts +0 -15
- package/src/discovery/metadata-codec.ts +0 -453
- package/src/discovery/metadata-resolver.ts +0 -7
- package/src/discovery/metadata-server.ts +0 -73
- package/src/discovery/metadata-validator.ts +0 -172
- package/src/discovery/peer-lookup.ts +0 -122
- package/src/discovery/peer-metadata.ts +0 -34
- package/src/discovery/peer-selector.ts +0 -134
- package/src/discovery/profile-manager.ts +0 -131
- package/src/discovery/profile-search.ts +0 -100
- package/src/discovery/reputation-verifier.ts +0 -54
- package/src/index.ts +0 -61
- package/src/interfaces/buyer-router.ts +0 -21
- package/src/interfaces/plugin.ts +0 -36
- package/src/interfaces/seller-provider.ts +0 -81
- package/src/metering/index.ts +0 -6
- package/src/metering/receipt-generator.ts +0 -105
- package/src/metering/receipt-verifier.ts +0 -102
- package/src/metering/session-tracker.ts +0 -145
- package/src/metering/storage.ts +0 -600
- package/src/metering/token-counter.ts +0 -127
- package/src/metering/usage-aggregator.ts +0 -236
- package/src/node.ts +0 -1698
- package/src/p2p/connection-auth.ts +0 -152
- package/src/p2p/connection-manager.ts +0 -916
- package/src/p2p/handshake.ts +0 -162
- package/src/p2p/ice-config.ts +0 -59
- package/src/p2p/identity.ts +0 -110
- package/src/p2p/index.ts +0 -11
- package/src/p2p/keepalive.ts +0 -118
- package/src/p2p/message-protocol.ts +0 -171
- package/src/p2p/nat-traversal.ts +0 -169
- package/src/p2p/payment-codec.ts +0 -165
- package/src/p2p/payment-mux.ts +0 -153
- package/src/p2p/reconnect.ts +0 -117
- package/src/payments/balance-manager.ts +0 -77
- package/src/payments/buyer-payment-manager.ts +0 -414
- package/src/payments/disputes.ts +0 -72
- package/src/payments/evm/escrow-client.ts +0 -263
- package/src/payments/evm/keypair.ts +0 -31
- package/src/payments/evm/signatures.ts +0 -103
- package/src/payments/evm/wallet.ts +0 -42
- package/src/payments/index.ts +0 -50
- package/src/payments/settlement.ts +0 -40
- package/src/payments/types.ts +0 -79
- package/src/proxy/index.ts +0 -3
- package/src/proxy/provider-detection.ts +0 -78
- package/src/proxy/proxy-mux.ts +0 -173
- package/src/proxy/request-codec.ts +0 -294
- package/src/reputation/index.ts +0 -6
- package/src/reputation/rating-manager.ts +0 -118
- package/src/reputation/report-manager.ts +0 -91
- package/src/reputation/trust-engine.ts +0 -120
- package/src/reputation/trust-score.ts +0 -74
- package/src/reputation/uptime-tracker.ts +0 -155
- package/src/routing/default-router.ts +0 -75
- package/src/types/bittorrent-dht.d.ts +0 -19
- package/src/types/buyer.ts +0 -37
- package/src/types/capability.ts +0 -34
- package/src/types/connection.ts +0 -29
- package/src/types/http.ts +0 -20
- package/src/types/index.ts +0 -14
- package/src/types/metering.ts +0 -175
- package/src/types/nat-api.d.ts +0 -29
- package/src/types/peer-profile.ts +0 -25
- package/src/types/peer.ts +0 -62
- package/src/types/plugin-config.ts +0 -31
- package/src/types/protocol.ts +0 -162
- package/src/types/provider.ts +0 -40
- package/src/types/rating.ts +0 -23
- package/src/types/report.ts +0 -30
- package/src/types/seller.ts +0 -38
- package/src/types/staking.ts +0 -23
- package/src/utils/debug.ts +0 -30
- package/src/utils/hex.ts +0 -14
- package/tests/balance-manager.test.ts +0 -156
- package/tests/bootstrap.test.ts +0 -108
- package/tests/buyer-payment-manager.test.ts +0 -358
- package/tests/connection-auth.test.ts +0 -87
- package/tests/default-router.test.ts +0 -148
- package/tests/evm-keypair.test.ts +0 -173
- package/tests/identity.test.ts +0 -133
- package/tests/message-protocol.test.ts +0 -212
- package/tests/metadata-codec.test.ts +0 -165
- package/tests/metadata-validator.test.ts +0 -261
- package/tests/metering-storage.test.ts +0 -244
- package/tests/payment-codec.test.ts +0 -95
- package/tests/payment-mux.test.ts +0 -191
- package/tests/peer-selector.test.ts +0 -184
- package/tests/provider-detection.test.ts +0 -107
- package/tests/proxy-mux-security.test.ts +0 -38
- package/tests/receipt.test.ts +0 -215
- package/tests/reputation-integration.test.ts +0 -195
- package/tests/request-codec.test.ts +0 -144
- package/tests/token-counter.test.ts +0 -122
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -7
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
[](https://nodejs.org/)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
Core protocol SDK for AntSeed
|
|
7
|
+
Core protocol SDK for AntSeed — a peer-to-peer AI services network. Providers offer AI services, buyers discover providers via DHT and send requests over encrypted P2P connections.
|
|
8
|
+
|
|
9
|
+
> **Important:** AntSeed is designed for providers who build differentiated services on top of AI APIs — such as TEE-secured inference, domain-specific skills and agents, fine-tuned models, or managed product experiences. Simply reselling raw API access or subscription credentials is not the intended use and may violate your upstream provider's terms of service.
|
|
8
10
|
|
|
9
11
|
## Installation
|
|
10
12
|
|
|
@@ -14,9 +16,9 @@ npm install @antseed/node
|
|
|
14
16
|
|
|
15
17
|
## Quick Start
|
|
16
18
|
|
|
17
|
-
###
|
|
19
|
+
### Provider Mode
|
|
18
20
|
|
|
19
|
-
A
|
|
21
|
+
A provider node announces its capacity on the DHT and serves inference requests from buyers.
|
|
20
22
|
|
|
21
23
|
```ts
|
|
22
24
|
import { AntseedNode } from '@antseed/node';
|
|
@@ -207,7 +209,7 @@ import { BalanceManager } from '@antseed/node/payments';
|
|
|
207
209
|
|
|
208
210
|
## Provider Interface
|
|
209
211
|
|
|
210
|
-
Implement `Provider` to expose any LLM backend as a
|
|
212
|
+
Implement `Provider` to expose any LLM backend as a provider on the network.
|
|
211
213
|
|
|
212
214
|
```ts
|
|
213
215
|
interface Provider {
|
|
@@ -321,7 +323,7 @@ const plugin: AntseedProviderPlugin = {
|
|
|
321
323
|
displayName: 'My Provider',
|
|
322
324
|
version: '1.0.0',
|
|
323
325
|
type: 'provider',
|
|
324
|
-
description: '
|
|
326
|
+
description: 'Provides My LLM capacity on the Antseed Network',
|
|
325
327
|
configSchema: [
|
|
326
328
|
{ key: 'MY_API_KEY', label: 'API Key', type: 'secret', required: true, description: 'API key for My LLM' },
|
|
327
329
|
{ key: 'MY_MODELS', label: 'Models', type: 'string[]', required: false, description: 'Comma-separated model list' },
|
|
@@ -5,11 +5,17 @@ export interface HttpMetadataResolverConfig {
|
|
|
5
5
|
timeoutMs?: number;
|
|
6
6
|
/** Port offset from the signaling port to the metadata HTTP port. Default: 0 (same port) */
|
|
7
7
|
metadataPortOffset?: number;
|
|
8
|
+
/** Cooldown in ms before retrying an endpoint that recently failed. Default: 30000 */
|
|
9
|
+
failureCooldownMs?: number;
|
|
8
10
|
}
|
|
9
11
|
export declare class HttpMetadataResolver implements MetadataResolver {
|
|
10
12
|
private readonly timeoutMs;
|
|
11
13
|
private readonly metadataPortOffset;
|
|
14
|
+
private readonly failureCooldownMs;
|
|
15
|
+
private readonly failedEndpoints;
|
|
12
16
|
constructor(config?: HttpMetadataResolverConfig);
|
|
13
17
|
resolve(peer: PeerEndpoint): Promise<PeerMetadata | null>;
|
|
18
|
+
private markEndpointFailure;
|
|
19
|
+
private getEndpointKey;
|
|
14
20
|
}
|
|
15
21
|
//# sourceMappingURL=http-metadata-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-metadata-resolver.d.ts","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"http-metadata-resolver.d.ts","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsB;gBAE1C,MAAM,CAAC,EAAE,0BAA0B;IAOzC,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAyC/D,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,cAAc;CAGvB"}
|
|
@@ -2,24 +2,40 @@ import { debugWarn } from '../utils/debug.js';
|
|
|
2
2
|
export class HttpMetadataResolver {
|
|
3
3
|
timeoutMs;
|
|
4
4
|
metadataPortOffset;
|
|
5
|
+
failureCooldownMs;
|
|
6
|
+
failedEndpoints;
|
|
5
7
|
constructor(config) {
|
|
6
8
|
this.timeoutMs = config?.timeoutMs ?? 5000;
|
|
7
9
|
this.metadataPortOffset = config?.metadataPortOffset ?? 0;
|
|
10
|
+
this.failureCooldownMs = Math.max(0, config?.failureCooldownMs ?? 30_000);
|
|
11
|
+
this.failedEndpoints = new Map();
|
|
8
12
|
}
|
|
9
13
|
async resolve(peer) {
|
|
10
14
|
const metadataPort = peer.port + this.metadataPortOffset;
|
|
15
|
+
const endpointKey = this.getEndpointKey(peer.host, metadataPort);
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
const failedUntil = this.failedEndpoints.get(endpointKey);
|
|
18
|
+
if (failedUntil !== undefined) {
|
|
19
|
+
if (failedUntil > now) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
this.failedEndpoints.delete(endpointKey);
|
|
23
|
+
}
|
|
11
24
|
const url = `http://${peer.host}:${metadataPort}/metadata`;
|
|
25
|
+
const controller = new AbortController();
|
|
26
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
12
27
|
try {
|
|
13
|
-
const controller = new AbortController();
|
|
14
|
-
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
15
28
|
const response = await fetch(url, { signal: controller.signal });
|
|
16
|
-
clearTimeout(timeout);
|
|
17
29
|
if (!response.ok) {
|
|
30
|
+
this.markEndpointFailure(endpointKey);
|
|
18
31
|
return null;
|
|
19
32
|
}
|
|
20
|
-
|
|
33
|
+
const metadata = (await response.json());
|
|
34
|
+
this.failedEndpoints.delete(endpointKey);
|
|
35
|
+
return metadata;
|
|
21
36
|
}
|
|
22
37
|
catch (err) {
|
|
38
|
+
this.markEndpointFailure(endpointKey);
|
|
23
39
|
const reason = err instanceof DOMException && err.name === 'AbortError'
|
|
24
40
|
? 'timeout'
|
|
25
41
|
: err instanceof SyntaxError
|
|
@@ -28,6 +44,18 @@ export class HttpMetadataResolver {
|
|
|
28
44
|
debugWarn(`[MetadataResolver] Failed to resolve ${url}: ${reason}`);
|
|
29
45
|
return null;
|
|
30
46
|
}
|
|
47
|
+
finally {
|
|
48
|
+
clearTimeout(timeout);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
markEndpointFailure(endpointKey) {
|
|
52
|
+
if (this.failureCooldownMs <= 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this.failedEndpoints.set(endpointKey, Date.now() + this.failureCooldownMs);
|
|
56
|
+
}
|
|
57
|
+
getEndpointKey(host, port) {
|
|
58
|
+
return `${host.toLowerCase()}:${port}`;
|
|
31
59
|
}
|
|
32
60
|
}
|
|
33
61
|
//# sourceMappingURL=http-metadata-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-metadata-resolver.js","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"http-metadata-resolver.js","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@ export declare class PeerLookup {
|
|
|
20
20
|
constructor(config: LookupConfig);
|
|
21
21
|
findSellers(provider: string): Promise<LookupResult[]>;
|
|
22
22
|
findByCapability(capability: string, name?: string): Promise<LookupResult[]>;
|
|
23
|
+
private resolveLookupResults;
|
|
23
24
|
verifyMetadataSignature(metadata: PeerMetadata): Promise<boolean>;
|
|
24
25
|
isStale(metadata: PeerMetadata): boolean;
|
|
25
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer-lookup.d.ts","sourceRoot":"","sources":["../../src/discovery/peer-lookup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"peer-lookup.d.ts","sourceRoot":"","sources":["../../src/discovery/peer-lookup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,wBAAwB,CAAC;AAE7E,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,OAAO,CAAC;IACb,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,qBAAqB,EAAE,IAAI,CAAC,YAAY,EAAE,KAAK,GAAG,kBAAkB,CAKhF,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,YAAY;IAI1B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAOtD,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;YAOpE,oBAAoB;IAyC5B,uBAAuB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAOvE,OAAO,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO;CAIzC"}
|
|
@@ -16,41 +16,26 @@ export class PeerLookup {
|
|
|
16
16
|
const topic = providerTopic(provider);
|
|
17
17
|
const infoHash = topicToInfoHash(topic);
|
|
18
18
|
const peers = await this.config.dht.lookup(infoHash);
|
|
19
|
-
|
|
20
|
-
for (const peer of peers) {
|
|
21
|
-
if (results.length >= this.config.maxResults) {
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
const metadata = await this.config.metadataResolver.resolve(peer);
|
|
25
|
-
if (metadata === null) {
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
if (this.config.requireValidSignature) {
|
|
29
|
-
const valid = await this.verifyMetadataSignature(metadata);
|
|
30
|
-
if (!valid) {
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (!this.config.allowStaleMetadata && this.isStale(metadata)) {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
results.push({
|
|
38
|
-
metadata,
|
|
39
|
-
host: peer.host,
|
|
40
|
-
port: peer.port,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
return results;
|
|
19
|
+
return this.resolveLookupResults(peers);
|
|
44
20
|
}
|
|
45
21
|
async findByCapability(capability, name) {
|
|
46
22
|
const topic = capabilityTopic(capability, name);
|
|
47
23
|
const infoHash = topicToInfoHash(topic);
|
|
48
24
|
const peers = await this.config.dht.lookup(infoHash);
|
|
25
|
+
return this.resolveLookupResults(peers);
|
|
26
|
+
}
|
|
27
|
+
async resolveLookupResults(peers) {
|
|
49
28
|
const results = [];
|
|
29
|
+
const seenEndpoints = new Set();
|
|
50
30
|
for (const peer of peers) {
|
|
51
31
|
if (results.length >= this.config.maxResults) {
|
|
52
32
|
break;
|
|
53
33
|
}
|
|
34
|
+
const endpointKey = `${peer.host.toLowerCase()}:${peer.port}`;
|
|
35
|
+
if (seenEndpoints.has(endpointKey)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
seenEndpoints.add(endpointKey);
|
|
54
39
|
const metadata = await this.config.metadataResolver.resolve(peer);
|
|
55
40
|
if (metadata === null) {
|
|
56
41
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer-lookup.js","sourceRoot":"","sources":["../../src/discovery/peer-lookup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAY/D,MAAM,CAAC,MAAM,qBAAqB,GAAmD;IACnF,qBAAqB,EAAE,IAAI;IAC3B,kBAAkB,EAAE,KAAK;IACzB,oBAAoB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACpC,UAAU,EAAE,EAAE;CACf,CAAC;AAQF,MAAM,OAAO,UAAU;IACJ,MAAM,CAAe;IAEtC,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAgB;QAChC,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"peer-lookup.js","sourceRoot":"","sources":["../../src/discovery/peer-lookup.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { AntseedNode, type NodeConfig, type BuyerPaymentConfig, type NodePaymentsConfig } from './node.js';
|
|
2
|
-
export type { Provider, TaskRequest, TaskEvent, SkillRequest, SkillResponse } from './interfaces/seller-provider.js';
|
|
1
|
+
export { AntseedNode, type NodeConfig, type BuyerPaymentConfig, type NodePaymentsConfig, type RequestStreamCallbacks, type RequestStreamResponseMetadata, } from './node.js';
|
|
2
|
+
export type { Provider, ProviderStreamCallbacks, TaskRequest, TaskEvent, SkillRequest, SkillResponse } from './interfaces/seller-provider.js';
|
|
3
3
|
export type { Router } from './interfaces/buyer-router.js';
|
|
4
4
|
export * from './types/index.js';
|
|
5
5
|
export { loadOrCreateIdentity, type Identity } from './p2p/identity.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,GACnC,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,QAAQ,EAAE,uBAAuB,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAC9I,YAAY,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAG3D,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,oBAAoB,EAAE,KAAK,QAAQ,EAAE,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,EAAE,KAAK,YAAY,EAAE,KAAK,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,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,EAAE,KAAK,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEtF,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACrI,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG9E,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;AACvF,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC/E,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAG7F,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,EACd,KAAK,cAAc,EACnB,KAAK,YAAY,GAClB,MAAM,2BAA2B,CAAA"}
|
package/dist/index.js
CHANGED
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,
|
|
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;AAE5G,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,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,4 +1,4 @@
|
|
|
1
|
-
import type { SerializedHttpRequest, SerializedHttpResponse } from '../types/http.js';
|
|
1
|
+
import type { SerializedHttpRequest, SerializedHttpResponse, SerializedHttpResponseChunk } from '../types/http.js';
|
|
2
2
|
import type { ProviderCapability } from '../types/capability.js';
|
|
3
3
|
export interface ProviderTokenPricingUsdPerMillion {
|
|
4
4
|
inputUsdPerMillion: number;
|
|
@@ -28,6 +28,14 @@ export interface Provider {
|
|
|
28
28
|
* Handle an incoming inference request and return the response.
|
|
29
29
|
*/
|
|
30
30
|
handleRequest(req: SerializedHttpRequest): Promise<SerializedHttpResponse>;
|
|
31
|
+
/**
|
|
32
|
+
* Optional streaming request handler. Implementations should call
|
|
33
|
+
* `callbacks.onResponseStart` once, then `callbacks.onResponseChunk`
|
|
34
|
+
* zero or more times (including a final `done=true` chunk).
|
|
35
|
+
*
|
|
36
|
+
* Must resolve with the complete reconstructed response body.
|
|
37
|
+
*/
|
|
38
|
+
handleRequestStream?(req: SerializedHttpRequest, callbacks: ProviderStreamCallbacks): Promise<SerializedHttpResponse>;
|
|
31
39
|
/** Optional startup hook — validate credentials, warm caches, etc. */
|
|
32
40
|
init?(): Promise<void>;
|
|
33
41
|
/** Return current and maximum concurrent request counts */
|
|
@@ -42,6 +50,10 @@ export interface Provider {
|
|
|
42
50
|
/** Handle a one-shot skill request. */
|
|
43
51
|
handleSkill?(skill: SkillRequest): Promise<SkillResponse>;
|
|
44
52
|
}
|
|
53
|
+
export interface ProviderStreamCallbacks {
|
|
54
|
+
onResponseStart: (response: SerializedHttpResponse) => void;
|
|
55
|
+
onResponseChunk: (chunk: SerializedHttpResponseChunk) => void;
|
|
56
|
+
}
|
|
45
57
|
export interface TaskRequest {
|
|
46
58
|
taskId: string;
|
|
47
59
|
capability: ProviderCapability;
|
|
@@ -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,MAAM,kBAAkB,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;AAEjE,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,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
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
2
|
import type { Identity } from "./p2p/identity.js";
|
|
3
3
|
import type { PeerInfo } from "./types/peer.js";
|
|
4
|
-
import type
|
|
5
|
-
import type { Provider, TaskRequest, TaskEvent, SkillRequest, SkillResponse } from "./interfaces/seller-provider.js";
|
|
4
|
+
import { type SerializedHttpRequest, type SerializedHttpResponse, type SerializedHttpResponseChunk } from "./types/http.js";
|
|
5
|
+
import type { Provider, ProviderStreamCallbacks, TaskRequest, TaskEvent, SkillRequest, SkillResponse } from "./interfaces/seller-provider.js";
|
|
6
6
|
import type { Router } from "./interfaces/buyer-router.js";
|
|
7
7
|
import { type PaymentConfig, type PaymentMethod } from "./payments/index.js";
|
|
8
8
|
import { BuyerPaymentManager, type BuyerPaymentConfig } from "./payments/buyer-payment-manager.js";
|
|
9
|
-
export type { Provider, TaskRequest, TaskEvent, SkillRequest, SkillResponse };
|
|
9
|
+
export type { Provider, ProviderStreamCallbacks, TaskRequest, TaskEvent, SkillRequest, SkillResponse };
|
|
10
10
|
export type { Router };
|
|
11
11
|
export type { BuyerPaymentConfig };
|
|
12
12
|
export interface NodePaymentsConfig {
|
|
@@ -61,6 +61,13 @@ export interface SellerSessionSnapshot {
|
|
|
61
61
|
runningTotalUSDC: string;
|
|
62
62
|
ackedRequestCount: number;
|
|
63
63
|
}
|
|
64
|
+
export interface RequestStreamResponseMetadata {
|
|
65
|
+
streaming: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface RequestStreamCallbacks {
|
|
68
|
+
onResponseStart?: (response: SerializedHttpResponse, metadata: RequestStreamResponseMetadata) => void;
|
|
69
|
+
onResponseChunk?: (chunk: SerializedHttpResponseChunk) => void;
|
|
70
|
+
}
|
|
64
71
|
export declare class AntseedNode extends EventEmitter {
|
|
65
72
|
private _config;
|
|
66
73
|
private _identity;
|
|
@@ -109,6 +116,8 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
109
116
|
stop(): Promise<void>;
|
|
110
117
|
discoverPeers(model?: string): Promise<PeerInfo[]>;
|
|
111
118
|
sendRequest(peer: PeerInfo, req: SerializedHttpRequest): Promise<SerializedHttpResponse>;
|
|
119
|
+
sendRequestStream(peer: PeerInfo, req: SerializedHttpRequest, callbacks: RequestStreamCallbacks): Promise<SerializedHttpResponse>;
|
|
120
|
+
private _sendRequestInternal;
|
|
112
121
|
sendTask(peer: PeerInfo, task: TaskRequest): AsyncIterable<TaskEvent>;
|
|
113
122
|
sendSkill(peer: PeerInfo, skill: SkillRequest): Promise<SkillResponse>;
|
|
114
123
|
private _createDHTConfig;
|
|
@@ -117,6 +126,7 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
117
126
|
private _startBuyer;
|
|
118
127
|
private _handleIncomingConnection;
|
|
119
128
|
private _executeProviderRequest;
|
|
129
|
+
private _stripStreamingHeader;
|
|
120
130
|
private _parseJsonBody;
|
|
121
131
|
private _extractRequestedModel;
|
|
122
132
|
private _resolveProviderPricing;
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
|
package/dist/node.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { loadOrCreateIdentity } from "./p2p/identity.js";
|
|
6
|
+
import { ANTSEED_STREAMING_RESPONSE_HEADER, } from "./types/http.js";
|
|
6
7
|
import { MeteringStorage } from "./metering/storage.js";
|
|
7
8
|
import { ReceiptGenerator } from "./metering/receipt-generator.js";
|
|
8
9
|
import { ConnectionState } from "./types/connection.js";
|
|
@@ -241,13 +242,20 @@ export class AntseedNode extends EventEmitter {
|
|
|
241
242
|
return peers;
|
|
242
243
|
}
|
|
243
244
|
async sendRequest(peer, req) {
|
|
245
|
+
return this._sendRequestInternal(peer, req);
|
|
246
|
+
}
|
|
247
|
+
async sendRequestStream(peer, req, callbacks) {
|
|
248
|
+
return this._sendRequestInternal(peer, req, callbacks);
|
|
249
|
+
}
|
|
250
|
+
async _sendRequestInternal(peer, req, callbacks) {
|
|
244
251
|
if (!req.requestId || typeof req.requestId !== "string") {
|
|
245
252
|
throw new Error("requestId must be a non-empty string");
|
|
246
253
|
}
|
|
247
254
|
if (!this._connectionManager || !this._identity) {
|
|
248
255
|
throw new Error("Node not started");
|
|
249
256
|
}
|
|
250
|
-
|
|
257
|
+
const opName = callbacks ? "sendRequestStream" : "sendRequest";
|
|
258
|
+
debugLog(`[Node] ${opName} ${req.method} ${req.path} → peer ${peer.peerId.slice(0, 12)}... (reqId=${req.requestId.slice(0, 8)})`);
|
|
251
259
|
const conn = await this._getOrCreateConnection(peer);
|
|
252
260
|
debugLog(`[Node] Connection to ${peer.peerId.slice(0, 12)}... state=${conn.state}`);
|
|
253
261
|
const mux = this._getOrCreateMux(peer.peerId, conn);
|
|
@@ -258,17 +266,77 @@ export class AntseedNode extends EventEmitter {
|
|
|
258
266
|
const startTime = Date.now();
|
|
259
267
|
return new Promise((resolve, reject) => {
|
|
260
268
|
const timeoutMs = this._config.requestTimeoutMs ?? 30_000;
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
269
|
+
// Idle timeout for streaming: resets on each chunk so long-running
|
|
270
|
+
// streams (thinking models, large outputs) stay alive as long as
|
|
271
|
+
// data keeps flowing.
|
|
272
|
+
const streamIdleTimeoutMs = Math.max(timeoutMs, 60_000);
|
|
273
|
+
let settled = false;
|
|
274
|
+
let streamStarted = false;
|
|
275
|
+
let streamStartResponse = null;
|
|
276
|
+
const streamChunks = [];
|
|
277
|
+
let activeTimeout = null;
|
|
278
|
+
const resetTimeout = (ms) => {
|
|
279
|
+
if (activeTimeout)
|
|
280
|
+
clearTimeout(activeTimeout);
|
|
281
|
+
activeTimeout = setTimeout(() => {
|
|
282
|
+
if (settled)
|
|
283
|
+
return;
|
|
284
|
+
settled = true;
|
|
285
|
+
debugWarn(`[Node] Request ${req.requestId.slice(0, 8)} timed out after ${Date.now() - startTime}ms`);
|
|
286
|
+
mux.cancelProxyRequest(req.requestId);
|
|
287
|
+
reject(new Error(`Request ${req.requestId} timed out`));
|
|
288
|
+
}, ms);
|
|
289
|
+
};
|
|
290
|
+
// Initial timeout: wait for the first response frame.
|
|
291
|
+
resetTimeout(timeoutMs);
|
|
292
|
+
const finish = (response) => {
|
|
293
|
+
if (settled)
|
|
294
|
+
return;
|
|
295
|
+
settled = true;
|
|
296
|
+
if (activeTimeout)
|
|
297
|
+
clearTimeout(activeTimeout);
|
|
298
|
+
const cleaned = this._stripStreamingHeader(response);
|
|
299
|
+
debugLog(`[Node] Response for ${req.requestId.slice(0, 8)}: status=${cleaned.statusCode} (${Date.now() - startTime}ms, ${cleaned.body.length}b)`);
|
|
300
|
+
resolve(cleaned);
|
|
301
|
+
};
|
|
302
|
+
const fail = (error) => {
|
|
303
|
+
if (settled)
|
|
304
|
+
return;
|
|
305
|
+
settled = true;
|
|
306
|
+
if (activeTimeout)
|
|
307
|
+
clearTimeout(activeTimeout);
|
|
308
|
+
reject(error);
|
|
309
|
+
};
|
|
310
|
+
mux.sendProxyRequest(req, (response, metadata) => {
|
|
311
|
+
if (metadata.streamingStart) {
|
|
312
|
+
streamStarted = true;
|
|
313
|
+
streamStartResponse = this._stripStreamingHeader(response);
|
|
314
|
+
// Switch to streaming idle timeout: resets on each chunk.
|
|
315
|
+
resetTimeout(streamIdleTimeoutMs);
|
|
316
|
+
callbacks?.onResponseStart?.(streamStartResponse, { streaming: true });
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
callbacks?.onResponseStart?.(this._stripStreamingHeader(response), { streaming: false });
|
|
320
|
+
finish(response);
|
|
321
|
+
}, (chunk) => {
|
|
322
|
+
if (!streamStarted)
|
|
323
|
+
return;
|
|
324
|
+
// Reset idle timeout on each chunk so streaming stays alive.
|
|
325
|
+
resetTimeout(streamIdleTimeoutMs);
|
|
326
|
+
callbacks?.onResponseChunk?.(chunk);
|
|
327
|
+
if (chunk.data.length > 0) {
|
|
328
|
+
streamChunks.push(chunk.data);
|
|
329
|
+
}
|
|
330
|
+
if (!chunk.done)
|
|
331
|
+
return;
|
|
332
|
+
if (!streamStartResponse) {
|
|
333
|
+
fail(new Error(`Stream ${req.requestId} ended before response start`));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
finish({
|
|
337
|
+
...streamStartResponse,
|
|
338
|
+
body: concatChunks(streamChunks),
|
|
339
|
+
});
|
|
272
340
|
});
|
|
273
341
|
});
|
|
274
342
|
}
|
|
@@ -524,23 +592,52 @@ export class AntseedNode extends EventEmitter {
|
|
|
524
592
|
const startTime = Date.now();
|
|
525
593
|
let statusCode = 500;
|
|
526
594
|
let responseBody = new Uint8Array(0);
|
|
595
|
+
let streamedResponseStarted = false;
|
|
527
596
|
try {
|
|
528
|
-
const response = await this._executeProviderRequest(provider, request
|
|
597
|
+
const response = await this._executeProviderRequest(provider, request, {
|
|
598
|
+
onResponseStart: (streamResponseStart) => {
|
|
599
|
+
streamedResponseStarted = true;
|
|
600
|
+
statusCode = streamResponseStart.statusCode;
|
|
601
|
+
mux.sendProxyResponse(streamResponseStart);
|
|
602
|
+
},
|
|
603
|
+
onResponseChunk: (chunk) => {
|
|
604
|
+
if (!streamedResponseStarted)
|
|
605
|
+
return;
|
|
606
|
+
mux.sendProxyChunk(chunk);
|
|
607
|
+
},
|
|
608
|
+
});
|
|
529
609
|
statusCode = response.statusCode;
|
|
530
610
|
responseBody = response.body;
|
|
531
611
|
debugLog(`[Node] Provider responded: status=${statusCode} (${Date.now() - startTime}ms, ${responseBody.length}b)`);
|
|
532
|
-
|
|
612
|
+
if (!streamedResponseStarted) {
|
|
613
|
+
mux.sendProxyResponse(response);
|
|
614
|
+
}
|
|
533
615
|
}
|
|
534
616
|
catch (err) {
|
|
535
617
|
const message = err instanceof Error ? err.message : "Internal error";
|
|
536
618
|
debugWarn(`[Node] Provider error after ${Date.now() - startTime}ms: ${message}`);
|
|
537
619
|
responseBody = new TextEncoder().encode(message);
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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,
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
statusCode = 500;
|
|
634
|
+
mux.sendProxyResponse({
|
|
635
|
+
requestId: request.requestId,
|
|
636
|
+
statusCode: 500,
|
|
637
|
+
headers: { "content-type": "text/plain" },
|
|
638
|
+
body: responseBody,
|
|
639
|
+
});
|
|
640
|
+
}
|
|
544
641
|
}
|
|
545
642
|
// Record metering
|
|
546
643
|
const latencyMs = Date.now() - startTime;
|
|
@@ -556,7 +653,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
556
653
|
this._wireConnection(conn, buyerPeerId);
|
|
557
654
|
this.emit("connection", conn);
|
|
558
655
|
}
|
|
559
|
-
async _executeProviderRequest(provider, request) {
|
|
656
|
+
async _executeProviderRequest(provider, request, streamCallbacks) {
|
|
560
657
|
const capability = request.headers["x-antseed-capability"]?.toLowerCase();
|
|
561
658
|
const isTask = capability === "task" || request.path === "/v1/task";
|
|
562
659
|
const isSkill = capability === "skill" || request.path === "/v1/skill";
|
|
@@ -641,8 +738,22 @@ export class AntseedNode extends EventEmitter {
|
|
|
641
738
|
body: new TextEncoder().encode(JSON.stringify(payload)),
|
|
642
739
|
};
|
|
643
740
|
}
|
|
741
|
+
if (streamCallbacks && provider.handleRequestStream) {
|
|
742
|
+
return provider.handleRequestStream(request, streamCallbacks);
|
|
743
|
+
}
|
|
644
744
|
return provider.handleRequest(request);
|
|
645
745
|
}
|
|
746
|
+
_stripStreamingHeader(response) {
|
|
747
|
+
if (response.headers[ANTSEED_STREAMING_RESPONSE_HEADER] !== "1") {
|
|
748
|
+
return response;
|
|
749
|
+
}
|
|
750
|
+
const headers = { ...response.headers };
|
|
751
|
+
delete headers[ANTSEED_STREAMING_RESPONSE_HEADER];
|
|
752
|
+
return {
|
|
753
|
+
...response,
|
|
754
|
+
headers,
|
|
755
|
+
};
|
|
756
|
+
}
|
|
646
757
|
_parseJsonBody(body) {
|
|
647
758
|
try {
|
|
648
759
|
return JSON.parse(new TextDecoder().decode(body));
|
|
@@ -1325,4 +1436,18 @@ export class AntseedNode extends EventEmitter {
|
|
|
1325
1436
|
};
|
|
1326
1437
|
}
|
|
1327
1438
|
}
|
|
1439
|
+
function concatChunks(chunks) {
|
|
1440
|
+
if (chunks.length === 0)
|
|
1441
|
+
return new Uint8Array(0);
|
|
1442
|
+
if (chunks.length === 1)
|
|
1443
|
+
return chunks[0];
|
|
1444
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
1445
|
+
const output = new Uint8Array(totalLength);
|
|
1446
|
+
let offset = 0;
|
|
1447
|
+
for (const chunk of chunks) {
|
|
1448
|
+
output.set(chunk, offset);
|
|
1449
|
+
offset += chunk.length;
|
|
1450
|
+
}
|
|
1451
|
+
return output;
|
|
1452
|
+
}
|
|
1328
1453
|
//# sourceMappingURL=node.js.map
|