@quantish/agent 0.1.46 → 0.1.47

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.
Files changed (3) hide show
  1. package/LICENSE +2 -0
  2. package/dist/index.js +162 -72
  3. package/package.json +1 -1
package/LICENSE CHANGED
@@ -142,3 +142,5 @@ please contact Quantish Inc. for a commercial license:
142
142
 
143
143
  Email: hello@quantish.live
144
144
  Website: https://quantish.live
145
+
146
+
package/dist/index.js CHANGED
@@ -1052,6 +1052,65 @@ async function fileExists(filePath) {
1052
1052
  return { success: false, error: `Failed to check file: ${error2 instanceof Error ? error2.message : String(error2)}` };
1053
1053
  }
1054
1054
  }
1055
+ async function workspaceSummary(dirPath, options) {
1056
+ const maxDepth = options?.maxDepth ?? 3;
1057
+ const maxFiles = options?.maxFiles ?? 100;
1058
+ try {
1059
+ const resolvedPath = path.resolve(dirPath);
1060
+ if (!existsSync(resolvedPath)) {
1061
+ return { success: false, error: `Directory not found: ${dirPath}` };
1062
+ }
1063
+ const tree = [];
1064
+ let fileCount = 0;
1065
+ let dirCount = 0;
1066
+ const skipDirs = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".next", "__pycache__", "venv", ".venv", "target"]);
1067
+ async function walkDir(currentPath, prefix, depth) {
1068
+ if (depth > maxDepth || fileCount >= maxFiles) return;
1069
+ const entries = await fs.readdir(currentPath, { withFileTypes: true });
1070
+ entries.sort((a, b) => {
1071
+ if (a.isDirectory() === b.isDirectory()) return a.name.localeCompare(b.name);
1072
+ return a.isDirectory() ? -1 : 1;
1073
+ });
1074
+ for (let i = 0; i < entries.length && fileCount < maxFiles; i++) {
1075
+ const entry = entries[i];
1076
+ const isLast = i === entries.length - 1;
1077
+ const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
1078
+ const newPrefix = isLast ? prefix + " " : prefix + "\u2502 ";
1079
+ if (entry.isDirectory()) {
1080
+ if (skipDirs.has(entry.name)) {
1081
+ tree.push(`${prefix}${connector}${entry.name}/ (skipped)`);
1082
+ } else {
1083
+ dirCount++;
1084
+ tree.push(`${prefix}${connector}${entry.name}/`);
1085
+ await walkDir(path.join(currentPath, entry.name), newPrefix, depth + 1);
1086
+ }
1087
+ } else {
1088
+ fileCount++;
1089
+ const filePath = path.join(currentPath, entry.name);
1090
+ const stats = await fs.stat(filePath);
1091
+ const size = stats.size < 1024 ? `${stats.size}B` : stats.size < 1024 * 1024 ? `${Math.round(stats.size / 1024)}KB` : `${Math.round(stats.size / (1024 * 1024))}MB`;
1092
+ tree.push(`${prefix}${connector}${entry.name} (${size})`);
1093
+ }
1094
+ }
1095
+ }
1096
+ tree.push(path.basename(resolvedPath) + "/");
1097
+ await walkDir(resolvedPath, "", 1);
1098
+ return {
1099
+ success: true,
1100
+ data: {
1101
+ path: resolvedPath,
1102
+ tree: tree.join("\n"),
1103
+ stats: {
1104
+ totalFiles: fileCount,
1105
+ totalDirectories: dirCount,
1106
+ truncated: fileCount >= maxFiles
1107
+ }
1108
+ }
1109
+ };
1110
+ } catch (error2) {
1111
+ return { success: false, error: `Failed to summarize workspace: ${error2 instanceof Error ? error2.message : String(error2)}` };
1112
+ }
1113
+ }
1055
1114
  async function editFile(filePath, oldString, newString, options) {
1056
1115
  try {
1057
1116
  const resolvedPath = path.resolve(filePath);
@@ -1194,6 +1253,35 @@ var filesystemTools = [
1194
1253
  },
1195
1254
  required: ["path", "old_string", "new_string"]
1196
1255
  }
1256
+ },
1257
+ {
1258
+ name: "workspace_summary",
1259
+ description: `Get a tree-view summary of a directory. Perfect for understanding project structure after scaffolding or cloning.
1260
+
1261
+ Automatically skips: node_modules, .git, dist, build, .next, __pycache__, venv
1262
+
1263
+ Shows file sizes and provides a quick overview. Use this after:
1264
+ - Running npx create-react-app, npm create vite, etc.
1265
+ - Cloning a repo
1266
+ - Any command that creates multiple files`,
1267
+ input_schema: {
1268
+ type: "object",
1269
+ properties: {
1270
+ path: {
1271
+ type: "string",
1272
+ description: "The directory path to summarize"
1273
+ },
1274
+ max_depth: {
1275
+ type: "number",
1276
+ description: "Optional: Maximum depth to traverse (default: 3)"
1277
+ },
1278
+ max_files: {
1279
+ type: "number",
1280
+ description: "Optional: Maximum files to show (default: 100)"
1281
+ }
1282
+ },
1283
+ required: ["path"]
1284
+ }
1197
1285
  }
