@antseed/cli 0.1.178 → 0.1.179
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 +3 -0
- package/dist/cli/commands/apps/index.d.ts +42 -0
- package/dist/cli/commands/apps/index.d.ts.map +1 -0
- package/dist/cli/commands/apps/index.js +224 -0
- package/dist/cli/commands/apps/index.js.map +1 -0
- package/dist/cli/commands/apps/index.test.d.ts +2 -0
- package/dist/cli/commands/apps/index.test.d.ts.map +1 -0
- package/dist/cli/commands/apps/index.test.js +206 -0
- package/dist/cli/commands/apps/index.test.js.map +1 -0
- package/dist/cli/commands/buyer/deposit.d.ts.map +1 -1
- package/dist/cli/commands/buyer/deposit.js +9 -1
- package/dist/cli/commands/buyer/deposit.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/gateway/gateway.test.js +31 -0
- package/dist/gateway/gateway.test.js.map +1 -1
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/gateway/server.js +4 -1
- package/dist/gateway/server.js.map +1 -1
- package/dist/proxy/buyer-proxy.d.ts.map +1 -1
- package/dist/proxy/buyer-proxy.js +9 -1
- package/dist/proxy/buyer-proxy.js.map +1 -1
- package/dist/proxy/buyer-proxy.test.js +77 -0
- package/dist/proxy/buyer-proxy.test.js.map +1 -1
- package/dist/proxy/credential-headers.d.ts +17 -0
- package/dist/proxy/credential-headers.d.ts.map +1 -0
- package/dist/proxy/credential-headers.js +29 -0
- package/dist/proxy/credential-headers.js.map +1 -0
- package/dist/proxy/deposit-watcher.d.ts +19 -0
- package/dist/proxy/deposit-watcher.d.ts.map +1 -1
- package/dist/proxy/deposit-watcher.js +44 -8
- package/dist/proxy/deposit-watcher.js.map +1 -1
- package/dist/proxy/deposit-watcher.test.js +27 -4
- package/dist/proxy/deposit-watcher.test.js.map +1 -1
- package/dist/system-proxy/proxy-server.js +2 -2
- package/dist/system-proxy/proxy-server.js.map +1 -1
- package/dist/system-proxy/proxy-server.test.js +40 -0
- package/dist/system-proxy/proxy-server.test.js.map +1 -1
- package/package.json +7 -6
|
@@ -803,6 +803,29 @@ test('conversation routing keeps the actual peer as a soft preference and fails
|
|
|
803
803
|
assert.equal(route.statusCode, 200);
|
|
804
804
|
assert.equal(JSON.parse(route.body).conversation.lastModel, `${rankedFirst.peerId}@Kimi K3`);
|
|
805
805
|
});
|
|
806
|
+
test('BuyerProxy does not forward the Expect header to the seller', async () => {
|
|
807
|
+
const peer = makePeer('c', ['openai']);
|
|
808
|
+
peer.providerServiceApiProtocols = {
|
|
809
|
+
openai: { services: { 'kimi-k3': ['openai-chat-completions'] } },
|
|
810
|
+
};
|
|
811
|
+
const proxy = makeBuyerProxyWithPeers([peer], [peer], permissiveRouter());
|
|
812
|
+
let forwardedHeaders;
|
|
813
|
+
proxy._node.sendRequest = async (_peer, request) => {
|
|
814
|
+
forwardedHeaders = request.headers;
|
|
815
|
+
return {
|
|
816
|
+
requestId: request.requestId,
|
|
817
|
+
statusCode: 200,
|
|
818
|
+
headers: { 'content-type': 'application/json' },
|
|
819
|
+
body: Buffer.from('{}'),
|
|
820
|
+
};
|
|
821
|
+
};
|
|
822
|
+
await invokeProxy(proxy, makeProxyRequest({
|
|
823
|
+
headers: { expect: '100-continue' },
|
|
824
|
+
body: { model: 'kimi-k3', messages: [{ role: 'user', content: 'hello' }] },
|
|
825
|
+
}));
|
|
826
|
+
assert.ok(forwardedHeaders);
|
|
827
|
+
assert.equal(forwardedHeaders['expect'], undefined);
|
|
828
|
+
});
|
|
806
829
|
test('model-only request applies a cached-input pricing reputation penalty', async () => {
|
|
807
830
|
const priced = makePeer('a', ['openai']);
|
|
808
831
|
priced.reputationScore = 75;
|
|
@@ -3403,6 +3426,60 @@ test('getSweepReceipt returns cached relayer receipts case-insensitively', () =>
|
|
|
3403
3426
|
assert.equal(proxy.getSweepReceipt(nonce.toLowerCase()), receipt);
|
|
3404
3427
|
assert.equal(proxy.getSweepReceipt('0x' + '00'.repeat(32)), null);
|
|
3405
3428
|
});
|
|
3429
|
+
// Issue #1104: a client's own provider credentials must never reach a seller.
|
|
3430
|
+
// Sellers authenticate their upstream with their own keys; the buyer pays
|
|
3431
|
+
// on-chain. A malicious seller would otherwise read the raw key off the wire.
|
|
3432
|
+
const CLIENT_CREDENTIAL_HEADERS = {
|
|
3433
|
+
authorization: 'Bearer sk-real',
|
|
3434
|
+
'proxy-authorization': 'Basic cHJveHk6c2VjcmV0',
|
|
3435
|
+
'x-api-key': 'sk-ant-real',
|
|
3436
|
+
'x-goog-api-key': 'AIza-real',
|
|
3437
|
+
'api-key': 'azure-real',
|
|
3438
|
+
cookie: 'session=real',
|
|
3439
|
+
};
|
|
3440
|
+
test('buyer proxy does not forward client credential headers to the seller (buffered)', async () => {
|
|
3441
|
+
const peer = makePeer('e', ['openai']);
|
|
3442
|
+
const proxy = makeBuyerProxyWithPeers([peer], [peer], permissiveRouter());
|
|
3443
|
+
let seen = null;
|
|
3444
|
+
proxy._node.sendRequest = async (_peer, request) => {
|
|
3445
|
+
seen = request.headers;
|
|
3446
|
+
return { requestId: request.requestId, statusCode: 200, headers: { 'content-type': 'application/json' }, body: Buffer.from('{}') };
|
|
3447
|
+
};
|
|
3448
|
+
const res = await invokeProxy(proxy, makeProxyRequest({
|
|
3449
|
+
headers: {
|
|
3450
|
+
...CLIENT_CREDENTIAL_HEADERS,
|
|
3451
|
+
'x-antseed-pin-peer': peer.peerId,
|
|
3452
|
+
'anthropic-version': '2023-06-01',
|
|
3453
|
+
'x-antseed-spending-auth': 'signed-auth-payload',
|
|
3454
|
+
},
|
|
3455
|
+
}));
|
|
3456
|
+
assert.equal(res.statusCode, 200);
|
|
3457
|
+
assert.ok(seen, 'seller received a request');
|
|
3458
|
+
const leaked = Object.keys(CLIENT_CREDENTIAL_HEADERS).filter((name) => seen[name] !== undefined);
|
|
3459
|
+
assert.deepEqual(leaked, [], `credential headers reached the seller: ${leaked.join(', ')}`);
|
|
3460
|
+
// Non-credential client headers still pass through.
|
|
3461
|
+
assert.equal(seen['anthropic-version'], '2023-06-01');
|
|
3462
|
+
assert.equal(seen['content-type'], 'application/json');
|
|
3463
|
+
// AntSeed's own payment-auth header is not a client credential.
|
|
3464
|
+
assert.equal(seen['x-antseed-spending-auth'], 'signed-auth-payload');
|
|
3465
|
+
});
|
|
3466
|
+
test('buyer proxy does not forward client credential headers to the seller (streaming)', async () => {
|
|
3467
|
+
const peer = makePeer('f', ['openai']);
|
|
3468
|
+
const proxy = makeBuyerProxyWithPeers([peer], [peer], permissiveRouter());
|
|
3469
|
+
let seen = null;
|
|
3470
|
+
proxy._node.sendRequestStream = async (_peer, request) => {
|
|
3471
|
+
seen = request.headers;
|
|
3472
|
+
return { requestId: request.requestId, statusCode: 200, headers: { 'content-type': 'application/json' }, body: Buffer.from('{}') };
|
|
3473
|
+
};
|
|
3474
|
+
proxy._node.sendRequest = proxy._node.sendRequestStream;
|
|
3475
|
+
await invokeProxy(proxy, makeProxyRequest({
|
|
3476
|
+
headers: { ...CLIENT_CREDENTIAL_HEADERS, accept: 'text/event-stream', 'x-antseed-pin-peer': peer.peerId },
|
|
3477
|
+
body: { model: 'gpt-4o', stream: true, messages: [] },
|
|
3478
|
+
}));
|
|
3479
|
+
assert.ok(seen, 'seller received a request');
|
|
3480
|
+
const leaked = Object.keys(CLIENT_CREDENTIAL_HEADERS).filter((name) => seen[name] !== undefined);
|
|
3481
|
+
assert.deepEqual(leaked, [], `credential headers reached the seller: ${leaked.join(', ')}`);
|
|
3482
|
+
});
|
|
3406
3483
|
test('switching a chat route while a request is in flight is not reverted when that request completes', async () => {
|
|
3407
3484
|
const dir = await mkdtemp(join(tmpdir(), 'antseed-buyer-route-race-'));
|
|
3408
3485
|
try {
|