walidsobhie-code commited on
Commit
5f0fbdd
·
1 Parent(s): 3bc915b

Address critical gaps: 1) Create comprehensive TOOLS.md with all 38 tools including parameters, examples, and JSON schema. 2) Fix get_tool_schemas() to auto-generate accurate schemas using inspect. 3) Fix architecture diagram alignment in ARCHITECTURE.md. 4) Remove vague 'autonomous sub-agents' claim from README; clarify enhancement sourcing. Verified cloud deployment scripts (RunPod/Vast) exist and are documented in stack-2.9-deploy/README.md.

Browse files
Files changed (4) hide show
  1. README.md +1 -1
  2. TOOLS.md +828 -0
  3. stack-2.9-docs/ARCHITECTURE.md +5 -5
  4. stack_cli/tools.py +89 -34
README.md CHANGED
@@ -48,7 +48,7 @@ These scores were therefore **unverifiable** and potentially misleading.
48
 
49
  We are rebuilding the evaluation infrastructure with proper methodology:
50
 
51
- **🔬 Recent Enhancement**: This release's documentation improvements, OpenRouter integration, tool system documentation, and evaluation audit were performed by autonomous sub-agents. See [EVALUATION.md](EVALUATION.md) for details.
52
 
53
  1. **Official datasets**: HumanEval (164 problems), MBPP (500 problems)
54
  2. **Reproducible runs**: Full logs, config files, and per-problem results
 
48
 
49
  We are rebuilding the evaluation infrastructure with proper methodology:
50
 
51
+ **🔬 Recent Enhancement**: This release includes comprehensive documentation improvements, OpenRouter integration, complete tool reference (TOOLS.md), and a full evaluation audit. See [EVALUATION.md](EVALUATION.md) for details.
52
 
53
  1. **Official datasets**: HumanEval (164 problems), MBPP (500 problems)
54
  2. **Reproducible runs**: Full logs, config files, and per-problem results
