create-polyclaw-agent 0.1.0 → 0.2.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/dist/index.js CHANGED
@@ -11,9 +11,18 @@ import { generateName, registerAgent, getLinkUrl } from './api.js';
11
11
  import { scaffoldProject, nameToDir } from './scaffold.js';
12
12
  const LOBSTER = '\u{1F99E}';
13
13
  async function main() {
14
- console.log();
15
- console.log(chalk.bold(' Welcome to Polyclaw!'));
16
- console.log();
14
+ const BANNER = `
15
+ ${chalk.red(` .-----.
16
+ _ | o o | _
17
+ | | | w | | |
18
+ |_| '-----' |_|`)}
19
+
20
+ ${chalk.bold(` █▀█ █▀█ █ █ █ █▀▀ █ █▀█ █ █
21
+ █▀▀ █ █ █ █ █ █ █▀█ █ █ █
22
+ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀ ▀`)}
23
+ ${chalk.dim(' AI-Powered Prediction Market Agent')}
24
+ `;
25
+ console.log(BANNER);
17
26
  // Step 1: Generate and pick a name
18
27
  let agentName;
19
28
  try {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/scaffold.js CHANGED
@@ -44,7 +44,7 @@ function scaffoldPython(dir, options) {
44
44
  ? `AI_API_KEY = os.getenv("OPENAI_API_KEY")`
45
45
  : '';
46
46
  const aiAnalyzeFunc = options.aiProvider === 'anthropic' ? `
47
- def analyze_markets(markets):
47
+ def analyze_markets(markets, num_proposals=5):
48
48
  """Use Claude to analyze prediction markets and pick the best bets."""
49
49
  client = anthropic.Anthropic(api_key=AI_API_KEY)
50
50
 
@@ -65,10 +65,10 @@ def analyze_markets(markets):
65
65
 
66
66
  response = client.messages.create(
67
67
  model="claude-sonnet-4-20250514",
68
- max_tokens=1024,
68
+ max_tokens=2048,
69
69
  messages=[{
70
70
  "role": "user",
71
- "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to 3 best betting opportunities.
71
+ "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to {num_proposals} best betting opportunities.
72
72
 
73
73
  Markets:
74
74
  {markets_text}
@@ -86,7 +86,7 @@ For each pick, respond in this exact JSON format (no markdown, just raw JSON arr
86
86
  ]
87
87
 
88
88
  Rules:
89
- - Pick 1-3 markets that look like good opportunities
89
+ - Pick up to {num_proposals} markets that look like good opportunities
90
90
  - Consider the current price, volume, and whether the market seems mispriced
91
91
  - Be diverse -- don't pick markets that are all about the same topic
92
92
  - Higher confidence = stronger conviction (0.5 = coin flip, 0.9 = very confident)
@@ -95,16 +95,21 @@ Rules:
95
95
  }]
96
96
  )
97
97
 
98
- # Parse the AI response
98
+ # Parse the AI response (strip markdown code fences if present)
99
99
  try:
100
- picks = json.loads(response.content[0].text)
100
+ text = response.content[0].text.strip()
101
+ if text.startswith("\`\`\`"):
102
+ text = text.split("\`\`\`", 2)[1]
103
+ if text.startswith("json"):
104
+ text = text[4:]
105
+ picks = json.loads(text.strip())
101
106
  model_name = response.model
102
107
  return picks, model_name
103
108
  except (json.JSONDecodeError, IndexError):
104
109
  print(f" AI response: {response.content[0].text}")
105
110
  return [], response.model
106
111
  ` : options.aiProvider === 'openai' ? `
107
- def analyze_markets(markets):
112
+ def analyze_markets(markets, num_proposals=5):
108
113
  """Use GPT to analyze prediction markets and pick the best bets."""
109
114
  client = openai.OpenAI(api_key=AI_API_KEY)
110
115
 
@@ -127,7 +132,7 @@ def analyze_markets(markets):
127
132
  model="gpt-4o",
128
133
  messages=[{
129
134
  "role": "user",
130
- "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to 3 best betting opportunities.
135
+ "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to {num_proposals} best betting opportunities.
131
136
 
132
137
  Markets:
133
138
  {markets_text}
@@ -145,7 +150,7 @@ For each pick, respond in this exact JSON format (no markdown, just raw JSON arr
145
150
  ]
146
151
 
147
152
  Rules:
148
- - Pick 1-3 markets that look like good opportunities
153
+ - Pick up to {num_proposals} markets that look like good opportunities
149
154
  - Consider the current price, volume, and whether the market seems mispriced
150
155
  - Be diverse -- don't pick markets that are all about the same topic
151
156
  - Higher confidence = stronger conviction (0.5 = coin flip, 0.9 = very confident)
@@ -154,16 +159,21 @@ Rules:
154
159
  }],
155
160
  )
156
161
 
157
- # Parse the AI response
162
+ # Parse the AI response (strip markdown code fences if present)
158
163
  try:
159
- picks = json.loads(response.choices[0].message.content)
164
+ text = response.choices[0].message.content.strip()
165
+ if text.startswith("\`\`\`"):
166
+ text = text.split("\`\`\`", 2)[1]
167
+ if text.startswith("json"):
168
+ text = text[4:]
169
+ picks = json.loads(text.strip())
160
170
  model_name = response.model
161
171
  return picks, model_name
162
172
  except (json.JSONDecodeError, IndexError):
163
173
  print(f" AI response: {response.choices[0].message.content}")
164
174
  return [], response.model
165
175
  ` : `
166
- def analyze_markets(markets):
176
+ def analyze_markets(markets, num_proposals=5):
167
177
  """Placeholder: Add your own AI logic here to analyze markets."""
168
178
  # This is where you connect your AI model.
169
179
  # Return a list of picks in this format:
@@ -240,8 +250,14 @@ class PolyclawClient:
240
250
  response = requests.request(method, url, headers=headers, json=body)
241
251
  return response.json()
242
252
 
243
- def get_markets(self, page: int = 1, limit: int = 20):
244
- return self._request("GET", f"/api/markets?page={page}&limit={limit}")
253
+ def get_markets(self, page: int = 1, limit: int = 20, tag: str = None):
254
+ path = f"/api/markets?page={page}&limit={limit}"
255
+ if tag and tag != "all":
256
+ path += f"&tag={tag}"
257
+ return self._request("GET", path)
258
+
259
+ def get_my_proposals(self, limit: int = 100):
260
+ return self._request("GET", f"/api/proposals?limit={limit}")
245
261
 
246
262
  def submit_proposal(self, market_id, outcome, side, recommended_amount, confidence, reasoning=None, model=None):
247
263
  body = {"marketId": market_id, "outcome": outcome, "side": side,
@@ -252,35 +268,50 @@ class PolyclawClient:
252
268
 
253
269
  ${aiAnalyzeFunc}
254
270
 
255
- def main():
256
- if not API_KEY or not API_SECRET:
257
- print("Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env")
258
- return
259
- ${options.aiProvider !== 'none' ? `
260
- ai_key_name = "${options.aiProvider === 'anthropic' ? 'ANTHROPIC_API_KEY' : 'OPENAI_API_KEY'}"
261
- if not AI_API_KEY:
262
- print(f"Error: {ai_key_name} must be set in .env")
263
- return
264
- ` : ''}
265
- client = PolyclawClient(API_KEY, API_SECRET, BASE_URL)
266
- print(f"${options.name} is online!")
267
- print()
271
+ def get_proposed_market_ids(client):
272
+ """Fetch markets we've already proposed on to avoid duplicates."""
273
+ result = client.get_my_proposals(limit=100)
274
+ if not result.get("success"):
275
+ return set()
276
+ proposals = result.get("data", result.get("proposals", []))
277
+ if isinstance(proposals, dict):
278
+ proposals = proposals.get("proposals", [])
279
+ return {p.get("marketId") for p in proposals if p.get("marketId")}
280
+
281
+
282
+ def run_round(client, tag="all", search_size=20, num_proposals=5, page=1):
283
+ """Fetch markets, filter out already-proposed ones, analyze, and submit."""
284
+ category_label = tag if tag != "all" else "all topics"
268
285
 
269
- # Fetch markets
270
- print("Fetching markets from Polymarket...")
271
- result = client.get_markets(limit=20)
286
+ # Get markets we've already proposed on
287
+ print("Checking existing proposals...")
288
+ already_proposed = get_proposed_market_ids(client)
289
+ if already_proposed:
290
+ print(f" Skipping {len(already_proposed)} market(s) with existing proposals")
291
+
292
+ # Fetch markets with category filter
293
+ print(f"Scanning {search_size} {category_label} markets...")
294
+ result = client.get_markets(page=page, limit=search_size, tag=tag)
272
295
 
273
296
  if not result.get("success"):
274
297
  print(f"Error: {result.get('error', 'Unknown error')}")
275
298
  return
276
299
 
277
- markets = result.get("data", [])
278
- print(f"Found {len(markets)} markets")
300
+ all_markets = result.get("data", [])
301
+
302
+ # Filter out markets we've already proposed on
303
+ markets = [m for m in all_markets if m.get("id") not in already_proposed]
304
+ print(f"Found {len(all_markets)} markets, {len(markets)} new ones to analyze")
305
+
306
+ if not markets:
307
+ print("No new markets to analyze. Try again later or pick a different category.")
308
+ return
309
+
279
310
  print()
280
311
 
281
312
  # Ask AI to analyze and pick the best bets
282
- print("Asking AI to analyze markets...\\n")
283
- picks, model_name = analyze_markets(markets)
313
+ print(f"Asking AI to pick {num_proposals} best bets...\\n")
314
+ picks, model_name = analyze_markets(markets, num_proposals=num_proposals)
284
315
 
285
316
  if not picks:
286
317
  print("No picks from AI. Try again later.")
@@ -317,6 +348,124 @@ ${options.aiProvider !== 'none' ? `
317
348
  print("Done! Check your dashboard to review proposals.")
318
349
 
319
350
 
351
+ BANNER = """
352
+ \\033[91m .-----.
353
+ _ | o o | _
354
+ | | | w | | |
355
+ |_| '-----' |_|\\033[0m
356
+
357
+ \\033[1m █▀█ █▀█ █ █ █ █▀▀ █ █▀█ █ █
358
+ █▀▀ █ █ █ █ █ █ █▀█ █ █ █
359
+ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀ ▀\\033[0m
360
+ \\033[90m AI-Powered Prediction Market Agent\\033[0m
361
+ """
362
+
363
+
364
+ # --- Interactive prompts ---
365
+
366
+ CATEGORIES = [
367
+ ("politics", "Politics"),
368
+ ("sports", "Sports"),
369
+ ("crypto", "Crypto"),
370
+ ("finance", "Finance"),
371
+ ("tech", "Tech"),
372
+ ("culture", "Culture"),
373
+ ("all", "All topics"),
374
+ ]
375
+
376
+ SEARCH_SIZES = [20, 40, 60, 100, 200, 400]
377
+ PROPOSAL_COUNTS = [5, 10, 15]
378
+
379
+
380
+ def ask_category(agent_name):
381
+ print(f"What category would you like {agent_name} to look into?")
382
+ for i, (_, label) in enumerate(CATEGORIES, 1):
383
+ print(f" {i}. {label}")
384
+ print()
385
+ while True:
386
+ try:
387
+ choice = input("Pick a number: ").strip()
388
+ except (EOFError, KeyboardInterrupt):
389
+ return "all"
390
+ if choice.isdigit() and 1 <= int(choice) <= len(CATEGORIES):
391
+ print()
392
+ return CATEGORIES[int(choice) - 1][0]
393
+ print(f" Please enter a number between 1 and {len(CATEGORIES)}")
394
+
395
+
396
+ def ask_search_size():
397
+ print("How big do you want your search to be?")
398
+ for i, size in enumerate(SEARCH_SIZES, 1):
399
+ print(f" {i}. {size} markets")
400
+ print()
401
+ while True:
402
+ try:
403
+ choice = input("Pick a number [1]: ").strip() or "1"
404
+ except (EOFError, KeyboardInterrupt):
405
+ return SEARCH_SIZES[0]
406
+ if choice.isdigit() and 1 <= int(choice) <= len(SEARCH_SIZES):
407
+ print()
408
+ return SEARCH_SIZES[int(choice) - 1]
409
+ print(f" Please enter a number between 1 and {len(SEARCH_SIZES)}")
410
+
411
+
412
+ def ask_num_proposals():
413
+ print("How many proposals do you want?")
414
+ for i, count in enumerate(PROPOSAL_COUNTS, 1):
415
+ print(f" {i}. {count} proposals")
416
+ print()
417
+ while True:
418
+ try:
419
+ choice = input("Pick a number [1]: ").strip() or "1"
420
+ except (EOFError, KeyboardInterrupt):
421
+ return PROPOSAL_COUNTS[0]
422
+ if choice.isdigit() and 1 <= int(choice) <= len(PROPOSAL_COUNTS):
423
+ print()
424
+ return PROPOSAL_COUNTS[int(choice) - 1]
425
+ print(f" Please enter a number between 1 and {len(PROPOSAL_COUNTS)}")
426
+
427
+
428
+ # --- Main ---
429
+
430
+ def main():
431
+ if not API_KEY or not API_SECRET:
432
+ print("Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env")
433
+ return
434
+ ${options.aiProvider !== 'none' ? `
435
+ ai_key_name = "${options.aiProvider === 'anthropic' ? 'ANTHROPIC_API_KEY' : 'OPENAI_API_KEY'}"
436
+ if not AI_API_KEY:
437
+ print(f"Error: {ai_key_name} must be set in .env")
438
+ return
439
+ ` : ''}
440
+ client = PolyclawClient(API_KEY, API_SECRET, BASE_URL)
441
+ print(BANNER)
442
+ print(" Welcome to Polyclaw!")
443
+ print()
444
+ print(" Your agent: \\033[1m${options.name}\\033[0m")
445
+ print()
446
+
447
+ # Ask user preferences
448
+ tag = ask_category("${options.name}")
449
+ search_size = ask_search_size()
450
+ num_proposals = ask_num_proposals()
451
+
452
+ page = 1
453
+ run_round(client, tag=tag, search_size=search_size, num_proposals=num_proposals, page=page)
454
+
455
+ # Interactive loop
456
+ while True:
457
+ print()
458
+ try:
459
+ reply = input("Press Enter for more proposals, or q to quit: ").strip().lower()
460
+ except (EOFError, KeyboardInterrupt):
461
+ break
462
+ if reply in ("q", "quit", "exit"):
463
+ break
464
+ page += 1
465
+ print()
466
+ run_round(client, tag=tag, search_size=search_size, num_proposals=num_proposals, page=page)
467
+
468
+
320
469
  if __name__ == "__main__":
321
470
  main()
322
471
  `;
@@ -391,8 +540,14 @@ class PolyclawClient {
391
540
  return response.json() as T;
392
541
  }
393
542
 
394
- async getMarkets(page = 1, limit = 20) {
395
- return this.request<any>('GET', \`/api/markets?page=\${page}&limit=\${limit}\`);
543
+ async getMarkets(page = 1, limit = 20, tag?: string) {
544
+ let path = \`/api/markets?page=\${page}&limit=\${limit}\`;
545
+ if (tag && tag !== 'all') path += \`&tag=\${tag}\`;
546
+ return this.request<any>('GET', path);
547
+ }
548
+
549
+ async getMyProposals(limit = 100) {
550
+ return this.request<any>('GET', \`/api/proposals?limit=\${limit}\`);
396
551
  }
397
552
 
398
553
  async submitProposal(proposal: {
@@ -456,63 +611,186 @@ function findBestPlay(markets: any[]): MarketPlay | null {
456
611
  return scored[0] || null;
457
612
  }
458
613
 
459
- async function main() {
460
- if (!API_KEY || !API_SECRET) {
461
- console.error('Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env');
462
- return;
614
+ import * as readline from 'readline';
615
+
616
+ function prompt(question: string): Promise<string> {
617
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
618
+ return new Promise((resolve) => {
619
+ rl.question(question, (answer) => { rl.close(); resolve(answer.trim().toLowerCase()); });
620
+ });
621
+ }
622
+
623
+ // --- Interactive prompts ---
624
+
625
+ const BANNER = \`
626
+ \\x1b[91m .-----.
627
+ _ | o o | _
628
+ | | | w | | |
629
+ |_| '-----' |_|\\x1b[0m
630
+
631
+ \\x1b[1m █▀█ █▀█ █ █ █ █▀▀ █ █▀█ █ █
632
+ █▀▀ █ █ █ █ █ █ █▀█ █ █ █
633
+ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀ ▀\\x1b[0m
634
+ \\x1b[90m AI-Powered Prediction Market Agent\\x1b[0m
635
+ \`;
636
+
637
+ const CATEGORIES = [
638
+ ['politics', 'Politics'],
639
+ ['sports', 'Sports'],
640
+ ['crypto', 'Crypto'],
641
+ ['finance', 'Finance'],
642
+ ['tech', 'Tech'],
643
+ ['culture', 'Culture'],
644
+ ['all', 'All topics'],
645
+ ] as const;
646
+
647
+ const SEARCH_SIZES = [20, 40, 60, 100, 200, 400];
648
+ const PROPOSAL_COUNTS = [5, 10, 15];
649
+
650
+ async function askCategory(agentName: string): Promise<string> {
651
+ console.log(\`What category would you like \${agentName} to look into?\`);
652
+ CATEGORIES.forEach(([, label], i) => console.log(\` \${i + 1}. \${label}\`));
653
+ console.log();
654
+ while (true) {
655
+ const choice = await prompt('Pick a number: ');
656
+ const n = parseInt(choice);
657
+ if (n >= 1 && n <= CATEGORIES.length) { console.log(); return CATEGORIES[n - 1][0]; }
658
+ console.log(\` Please enter a number between 1 and \${CATEGORIES.length}\`);
463
659
  }
660
+ }
464
661
 
465
- const client = new PolyclawClient({ apiKey: API_KEY, apiSecret: API_SECRET, baseUrl: BASE_URL });
466
- console.log('${options.name} is online!');
662
+ async function askSearchSize(): Promise<number> {
663
+ console.log('How big do you want your search to be?');
664
+ SEARCH_SIZES.forEach((s, i) => console.log(\` \${i + 1}. \${s} markets\`));
467
665
  console.log();
666
+ while (true) {
667
+ const choice = (await prompt('Pick a number [1]: ')) || '1';
668
+ const n = parseInt(choice);
669
+ if (n >= 1 && n <= SEARCH_SIZES.length) { console.log(); return SEARCH_SIZES[n - 1]; }
670
+ console.log(\` Please enter a number between 1 and \${SEARCH_SIZES.length}\`);
671
+ }
672
+ }
673
+
674
+ async function askNumProposals(): Promise<number> {
675
+ console.log('How many proposals do you want?');
676
+ PROPOSAL_COUNTS.forEach((c, i) => console.log(\` \${i + 1}. \${c} proposals\`));
677
+ console.log();
678
+ while (true) {
679
+ const choice = (await prompt('Pick a number [1]: ')) || '1';
680
+ const n = parseInt(choice);
681
+ if (n >= 1 && n <= PROPOSAL_COUNTS.length) { console.log(); return PROPOSAL_COUNTS[n - 1]; }
682
+ console.log(\` Please enter a number between 1 and \${PROPOSAL_COUNTS.length}\`);
683
+ }
684
+ }
468
685
 
469
- // Fetch markets
470
- console.log('Scanning markets...');
471
- const result = await client.getMarkets(1, 20);
686
+ async function getProposedMarketIds(client: PolyclawClient): Promise<Set<string>> {
687
+ const result = await client.getMyProposals(100);
688
+ if (!result.success) return new Set();
689
+ const proposals = Array.isArray(result.data) ? result.data : (result.data?.proposals || []);
690
+ return new Set(proposals.map((p: any) => p.marketId).filter(Boolean));
691
+ }
692
+
693
+ async function runRound(client: PolyclawClient, opts: { tag: string; searchSize: number; numProposals: number; page: number }) {
694
+ const categoryLabel = opts.tag !== 'all' ? opts.tag : 'all topics';
695
+
696
+ console.log('Checking existing proposals...');
697
+ const alreadyProposed = await getProposedMarketIds(client);
698
+ if (alreadyProposed.size) console.log(\` Skipping \${alreadyProposed.size} market(s) with existing proposals\`);
699
+
700
+ console.log(\`Scanning \${opts.searchSize} \${categoryLabel} markets...\`);
701
+ const result = await client.getMarkets(opts.page, opts.searchSize, opts.tag);
472
702
 
473
703
  if (!result.success) {
474
704
  console.error(\`Error: \${result.error || 'Unknown error'}\`);
475
705
  return;
476
706
  }
477
707
 
478
- const markets = result.data || [];
479
- console.log(\`Analyzing \${markets.length} markets...\\n\`);
708
+ const allMarkets = result.data || [];
709
+ const markets = allMarkets.filter((m: any) => !alreadyProposed.has(m.id));
710
+ console.log(\`Found \${allMarkets.length} markets, \${markets.length} new ones to analyze\\n\`);
480
711
 
481
- // Find the best play
482
- const best = findBestPlay(markets);
712
+ if (!markets.length) {
713
+ console.log('No new markets to analyze. Try again later or pick a different category.');
714
+ return;
715
+ }
483
716
 
484
- if (!best) {
717
+ // Find top plays using the scoring heuristic
718
+ const scored = markets
719
+ .map((market: any) => {
720
+ const yesPrice = parseFloat(market.outcomePrices?.[0] ?? '0.5');
721
+ const volume = parseFloat(market.volume ?? '0');
722
+ if (yesPrice < 0.05 || yesPrice > 0.95) return null;
723
+ const edge = Math.abs(yesPrice - 0.5);
724
+ const liquidityScore = Math.min(volume / 500000, 1.0);
725
+ const score = edge * 0.6 + liquidityScore * 0.4;
726
+ const outcome = yesPrice < 0.5 ? 'Yes' : 'No';
727
+ const confidence = Math.min(Math.round((0.5 + edge) * 100) / 100, 0.95);
728
+ const reasoning = \`Priced at \${(yesPrice * 100).toFixed(0)}% with $\${volume.toLocaleString()} volume\`;
729
+ return { market, outcome, side: 'BUY', confidence, reasoning, score };
730
+ })
731
+ .filter(Boolean)
732
+ .sort((a: any, b: any) => b.score - a.score)
733
+ .slice(0, opts.numProposals);
734
+
735
+ if (!scored.length) {
485
736
  console.log('No good opportunities found right now.');
486
737
  return;
487
738
  }
488
739
 
489
- const yesPrice = parseFloat(best.market.outcomePrices?.[0] ?? '0.5');
490
- console.log(' Best opportunity found:');
491
- console.log(\` \${best.market.question}\`);
492
- console.log(\` Yes: \${(yesPrice * 100).toFixed(0)}% | Volume: $\${parseFloat(best.market.volume || '0').toLocaleString()}\`);
493
- console.log(\` Play: \${best.side} \${best.outcome} | Confidence: \${(best.confidence * 100).toFixed(0)}%\`);
494
- console.log(\` Reasoning: \${best.reasoning}\`);
740
+ console.log(\`Submitting \${scored.length} proposal(s)...\\n\`);
741
+
742
+ for (const pick of scored) {
743
+ console.log(\` -> \${pick.market.question}\`);
744
+ console.log(\` BUY \${pick.outcome} | Confidence: \${(pick.confidence * 100).toFixed(0)}%\`);
745
+ console.log(\` \${pick.reasoning}\`);
746
+
747
+ const proposal = await client.submitProposal({
748
+ marketId: pick.market.id,
749
+ outcome: pick.outcome,
750
+ side: pick.side,
751
+ recommendedAmount: 10.0,
752
+ confidence: pick.confidence,
753
+ reasoning: pick.reasoning,
754
+ model: 'your-model-here',
755
+ });
756
+
757
+ if (proposal.success) {
758
+ console.log(' Submitted!\\n');
759
+ } else {
760
+ console.error(\` Error: \${proposal.error || 'Unknown'}\\n\`);
761
+ }
762
+ }
763
+
764
+ console.log('Done! Check your dashboard to review proposals.');
765
+ }
766
+
767
+ async function main() {
768
+ if (!API_KEY || !API_SECRET) {
769
+ console.error('Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env');
770
+ return;
771
+ }
772
+
773
+ const client = new PolyclawClient({ apiKey: API_KEY, apiSecret: API_SECRET, baseUrl: BASE_URL });
774
+ console.log(BANNER);
775
+ console.log(' Welcome to Polyclaw!');
776
+ console.log();
777
+ console.log(\` Your agent: \\x1b[1m${options.name}\\x1b[0m\`);
495
778
  console.log();
496
779
 
497
- // Submit proposal
498
- // Tip: Replace this logic with your own AI model for smarter predictions!
499
- // const aiResponse = await openai.chat.completions.create({ model: 'gpt-4o', ... });
500
- // const modelName = aiResponse.model; // e.g. "gpt-4o-2025-01-15"
501
- console.log('Submitting proposal...');
502
- const proposal = await client.submitProposal({
503
- marketId: best.market.id,
504
- outcome: best.outcome,
505
- side: best.side,
506
- recommendedAmount: 10.0,
507
- confidence: best.confidence,
508
- reasoning: best.reasoning,
509
- model: 'your-model-here', // Replace with your AI model name
510
- });
780
+ const tag = await askCategory('${options.name}');
781
+ const searchSize = await askSearchSize();
782
+ const numProposals = await askNumProposals();
783
+
784
+ let page = 1;
785
+ await runRound(client, { tag, searchSize, numProposals, page });
511
786
 
512
- if (proposal.success) {
513
- console.log('Proposal submitted! Check your dashboard to approve it.');
514
- } else {
515
- console.error(\`Proposal error: \${proposal.error || 'Unknown'}\`);
787
+ while (true) {
788
+ console.log();
789
+ const reply = await prompt('Press Enter for more proposals, or q to quit: ');
790
+ if (['q', 'quit', 'exit'].includes(reply)) break;
791
+ page++;
792
+ console.log();
793
+ await runRound(client, { tag, searchSize, numProposals, page });
516
794
  }
517
795
  }
518
796
 
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-polyclaw-agent",
3
- "version": "0.1.0",
3
+ "version": "0.2.2",
4
4
  "description": "Create a Polyclaw AI trading agent in seconds",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,6 +20,11 @@
20
20
  "@types/prompts": "^2.4.9",
21
21
  "typescript": "^5.4.0"
22
22
  },
23
- "keywords": ["polyclaw", "polymarket", "ai-agent", "prediction-markets"],
23
+ "keywords": [
24
+ "polyclaw",
25
+ "polymarket",
26
+ "ai-agent",
27
+ "prediction-markets"
28
+ ],
24
29
  "license": "MIT"
25
30
  }
package/src/index.ts CHANGED
@@ -15,9 +15,18 @@ import { scaffoldProject, nameToDir } from './scaffold.js';
15
15
  const LOBSTER = '\u{1F99E}';
16
16
 
17
17
  async function main() {
18
- console.log();
19
- console.log(chalk.bold(' Welcome to Polyclaw!'));
20
- console.log();
18
+ const BANNER = `
19
+ ${chalk.red(` .-----.
20
+ _ | o o | _
21
+ | | | w | | |
22
+ |_| '-----' |_|`)}
23
+
24
+ ${chalk.bold(` █▀█ █▀█ █ █ █ █▀▀ █ █▀█ █ █
25
+ █▀▀ █ █ █ █ █ █ █▀█ █ █ █
26
+ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀ ▀`)}
27
+ ${chalk.dim(' AI-Powered Prediction Market Agent')}
28
+ `;
29
+ console.log(BANNER);
21
30
 
22
31
  // Step 1: Generate and pick a name
23
32
  let agentName: string;
package/src/scaffold.ts CHANGED
@@ -63,7 +63,7 @@ function scaffoldPython(dir: string, options: ScaffoldOptions) {
63
63
  : '';
64
64
 
65
65
  const aiAnalyzeFunc = options.aiProvider === 'anthropic' ? `
66
- def analyze_markets(markets):
66
+ def analyze_markets(markets, num_proposals=5):
67
67
  """Use Claude to analyze prediction markets and pick the best bets."""
68
68
  client = anthropic.Anthropic(api_key=AI_API_KEY)
69
69
 
@@ -84,10 +84,10 @@ def analyze_markets(markets):
84
84
 
85
85
  response = client.messages.create(
86
86
  model="claude-sonnet-4-20250514",
87
- max_tokens=1024,
87
+ max_tokens=2048,
88
88
  messages=[{
89
89
  "role": "user",
90
- "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to 3 best betting opportunities.
90
+ "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to {num_proposals} best betting opportunities.
91
91
 
92
92
  Markets:
93
93
  {markets_text}
@@ -105,7 +105,7 @@ For each pick, respond in this exact JSON format (no markdown, just raw JSON arr
105
105
  ]
106
106
 
107
107
  Rules:
108
- - Pick 1-3 markets that look like good opportunities
108
+ - Pick up to {num_proposals} markets that look like good opportunities
109
109
  - Consider the current price, volume, and whether the market seems mispriced
110
110
  - Be diverse -- don't pick markets that are all about the same topic
111
111
  - Higher confidence = stronger conviction (0.5 = coin flip, 0.9 = very confident)
@@ -114,16 +114,21 @@ Rules:
114
114
  }]
115
115
  )
116
116
 
117
- # Parse the AI response
117
+ # Parse the AI response (strip markdown code fences if present)
118
118
  try:
119
- picks = json.loads(response.content[0].text)
119
+ text = response.content[0].text.strip()
120
+ if text.startswith("\`\`\`"):
121
+ text = text.split("\`\`\`", 2)[1]
122
+ if text.startswith("json"):
123
+ text = text[4:]
124
+ picks = json.loads(text.strip())
120
125
  model_name = response.model
121
126
  return picks, model_name
122
127
  except (json.JSONDecodeError, IndexError):
123
128
  print(f" AI response: {response.content[0].text}")
124
129
  return [], response.model
125
130
  ` : options.aiProvider === 'openai' ? `
126
- def analyze_markets(markets):
131
+ def analyze_markets(markets, num_proposals=5):
127
132
  """Use GPT to analyze prediction markets and pick the best bets."""
128
133
  client = openai.OpenAI(api_key=AI_API_KEY)
129
134
 
@@ -146,7 +151,7 @@ def analyze_markets(markets):
146
151
  model="gpt-4o",
147
152
  messages=[{
148
153
  "role": "user",
149
- "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to 3 best betting opportunities.
154
+ "content": f"""You are a prediction market analyst. Analyze these Polymarket markets and pick up to {num_proposals} best betting opportunities.
150
155
 
151
156
  Markets:
152
157
  {markets_text}
@@ -164,7 +169,7 @@ For each pick, respond in this exact JSON format (no markdown, just raw JSON arr
164
169
  ]
165
170
 
166
171
  Rules:
167
- - Pick 1-3 markets that look like good opportunities
172
+ - Pick up to {num_proposals} markets that look like good opportunities
168
173
  - Consider the current price, volume, and whether the market seems mispriced
169
174
  - Be diverse -- don't pick markets that are all about the same topic
170
175
  - Higher confidence = stronger conviction (0.5 = coin flip, 0.9 = very confident)
@@ -173,16 +178,21 @@ Rules:
173
178
  }],
174
179
  )
175
180
 
176
- # Parse the AI response
181
+ # Parse the AI response (strip markdown code fences if present)
177
182
  try:
178
- picks = json.loads(response.choices[0].message.content)
183
+ text = response.choices[0].message.content.strip()
184
+ if text.startswith("\`\`\`"):
185
+ text = text.split("\`\`\`", 2)[1]
186
+ if text.startswith("json"):
187
+ text = text[4:]
188
+ picks = json.loads(text.strip())
179
189
  model_name = response.model
180
190
  return picks, model_name
181
191
  except (json.JSONDecodeError, IndexError):
182
192
  print(f" AI response: {response.choices[0].message.content}")
183
193
  return [], response.model
184
194
  ` : `
185
- def analyze_markets(markets):
195
+ def analyze_markets(markets, num_proposals=5):
186
196
  """Placeholder: Add your own AI logic here to analyze markets."""
187
197
  # This is where you connect your AI model.
188
198
  # Return a list of picks in this format:
@@ -260,8 +270,14 @@ class PolyclawClient:
260
270
  response = requests.request(method, url, headers=headers, json=body)
261
271
  return response.json()
262
272
 
263
- def get_markets(self, page: int = 1, limit: int = 20):
264
- return self._request("GET", f"/api/markets?page={page}&limit={limit}")
273
+ def get_markets(self, page: int = 1, limit: int = 20, tag: str = None):
274
+ path = f"/api/markets?page={page}&limit={limit}"
275
+ if tag and tag != "all":
276
+ path += f"&tag={tag}"
277
+ return self._request("GET", path)
278
+
279
+ def get_my_proposals(self, limit: int = 100):
280
+ return self._request("GET", f"/api/proposals?limit={limit}")
265
281
 
266
282
  def submit_proposal(self, market_id, outcome, side, recommended_amount, confidence, reasoning=None, model=None):
267
283
  body = {"marketId": market_id, "outcome": outcome, "side": side,
@@ -272,35 +288,50 @@ class PolyclawClient:
272
288
 
273
289
  ${aiAnalyzeFunc}
274
290
 
275
- def main():
276
- if not API_KEY or not API_SECRET:
277
- print("Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env")
278
- return
279
- ${options.aiProvider !== 'none' ? `
280
- ai_key_name = "${options.aiProvider === 'anthropic' ? 'ANTHROPIC_API_KEY' : 'OPENAI_API_KEY'}"
281
- if not AI_API_KEY:
282
- print(f"Error: {ai_key_name} must be set in .env")
283
- return
284
- ` : ''}
285
- client = PolyclawClient(API_KEY, API_SECRET, BASE_URL)
286
- print(f"${options.name} is online!")
287
- print()
291
+ def get_proposed_market_ids(client):
292
+ """Fetch markets we've already proposed on to avoid duplicates."""
293
+ result = client.get_my_proposals(limit=100)
294
+ if not result.get("success"):
295
+ return set()
296
+ proposals = result.get("data", result.get("proposals", []))
297
+ if isinstance(proposals, dict):
298
+ proposals = proposals.get("proposals", [])
299
+ return {p.get("marketId") for p in proposals if p.get("marketId")}
300
+
301
+
302
+ def run_round(client, tag="all", search_size=20, num_proposals=5, page=1):
303
+ """Fetch markets, filter out already-proposed ones, analyze, and submit."""
304
+ category_label = tag if tag != "all" else "all topics"
288
305
 
289
- # Fetch markets
290
- print("Fetching markets from Polymarket...")
291
- result = client.get_markets(limit=20)
306
+ # Get markets we've already proposed on
307
+ print("Checking existing proposals...")
308
+ already_proposed = get_proposed_market_ids(client)
309
+ if already_proposed:
310
+ print(f" Skipping {len(already_proposed)} market(s) with existing proposals")
311
+
312
+ # Fetch markets with category filter
313
+ print(f"Scanning {search_size} {category_label} markets...")
314
+ result = client.get_markets(page=page, limit=search_size, tag=tag)
292
315
 
293
316
  if not result.get("success"):
294
317
  print(f"Error: {result.get('error', 'Unknown error')}")
295
318
  return
296
319
 
297
- markets = result.get("data", [])
298
- print(f"Found {len(markets)} markets")
320
+ all_markets = result.get("data", [])
321
+
322
+ # Filter out markets we've already proposed on
323
+ markets = [m for m in all_markets if m.get("id") not in already_proposed]
324
+ print(f"Found {len(all_markets)} markets, {len(markets)} new ones to analyze")
325
+
326
+ if not markets:
327
+ print("No new markets to analyze. Try again later or pick a different category.")
328
+ return
329
+
299
330
  print()
300
331
 
301
332
  # Ask AI to analyze and pick the best bets
302
- print("Asking AI to analyze markets...\\n")
303
- picks, model_name = analyze_markets(markets)
333
+ print(f"Asking AI to pick {num_proposals} best bets...\\n")
334
+ picks, model_name = analyze_markets(markets, num_proposals=num_proposals)
304
335
 
305
336
  if not picks:
306
337
  print("No picks from AI. Try again later.")
@@ -337,6 +368,124 @@ ${options.aiProvider !== 'none' ? `
337
368
  print("Done! Check your dashboard to review proposals.")
338
369
 
339
370
 
371
+ BANNER = """
372
+ \\033[91m .-----.
373
+ _ | o o | _
374
+ | | | w | | |
375
+ |_| '-----' |_|\\033[0m
376
+
377
+ \\033[1m █▀█ █▀█ █ █ █ █▀▀ █ █▀█ █ █
378
+ █▀▀ █ █ █ █ █ █ █▀█ █ █ █
379
+ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀ ▀\\033[0m
380
+ \\033[90m AI-Powered Prediction Market Agent\\033[0m
381
+ """
382
+
383
+
384
+ # --- Interactive prompts ---
385
+
386
+ CATEGORIES = [
387
+ ("politics", "Politics"),
388
+ ("sports", "Sports"),
389
+ ("crypto", "Crypto"),
390
+ ("finance", "Finance"),
391
+ ("tech", "Tech"),
392
+ ("culture", "Culture"),
393
+ ("all", "All topics"),
394
+ ]
395
+
396
+ SEARCH_SIZES = [20, 40, 60, 100, 200, 400]
397
+ PROPOSAL_COUNTS = [5, 10, 15]
398
+
399
+
400
+ def ask_category(agent_name):
401
+ print(f"What category would you like {agent_name} to look into?")
402
+ for i, (_, label) in enumerate(CATEGORIES, 1):
403
+ print(f" {i}. {label}")
404
+ print()
405
+ while True:
406
+ try:
407
+ choice = input("Pick a number: ").strip()
408
+ except (EOFError, KeyboardInterrupt):
409
+ return "all"
410
+ if choice.isdigit() and 1 <= int(choice) <= len(CATEGORIES):
411
+ print()
412
+ return CATEGORIES[int(choice) - 1][0]
413
+ print(f" Please enter a number between 1 and {len(CATEGORIES)}")
414
+
415
+
416
+ def ask_search_size():
417
+ print("How big do you want your search to be?")
418
+ for i, size in enumerate(SEARCH_SIZES, 1):
419
+ print(f" {i}. {size} markets")
420
+ print()
421
+ while True:
422
+ try:
423
+ choice = input("Pick a number [1]: ").strip() or "1"
424
+ except (EOFError, KeyboardInterrupt):
425
+ return SEARCH_SIZES[0]
426
+ if choice.isdigit() and 1 <= int(choice) <= len(SEARCH_SIZES):
427
+ print()
428
+ return SEARCH_SIZES[int(choice) - 1]
429
+ print(f" Please enter a number between 1 and {len(SEARCH_SIZES)}")
430
+
431
+
432
+ def ask_num_proposals():
433
+ print("How many proposals do you want?")
434
+ for i, count in enumerate(PROPOSAL_COUNTS, 1):
435
+ print(f" {i}. {count} proposals")
436
+ print()
437
+ while True:
438
+ try:
439
+ choice = input("Pick a number [1]: ").strip() or "1"
440
+ except (EOFError, KeyboardInterrupt):
441
+ return PROPOSAL_COUNTS[0]
442
+ if choice.isdigit() and 1 <= int(choice) <= len(PROPOSAL_COUNTS):
443
+ print()
444
+ return PROPOSAL_COUNTS[int(choice) - 1]
445
+ print(f" Please enter a number between 1 and {len(PROPOSAL_COUNTS)}")
446
+
447
+
448
+ # --- Main ---
449
+
450
+ def main():
451
+ if not API_KEY or not API_SECRET:
452
+ print("Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env")
453
+ return
454
+ ${options.aiProvider !== 'none' ? `
455
+ ai_key_name = "${options.aiProvider === 'anthropic' ? 'ANTHROPIC_API_KEY' : 'OPENAI_API_KEY'}"
456
+ if not AI_API_KEY:
457
+ print(f"Error: {ai_key_name} must be set in .env")
458
+ return
459
+ ` : ''}
460
+ client = PolyclawClient(API_KEY, API_SECRET, BASE_URL)
461
+ print(BANNER)
462
+ print(" Welcome to Polyclaw!")
463
+ print()
464
+ print(" Your agent: \\033[1m${options.name}\\033[0m")
465
+ print()
466
+
467
+ # Ask user preferences
468
+ tag = ask_category("${options.name}")
469
+ search_size = ask_search_size()
470
+ num_proposals = ask_num_proposals()
471
+
472
+ page = 1
473
+ run_round(client, tag=tag, search_size=search_size, num_proposals=num_proposals, page=page)
474
+
475
+ # Interactive loop
476
+ while True:
477
+ print()
478
+ try:
479
+ reply = input("Press Enter for more proposals, or q to quit: ").strip().lower()
480
+ except (EOFError, KeyboardInterrupt):
481
+ break
482
+ if reply in ("q", "quit", "exit"):
483
+ break
484
+ page += 1
485
+ print()
486
+ run_round(client, tag=tag, search_size=search_size, num_proposals=num_proposals, page=page)
487
+
488
+
340
489
  if __name__ == "__main__":
341
490
  main()
342
491
  `;
@@ -416,8 +565,14 @@ class PolyclawClient {
416
565
  return response.json() as T;
417
566
  }
418
567
 
419
- async getMarkets(page = 1, limit = 20) {
420
- return this.request<any>('GET', \`/api/markets?page=\${page}&limit=\${limit}\`);
568
+ async getMarkets(page = 1, limit = 20, tag?: string) {
569
+ let path = \`/api/markets?page=\${page}&limit=\${limit}\`;
570
+ if (tag && tag !== 'all') path += \`&tag=\${tag}\`;
571
+ return this.request<any>('GET', path);
572
+ }
573
+
574
+ async getMyProposals(limit = 100) {
575
+ return this.request<any>('GET', \`/api/proposals?limit=\${limit}\`);
421
576
  }
422
577
 
423
578
  async submitProposal(proposal: {
@@ -481,63 +636,186 @@ function findBestPlay(markets: any[]): MarketPlay | null {
481
636
  return scored[0] || null;
482
637
  }
483
638
 
484
- async function main() {
485
- if (!API_KEY || !API_SECRET) {
486
- console.error('Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env');
487
- return;
639
+ import * as readline from 'readline';
640
+
641
+ function prompt(question: string): Promise<string> {
642
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
643
+ return new Promise((resolve) => {
644
+ rl.question(question, (answer) => { rl.close(); resolve(answer.trim().toLowerCase()); });
645
+ });
646
+ }
647
+
648
+ // --- Interactive prompts ---
649
+
650
+ const BANNER = \`
651
+ \\x1b[91m .-----.
652
+ _ | o o | _
653
+ | | | w | | |
654
+ |_| '-----' |_|\\x1b[0m
655
+
656
+ \\x1b[1m █▀█ █▀█ █ █ █ █▀▀ █ █▀█ █ █
657
+ █▀▀ █ █ █ █ █ █ █▀█ █ █ █
658
+ ▀ ▀▀▀ ▀▀▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀ ▀\\x1b[0m
659
+ \\x1b[90m AI-Powered Prediction Market Agent\\x1b[0m
660
+ \`;
661
+
662
+ const CATEGORIES = [
663
+ ['politics', 'Politics'],
664
+ ['sports', 'Sports'],
665
+ ['crypto', 'Crypto'],
666
+ ['finance', 'Finance'],
667
+ ['tech', 'Tech'],
668
+ ['culture', 'Culture'],
669
+ ['all', 'All topics'],
670
+ ] as const;
671
+
672
+ const SEARCH_SIZES = [20, 40, 60, 100, 200, 400];
673
+ const PROPOSAL_COUNTS = [5, 10, 15];
674
+
675
+ async function askCategory(agentName: string): Promise<string> {
676
+ console.log(\`What category would you like \${agentName} to look into?\`);
677
+ CATEGORIES.forEach(([, label], i) => console.log(\` \${i + 1}. \${label}\`));
678
+ console.log();
679
+ while (true) {
680
+ const choice = await prompt('Pick a number: ');
681
+ const n = parseInt(choice);
682
+ if (n >= 1 && n <= CATEGORIES.length) { console.log(); return CATEGORIES[n - 1][0]; }
683
+ console.log(\` Please enter a number between 1 and \${CATEGORIES.length}\`);
488
684
  }
685
+ }
489
686
 
490
- const client = new PolyclawClient({ apiKey: API_KEY, apiSecret: API_SECRET, baseUrl: BASE_URL });
491
- console.log('${options.name} is online!');
687
+ async function askSearchSize(): Promise<number> {
688
+ console.log('How big do you want your search to be?');
689
+ SEARCH_SIZES.forEach((s, i) => console.log(\` \${i + 1}. \${s} markets\`));
690
+ console.log();
691
+ while (true) {
692
+ const choice = (await prompt('Pick a number [1]: ')) || '1';
693
+ const n = parseInt(choice);
694
+ if (n >= 1 && n <= SEARCH_SIZES.length) { console.log(); return SEARCH_SIZES[n - 1]; }
695
+ console.log(\` Please enter a number between 1 and \${SEARCH_SIZES.length}\`);
696
+ }
697
+ }
698
+
699
+ async function askNumProposals(): Promise<number> {
700
+ console.log('How many proposals do you want?');
701
+ PROPOSAL_COUNTS.forEach((c, i) => console.log(\` \${i + 1}. \${c} proposals\`));
492
702
  console.log();
703
+ while (true) {
704
+ const choice = (await prompt('Pick a number [1]: ')) || '1';
705
+ const n = parseInt(choice);
706
+ if (n >= 1 && n <= PROPOSAL_COUNTS.length) { console.log(); return PROPOSAL_COUNTS[n - 1]; }
707
+ console.log(\` Please enter a number between 1 and \${PROPOSAL_COUNTS.length}\`);
708
+ }
709
+ }
493
710
 
494
- // Fetch markets
495
- console.log('Scanning markets...');
496
- const result = await client.getMarkets(1, 20);
711
+ async function getProposedMarketIds(client: PolyclawClient): Promise<Set<string>> {
712
+ const result = await client.getMyProposals(100);
713
+ if (!result.success) return new Set();
714
+ const proposals = Array.isArray(result.data) ? result.data : (result.data?.proposals || []);
715
+ return new Set(proposals.map((p: any) => p.marketId).filter(Boolean));
716
+ }
717
+
718
+ async function runRound(client: PolyclawClient, opts: { tag: string; searchSize: number; numProposals: number; page: number }) {
719
+ const categoryLabel = opts.tag !== 'all' ? opts.tag : 'all topics';
720
+
721
+ console.log('Checking existing proposals...');
722
+ const alreadyProposed = await getProposedMarketIds(client);
723
+ if (alreadyProposed.size) console.log(\` Skipping \${alreadyProposed.size} market(s) with existing proposals\`);
724
+
725
+ console.log(\`Scanning \${opts.searchSize} \${categoryLabel} markets...\`);
726
+ const result = await client.getMarkets(opts.page, opts.searchSize, opts.tag);
497
727
 
498
728
  if (!result.success) {
499
729
  console.error(\`Error: \${result.error || 'Unknown error'}\`);
500
730
  return;
501
731
  }
502
732
 
503
- const markets = result.data || [];
504
- console.log(\`Analyzing \${markets.length} markets...\\n\`);
733
+ const allMarkets = result.data || [];
734
+ const markets = allMarkets.filter((m: any) => !alreadyProposed.has(m.id));
735
+ console.log(\`Found \${allMarkets.length} markets, \${markets.length} new ones to analyze\\n\`);
505
736
 
506
- // Find the best play
507
- const best = findBestPlay(markets);
737
+ if (!markets.length) {
738
+ console.log('No new markets to analyze. Try again later or pick a different category.');
739
+ return;
740
+ }
508
741
 
509
- if (!best) {
742
+ // Find top plays using the scoring heuristic
743
+ const scored = markets
744
+ .map((market: any) => {
745
+ const yesPrice = parseFloat(market.outcomePrices?.[0] ?? '0.5');
746
+ const volume = parseFloat(market.volume ?? '0');
747
+ if (yesPrice < 0.05 || yesPrice > 0.95) return null;
748
+ const edge = Math.abs(yesPrice - 0.5);
749
+ const liquidityScore = Math.min(volume / 500000, 1.0);
750
+ const score = edge * 0.6 + liquidityScore * 0.4;
751
+ const outcome = yesPrice < 0.5 ? 'Yes' : 'No';
752
+ const confidence = Math.min(Math.round((0.5 + edge) * 100) / 100, 0.95);
753
+ const reasoning = \`Priced at \${(yesPrice * 100).toFixed(0)}% with $\${volume.toLocaleString()} volume\`;
754
+ return { market, outcome, side: 'BUY', confidence, reasoning, score };
755
+ })
756
+ .filter(Boolean)
757
+ .sort((a: any, b: any) => b.score - a.score)
758
+ .slice(0, opts.numProposals);
759
+
760
+ if (!scored.length) {
510
761
  console.log('No good opportunities found right now.');
511
762
  return;
512
763
  }
513
764
 
514
- const yesPrice = parseFloat(best.market.outcomePrices?.[0] ?? '0.5');
515
- console.log(' Best opportunity found:');
516
- console.log(\` \${best.market.question}\`);
517
- console.log(\` Yes: \${(yesPrice * 100).toFixed(0)}% | Volume: $\${parseFloat(best.market.volume || '0').toLocaleString()}\`);
518
- console.log(\` Play: \${best.side} \${best.outcome} | Confidence: \${(best.confidence * 100).toFixed(0)}%\`);
519
- console.log(\` Reasoning: \${best.reasoning}\`);
765
+ console.log(\`Submitting \${scored.length} proposal(s)...\\n\`);
766
+
767
+ for (const pick of scored) {
768
+ console.log(\` -> \${pick.market.question}\`);
769
+ console.log(\` BUY \${pick.outcome} | Confidence: \${(pick.confidence * 100).toFixed(0)}%\`);
770
+ console.log(\` \${pick.reasoning}\`);
771
+
772
+ const proposal = await client.submitProposal({
773
+ marketId: pick.market.id,
774
+ outcome: pick.outcome,
775
+ side: pick.side,
776
+ recommendedAmount: 10.0,
777
+ confidence: pick.confidence,
778
+ reasoning: pick.reasoning,
779
+ model: 'your-model-here',
780
+ });
781
+
782
+ if (proposal.success) {
783
+ console.log(' Submitted!\\n');
784
+ } else {
785
+ console.error(\` Error: \${proposal.error || 'Unknown'}\\n\`);
786
+ }
787
+ }
788
+
789
+ console.log('Done! Check your dashboard to review proposals.');
790
+ }
791
+
792
+ async function main() {
793
+ if (!API_KEY || !API_SECRET) {
794
+ console.error('Error: POLYCLAW_API_KEY and POLYCLAW_API_SECRET must be set in .env');
795
+ return;
796
+ }
797
+
798
+ const client = new PolyclawClient({ apiKey: API_KEY, apiSecret: API_SECRET, baseUrl: BASE_URL });
799
+ console.log(BANNER);
800
+ console.log(' Welcome to Polyclaw!');
801
+ console.log();
802
+ console.log(\` Your agent: \\x1b[1m${options.name}\\x1b[0m\`);
520
803
  console.log();
521
804
 
522
- // Submit proposal
523
- // Tip: Replace this logic with your own AI model for smarter predictions!
524
- // const aiResponse = await openai.chat.completions.create({ model: 'gpt-4o', ... });
525
- // const modelName = aiResponse.model; // e.g. "gpt-4o-2025-01-15"
526
- console.log('Submitting proposal...');
527
- const proposal = await client.submitProposal({
528
- marketId: best.market.id,
529
- outcome: best.outcome,
530
- side: best.side,
531
- recommendedAmount: 10.0,
532
- confidence: best.confidence,
533
- reasoning: best.reasoning,
534
- model: 'your-model-here', // Replace with your AI model name
535
- });
805
+ const tag = await askCategory('${options.name}');
806
+ const searchSize = await askSearchSize();
807
+ const numProposals = await askNumProposals();
536
808
 
537
- if (proposal.success) {
538
- console.log('Proposal submitted! Check your dashboard to approve it.');
539
- } else {
540
- console.error(\`Proposal error: \${proposal.error || 'Unknown'}\`);
809
+ let page = 1;
810
+ await runRound(client, { tag, searchSize, numProposals, page });
811
+
812
+ while (true) {
813
+ console.log();
814
+ const reply = await prompt('Press Enter for more proposals, or q to quit: ');
815
+ if (['q', 'quit', 'exit'].includes(reply)) break;
816
+ page++;
817
+ console.log();
818
+ await runRound(client, { tag, searchSize, numProposals, page });
541
819
  }
542
820
  }
543
821