1198
1286
  ];
1199
1287
  async function executeFilesystemTool(name, args) {
@@ -1218,6 +1306,11 @@ async function executeFilesystemTool(name, args) {
1218
1306
  args.new_string,
1219
1307
  { replaceAll: args.replace_all }
1220
1308
  );
1309
+ case "workspace_summary":
1310
+ return workspaceSummary(args.path, {
1311
+ maxDepth: args.max_depth,
1312
+ maxFiles: args.max_files
1313
+ });
1221
1314
  default:
1222
1315
  return { success: false, error: `Unknown filesystem tool: ${name}` };
1223
1316
  }
@@ -1434,15 +1527,40 @@ var PACKAGE_MANAGER_PATTERNS = [
1434
1527
  /^cargo\s+(build|install)/,
1435
1528
  /^go\s+(build|get|mod)/
1436
1529
  ];
1530
+ var SCAFFOLDING_PATTERNS = [
1531
+ /^npx\s+(--yes\s+)?create-/,
1532
+ // npx create-react-app, npx create-next-app
1533
+ /^npx\s+(--yes\s+)?@\w+\/create-/,
1534
+ // npx @vue/create-app, etc.
1535
+ /^bunx\s+create-/,
1536
+ // bunx create-react-app
1537
+ /^pnpm\s+(dlx\s+)?create-/,
1538
+ // pnpm create vite
1539
+ /^npm\s+create\s+/,
1540
+ // npm create vite@latest
1541
+ /^yarn\s+create\s+/,
1542
+ // yarn create react-app
1543
+ /^npx\s+degit/,
1544
+ // npx degit for templates
1545
+ /^npx\s+(--yes\s+)?(vite|astro|nuxt|remix|svelte)/
1546
+ // Direct scaffolding
1547
+ ];
1437
1548
  var LONG_RUNNING_PATTERNS = [
1438
1549
  /^(npm|yarn|pnpm|bun)\s+(build|test|run)/,
1439
1550
  /webpack|vite|esbuild|rollup/,
1440
- /docker\s+(build|pull|push)/
1551
+ /docker\s+(build|pull|push)/,
1552
+ /^npx\s+/
1553
+ // Most npx commands need more time than 30s default
1441
1554
  ];
