@antseed/cli 0.1.174 → 0.1.175

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.
@@ -3384,4 +3384,83 @@ test('getSweepReceipt returns cached relayer receipts case-insensitively', () =>
3384
3384
  assert.equal(proxy.getSweepReceipt(nonce.toLowerCase()), receipt);
3385
3385
  assert.equal(proxy.getSweepReceipt('0x' + '00'.repeat(32)), null);
3386
3386
  });
3387
+ test('switching a chat route while a request is in flight is not reverted when that request completes', async () => {
3388
+ const dir = await mkdtemp(join(tmpdir(), 'antseed-buyer-route-race-'));
3389
+ try {
3390
+ const oldPeer = makePeer('a', ['openai']);
3391
+ oldPeer.providerServiceApiProtocols = { openai: { services: { 'gpt-5': ['openai-chat-completions'] } } };
3392
+ const newPeer = makePeer('b', ['openai']);
3393
+ newPeer.providerServiceApiProtocols = { openai: { services: { 'claude-sonnet': ['openai-chat-completions'] } } };
3394
+ const proxy = new BuyerProxy({
3395
+ port: 0,
3396
+ dataDir: dir,
3397
+ node: { router: permissiveRouter() },
3398
+ });
3399
+ proxy._getPeers = async () => [oldPeer, newPeer];
3400
+ proxy._cacheLastUpdatedAtMs = Date.now();
3401
+ proxy._defaultRoutedModel = 'gpt-5';
3402
+ const attempts = [];
3403
+ let holdNext = false;
3404
+ let releaseHeld = null;
3405
+ let markDispatched = null;
3406
+ const dispatched = new Promise((resolve) => { markDispatched = resolve; });
3407
+ proxy._node.sendRequest = async (peer, request) => {
3408
+ attempts.push(peer.peerId);
3409
+ if (holdNext) {
3410
+ holdNext = false;
3411
+ markDispatched?.();
3412
+ await new Promise((resolve) => { releaseHeld = resolve; });
3413
+ }
3414
+ return {
3415
+ requestId: request.requestId,
3416
+ statusCode: 200,
3417
+ headers: { 'content-type': 'application/json' },
3418
+ body: Buffer.from(JSON.stringify({ peerId: peer.peerId })),
3419
+ };
3420
+ };
3421
+ const headers = { 'x-vpr-session-id': 'route-race' };
3422
+ const chatId = 'vpr:route-race';
3423
+ const store = proxy._conversations;
3424
+ // Turn 1 settles the chat on the old route as soft (auto) affinity.
3425
+ const first = await invokeProxy(proxy, makeProxyRequest({
3426
+ headers,
3427
+ body: { model: 'antseed', messages: [{ role: 'user', content: 'first turn' }] },
3428
+ }));
3429
+ assert.equal(first.statusCode, 200);
3430
+ assert.equal(store.get(chatId)?.pinnedModel, `${oldPeer.peerId}@gpt-5`);
3431
+ assert.equal(store.get(chatId)?.peerSource, 'auto');
3432
+ // Turn 2 is held open upstream on the old route.
3433
+ holdNext = true;
3434
+ const inFlight = invokeProxy(proxy, makeProxyRequest({
3435
+ headers,
3436
+ body: { model: 'antseed', messages: [{ role: 'user', content: 'long turn' }] },
3437
+ }));
3438
+ await dispatched;
3439
+ // The user switches the chat's model mid-flight.
3440
+ const update = await invokeProxy(proxy, makeProxyRequest({
3441
+ path: '/_antseed/conversations/update',
3442
+ body: { id: chatId, pinnedModel: 'claude-sonnet', peerSource: 'auto' },
3443
+ }));
3444
+ assert.equal(update.statusCode, 200);
3445
+ releaseHeld?.();
3446
+ const finished = await inFlight;
3447
+ assert.equal(finished.statusCode, 200);
3448
+ assert.equal(store.get(chatId)?.pinnedModel, 'claude-sonnet');
3449
+ assert.equal(store.get(chatId)?.peerSource, 'auto');
3450
+ assert.equal(store.get(chatId)?.lastModel, `${oldPeer.peerId}@gpt-5`);
3451
+ // The next turn routes to the newly selected model.
3452
+ attempts.length = 0;
3453
+ const next = await invokeProxy(proxy, makeProxyRequest({
3454
+ headers,
3455
+ body: { model: 'antseed', messages: [{ role: 'user', content: 'after switch' }] },
3456
+ }));
3457
+ assert.equal(next.statusCode, 200);
3458
+ assert.deepEqual(attempts, [newPeer.peerId]);
3459
+ assert.equal(store.get(chatId)?.pinnedModel, `${newPeer.peerId}@claude-sonnet`);
3460
+ await store.flush();
3461
+ }
3462
+ finally {
3463
+ await rm(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
3464
+ }
3465
+ });
3387
3466
  //# sourceMappingURL=buyer-proxy.test.js.map