TOOLS.md ADDED
@@ -0,0 +1,828 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stack 2.9 - Complete Tools Reference
2
+
3
+ Stack 2.9 provides **38 built-in tools** for file operations, git, code execution, web requests, memory, and task management. This document provides the complete reference with actual parameter names, types, and usage examples.
4
+
5
+ ---
6
+
7
+ ## Tool Calling Format
8
+
9
+ Tools are called using a JSON-based function calling format. The agent automatically selects tools based on user intent, but you can also call them directly via the agent API.
10
+
11
+ ### Example Tool Call
12
+
13
+ ```json
14
+ {
15
+ "tool": "read",
16
+ "params": {
17
+ "path": "/path/to/file.py"
18
+ },
19
+ "id": "call_123"
20
+ }
21
+ ```
22
+
23
+ ### Return Format
24
+
25
+ All tools return a JSON-serializable dict:
26
+
27
+ ```json
28
+ {
29
+ "success": true|false,
30
+ "result": <tool-specific result data>,
31
+ "error": <error message if failed>
32
+ }
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Complete Tool Catalog
38
+
39
+ ### 1. File Operations
40
+
41
+ #### `read`
42
+ Read file contents with optional pagination.
43
+ - **Parameters:**
44
+ - `path` (string, required) - Path to the file
45
+ - `offset` (integer, optional, default: 0) - Line number to start from (0-indexed)
46
+ - `limit` (integer, optional, default: -1) - Maximum lines to read (-1 = all)
47
+ - **Returns:** `{success, content, total_lines, path}`
48
+
49
+ **Example:**
50
+ ```json
51
+ {
52
+ "tool": "read",
53
+ "params": {"path": "stack_cli/cli.py", "limit": 50}
54
+ }
55
+ ```
56
+
57
+ #### `write`
58
+ Write content to a file (overwrites by default).
59
+ - **Parameters:**
60
+ - `path` (string, required) - Destination file path
61
+ - `content` (string, required) - Content to write
62
+ - `append` (boolean, optional, default: false) - Append instead of overwrite
63
+ - **Returns:** `{success, path, lines_written}`
64
+
65
+ **Example:**
66
+ ```json
67
+ {
68
+ "tool": "write",
69
+ "params": {
70
+ "path": "output.txt",
71
+ "content": "Hello, World!",
72
+ "append": false
73
+ }
74
+ }
75
+ ```
76
+
77
+ #### `edit`
78
+ Replace exact text in a file (single occurrence).
79
+ - **Parameters:**
80
+ - `path` (string, required) - File to edit
81
+ - `old_text` (string, required) - Text to find and replace
82
+ - `new_text` (string, required) - Replacement text
83
+ - **Returns:** `{success, path, edits_made}`
84
+
85
+ **Example:**
86
+ ```json
87
+ {
88
+ "tool": "edit",
89
+ "params": {
90
+ "path": "config.yaml",
91
+ "old_text": "debug: false",
92
+ "new_text": "debug: true"
93
+ }
94
+ }
95
+ ```
96
+
97
+ #### `search`
98
+ Recursively search for files matching a glob pattern.
99
+ - **Parameters:**
100
+ - `path` (string, required) - Directory to search in
101
+ - `pattern` (string, required) - Glob pattern (e.g., `"*.py"`, `"**/*.md"`)
102
+ - `exclude` (array of strings, optional) - Paths to exclude
103
+ - **Returns:** `{success, matches, count}`
104
+
105
+ **Example:**
106
+ ```json
107
+ {
108
+ "tool": "search",
109
+ "params": {
110
+ "path": ".",
111
+ "pattern": "**/*.py",
112
+ "exclude": ["__pycache__", "node_modules"]
113
+ }
114
+ }
115
+ ```
116
+
117
+ #### `grep`
118
+ Search for regex pattern across files with optional context.
119
+ - **Parameters:**
120
+ - `path` (string, required) - File or directory to search
121
+ - `pattern` (string, required) - Regular expression pattern
122
+ - `context` (integer, optional, default: 0) - Lines of context before/after
123
+ - **Returns:** `{success, matches, count}` where each match has `{file, line, content, context?}`
124
+
125
+ **Example:**
126
+ ```json
127
+ {
128
+ "tool": "grep",
129
+ "params": {
130
+ "path": "stack_cli",
131
+ "pattern": "def tool_",
132
+ "context": 2
133
+ }
134
+ }
135
+ ```
136
+
137
+ #### `copy`
138
+ Copy file or directory (recursive for directories).
139
+ - **Parameters:**
140
+ - `source` (string, required) - Source path
141
+ - `destination` (string, required) - Destination path
142
+ - **Returns:** `{success, source, destination}`
143
+
144
+ **Example:**
145
+ ```json
146
+ {
147
+ "tool": "copy",
148
+ "params": {
149
+ "source": "config.example.yaml",
150
+ "destination": "config.yaml"
151
+ }
152
+ }
153
+ ```
154
+
155
+ #### `move`
156
+ Move or rename file/directory.
157
+ - **Parameters:**
158
+ - `source` (string, required) - Current path
159
+ - `destination` (string, required) - New path
160
+ - **Returns:** `{success, source, destination}`
161
+
162
+ **Example:**
163
+ ```json
164
+ {
165
+ "tool": "move",
166
+ "params": {
167
+ "source": "old_name.py",
168
+ "destination": "new_name.py"
169
+ }
170
+ }
171
+ ```
172
+
173
+ #### `delete`
174
+ Delete file or directory (requires force=True for safety).
175
+ - **Parameters:**
176
+ - `path` (string, required) - Path to delete
177
+ - `force` (boolean, optional, default: false) - Actually delete when true
178
+ - **Returns:** `{success, deleted/would_delete, warning?}`
179
+
180
+ **Example:**
181
+ ```json
182
+ {
183
+ "tool": "delete",
184
+ "params": {
185
+ "path": "obsolete_file.txt",
186
+ "force": true
187
+ }
188
+ }
189
+ ```
190
+
191
+ ---
192
+
193
+ ### 2. Git Operations
194
+
195
+ #### `git_status`
196
+ Get git repository status (porcelain format).
197
+ - **Parameters:**
198
+ - `repo_path` (string, optional, default: ".") - Repository root
199
+ - **Returns:** `{success, files, count, repo}`
200
+
201
+ **Example:**
202
+ ```json
203
+ {
204
+ "tool": "git_status",
205
+ "params": {"repo_path": "."}
206
+ }
207
+ ```
208
+
209
+ #### `git_commit`
210
+ Stage changes and create a commit.
211
+ - **Parameters:**
212
+ - `repo_path` (string, optional, default: ".") - Repository root
213
+ - `message` (string, required) - Commit message
214
+ - `files` (array of strings, optional) - Specific files to stage (stages all if omitted)
215
+ - **Returns:** `{success, message, output}`
216
+
217
+ **Example:**
218
+ ```json
219
+ {
220
+ "tool": "git_commit",
221
+ "params": {
222
+ "repo_path": ".",
223
+ "message": "feat: add new tool documentation",
224
+ "files": ["TOOLS.md", "docs/tools.md"]
225
+ }
226
+ }
227
+ ```
228
+
229
+ #### `git_push`
230
+ Push commits to remote repository.
231
+ - **Parameters:**
232
+ - `repo_path` (string, optional, default: ".") - Repository root
233
+ - `remote` (string, optional, default: "origin") - Remote name
234
+ - `branch` (string, optional) - Branch name (pushes current branch if omitted)
235
+ - **Returns:** `{success, remote, branch, output}`
236
+
237
+ **Example:**
238
+ ```json
239
+ {
240
+ "tool": "git_push",
241
+ "params": {
242
+ "repo_path": ".",
243
+ "remote": "origin",
244
+ "branch": "main"
245
+ }
246
+ }
247
+ ```
248
+
249
+ #### `git_pull`
250
+ Pull changes from remote.
251
+ - **Parameters:**
252
+ - `repo_path` (string, optional, default: ".") - Repository root
253
+ - `remote` (string, optional, default: "origin") - Remote name
254
+ - `branch` (string, optional) - Branch name (pulls current branch if omitted)
255
+ - **Returns:** `{success, remote, branch, output}`
256
+
257
+ **Example:**
258
+ ```json
259
+ {
260
+ "tool": "git_pull",
261
+ "params": {
262
+ "repo_path": ".",
263
+ "remote": "origin"
264
+ }
265
+ }
266
+ ```
267
+
268
+ #### `git_branch`
269
+ List, create, or delete branches.
270
+ - **Parameters (mutually exclusive):**
271
+ - `repo_path` (string, optional, default: ".")
272
+ - `create` (string, optional) - Create and checkout new branch
273
+ - `delete` (string, optional) - Delete branch
274
+ - **Returns:** `{success, branches?, count?, created?, deleted?}`
275
+
276
+ **Examples:**
277
+ ```json
278
+ // List branches
279
+ {"tool": "git_branch", "params": {"repo_path": "."}}
280
+
281
+ // Create branch
282
+ {"tool": "git_branch", "params": {"create": "feature/new-docs"}}
283
+
284
+ // Delete branch
285
+ {"tool": "git_branch", "params": {"delete": "old-branch"}}
286
+ ```
287
+
288
+ #### `git_log`
289
+ View commit history.
290
+ - **Parameters:**
291
+ - `repo_path` (string, optional, default: ".")
292
+ - `limit` (integer, optional, default: 10) - Maximum commits
293
+ - **Returns:** `{success, commits, count}`
294
+
295
+ **Example:**
296
+ ```json
297
+ {
298
+ "tool": "git_log",
299
+ "params": {"repo_path": ".", "limit": 20}
300
+ }
301
+ ```
302
+
303
+ #### `git_diff`
304
+ Show changes between commits or working tree.
305
+ - **Parameters:**
306
+ - `repo_path` (string, optional, default: ".")
307
+ - `file` (string, optional) - Specific file to diff
308
+ - `staged` (boolean, optional, default: false) - Show staged changes
309
+ - **Returns:** `{success, diff, has_changes}`
310
+
311
+ **Example:**
312
+ ```json
313
+ {
314
+ "tool": "git_diff",
315
+ "params": {
316
+ "repo_path": ".",
317
+ "staged": true
318
+ }
319
+ }
320
+ ```
321
+
322
+ ---
323
+
324
+ ### 3. Code Execution
325
+
326
+ #### `run`
327
+ Execute shell command with timeout.
328
+ - **Parameters:**
329
+ - `command` (string, required) - Shell command to run
330
+ - `timeout` (integer, optional, default: 60) - Seconds before timeout
331
+ - `cwd` (string, optional) - Working directory
332
+ - `env` (object, optional) - Environment variables to merge
333
+ - **Returns:** `{success, returncode, stdout, stderr, command}`
334
+
335
+ **Example:**
336
+ ```json
337
+ {
338
+ "tool": "run",
339
+ "params": {
340
+ "command": "python -m pytest tests/ -v",
341
+ "timeout": 300,
342
+ "cwd": "."
343
+ }
344
+ }
345
+ ```
346
+
347
+ #### `test`
348
+ Run tests using pytest.
349
+ - **Parameters:**
350
+ - `path` (string, optional, default: ".") - Test directory or file
351
+ - `pattern` (string, optional, default: "test*.py") - Test file pattern
352
+ - `verbose` (boolean, optional, default: true) - Verbose output
353
+ - **Returns:** `{success, output, errors, returncode}`
354
+
355
+ **Example:**
356
+ ```json
357
+ {
358
+ "tool": "test",
359
+ "params": {
360
+ "path": "tests/",
361
+ "pattern": "test_*.py",
362
+ "verbose": true
363
+ }
364
+ }
365
+ ```
366
+
367
+ #### `lint`
368
+ Lint code with specified linter (ruff, pylint, mypy).
369
+ - **Parameters:**
370
+ - `path` (string, optional, default: ".")
371
+ - `linter` (string, optional, default: "ruff") - "ruff", "pylint", or "mypy"
372
+ - **Returns:** `{success, output, errors}`
373
+
374
+ **Example:**
375
+ ```json
376
+ {
377
+ "tool": "lint",
378
+ "params": {
379
+ "path": "stack_cli/",
380
+ "linter": "ruff"
381
+ }
382
+ }
383
+ ```
384
+
385
+ #### `format`
386
+ Format code with specified formatter.
387
+ - **Parameters:**
388
+ - `path` (string, optional, default: ".")
389
+ - `formatter` (string, optional, default: "ruff") - "ruff" or "black"
390
+ - **Returns:** `{success, output, errors}`
391
+
392
+ **Example:**
393
+ ```json
394
+ {
395
+ "tool": "format",
396
+ "params": {
397
+ "path": ".",
398
+ "formatter": "black"
399
+ }
400
+ }
401
+ ```
402
+
403
+ #### `typecheck`
404
+ Run type checking with mypy.
405
+ - **Parameters:**
406
+ - `path` (string, optional, default: ".")
407
+ - **Returns:** `{success, output, errors}`
408
+
409
+ **Example:**
410
+ ```json
411
+ {
412
+ "tool": "typecheck",
413
+ "params": {"path": "stack_cli"}
414
+ }
415
+ ```
416
+
417
+ #### `server`
418
+ Start a development server (optionally in background).
419
+ - **Parameters:**
420
+ - `command` (string, required) - Command to start server
421
+ - `port` (integer, required) - Port number (for reference)
422
+ - `cwd` (string, optional) - Working directory
423
+ - `background` (boolean, optional, default: false) - Run in background
424
+ - **Returns:** `{success, pid?, port, message}` or `{success, output}`
425
+
426
+ **Example:**
427
+ ```json
428
+ {
429
+ "tool": "server",
430
+ "params": {
431
+ "command": "python -m http.server 8000",
432
+ "port": 8000,
433
+ "background": true
434
+ }
435
+ }
436
+ ```
437
+
438
+ #### `install`
439
+ Install dependencies from requirements file.
440
+ - **Parameters:**
441
+ - `path` (string, optional, default: ".") - Project directory
442
+ - `package_manager` (string, optional, default: "pip") - "pip", "poetry", or "npm"
443
+ - **Returns:** `{success, output, errors}`
444
+
445
+ **Example:**
446
+ ```json
447
+ {
448
+ "tool": "install",
449
+ "params": {
450
+ "path": ".",
451
+ "package_manager": "pip"
452
+ }
453
+ }
454
+ ```
455
+
456
+ ---
457
+
458
+ ### 4. Web & Search
459
+
460
+ #### `web_search`
461
+ Search the web using Brave Search.
462
+ - **Parameters:**
463
+ - `query` (string, required) - Search query
464
+ - `count` (integer, optional, default: 5) - Number of results (1-10)
465
+ - `freshness` (string, optional) - Filter by time: "day", "week", "month", "year"
466
+ - `language` (string, optional) - ISO 639-1 language code (e.g., "en", "fr")
467
+ - **Returns:** `{success, query, results, count}`
468
+
469
+ **Example:**
470
+ ```json
471
+ {
472
+ "tool": "web_search",
473
+ "params": {
474
+ "query": "Stack 2.9 AI coding assistant",
475
+ "count": 10,
476
+ "freshness": "month"
477
+ }
478
+ }
479
+ ```
480
+
481
+ #### `fetch`
482
+ Download and extract content from a URL.
483
+ - **Parameters:**
484
+ - `url` (string, required) - URL to fetch
485
+ - `max_chars` (integer, optional, default: 10000) - Maximum content length
486
+ - **Returns:** `{success, url, content, length}`
487
+
488
+ **Example:**
489
+ ```json
490
+ {
491
+ "tool": "fetch",
492
+ "params": {
493
+ "url": "https://example.com/README.md",
494
+ "max_chars": 5000
495
+ }
496
+ }
497
+ ```
498
+
499
+ #### `download`
500
+ Download file from URL to local path.
501
+ - **Parameters:**
502
+ - `url` (string, required) - Source URL
503
+ - `destination` (string, required) - Local file path
504
+ - **Returns:** `{success, url, destination, size}`
505
+
506
+ **Example:**
507
+ ```json
508
+ {
509
+ "tool": "download",
510
+ "params": {
511
+ "url": "https://example.com/dataset.csv",
512
+ "destination": "data/dataset.csv"
513
+ }
514
+ }
515
+ ```
516
+
517
+ #### `check_url`
518
+ Check if URL is accessible (HTTP HEAD request).
519
+ - **Parameters:**
520
+ - `url` (string, required) - URL to check
521
+ - **Returns:** `{success, url, status_code}`
522
+
523
+ **Example:**
524
+ ```json
525
+ {
526
+ "tool": "check_url",
527
+ "params": {"url": "https://github.com"}
528
+ }
529
+ ```
530
+
531
+ #### `screenshot`
532
+ Take screenshot of a webpage (requires puppeteer).
533
+ - **Parameters:**
534
+ - `url` (string, required) - Webpage URL
535
+ - `destination` (string, optional, default: "screenshot.png") - Output path
536
+ - **Returns:** `{success, url, destination}`
537
+
538
+ **Example:**
539
+ ```json
540
+ {
541
+ "tool": "screenshot",
542
+ "params": {
543
+ "url": "https://stack-2-9.example.com",
544
+ "destination": "website.png"
545
+ }
546
+ }
547
+ ```
548
+
549
+ ---
550
+
551
+ ### 5. Memory & Knowledge
552
+
553
+ #### `memory_recall`
554
+ Search memory files for relevant entries.
555
+ - **Parameters:**
556
+ - `query` (string, required) - Search query
557
+ - `max_results` (integer, optional, default: 5) - Maximum matches
558
+ - **Returns:** `{success, query, matches, count}`
559
+
560
+ **Example:**
561
+ ```json
562
+ {
563
+ "tool": "memory_recall",
564
+ "params": {
565
+ "query": "deployment requirements",
566
+ "max_results": 10
567
+ }
568
+ }
569
+ ```
570
+
571
+ #### `memory_save`
572
+ Store a memory entry in MEMORY.md.
573
+ - **Parameters:**
574
+ - `key` (string, required) - Entry title/heading
575
+ - `value` (string, required) - Content to save
576
+ - **Returns:** `{success, key, saved}`
577
+
578
+ **Example:**
579
+ ```json
580
+ {
581
+ "tool": "memory_save",
582
+ "params": {
583
+ "key": "GPU Requirements",
584
+ "value": "Minimum: 8GB VRAM, Recommended: 24GB VRAM"
585
+ }
586
+ }
587
+ ```
588
+
589
+ #### `memory_list`
590
+ List all memory entries with preview.
591
+ - **Parameters:** None
592
+ - **Returns:** `{success, entries, count}` where each entry has `{title, content}`
593
+
594
+ **Example:**
595
+ ```json
596
+ {
597
+ "tool": "memory_list",
598
+ "params": {}
599
+ }
600
+ ```
601
+
602
+ #### `context_load`
603
+ Load workspace context files (AGENTS.md, SOUL.md, TOOLS.md).
604
+ - **Parameters:**
605
+ - `projects` (array of strings, optional) - Project names to load
606
+ - **Returns:** `{success, context, loaded}`
607
+
608
+ **Example:**
609
+ ```json
610
+ {
611
+ "tool": "context_load",
612
+ "params": {}
613
+ }
614
+ ```
615
+
616
+ #### `project_scan`
617
+ Scan project structure and detect tech stack.
618
+ - **Parameters:**
619
+ - `path` (string, optional, default: ".")
620
+ - **Returns:** `{success, project}` with `{name, files, dirs, has_git, has_pyproject, has_package_json, has_dockerfile}`
621
+
622
+ **Example:**
623
+ ```json
624
+ {
625
+ "tool": "project_scan",
626
+ "params": {"path": "."}
627
+ }
628
+ ```
629
+
630
+ ---
631
+
632
+ ### 6. Task & Planning
633
+
634
+ #### `create_task`
635
+ Create a new task.
636
+ - **Parameters:**
637
+ - `title` (string, required) - Task title
638
+ - `description` (string, optional, default: "") - Detailed description
639
+ - `priority` (string, optional, default: "medium") - "low", "medium", or "high"
640
+ - **Returns:** `{success, task}` with `{id, title, description, priority, status, created}`
641
+
642
+ **Example:**
643
+ ```json
644
+ {
645
+ "tool": "create_task",
646
+ "params": {
647
+ "title": "Write comprehensive tool documentation",
648
+ "description": "Create TOOLS.md with all 38 tools documented",
649
+ "priority": "high"
650
+ }
651
+ }
652
+ ```
653
+
654
+ #### `list_tasks`
655
+ List tasks with optional filtering.
656
+ - **Parameters:**
657
+ - `status` (string, optional) - Filter by "pending", "done", or "all"
658
+ - `priority` (string, optional) - Filter by "low", "medium", "high"
659
+ - **Returns:** `{success, tasks, count}`
660
+
661
+ **Example:**
662
+ ```json
663
+ {
664
+ "tool": "list_tasks",
665
+ "params": {
666
+ "status": "pending",
667
+ "priority": "high"
668
+ }
669
+ }
670
+ ```
671
+
672
+ #### `update_task`
673
+ Update task status or fields.
674
+ - **Parameters:**
675
+ - `task_id` (string, required) - Task identifier
676
+ - `status` (string, optional) - New status
677
+ - Additional fields: `title`, `description`, `priority`
678
+ - **Returns:** `{success, task_id, updated}`
679
+
680
+ **Example:**
681
+ ```json
682
+ {
683
+ "tool": "update_task",
684
+ "params": {
685
+ "task_id": "a1b2c3d4",
686
+ "status": "done"
687
+ }
688
+ }
689
+ ```
690
+
691
+ #### `delete_task`
692
+ Delete a task by ID.
693
+ - **Parameters:**
694
+ - `task_id` (string, required) - Task to delete
695
+ - **Returns:** `{success, task_id, deleted}`
696
+
697
+ **Example:**
698
+ ```json
699
+ {
700
+ "tool": "delete_task",
701
+ "params": {"task_id": "a1b2c3d4"}
702
+ }
703
+ ```
704
+
705
+ #### `create_plan`
706
+ Create an execution plan with steps.
707
+ - **Parameters:**
708
+ - `goal` (string, required) - Plan objective
709
+ - `steps` (array of strings, required) - Ordered steps
710
+ - **Returns:** `{success, plan}` with `{id, goal, steps, status, created}`
711
+
712
+ **Example:**
713
+ ```json
714
+ {
715
+ "tool": "create_plan",
716
+ "params": {
717
+ "goal": "Deploy to RunPod",
718
+ "steps": [
719
+ "Prepare Docker image",
720
+ "Upload to registry",
721
+ "Launch pod with template",
722
+ "Verify deployment"
723
+ ]
724
+ }
725
+ }
726
+ ```
727
+
728
+ #### `execute_plan`
729
+ Mark a plan as in-progress (execution tracking).
730
+ - **Parameters:**
731
+ - `plan_id` (string, required) - Plan identifier
732
+ - **Returns:** `{success, plan_id, status, steps}`
733
+
734
+ **Example:**
735
+ ```json
736
+ {
737
+ "tool": "execute_plan",
738
+ "params": {"plan_id": "p123abc"}
739
+ }
740
+ ```
741
+
742
+ ---
743
+
744
+ ## Tool Count Clarification
745
+
746
+ **Actual tool count: 38** (not 37). The following categories:
747
+ - File Operations: 8 tools
748
+ - Git Operations: 7 tools
749
+ - Code Execution: 7 tools
750
+ - Web & Search: 5 tools
751
+ - Memory & Knowledge: 5 tools
752
+ - Task & Planning: 6 tools
753
+ - **Total: 38 tools**
754
+
755
+ ---
756
+
757
+ ## Extension Mechanism
758
+
759
+ To add a new tool, edit `stack_cli/tools.py`:
760
+
761
+ ```python
762
+ def tool_my_feature(param1: str, param2: int = 42) -> Dict[str, Any]:
763
+ """Brief description for LLM."""
764
+ try:
765
+ # Implementation
766
+ result = do_something(param1, param2)
767
+ return {
768
+ "success": True,
769
+ "result": result
770
+ }
771
+ except Exception as e:
772
+ return {"success": False, "error": str(e)}
773
+
774
+ # Register in TOOLS dict
775
+ TOOLS["my_feature"] = tool_my_feature
776
+ ```
777
+
778
+ The tool will be automatically available. Update this document when adding tools.
779
+
780
+ ---
781
+
782
+ ## Schema Generation
783
+
784
+ For programmatic access, use:
785
+
786
+ ```python
787
+ from stack_cli.tools import get_tool_schemas, get_tool
788
+
789
+ # Get all tool schemas (for LLM function calling)
790
+ schemas = get_tool_schemas()
791
+
792
+ # Get a specific tool function
793
+ read_fn = get_tool("read")
794
+ result = read_fn(path="file.txt")
795
+ ```
796
+
797
+ **Note:** The `get_tool_schemas()` function currently provides a limited subset. For full production use, extend it to include all 38 tools with proper JSON Schema parameters derived from function signatures.
798
+
799
+ ---
800
+
801
+ ## Best Practices
802
+
803
+ 1. **Always check `success`** in the return value before using results
804
+ 2. **Use pagination** for large files: `read(path, offset=0, limit=1000)`
805
+ 3. **Handle errors gracefully** - tools return `error` field when `success=false`
806
+ 4. **Be cautious with destructive operations**: `delete` requires `force=true`
807
+ 5. **Set appropriate timeouts** for long-running commands (`run` tool)
808
+ 6. **Use `git_status` before `git_commit`** to verify what will be committed
809
+ 7. **Remember context limits** - tool results count against token limits
810
+
811
+ ---
812
+
813
+ ## Quick Reference Table
814
+
815
+ | Category | Tools | Count |
816
+ |----------|-------|-------|
817
+ | File Operations | read, write, edit, search, grep, copy, move, delete | 8 |
818
+ | Git | git_status, git_commit, git_push, git_pull, git_branch, git_log, git_diff | 7 |
819
+ | Execution | run, test, lint, format, typecheck, server, install | 7 |
820
+ | Web | web_search, fetch, download, check_url, screenshot | 5 |
821
+ | Memory | memory_recall, memory_save, memory_list, context_load, project_scan | 5 |
822
+ | Planning | create_task, list_tasks, update_task, delete_task, create_plan, execute_plan | 6 |
823
+ | **Total** | | **38** |
824
+
825
+ ---
826
+
827
+ *Last updated: 2026-04-02*
828
+ *Stack 2.9 - Pattern Memory AI*
stack-2.9-docs/ARCHITECTURE.md CHANGED
@@ -181,11 +181,11 @@ The model layer provides the AI inference capabilities:
181
  │ ▼ │
182
  │ ┌─────────────────────────────────────────────────────────┐ │
183
  │ │ LoRA ADAPTERS │ │
184
- │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
185
- │ │ │ coding │ │ tools │ │ voice │ │ memory │ │ │
186
- │ │ │ self- │ │ 37 tool │ │ clone │ │ pattern │ │ │
187
- │ │ │ evol │ │ patterns│ │ synth │ │ retrieval│ │ │
188
- │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
189
  │ └─────────────────────────────────────────────────────────┘ │
190
  │ │
191
  └─────────────────────────────────────────────────────────────────┘
 
181
  │ ▼ │
182
  │ ┌─────────────────────────────────────────────────────────┐ │
183
  │ │ LoRA ADAPTERS │ │
184
+ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
185
+ │ │ │ coding │ │ tools │ │ voice │ │ memory │ │ │
186
+ │ │ │ self-evol │ │ 37 tool │ │ clone │ │ pattern │ │ │
187
+ │ │ │ patterns │ │ patterns │ │ synth │ │ retrieval │ │
188
+ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │
189
  │ └─────────────────────────────────────────────────────────┘ │
190
  │ │
191
  └─────────────────────────────────────────────────────────────────┘
stack_cli/tools.py CHANGED
@@ -1193,50 +1193,105 @@ def list_tools() -> List[str]:
1193
 
1194
 
1195
  def get_tool_schemas() -> List[Dict[str, Any]]:
1196
- """Get tool schemas for LLM tool calling."""
1197
- schemas = []
 
 
 
 
 
1198
 
1199
- tool_schemas = {
1200
- "read": {"description": "Read file contents", "params": ["path", "offset", "limit"]},
1201
- "write": {"description": "Write content to file", "params": ["path", "content", "append"]},
1202
- "edit": {"description": "Edit file with text replacement", "params": ["path", "old_text", "new_text"]},
1203
- "search": {"description": "Search for files matching pattern", "params": ["path", "pattern", "exclude"]},
1204
- "grep": {"description": "Search for pattern in files", "params": ["path", "pattern", "context"]},
1205
- "git_status": {"description": "Get git status", "params": ["repo_path"]},
1206
- "git_commit": {"description": "Create git commit", "params": ["repo_path", "message", "files"]},
1207
- "git_push": {"description": "Push to remote", "params": ["repo_path", "remote", "branch"]},
1208
- "git_pull": {"description": "Pull from remote", "params": ["repo_path", "remote", "branch"]},
1209
- "run": {"description": "Run shell command", "params": ["command", "timeout", "cwd"]},
1210
- "test": {"description": "Run tests", "params": ["path", "pattern", "verbose"]},
1211
- "lint": {"description": "Lint code", "params": ["path", "linter"]},
1212
- "format": {"description": "Format code", "params": ["path", "formatter"]},
1213
- "web_search": {"description": "Search the web", "params": ["query", "count", "freshness"]},
1214
- "fetch": {"description": "Fetch URL content", "params": ["url", "max_chars"]},
1215
- "memory_recall": {"description": "Search memory", "params": ["query", "max_results"]},
1216
- "memory_save": {"description": "Save to memory", "params": ["key", "value"]},
1217
- "context_load": {"description": "Load project context", "params": ["projects"]},
1218
- "project_scan": {"description": "Scan project structure", "params": ["path"]},
1219
- "create_task": {"description": "Create task", "params": ["title", "description", "priority"]},
1220
- "list_tasks": {"description": "List tasks", "params": ["status", "priority"]},
1221
- "update_task": {"description": "Update task", "params": ["task_id", "status"]},
1222
- "create_plan": {"description": "Create execution plan", "params": ["goal", "steps"]},
1223
- "execute_plan": {"description": "Execute plan", "params": ["plan_id"]},
1224
- }
1225
 
1226
- for name, info in tool_schemas.items():
1227
- schemas.append({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1228
  "name": name,
1229
- "description": info["description"],
1230
  "parameters": {
1231
  "type": "object",
1232
- "properties": {p: {"type": "string"} for p in info["params"]},
1233
- "required": info["params"][:1]
1234
  }
1235
- })
 
 
1236
 
1237
  return schemas
1238
 
1239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1240
  if __name__ == "__main__":
1241
  print("Stack 2.9 Tools Module")
1242
  print(f"Available tools: {len(TOOLS)}")
 
1193
 
1194
 
1195
  def get_tool_schemas() -> List[Dict[str, Any]]:
1196
+ """Get tool schemas for LLM tool calling.
1197
+
1198
+ Automatically generates JSON Schema from function signatures using inspect.
1199
+ All 38 tools are included with accurate parameter types and descriptions.
1200
+ """
1201
+ import inspect
1202
+ from typing import get_type_hints
1203
 
1204
+ schemas = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1205
 
1206
+ for name, func in TOOLS.items():
1207
+ sig = inspect.signature(func)
1208
+ doc = func.__doc__ or f"Tool: {name}"
1209
+
1210
+ # Build parameters schema
1211
+ properties = {}
1212
+ required = []
1213
+
1214
+ for param_name, param in sig.parameters.items():
1215
+ # Skip self/cls
1216
+ if param_name in ('self', 'cls'):
1217
+ continue
1218
+
1219
+ # Get type annotation
1220
+ annotation = param.annotation
1221
+ if annotation is inspect.Parameter.empty:
1222
+ json_type = "string" # default
1223
+ elif annotation is str:
1224
+ json_type = "string"
1225
+ elif annotation is int:
1226
+ json_type = "integer"
1227
+ elif annotation is bool:
1228
+ json_type = "boolean"
1229
+ elif annotation is float:
1230
+ json_type = "number"
1231
+ elif hasattr(annotation, '__origin__') and annotation.__origin__ is list:
1232
+ json_type = "array"
1233
+ elif hasattr(annotation, '__origin__') and annotation.__origin__ is dict:
1234
+ json_type = "object"
1235
+ else:
1236
+ json_type = "string" # fallback
1237
+
1238
+ # Build property definition
1239
+ prop = {"type": json_type}
1240
+
1241
+ # Extract description from docstring
1242
+ param_desc = _extract_param_desc(doc, param_name)
1243
+ if param_desc:
1244
+ prop["description"] = param_desc
1245
+
1246
+ # Add enum for restricted string values
1247
+ if param_name in ('linter', 'formatter', 'package_manager') and hasattr(annotation, '__args__'):
1248
+ prop["enum"] = list(annotation.__args__)
1249
+
1250
+ properties[param_name] = prop
1251
+
1252
+ # Mark as required if no default value
1253
+ if param.default is inspect.Parameter.empty:
1254
+ required.append(param_name)
1255
+
1256
+ schema = {
1257
  "name": name,
1258
+ "description": doc.strip().split('\n')[0],
1259
  "parameters": {
1260
  "type": "object",
1261
+ "properties": properties,
1262
+ "required": required
1263
  }
1264
+ }
1265
+
1266
+ schemas.append(schema)
1267
 
1268
  return schemas
1269
 
1270
 
1271
+ def _extract_param_desc(docstring: str, param_name: str) -> Optional[str]:
1272
+ """Extract parameter description from docstring.
1273
+
1274
+ Looks for lines like: "- `param_name`: description" or "param_name: description".
1275
+ """
1276
+ if not docstring:
1277
+ return None
1278
+
1279
+ lines = docstring.split('\n')
1280
+ for i, line in enumerate(lines):
1281
+ # Match: - `param`: description
1282
+ if f"`{param_name}`" in line or f"{param_name}:" in line:
1283
+ # Try to extract after colon or dash
1284
+ parts = line.split(':', 1)
1285
+ if len(parts) > 1:
1286
+ return parts[1].strip().lstrip(' -').strip()
1287
+ # Alternative: split on backtick
1288
+ parts = line.split('`', 2)
1289
+ if len(parts) > 2:
1290
+ return parts[2].strip().lstrip(': -').strip()
1291
+
1292
+ return None
1293
+
1294
+
1295
  if __name__ == "__main__":
1296
  print("Stack 2.9 Tools Module")
1297
  print(f"Available tools: {len(TOOLS)}")