1442
1555
  function getSmartTimeout(command, explicitTimeout) {
1443
1556
  if (explicitTimeout !== void 0) {
1444
1557
  return explicitTimeout;
1445
1558
  }
1559
+ for (const pattern of SCAFFOLDING_PATTERNS) {
1560
+ if (pattern.test(command)) {
1561
+ return 6e5;
1562
+ }
1563
+ }
1446
1564
  for (const pattern of PACKAGE_MANAGER_PATTERNS) {
1447
1565
  if (pattern.test(command)) {
1448
1566
  return 3e5;
@@ -1602,7 +1720,19 @@ async function findFiles(pattern, directory = ".") {
1602
1720
  var shellTools = [
1603
1721
  {
1604
1722
  name: "run_command",
1605
- description: "Execute a shell command on the local machine. Returns stdout, stderr, and exit code. Some dangerous commands are blocked for safety. Supports compound commands (&&, ||). Smart timeout: 5 min for npm/yarn install, 3 min for builds, 30s default. For dev servers or long-running processes, use start_background_process instead.",
1723
+ description: `Execute a shell command on the local machine. Returns stdout, stderr, and exit code.
1724
+
1725
+ SMART TIMEOUTS (auto-detected):
1726
+ - 10 min: npx create-react-app, npm create vite, etc (scaffolding)
1727
+ - 5 min: npm install, yarn add, pip install (package installs)
1728
+ - 3 min: npm build, webpack, docker build (build commands)
1729
+ - 30 sec: all other commands
1730
+
1731
+ BEST PRACTICES:
1732
+ - For dev servers (npm start, npm run dev), use start_background_process instead
1733
+ - After creating a project, use list_dir to verify the files were created
1734
+ - Add --yes to npx commands to skip prompts (e.g., "npx --yes create-react-app myapp")
1735
+ - Compound commands (&&, ||, |) are supported`,
1606
1736
  input_schema: {
1607
1737
  type: "object",
1608
1738
  properties: {
@@ -1616,7 +1746,7 @@ var shellTools = [
1616
1746
  },
1617
1747
  timeout: {
1618
1748
  type: "number",
1619
- description: "Optional: Timeout in milliseconds. Smart defaults: 300000 for npm install, 180000 for builds, 30000 for quick commands."
1749
+ description: "Optional: Override timeout in milliseconds. Usually not needed - smart defaults handle most cases."
1620
1750
  }
1621
1751
  },
1622
1752
  required: ["command"]
@@ -1668,7 +1798,20 @@ var shellTools = [
1668
1798
  },
1669
1799
  {
1670
1800
  name: "start_background_process",
1671
- description: "Start a long-running process (like a dev server) in the background. The process runs independently and its output is captured. Returns a process ID that can be used to stop it later. Use this for: npm start, npm run dev, python servers, watch mode commands, etc.",
1801
+ description: `Start a long-running process in the background. Returns immediately with a process ID.
1802
+
1803
+ USE THIS FOR (runs indefinitely):
1804
+ - Dev servers: npm start, npm run dev, yarn dev
1805
+ - Watch modes: npm run watch, tsc --watch
1806
+ - Local servers: python -m http.server, serve -s build
1807
+ - Database servers: mongod, redis-server
1808
+
1809
+ DO NOT USE FOR (use run_command instead):
1810
+ - One-time installs: npm install, pip install
1811
+ - Project scaffolding: npx create-react-app
1812
+ - Build commands: npm run build
1813
+
1814
+ Returns a process ID to use with stop_process and get_process_output.`,
1672
1815
  input_schema: {
1673
1816
  type: "object",
1674
1817
  properties: {
@@ -3570,7 +3713,10 @@ var ACTIONABLE_FIELDS = /* @__PURE__ */ new Set([
3570
3713
  "status",
3571
3714
  "endDate",
3572
3715
  // Platform (for multi-platform support)
3573
- "platform"
3716
+ "platform",
3717
+ // Nested structures containing price data (Discovery MCP response)
3718
+ "markets",
3719
+ "outcomes"
3574
3720
  ]);
3575
3721
  var SUMMARY_FIELDS = /* @__PURE__ */ new Set([
3576
3722
  "volume",
@@ -3643,81 +3789,25 @@ function extractTokenInfo(token) {
3643
3789
  price: token.price ?? token.probability
3644
3790
  };
3645
3791
  }
3646
- var DEFAULT_SYSTEM_PROMPT = `You are Quantish, an AI trading agent for prediction markets.
3647
-
3648
- ## \u26A0\uFE0F MANDATORY TABLE FORMAT - READ THIS FIRST \u26A0\uFE0F
3649
-
3650
- When displaying market search results, you MUST include PRICES in your table. The data is in the response - extract it!
3651
-
3652
- Response structure: markets[].markets[].outcomes[] contains { name: "Yes"/"No", price: 0.05, probability: "5%" }
3653
-
3654
- REQUIRED table format:
3655
- | Market | Yes | No | Volume | End Date |
3656
- | Will X happen? | 5\xA2 (5%) | 95\xA2 (95%) | $1.2M | Jan 1 |
3657
-
3658
- DO NOT show tables without prices. The user needs prices to make trading decisions.
3659
-
3660
- ## Efficient Market Searching
3792
+ var DEFAULT_SYSTEM_PROMPT = `You are Quantish, an AI trading agent for prediction markets (Polymarket, Kalshi).
3661
3793
 
3662
- When user asks to find markets:
3663
- 1. Call search_markets ONCE with a good query
3664
- 2. Present results in the REQUIRED table format above (with prices!)
3665
- 3. STOP. Wait for user to ask for more.
3794
+ You have tools to search markets and place trades. When showing market data, display ALL relevant information from the response including prices/probabilities.
3666
3795
 
3667
- **DO NOT** make multiple searches or call get_market_details on every result.
3668
- search_markets already returns prices, volume, resolution criteria, and outcome probabilities.
3796
+ ## Building Applications
3669
3797
 
3670
- ## Tools Available
3798
+ When asked to create applications or projects:
3671
3799
 
3672
- **Discovery MCP** (market data - prices included):
3673
- - search_markets(query, limit=10) \u2192 Markets WITH prices from Polymarket/Kalshi/Limitless
3674
- - get_market_details(platform, marketId) \u2192 Full details WITH prices for ONE market
3675
- - get_trending_markets(limit=10) \u2192 Hot markets by volume
3800
+ 1. **Use run_command for scaffolding** - Commands like \`npx create-react-app\` or \`npm create vite\` are automatically given 10 minutes to complete. Always add \`--yes\` flag to skip prompts.
3676
3801
 
3677
- **Polymarket Trading** (requires conditionId from Discovery results):
3678
- - place_order, cancel_order, get_orders, get_positions, get_balances
3679
- - get_price(tokenId) \u2192 Live price (only if you need real-time, Discovery already has prices)
3680
- - get_orderbook(tokenId) \u2192 Bid/ask depth
3802
+ 2. **Verify after creation** - After scaffolding completes, use \`workspace_summary\` to see the file tree and confirm the project was created correctly.
3681
3803
 
3682
- NOTE: Don't use get_market - use get_market_details from Discovery instead.
3804
+ 3. **Use start_background_process for dev servers** - After the app is built, use this for \`npm start\`, \`npm run dev\`, etc. These run indefinitely until stopped.
3683
3805
 
3684
- **Kalshi Trading** (via DFlow):
3685
- - kalshi_buy_yes, kalshi_buy_no, kalshi_get_positions, kalshi_get_balances
3806
+ 4. **Read files before editing** - Always use \`read_file\` before \`edit_file\` to understand the existing code structure.
3686
3807
 
3687
- **Coding Tools** (for building apps/bots):
3688
- - read_file, write_file, edit_file, list_dir, grep, find_files
3689
- - run_command (blocking) - for npm install, build commands
3690
- - start_background_process (non-blocking) - for dev servers, watch mode
3691
- - get_process_output, list_processes, stop_process
3692
- - git operations: status, diff, add, commit
3808
+ 5. **Test incrementally** - After making changes, run the app and verify it works before making more changes.
3693
3809
 
3694
- ## CRITICAL: File Operations
3695
-
3696
- **NEVER repeat the same operation.** If write_file or edit_file fails:
3697
- 1. Stop and tell the user what went wrong
3698
- 2. Do NOT retry with the same content
3699
- 3. Do NOT delete and rewrite - use edit_file to fix specific issues
3700
-
3701
- When writing code files:
3702
- - Write complete, valid code (not JSON-escaped strings)
3703
- - Create one file at a time, verify it works
3704
- - If you get stuck, ask the user for help
3705
-
3706
- ## Building Trading Bots
3707
-
3708
- When user wants to build an app or bot:
3709
- 1. Create files one at a time with write_file
3710
- 2. The MCP servers are HTTP APIs - apps can call them directly
3711
- 3. Use start_background_process for dev servers
3712
- 4. API endpoints:
3713
- - Discovery: https://discovery-mcp-production.up.railway.app (read-only, public)
3714
- - Trading: https://quantish-mcp-production.up.railway.app (requires API key)
3715
-
3716
- ## Prices
3717
- - Polymarket: 0.01-0.99 (probability)
3718
- - Kalshi: percentages like 5% YES
3719
-
3720
- Be concise. Present results clearly. Wait for user input.`;
3810
+ Be concise and helpful.`;
3721
3811
  var Agent = class _Agent {
3722
3812
  anthropic;
3723
3813
  llmProvider;
@@ -4018,7 +4108,7 @@ ${userMessage}`;
4018
4108
  return this.runWithProvider(userMessage);
4019
4109
  }
4020
4110
  const maxIterations = this.config.maxIterations ?? 15;
4021
- const model = this.config.model ?? (this.config.provider === "openrouter" ? "z-ai/glm-4.7" : "claude-sonnet-4-5-20250929");
4111
+ const model = this.config.model ?? "claude-sonnet-4-5-20250929";
4022
4112
  const maxTokens = this.config.maxTokens ?? 8192;
4023
4113
  const systemPrompt = this.config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
4024
4114
  const useStreaming = this.config.streaming ?? true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantish/agent",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "description": "AI-powered agent for trading on Polymarket and Kalshi",
5
5
  "type": "module",
6
6
  "bin": {