@quantish/agent 0.1.11 → 0.1.13
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/dist/index.js +84 -491
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ var schema = {
|
|
|
27
27
|
},
|
|
28
28
|
model: {
|
|
29
29
|
type: "string",
|
|
30
|
-
default: "claude-sonnet-4-
|
|
30
|
+
default: "claude-sonnet-4-5-20250929"
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
var ConfigManager = class {
|
|
@@ -111,7 +111,7 @@ var ConfigManager = class {
|
|
|
111
111
|
* Get the model to use
|
|
112
112
|
*/
|
|
113
113
|
getModel() {
|
|
114
|
-
return this.conf.get("model") ?? "claude-sonnet-4-
|
|
114
|
+
return this.conf.get("model") ?? "claude-sonnet-4-5-20250929";
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
117
|
* Set the model to use
|
|
@@ -2287,7 +2287,7 @@ function parseCompactedSummary(response) {
|
|
|
2287
2287
|
}
|
|
2288
2288
|
return response.trim() || null;
|
|
2289
2289
|
}
|
|
2290
|
-
async function createCompactedSummary(anthropic, history, model = "claude-sonnet-4-
|
|
2290
|
+
async function createCompactedSummary(anthropic, history, model = "claude-sonnet-4-5-20250929", customPrompt) {
|
|
2291
2291
|
const prompt2 = customPrompt || COMPACTION_PROMPT;
|
|
2292
2292
|
const compactionMessages = [
|
|
2293
2293
|
...history,
|
|
@@ -2331,7 +2331,7 @@ async function compactConversation(anthropic, history, model, systemPrompt, tool
|
|
|
2331
2331
|
const contentLength = JSON.stringify(history).length;
|
|
2332
2332
|
originalTokens = Math.ceil(contentLength / 4);
|
|
2333
2333
|
}
|
|
2334
|
-
const summaryModel = "claude-sonnet-4-
|
|
2334
|
+
const summaryModel = "claude-sonnet-4-5-20250929";
|
|
2335
2335
|
const summary = await createCompactedSummary(anthropic, history, summaryModel);
|
|
2336
2336
|
const newHistory = historyFromSummary(summary);
|
|
2337
2337
|
let newTokens = 0;
|
|
@@ -2357,10 +2357,10 @@ async function compactConversation(anthropic, history, model, systemPrompt, tool
|
|
|
2357
2357
|
|
|
2358
2358
|
// src/agent/pricing.ts
|
|
2359
2359
|
var MODELS = {
|
|
2360
|
-
"claude-opus-4-
|
|
2361
|
-
id: "claude-opus-4-
|
|
2362
|
-
name: "opus-4",
|
|
2363
|
-
displayName: "Claude Opus 4",
|
|
2360
|
+
"claude-opus-4-5-20251101": {
|
|
2361
|
+
id: "claude-opus-4-5-20251101",
|
|
2362
|
+
name: "opus-4.5",
|
|
2363
|
+
displayName: "Claude Opus 4.5",
|
|
2364
2364
|
pricing: {
|
|
2365
2365
|
inputPerMTok: 15,
|
|
2366
2366
|
outputPerMTok: 75,
|
|
@@ -2372,10 +2372,10 @@ var MODELS = {
|
|
|
2372
2372
|
contextWindow: 2e5,
|
|
2373
2373
|
description: "Most capable model. Best for complex reasoning and creative tasks."
|
|
2374
2374
|
},
|
|
2375
|
-
"claude-sonnet-4-
|
|
2376
|
-
id: "claude-sonnet-4-
|
|
2377
|
-
name: "sonnet-4",
|
|
2378
|
-
displayName: "Claude Sonnet 4",
|
|
2375
|
+
"claude-sonnet-4-5-20250929": {
|
|
2376
|
+
id: "claude-sonnet-4-5-20250929",
|
|
2377
|
+
name: "sonnet-4.5",
|
|
2378
|
+
displayName: "Claude Sonnet 4.5",
|
|
2379
2379
|
pricing: {
|
|
2380
2380
|
inputPerMTok: 3,
|
|
2381
2381
|
outputPerMTok: 15,
|
|
@@ -2387,30 +2387,30 @@ var MODELS = {
|
|
|
2387
2387
|
contextWindow: 2e5,
|
|
2388
2388
|
description: "Balanced performance and cost. Great for most coding and trading tasks."
|
|
2389
2389
|
},
|
|
2390
|
-
"claude-
|
|
2391
|
-
id: "claude-
|
|
2392
|
-
name: "haiku-
|
|
2393
|
-
displayName: "Claude Haiku
|
|
2390
|
+
"claude-haiku-4-5-20251001": {
|
|
2391
|
+
id: "claude-haiku-4-5-20251001",
|
|
2392
|
+
name: "haiku-4.5",
|
|
2393
|
+
displayName: "Claude Haiku 4.5",
|
|
2394
2394
|
pricing: {
|
|
2395
|
-
inputPerMTok:
|
|
2396
|
-
outputPerMTok:
|
|
2397
|
-
cacheWritePerMTok: 1,
|
|
2395
|
+
inputPerMTok: 1,
|
|
2396
|
+
outputPerMTok: 5,
|
|
2397
|
+
cacheWritePerMTok: 1.25,
|
|
2398
2398
|
// 1.25x input
|
|
2399
|
-
cacheReadPerMTok: 0.
|
|
2399
|
+
cacheReadPerMTok: 0.1
|
|
2400
2400
|
// 0.1x input
|
|
2401
2401
|
},
|
|
2402
2402
|
contextWindow: 2e5,
|
|
2403
2403
|
description: "Fastest and most economical. Good for simple tasks and high volume."
|
|
2404
2404
|
}
|
|
2405
2405
|
};
|
|
2406
|
-
var DEFAULT_MODEL = "claude-sonnet-4-
|
|
2406
|
+
var DEFAULT_MODEL = "claude-sonnet-4-5-20250929";
|
|
2407
2407
|
var MODEL_ALIASES = {
|
|
2408
|
-
"opus": "claude-opus-4-
|
|
2409
|
-
"opus-4": "claude-opus-4-
|
|
2410
|
-
"sonnet": "claude-sonnet-4-
|
|
2411
|
-
"sonnet-4": "claude-sonnet-4-
|
|
2412
|
-
"haiku": "claude-
|
|
2413
|
-
"haiku-
|
|
2408
|
+
"opus": "claude-opus-4-5-20251101",
|
|
2409
|
+
"opus-4.5": "claude-opus-4-5-20251101",
|
|
2410
|
+
"sonnet": "claude-sonnet-4-5-20250929",
|
|
2411
|
+
"sonnet-4.5": "claude-sonnet-4-5-20250929",
|
|
2412
|
+
"haiku": "claude-haiku-4-5-20251001",
|
|
2413
|
+
"haiku-4.5": "claude-haiku-4-5-20251001"
|
|
2414
2414
|
};
|
|
2415
2415
|
function resolveModelId(nameOrAlias) {
|
|
2416
2416
|
const lower = nameOrAlias.toLowerCase();
|
|
@@ -2663,488 +2663,81 @@ function extractTokenInfo(token) {
|
|
|
2663
2663
|
}
|
|
2664
2664
|
var DEFAULT_SYSTEM_PROMPT = `You are Quantish, an AI coding and trading agent.
|
|
2665
2665
|
|
|
2666
|
-
|
|
2666
|
+
CRITICAL BEHAVIOR RULES:
|
|
2667
|
+
- Be concise. No emojis. No verbose explanations. Just code and brief descriptions.
|
|
2668
|
+
- When debugging, check logs FIRST before restarting servers.
|
|
2669
|
+
- If API returns found > 0, there ARE results. Read and use them.
|
|
2667
2670
|
|
|
2668
|
-
##
|
|
2669
|
-
You can interact with Polymarket prediction markets:
|
|
2670
|
-
- Check wallet balances and positions
|
|
2671
|
-
- Place, cancel, and manage orders
|
|
2672
|
-
- Transfer funds and claim winnings
|
|
2673
|
-
- Get market prices and orderbook data
|
|
2671
|
+
## Two APIs
|
|
2674
2672
|
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
-
|
|
2678
|
-
-
|
|
2679
|
-
- Run shell commands
|
|
2680
|
-
- Use git for version control
|
|
2673
|
+
TRADING API (requires QUANTISH_API_KEY):
|
|
2674
|
+
- URL: https://quantish-sdk-production.up.railway.app/mcp/execute
|
|
2675
|
+
- Format: JSON-RPC 2.0
|
|
2676
|
+
- Tools: get_balances, get_positions, place_order, cancel_order, get_orders, get_orderbook, get_price
|
|
2681
2677
|
|
|
2682
|
-
|
|
2683
|
-
-
|
|
2684
|
-
-
|
|
2685
|
-
-
|
|
2686
|
-
-
|
|
2687
|
-
- When writing code, follow existing patterns and conventions
|
|
2688
|
-
- For dangerous operations (rm, sudo), explain what you're doing
|
|
2678
|
+
DISCOVERY API (free, public):
|
|
2679
|
+
- URL: https://quantish.live/mcp/execute
|
|
2680
|
+
- Format: Simple { name, arguments }
|
|
2681
|
+
- Key: qm_ueQeqrmvZyHtR1zuVbLYkhx0fKyVAuV8
|
|
2682
|
+
- Tools: search_markets, get_market_details, get_trending_markets
|
|
2689
2683
|
|
|
2690
|
-
|
|
2684
|
+
## API Response Structure
|
|
2691
2685
|
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
When users ask you to create ANY application that uses prediction market data or trading (bots, APIs, web apps, scripts, etc.), you MUST use the Quantish MCP HTTP API. This is the ONLY way to access market data and trading functionality in standalone applications.
|
|
2695
|
-
|
|
2696
|
-
### \u26A0\uFE0F CRITICAL: DO NOT USE MCP SDK DIRECTLY
|
|
2697
|
-
NEVER import or use these packages in standalone apps:
|
|
2698
|
-
- \u274C @modelcontextprotocol/sdk
|
|
2699
|
-
- \u274C StdioClientTransport
|
|
2700
|
-
- \u274C Client from MCP SDK
|
|
2701
|
-
|
|
2702
|
-
These only work within the Quantish CLI itself. Standalone apps MUST use the HTTP API with fetch().
|
|
2703
|
-
|
|
2704
|
-
### MCP HTTP API Endpoint
|
|
2705
|
-
\`\`\`
|
|
2706
|
-
POST https://quantish-sdk-production.up.railway.app/mcp/execute
|
|
2707
|
-
\`\`\`
|
|
2708
|
-
|
|
2709
|
-
### Authentication
|
|
2710
|
-
\`\`\`
|
|
2711
|
-
Header: x-api-key: <QUANTISH_API_KEY>
|
|
2712
|
-
\`\`\`
|
|
2713
|
-
The API key is stored in the user's environment as QUANTISH_API_KEY. Always read from env vars, never hardcode.
|
|
2714
|
-
|
|
2715
|
-
### Request Format (JSON-RPC 2.0)
|
|
2716
|
-
\`\`\`javascript
|
|
2717
|
-
const response = await fetch('https://quantish-sdk-production.up.railway.app/mcp/execute', {
|
|
2718
|
-
method: 'POST',
|
|
2719
|
-
headers: {
|
|
2720
|
-
'Content-Type': 'application/json',
|
|
2721
|
-
'x-api-key': process.env.QUANTISH_API_KEY
|
|
2722
|
-
},
|
|
2723
|
-
body: JSON.stringify({
|
|
2724
|
-
jsonrpc: '2.0',
|
|
2725
|
-
method: 'tools/call',
|
|
2726
|
-
params: {
|
|
2727
|
-
name: 'tool_name',
|
|
2728
|
-
arguments: { /* tool args */ }
|
|
2729
|
-
},
|
|
2730
|
-
id: Date.now()
|
|
2731
|
-
})
|
|
2732
|
-
});
|
|
2733
|
-
\`\`\`
|
|
2734
|
-
|
|
2735
|
-
### Response Format
|
|
2736
|
-
\`\`\`javascript
|
|
2737
|
-
// Success response structure:
|
|
2686
|
+
search_markets returns:
|
|
2738
2687
|
{
|
|
2739
|
-
"
|
|
2740
|
-
"
|
|
2741
|
-
"
|
|
2742
|
-
|
|
2743
|
-
|
|
2688
|
+
"found": 10,
|
|
2689
|
+
"markets": [{
|
|
2690
|
+
"platform": "polymarket",
|
|
2691
|
+
"id": "12345",
|
|
2692
|
+
"title": "Bitcoin Up or Down - Dec 28, 5PM ET",
|
|
2693
|
+
"markets": [{
|
|
2694
|
+
"marketId": "67890",
|
|
2695
|
+
"question": "Bitcoin Up or Down?",
|
|
2696
|
+
"outcomes": [
|
|
2697
|
+
{ "name": "Up", "price": 0.52 },
|
|
2698
|
+
{ "name": "Down", "price": 0.48 }
|
|
2699
|
+
],
|
|
2700
|
+
"clobTokenIds": "["TOKEN_ID_YES", "TOKEN_ID_NO"]",
|
|
2701
|
+
"conditionId": "0xabc..."
|
|
2744
2702
|
}]
|
|
2745
|
-
}
|
|
2746
|
-
"id": 123
|
|
2747
|
-
}
|
|
2748
|
-
|
|
2749
|
-
// Parse the inner JSON:
|
|
2750
|
-
const data = await response.json();
|
|
2751
|
-
const result = JSON.parse(data.result.content[0].text);
|
|
2752
|
-
\`\`\`
|
|
2753
|
-
|
|
2754
|
-
### \u26A0\uFE0F CRITICAL: Tool-to-Server Mapping (MEMORIZE THIS)
|
|
2755
|
-
|
|
2756
|
-
| Tool Name | Server | Auth Required | Helper Function |
|
|
2757
|
-
|-----------|--------|---------------|-----------------|
|
|
2758
|
-
| \`get_balances\` | TRADING | Yes (QUANTISH_API_KEY) | callTradingTool() |
|
|
2759
|
-
| \`get_positions\` | TRADING | Yes | callTradingTool() |
|
|
2760
|
-
| \`place_order\` | TRADING | Yes | callTradingTool() |
|
|
2761
|
-
| \`cancel_order\` | TRADING | Yes | callTradingTool() |
|
|
2762
|
-
| \`get_orders\` | TRADING | Yes | callTradingTool() |
|
|
2763
|
-
| \`get_orderbook\` | TRADING | Yes | callTradingTool() |
|
|
2764
|
-
| \`get_price\` | TRADING | Yes | callTradingTool() |
|
|
2765
|
-
| \`get_deposit_addresses\` | TRADING | Yes | callTradingTool() |
|
|
2766
|
-
| \`transfer_usdc\` | TRADING | Yes | callTradingTool() |
|
|
2767
|
-
| \`search_markets\` | DISCOVERY | No (public key) | callDiscoveryTool() |
|
|
2768
|
-
| \`get_market_details\` | DISCOVERY | No | callDiscoveryTool() |
|
|
2769
|
-
| \`get_trending_markets\` | DISCOVERY | No | callDiscoveryTool() |
|
|
2770
|
-
| \`find_arbitrage\` | DISCOVERY | No | callDiscoveryTool() |
|
|
2771
|
-
|
|
2772
|
-
### Key Trading Tools (require QUANTISH_API_KEY)
|
|
2773
|
-
URL: https://quantish-sdk-production.up.railway.app/mcp/execute
|
|
2774
|
-
Format: JSON-RPC 2.0 ({ jsonrpc, method, params, id })
|
|
2775
|
-
|
|
2776
|
-
- \`get_balances\`: Returns { usdc, nativeUsdc, matic } for EOA and Safe wallets
|
|
2777
|
-
- \`get_positions\`: Returns array of current share holdings with market info
|
|
2778
|
-
- \`place_order\`: Place order. Args: { conditionId, tokenId, side: "BUY"|"SELL", price: 0.01-0.99, size: number }
|
|
2779
|
-
- \`cancel_order\`: Cancel order. Args: { orderId }
|
|
2780
|
-
- \`get_orders\`: List orders. Args: { status?: "LIVE"|"FILLED"|"CANCELLED" }
|
|
2781
|
-
- \`get_orderbook\`: Get bids/asks. Args: { tokenId }
|
|
2782
|
-
- \`get_price\`: Get midpoint price. Args: { tokenId }
|
|
2783
|
-
- \`get_deposit_addresses\`: Get addresses to fund wallet
|
|
2784
|
-
- \`transfer_usdc\`: Send USDC. Args: { toAddress, amount }
|
|
2785
|
-
|
|
2786
|
-
### Key Discovery Tools (free, no auth required)
|
|
2787
|
-
URL: https://quantish.live/mcp/execute
|
|
2788
|
-
Format: Simple ({ name, arguments }) - NOT JSON-RPC!
|
|
2789
|
-
Discovery uses a SIMPLER request format (not full JSON-RPC):
|
|
2790
|
-
\`\`\`javascript
|
|
2791
|
-
// Discovery API - uses simple { name, arguments } format
|
|
2792
|
-
const response = await fetch('https://quantish.live/mcp/execute', {
|
|
2793
|
-
method: 'POST',
|
|
2794
|
-
headers: {
|
|
2795
|
-
'Content-Type': 'application/json',
|
|
2796
|
-
'X-API-Key': 'qm_ueQeqrmvZyHtR1zuVbLYkhx0fKyVAuV8'
|
|
2797
|
-
},
|
|
2798
|
-
body: JSON.stringify({
|
|
2799
|
-
name: 'search_markets', // Tool name at top level
|
|
2800
|
-
arguments: { query: 'bitcoin', limit: 5 } // Arguments at top level
|
|
2801
|
-
})
|
|
2802
|
-
});
|
|
2803
|
-
|
|
2804
|
-
// Response is still JSON-RPC wrapped:
|
|
2805
|
-
const data = await response.json();
|
|
2806
|
-
const result = JSON.parse(data.result.content[0].text);
|
|
2807
|
-
\`\`\`
|
|
2808
|
-
|
|
2809
|
-
Available Discovery Tools:
|
|
2810
|
-
- \`search_markets\`: Find markets. Args: { query, limit?, platform?: "polymarket"|"kalshi"|"all" }
|
|
2811
|
-
- \`get_market_details\`: Get market info. Args: { platform, marketId }
|
|
2812
|
-
- \`get_trending_markets\`: Popular markets. Args: { limit?, platform? }
|
|
2813
|
-
- \`find_arbitrage\`: Find arb opportunities. Args: { minProfitPercent?, type? }
|
|
2814
|
-
|
|
2815
|
-
### Important: Token IDs and Condition IDs
|
|
2816
|
-
When placing orders, you need:
|
|
2817
|
-
- \`conditionId\`: The market's condition ID (from market details)
|
|
2818
|
-
- \`tokenId\`: The specific outcome's token ID (YES or NO token from market.tokens array)
|
|
2819
|
-
|
|
2820
|
-
Example flow:
|
|
2821
|
-
1. search_markets({ query: "bitcoin" }) \u2192 get market list
|
|
2822
|
-
2. get_market_details({ platform: "polymarket", marketId: "..." }) \u2192 get tokens array
|
|
2823
|
-
3. Extract tokenId for YES/NO outcome you want
|
|
2824
|
-
4. place_order({ conditionId, tokenId, side: "BUY", price: 0.55, size: 100 })
|
|
2825
|
-
|
|
2826
|
-
### \u26A0\uFE0F\u26A0\uFE0F\u26A0\uFE0F EXTREMELY CRITICAL: Market Search Results - READ THEM! \u26A0\uFE0F\u26A0\uFE0F\u26A0\uFE0F
|
|
2827
|
-
|
|
2828
|
-
**YOU MUST READ AND USE SEARCH RESULTS. NEVER SAY "I DON'T SEE ANY" WHEN RESULTS ARE RETURNED.**
|
|
2829
|
-
|
|
2830
|
-
When search_markets returns \`"found": 10\` or any number > 0, there ARE markets. READ THEM.
|
|
2831
|
-
|
|
2832
|
-
Example: If user asks for "15 minute BTC up/down market" and search returns:
|
|
2833
|
-
\`\`\`
|
|
2834
|
-
"found": 10,
|
|
2835
|
-
"markets": [
|
|
2836
|
-
{ "title": "Bitcoin Up or Down - December 28, 11:50PM-11:55PM ET", ... }
|
|
2837
|
-
]
|
|
2838
|
-
\`\`\`
|
|
2839
|
-
|
|
2840
|
-
You MUST say: "I found a 5-minute BTC Up/Down market: 'Bitcoin Up or Down - December 28, 11:50PM-11:55PM ET'. This is similar to what you requested."
|
|
2841
|
-
|
|
2842
|
-
**NEVER** say "I don't see any 15-minute markets" when the search returned 10 results!
|
|
2843
|
-
|
|
2844
|
-
Rules:
|
|
2845
|
-
1. **found > 0 means markets exist** - Read the titles and show them to the user
|
|
2846
|
-
2. **Be flexible** - 5min/10min/15min/30min are ALL acceptable for "short-term" requests
|
|
2847
|
-
3. **Use what's available** - Don't refuse to build because exact match isn't found
|
|
2848
|
-
4. **Extract the data** - clobTokenIds, conditionId, title are all in the results
|
|
2849
|
-
|
|
2850
|
-
The search results contain:
|
|
2851
|
-
- \`markets[].title\` - TELLS YOU THE MARKET NAME AND TIMEFRAME
|
|
2852
|
-
- \`markets[].markets[].clobTokenIds\` - Parse this JSON string for token IDs
|
|
2853
|
-
- \`markets[].markets[].conditionId\` - The condition ID for orders
|
|
2854
|
-
- \`markets[].markets[].outcomes[]\` - The Up/Down options with prices
|
|
2855
|
-
|
|
2856
|
-
### Bot Code Template (Node.js)
|
|
2857
|
-
\`\`\`javascript
|
|
2858
|
-
#!/usr/bin/env node
|
|
2859
|
-
require('dotenv').config();
|
|
2860
|
-
|
|
2861
|
-
const MCP_URL = 'https://quantish-sdk-production.up.railway.app/mcp/execute';
|
|
2862
|
-
const API_KEY = process.env.QUANTISH_API_KEY;
|
|
2863
|
-
|
|
2864
|
-
async function callTool(name, args = {}) {
|
|
2865
|
-
const response = await fetch(MCP_URL, {
|
|
2866
|
-
method: 'POST',
|
|
2867
|
-
headers: {
|
|
2868
|
-
'Content-Type': 'application/json',
|
|
2869
|
-
'x-api-key': API_KEY
|
|
2870
|
-
},
|
|
2871
|
-
body: JSON.stringify({
|
|
2872
|
-
jsonrpc: '2.0',
|
|
2873
|
-
method: 'tools/call',
|
|
2874
|
-
params: { name, arguments: args },
|
|
2875
|
-
id: Date.now()
|
|
2876
|
-
})
|
|
2877
|
-
});
|
|
2878
|
-
|
|
2879
|
-
const data = await response.json();
|
|
2880
|
-
if (data.error) throw new Error(data.error.message);
|
|
2881
|
-
|
|
2882
|
-
try {
|
|
2883
|
-
return JSON.parse(data.result.content[0].text);
|
|
2884
|
-
} catch {
|
|
2885
|
-
return data.result.content[0].text;
|
|
2886
|
-
}
|
|
2887
|
-
}
|
|
2888
|
-
|
|
2889
|
-
// Example: Monitor price and alert
|
|
2890
|
-
async function monitorPrice(tokenId, threshold) {
|
|
2891
|
-
const result = await callTool('get_price', { tokenId });
|
|
2892
|
-
console.log(\`Price: \${result.mid}\`);
|
|
2893
|
-
if (parseFloat(result.mid) > threshold) {
|
|
2894
|
-
console.log('ALERT: Price crossed threshold!');
|
|
2895
|
-
}
|
|
2703
|
+
}]
|
|
2896
2704
|
}
|
|
2897
2705
|
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
\`\`\`
|
|
2901
|
-
|
|
2902
|
-
### Best Practices
|
|
2903
|
-
1. **Environment Variables**: Always use process.env for API keys
|
|
2904
|
-
2. **Error Handling**: Wrap all API calls in try/catch
|
|
2905
|
-
3. **Rate Limiting**: Poll at 30-60 second intervals minimum
|
|
2906
|
-
4. **Logging**: Log all trades with timestamps for debugging
|
|
2907
|
-
5. **Testing**: Test with small amounts first
|
|
2908
|
-
6. **Graceful Shutdown**: Handle SIGINT to clean up
|
|
2909
|
-
7. **.env.example**: Always create a template for required env vars
|
|
2910
|
-
|
|
2911
|
-
## CRITICAL: Code Generation Rules (MUST FOLLOW)
|
|
2912
|
-
|
|
2913
|
-
When generating ANY code that uses Quantish/MCP (bots, apps, scripts, APIs, etc.):
|
|
2914
|
-
|
|
2915
|
-
### MANDATORY Requirements
|
|
2916
|
-
|
|
2917
|
-
1. **ALWAYS include BOTH callTradingTool() AND callDiscoveryTool() helper functions** - Copy them EXACTLY from the template
|
|
2918
|
-
2. **USE THE CORRECT HELPER FOR EACH TOOL** - Check the tool-to-server mapping table above!
|
|
2919
|
-
- Trading tools (get_price, get_orderbook, place_order, etc.) \u2192 callTradingTool()
|
|
2920
|
-
- Discovery tools (search_markets, get_market_details, etc.) \u2192 callDiscoveryTool()
|
|
2921
|
-
3. **NEVER hardcode prices, market data, or API responses** - Always fetch live data
|
|
2922
|
-
4. **NEVER comment out MCP calls** - All API calls must be real, working, executable code
|
|
2923
|
-
5. **ALWAYS create .env.example** - Document all required environment variables
|
|
2924
|
-
6. **ALWAYS validate QUANTISH_API_KEY exists** when using Trading tools - Fail fast with clear error if missing
|
|
2925
|
-
7. **ALWAYS use dotenv** - \`require('dotenv').config()\` at the top of every file
|
|
2926
|
-
|
|
2927
|
-
### \u26D4 NEVER DO WORKAROUNDS
|
|
2928
|
-
|
|
2929
|
-
- **NEVER try to "work around" missing tools** - If a tool requires auth, use auth
|
|
2930
|
-
- **NEVER substitute one tool for another** - get_market_details is NOT a replacement for get_price
|
|
2931
|
-
- **NEVER use the Discovery API for tools that require Trading API** - They are separate servers
|
|
2932
|
-
- **NEVER mock or simulate API responses** - Always make real API calls
|
|
2933
|
-
- **If a feature requires QUANTISH_API_KEY, tell the user they need one** - Don't try to avoid it
|
|
2934
|
-
|
|
2935
|
-
### File Structure for ANY Application
|
|
2936
|
-
|
|
2937
|
-
When creating an application, ALWAYS create these files:
|
|
2938
|
-
1. Main application file (e.g., \`app.js\`, \`bot.js\`, \`server.js\`)
|
|
2939
|
-
2. \`.env.example\` with all required variables documented
|
|
2940
|
-
3. \`package.json\` with dependencies (dotenv, etc.)
|
|
2941
|
-
4. \`README.md\` with setup instructions
|
|
2942
|
-
|
|
2943
|
-
### Example .env.example (ALWAYS CREATE THIS)
|
|
2944
|
-
\`\`\`
|
|
2945
|
-
# Quantish MCP API Key (required for trading)
|
|
2946
|
-
# Get yours at: https://quantish.live
|
|
2947
|
-
QUANTISH_API_KEY=your_api_key_here
|
|
2706
|
+
To extract token IDs: JSON.parse(market.markets[0].clobTokenIds)
|
|
2707
|
+
Outcome prices are in: market.markets[0].outcomes[].price
|
|
2948
2708
|
|
|
2949
|
-
|
|
2950
|
-
TOKEN_ID=your_token_id_here
|
|
2951
|
-
CONDITION_ID=your_condition_id_here
|
|
2952
|
-
\`\`\`
|
|
2709
|
+
## Helper Functions (copy exactly)
|
|
2953
2710
|
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
\`\`\`javascript
|
|
2958
|
-
const prices = { YES: 0.55, NO: 0.45 }; // WRONG: hardcoded
|
|
2959
|
-
const mockResult = { mid: "0.50" }; // WRONG: mock data
|
|
2960
|
-
// await callTool('place_order', {...}); // WRONG: commented out
|
|
2961
|
-
\`\`\`
|
|
2962
|
-
|
|
2963
|
-
CORRECT - Live MCP calls (ALWAYS DO THIS):
|
|
2964
|
-
\`\`\`javascript
|
|
2965
|
-
const priceResult = await callTool('get_price', { tokenId });
|
|
2966
|
-
const price = parseFloat(priceResult.mid);
|
|
2967
|
-
const orderResult = await callTool('place_order', {
|
|
2968
|
-
conditionId, tokenId, side: 'BUY', price, size
|
|
2969
|
-
});
|
|
2970
|
-
console.log('Order placed:', orderResult.orderId);
|
|
2971
|
-
\`\`\`
|
|
2972
|
-
|
|
2973
|
-
### SIMPLE EXAMPLE - Copy This Pattern Exactly
|
|
2974
|
-
|
|
2975
|
-
\`\`\`javascript
|
|
2976
|
-
// Simple bot that searches markets using Discovery API (free, no auth)
|
|
2977
|
-
require('dotenv').config();
|
|
2978
|
-
|
|
2979
|
-
// Discovery API uses SIMPLE format: { name, arguments }
|
|
2980
|
-
async function callDiscovery(name, args = {}) {
|
|
2981
|
-
const res = await fetch('https://quantish.live/mcp/execute', {
|
|
2711
|
+
Trading:
|
|
2712
|
+
async function callTradingTool(name, args = {}) {
|
|
2713
|
+
const res = await fetch('https://quantish-sdk-production.up.railway.app/mcp/execute', {
|
|
2982
2714
|
method: 'POST',
|
|
2983
|
-
headers: {
|
|
2984
|
-
|
|
2985
|
-
'X-API-Key': 'qm_ueQeqrmvZyHtR1zuVbLYkhx0fKyVAuV8' // Public key
|
|
2986
|
-
},
|
|
2987
|
-
body: JSON.stringify({ name, arguments: args }) // Simple format!
|
|
2715
|
+
headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.QUANTISH_API_KEY },
|
|
2716
|
+
body: JSON.stringify({ jsonrpc: '2.0', method: 'tools/call', params: { name, arguments: args }, id: Date.now() })
|
|
2988
2717
|
});
|
|
2989
2718
|
const data = await res.json();
|
|
2990
2719
|
return JSON.parse(data.result.content[0].text);
|
|
2991
2720
|
}
|
|
2992
2721
|
|
|
2993
|
-
|
|
2994
|
-
const markets = await callDiscovery('search_markets', { query: 'bitcoin', limit: 5 });
|
|
2995
|
-
console.log(markets);
|
|
2996
|
-
\`\`\`
|
|
2997
|
-
|
|
2998
|
-
### Complete Production-Ready Template
|
|
2999
|
-
|
|
3000
|
-
Use this as the starting point for ANY application:
|
|
3001
|
-
|
|
3002
|
-
\`\`\`javascript
|
|
3003
|
-
#!/usr/bin/env node
|
|
3004
|
-
/**
|
|
3005
|
-
* Quantish Application Template
|
|
3006
|
-
* Replace this with your application description
|
|
3007
|
-
*/
|
|
3008
|
-
|
|
3009
|
-
require('dotenv').config();
|
|
3010
|
-
|
|
3011
|
-
// ============================================
|
|
3012
|
-
// MCP Configuration - DO NOT MODIFY
|
|
3013
|
-
// ============================================
|
|
3014
|
-
const TRADING_MCP_URL = 'https://quantish-sdk-production.up.railway.app/mcp/execute';
|
|
3015
|
-
const DISCOVERY_MCP_URL = 'https://quantish.live/mcp/execute';
|
|
3016
|
-
const DISCOVERY_API_KEY = 'qm_ueQeqrmvZyHtR1zuVbLYkhx0fKyVAuV8'; // Public key for discovery
|
|
3017
|
-
|
|
3018
|
-
// Validate required environment variables
|
|
3019
|
-
if (!process.env.QUANTISH_API_KEY) {
|
|
3020
|
-
console.error('ERROR: QUANTISH_API_KEY environment variable is required');
|
|
3021
|
-
console.error('Get your API key at: https://quantish.live');
|
|
3022
|
-
console.error('Then create a .env file with: QUANTISH_API_KEY=your_key_here');
|
|
3023
|
-
process.exit(1);
|
|
3024
|
-
}
|
|
3025
|
-
|
|
3026
|
-
// ============================================
|
|
3027
|
-
// MCP Helper Functions - COPY THESE EXACTLY
|
|
3028
|
-
// ============================================
|
|
3029
|
-
|
|
3030
|
-
/**
|
|
3031
|
-
* Call a trading tool (requires QUANTISH_API_KEY)
|
|
3032
|
-
* Tools: get_balances, get_positions, place_order, cancel_order, get_orders,
|
|
3033
|
-
* get_orderbook, get_price, get_deposit_addresses, transfer_usdc
|
|
3034
|
-
*/
|
|
3035
|
-
async function callTradingTool(name, args = {}) {
|
|
3036
|
-
const response = await fetch(TRADING_MCP_URL, {
|
|
3037
|
-
method: 'POST',
|
|
3038
|
-
headers: {
|
|
3039
|
-
'Content-Type': 'application/json',
|
|
3040
|
-
'x-api-key': process.env.QUANTISH_API_KEY
|
|
3041
|
-
},
|
|
3042
|
-
body: JSON.stringify({
|
|
3043
|
-
jsonrpc: '2.0',
|
|
3044
|
-
method: 'tools/call',
|
|
3045
|
-
params: { name, arguments: args },
|
|
3046
|
-
id: Date.now()
|
|
3047
|
-
})
|
|
3048
|
-
});
|
|
3049
|
-
|
|
3050
|
-
const data = await response.json();
|
|
3051
|
-
if (data.error) throw new Error(data.error.message || JSON.stringify(data.error));
|
|
3052
|
-
|
|
3053
|
-
try {
|
|
3054
|
-
return JSON.parse(data.result.content[0].text);
|
|
3055
|
-
} catch {
|
|
3056
|
-
return data.result.content[0].text;
|
|
3057
|
-
}
|
|
3058
|
-
}
|
|
3059
|
-
|
|
3060
|
-
/**
|
|
3061
|
-
* Call a discovery tool (no auth required)
|
|
3062
|
-
* Uses SIMPLE format: { name, arguments } - NOT full JSON-RPC
|
|
3063
|
-
* Tools: search_markets, get_market_details, get_trending_markets, find_arbitrage
|
|
3064
|
-
*/
|
|
2722
|
+
Discovery:
|
|
3065
2723
|
async function callDiscoveryTool(name, args = {}) {
|
|
3066
|
-
const
|
|
2724
|
+
const res = await fetch('https://quantish.live/mcp/execute', {
|
|
3067
2725
|
method: 'POST',
|
|
3068
|
-
headers: {
|
|
3069
|
-
|
|
3070
|
-
'X-API-Key': DISCOVERY_API_KEY
|
|
3071
|
-
},
|
|
3072
|
-
body: JSON.stringify({ name, arguments: args }) // Simple format for Discovery!
|
|
2726
|
+
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'qm_ueQeqrmvZyHtR1zuVbLYkhx0fKyVAuV8' },
|
|
2727
|
+
body: JSON.stringify({ name, arguments: args })
|
|
3073
2728
|
});
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
if (data.error) throw new Error(data.error.message || JSON.stringify(data.error));
|
|
3077
|
-
|
|
3078
|
-
try {
|
|
3079
|
-
return JSON.parse(data.result.content[0].text);
|
|
3080
|
-
} catch {
|
|
3081
|
-
return data.result.content[0].text;
|
|
3082
|
-
}
|
|
3083
|
-
}
|
|
3084
|
-
|
|
3085
|
-
// Shorthand for common operations
|
|
3086
|
-
const callTool = callTradingTool; // Default to trading tools
|
|
3087
|
-
|
|
3088
|
-
// ============================================
|
|
3089
|
-
// Your Application Code Goes Here
|
|
3090
|
-
// ============================================
|
|
3091
|
-
|
|
3092
|
-
async function main() {
|
|
3093
|
-
console.log('Starting application...');
|
|
3094
|
-
|
|
3095
|
-
try {
|
|
3096
|
-
// Example: Get wallet balances
|
|
3097
|
-
const balances = await callTool('get_balances');
|
|
3098
|
-
console.log('Wallet balances:', balances);
|
|
3099
|
-
|
|
3100
|
-
// Example: Search for markets
|
|
3101
|
-
const markets = await callDiscoveryTool('search_markets', {
|
|
3102
|
-
query: 'Bitcoin',
|
|
3103
|
-
limit: 5
|
|
3104
|
-
});
|
|
3105
|
-
console.log('Found markets:', markets.found);
|
|
3106
|
-
|
|
3107
|
-
// Example: Get price for a token
|
|
3108
|
-
if (process.env.TOKEN_ID) {
|
|
3109
|
-
const price = await callTool('get_price', {
|
|
3110
|
-
tokenId: process.env.TOKEN_ID
|
|
3111
|
-
});
|
|
3112
|
-
console.log('Current price:', price.mid);
|
|
3113
|
-
}
|
|
3114
|
-
|
|
3115
|
-
} catch (error) {
|
|
3116
|
-
console.error('Error:', error.message);
|
|
3117
|
-
}
|
|
2729
|
+
const data = await res.json();
|
|
2730
|
+
return JSON.parse(data.result.content[0].text);
|
|
3118
2731
|
}
|
|
3119
2732
|
|
|
3120
|
-
|
|
3121
|
-
process.on('SIGINT', () => {
|
|
3122
|
-
console.log('\\nShutting down...');
|
|
3123
|
-
process.exit(0);
|
|
3124
|
-
});
|
|
3125
|
-
|
|
3126
|
-
process.on('SIGTERM', () => {
|
|
3127
|
-
console.log('\\nShutting down...');
|
|
3128
|
-
process.exit(0);
|
|
3129
|
-
});
|
|
3130
|
-
|
|
3131
|
-
// Run the application
|
|
3132
|
-
main().catch(console.error);
|
|
3133
|
-
\`\`\`
|
|
3134
|
-
|
|
3135
|
-
### Application Types You Can Build
|
|
3136
|
-
|
|
3137
|
-
- **Trading Bots**: Automated trading based on price thresholds, trends, or signals
|
|
3138
|
-
- **Price Monitors**: Alert systems for price movements via email, SMS, Discord, Telegram
|
|
3139
|
-
- **Web Dashboards**: React/Next.js apps displaying market data and portfolio
|
|
3140
|
-
- **API Backends**: Express/Fastify servers exposing market data to frontends
|
|
3141
|
-
- **Analytics Tools**: Scripts that analyze historical prices and trends
|
|
3142
|
-
- **Arbitrage Scanners**: Tools that find and execute arbitrage opportunities
|
|
3143
|
-
- **Portfolio Trackers**: Apps that track positions across multiple markets
|
|
3144
|
-
- **Notification Services**: Webhooks that trigger on market events
|
|
3145
|
-
- **Discord/Telegram Bots**: Chat bots that provide market info and execute trades
|
|
2733
|
+
## Rules
|
|
3146
2734
|
|
|
3147
|
-
|
|
2735
|
+
1. Never use @modelcontextprotocol/sdk in standalone apps - use fetch()
|
|
2736
|
+
2. Trading tools need QUANTISH_API_KEY. Discovery tools are free.
|
|
2737
|
+
3. Always create .env.example and use dotenv
|
|
2738
|
+
4. Never hardcode prices or mock data
|
|
2739
|
+
5. If found > 0, markets exist - use them
|
|
2740
|
+
6. Debug by reading logs, not by restarting servers repeatedly`;
|
|
3148
2741
|
var Agent = class {
|
|
3149
2742
|
anthropic;
|
|
3150
2743
|
mcpClient;
|
|
@@ -3246,7 +2839,7 @@ var Agent = class {
|
|
|
3246
2839
|
*/
|
|
3247
2840
|
async run(userMessage, options) {
|
|
3248
2841
|
const maxIterations = this.config.maxIterations ?? 15;
|
|
3249
|
-
const model = this.config.model ?? "claude-sonnet-4-
|
|
2842
|
+
const model = this.config.model ?? "claude-sonnet-4-5-20250929";
|
|
3250
2843
|
const maxTokens = this.config.maxTokens ?? 8192;
|
|
3251
2844
|
const systemPrompt = this.config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
3252
2845
|
const useStreaming = this.config.streaming ?? true;
|
|
@@ -3506,7 +3099,7 @@ ${userMessage}`;
|
|
|
3506
3099
|
* Count tokens in current conversation (uses Anthropic's token counting API)
|
|
3507
3100
|
*/
|
|
3508
3101
|
async countTokens() {
|
|
3509
|
-
const model = this.config.model ?? "claude-sonnet-4-
|
|
3102
|
+
const model = this.config.model ?? "claude-sonnet-4-5-20250929";
|
|
3510
3103
|
const systemPrompt = this.config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
3511
3104
|
const allTools = await this.getAllTools();
|
|
3512
3105
|
try {
|
|
@@ -3577,7 +3170,7 @@ ${userMessage}`;
|
|
|
3577
3170
|
* @returns Object with original/new token counts and the summary
|
|
3578
3171
|
*/
|
|
3579
3172
|
async compactHistory() {
|
|
3580
|
-
const model = this.config.model ?? "claude-sonnet-4-
|
|
3173
|
+
const model = this.config.model ?? "claude-sonnet-4-5-20250929";
|
|
3581
3174
|
const systemPrompt = this.config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
3582
3175
|
const allTools = await this.getAllTools();
|
|
3583
3176
|
if (this.conversationHistory.length < 2) {
|
|
@@ -4313,7 +3906,7 @@ program.command("config").description("View or edit configuration").option("-s,
|
|
|
4313
3906
|
console.log(`QUANTISH_API_KEY=${all2.quantishApiKey}`);
|
|
4314
3907
|
}
|
|
4315
3908
|
console.log(`QUANTISH_MCP_URL=${all2.mcpServerUrl}`);
|
|
4316
|
-
console.log(`QUANTISH_MODEL=${all2.model || "claude-sonnet-4-
|
|
3909
|
+
console.log(`QUANTISH_MODEL=${all2.model || "claude-sonnet-4-5-20250929"}`);
|
|
4317
3910
|
console.log();
|
|
4318
3911
|
console.log(chalk3.dim("# Discovery MCP (public, read-only market data)"));
|
|
4319
3912
|
console.log(`QUANTISH_DISCOVERY_URL=https://quantish.live/mcp`);
|
|
@@ -4334,7 +3927,7 @@ program.command("config").description("View or edit configuration").option("-s,
|
|
|
4334
3927
|
tableRow("Quantish API Key", all.quantishApiKey ? `${all.quantishApiKey.slice(0, 12)}...` : chalk3.dim("Not set"));
|
|
4335
3928
|
}
|
|
4336
3929
|
tableRow("MCP Server URL", all.mcpServerUrl);
|
|
4337
|
-
tableRow("Model", all.model || "claude-sonnet-4-
|
|
3930
|
+
tableRow("Model", all.model || "claude-sonnet-4-5-20250929");
|
|
4338
3931
|
printDivider();
|
|
4339
3932
|
console.log(chalk3.dim(`Config file: ${config.getConfigPath()}`));
|
|
4340
3933
|
console.log();
|