Skip to content

Commit 5edcdb2

Browse files
author
Ope Olatunji
committed
fix: sync stale placed orders to filled, improve market lookup
poly_get_open_orders: - Now syncs DB: orders marked 'placed' in DB but no longer on CLOB exchange are automatically updated to 'filled' (they were executed but status never updated) - This fixes Trade History showing empty — filled orders now appear there - Only truly live CLOB orders shown as open - Reports sync count so agent knows orders were reconciled poly_get_market: - Added token_id lookup via clob_token_ids param - Added CLOB API fallback to resolve condition_id from token - Error message now shows the input that failed for debugging
1 parent 7dc89d8 commit 5edcdb2

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@agenticmail/enterprise",
3-
"version": "0.5.533",
3+
"version": "0.5.534",
44
"description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
55
"type": "module",
66
"bin": {

src/agent-tools/tools/polymarket.ts

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -726,14 +726,31 @@ export function createPolymarketTools(options: ToolCreationOptions): AnyAgentToo
726726
m = Array.isArray(arr) && arr[0];
727727
} catch {}
728728
}
729+
// Try token_id lookup — agent often passes the CLOB token ID (long numeric string)
730+
if (!m) {
731+
try {
732+
const arr = await apiFetch(`${GAMMA_API}/markets?clob_token_ids=${encodeURIComponent(p.market_id)}&limit=1`).catch(() => []);
733+
m = Array.isArray(arr) && arr[0];
734+
} catch {}
735+
}
736+
// Try as CLOB token via the data API
737+
if (!m) {
738+
try {
739+
const tokenData = await apiFetch(`https://clob.polymarket.com/markets/${p.market_id}`).catch(() => null);
740+
if (tokenData && tokenData.condition_id) {
741+
const arr = await apiFetch(`${GAMMA_API}/markets?condition_id=${tokenData.condition_id}&limit=1`).catch(() => []);
742+
m = Array.isArray(arr) && arr[0];
743+
}
744+
} catch {}
745+
}
729746
// Final fallback: slug lookup (in case it looks numeric but is actually a slug)
730747
if (!m && (p.market_id.startsWith('0x') || /^\d+$/.test(p.market_id))) {
731748
try {
732749
const arr = await apiFetch(`${GAMMA_API}/markets?slug=${encodeURIComponent(p.market_id)}&limit=1`);
733750
m = Array.isArray(arr) && arr[0];
734751
} catch {}
735752
}
736-
if (!m) return errorResult('Market not found');
753+
if (!m) return errorResult('Market not found. Tried slug, ID, condition_id, and token_id lookups. Input: ' + p.market_id);
737754

738755
const result: any = {
739756
...slimMarket(m),
@@ -1825,28 +1842,49 @@ export function createPolymarketTools(options: ToolCreationOptions): AnyAgentToo
18251842
placedOrders = (Array.isArray(rows) ? rows : (rows as any)?.rows || []) as any[];
18261843
} catch {}
18271844

1828-
// 3. Also try to get live orders from CLOB API
1845+
// 3. Get live orders from CLOB API (primary source of truth)
18291846
let clobLiveOrders: any[] = [];
1847+
let clobError = '';
18301848
try {
18311849
const client = await getClobClient(agentId, db);
18321850
if (client) {
18331851
const openOrders = await client.client.getOpenOrders();
18341852
if (Array.isArray(openOrders)) clobLiveOrders = openOrders.map((o: any) => ({
1835-
clob_order_id: o.id, token_id: o.asset_id, side: o.side, price: o.price,
1836-
original_size: o.original_size, size_matched: o.size_matched, size_remaining: (parseFloat(o.original_size) - parseFloat(o.size_matched)).toFixed(2),
1837-
status: 'live_on_exchange', created_at: o.created_at,
1853+
clob_order_id: o.id, token_id: o.asset_id, side: o.side?.toUpperCase(), price: o.price,
1854+
original_size: o.original_size, size_matched: o.size_matched,
1855+
size_remaining: (parseFloat(o.original_size || '0') - parseFloat(o.size_matched || '0')).toFixed(2),
1856+
price_cents: (parseFloat(o.price || '0') * 100).toFixed(1) + '¢',
1857+
cost: '$' + (parseFloat(o.price || '0') * parseFloat(o.original_size || '0')).toFixed(2),
1858+
status: parseFloat(o.size_matched || '0') > 0 ? 'partially_filled' : 'open',
1859+
created_at: o.created_at,
18381860
}));
18391861
}
1840-
} catch {}
1862+
} catch (e: any) { clobError = e.message; }
1863+
1864+
// CLOB is source of truth — sync DB statuses
1865+
const clobIds = new Set(clobLiveOrders.map(o => o.clob_order_id));
1866+
const dbOnlyPlaced = placedOrders.filter((o: any) => !clobIds.has(o.clob_order_id));
1867+
let syncedCount = 0;
1868+
1869+
// Orders in DB as 'placed' but NOT on CLOB anymore = filled or cancelled
1870+
// Update their status so they show correctly in Trade History
1871+
for (const stale of dbOnlyPlaced) {
1872+
try {
1873+
await db?.execute(`UPDATE poly_trade_log SET status = 'filled' WHERE id = $1 AND status = 'placed'`, [stale.id]);
1874+
syncedCount++;
1875+
} catch {}
1876+
}
18411877

1842-
const totalPendingCapital = placedOrders.reduce((s: number, o: any) => s + (parseFloat(o.price) || 0) * (parseFloat(o.size) || 0), 0);
1878+
const totalPendingCapital = clobLiveOrders.reduce((s: number, o: any) => s + (parseFloat(o.price || '0')) * (parseFloat(o.original_size || '0')), 0);
18431879

18441880
return jsonResult({
1845-
summary: `${approvalPending.length} awaiting approval, ${placedOrders.length} placed (unfilled), ${clobLiveOrders.length} live on exchange`,
1881+
summary: `${clobLiveOrders.length} open on exchange, ${approvalPending.length} awaiting approval` + (syncedCount > 0 ? `, ${syncedCount} stale orders synced to filled` : ''),
1882+
total_open_orders: clobLiveOrders.length,
18461883
total_pending_capital: '$' + totalPendingCapital.toFixed(2),
18471884
awaiting_approval: approvalPending,
1848-
placed_unfilled: placedOrders.map((o: any) => ({ ...o, price_cents: ((parseFloat(o.price) || 0) * 100).toFixed(1) + '¢', cost: '$' + ((parseFloat(o.price) || 0) * (parseFloat(o.size) || 0)).toFixed(2) })),
1849-
live_on_exchange: clobLiveOrders,
1885+
open_orders: clobLiveOrders,
1886+
...(syncedCount > 0 ? { synced_to_filled: syncedCount, sync_note: `${syncedCount} orders were in DB as "placed" but no longer on exchange — marked as filled. They will now appear in Trade History.` } : {}),
1887+
...(clobError ? { clob_error: clobError } : {}),
18501888
});
18511889
},
18521890
},

0 commit comments

Comments
 (0)