@defai.digital/ax-cli 3.0.2 → 3.1.1

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 (91) hide show
  1. package/.ax-cli/memory.json +55 -0
  2. package/README.md +74 -0
  3. package/dist/agent/llm-agent.d.ts +21 -0
  4. package/dist/agent/llm-agent.js +64 -15
  5. package/dist/agent/llm-agent.js.map +1 -1
  6. package/dist/agent/subagent-orchestrator.js +4 -0
  7. package/dist/agent/subagent-orchestrator.js.map +1 -1
  8. package/dist/checkpoint/storage.d.ts +2 -0
  9. package/dist/checkpoint/storage.js +17 -0
  10. package/dist/checkpoint/storage.js.map +1 -1
  11. package/dist/commands/mcp.js +10 -6
  12. package/dist/commands/mcp.js.map +1 -1
  13. package/dist/commands/memory.d.ts +1 -0
  14. package/dist/commands/memory.js +285 -1
  15. package/dist/commands/memory.js.map +1 -1
  16. package/dist/hooks/use-enhanced-input.js +3 -1
  17. package/dist/hooks/use-enhanced-input.js.map +1 -1
  18. package/dist/hooks/use-input-handler.js +194 -7
  19. package/dist/hooks/use-input-handler.js.map +1 -1
  20. package/dist/index.js +4 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/llm/client.js +52 -5
  23. package/dist/llm/client.js.map +1 -1
  24. package/dist/llm/tools.js +12 -2
  25. package/dist/llm/tools.js.map +1 -1
  26. package/dist/llm/types.d.ts +93 -1
  27. package/dist/llm/types.js +60 -0
  28. package/dist/llm/types.js.map +1 -1
  29. package/dist/mcp/client.d.ts +1 -1
  30. package/dist/mcp/client.js +8 -3
  31. package/dist/mcp/client.js.map +1 -1
  32. package/dist/memory/context-generator.d.ts +84 -0
  33. package/dist/memory/context-generator.js +537 -0
  34. package/dist/memory/context-generator.js.map +1 -0
  35. package/dist/memory/context-injector.d.ts +83 -0
  36. package/dist/memory/context-injector.js +142 -0
  37. package/dist/memory/context-injector.js.map +1 -0
  38. package/dist/memory/context-store.d.ts +76 -0
  39. package/dist/memory/context-store.js +212 -0
  40. package/dist/memory/context-store.js.map +1 -0
  41. package/dist/memory/index.d.ts +42 -0
  42. package/dist/memory/index.js +47 -0
  43. package/dist/memory/index.js.map +1 -0
  44. package/dist/memory/schemas.d.ts +316 -0
  45. package/dist/memory/schemas.js +103 -0
  46. package/dist/memory/schemas.js.map +1 -0
  47. package/dist/memory/stats-collector.d.ts +73 -0
  48. package/dist/memory/stats-collector.js +170 -0
  49. package/dist/memory/stats-collector.js.map +1 -0
  50. package/dist/memory/types.d.ts +175 -0
  51. package/dist/memory/types.js +70 -0
  52. package/dist/memory/types.js.map +1 -0
  53. package/dist/planner/task-planner.js +19 -2
  54. package/dist/planner/task-planner.js.map +1 -1
  55. package/dist/schemas/api-schemas.js +1 -1
  56. package/dist/schemas/api-schemas.js.map +1 -1
  57. package/dist/schemas/index.d.ts +4 -4
  58. package/dist/schemas/settings-schemas.d.ts +14 -0
  59. package/dist/schemas/settings-schemas.js +10 -0
  60. package/dist/schemas/settings-schemas.js.map +1 -1
  61. package/dist/tools/bash.js +28 -7
  62. package/dist/tools/bash.js.map +1 -1
  63. package/dist/ui/components/chat-history.js +4 -2
  64. package/dist/ui/components/chat-history.js.map +1 -1
  65. package/dist/ui/components/chat-interface.js +9 -4
  66. package/dist/ui/components/chat-interface.js.map +1 -1
  67. package/dist/ui/components/quick-actions.js +2 -0
  68. package/dist/ui/components/quick-actions.js.map +1 -1
  69. package/dist/ui/components/toast-notification.d.ts +3 -0
  70. package/dist/ui/components/toast-notification.js +18 -12
  71. package/dist/ui/components/toast-notification.js.map +1 -1
  72. package/dist/ui/components/virtualized-chat-history.js +3 -1
  73. package/dist/ui/components/virtualized-chat-history.js.map +1 -1
  74. package/dist/utils/background-task-manager.js +31 -9
  75. package/dist/utils/background-task-manager.js.map +1 -1
  76. package/dist/utils/confirmation-service.js +16 -10
  77. package/dist/utils/confirmation-service.js.map +1 -1
  78. package/dist/utils/custom-instructions.js +9 -1
  79. package/dist/utils/custom-instructions.js.map +1 -1
  80. package/dist/utils/prompt-builder.d.ts +4 -0
  81. package/dist/utils/prompt-builder.js +15 -0
  82. package/dist/utils/prompt-builder.js.map +1 -1
  83. package/dist/utils/settings-manager.d.ts +16 -1
  84. package/dist/utils/settings-manager.js +49 -0
  85. package/dist/utils/settings-manager.js.map +1 -1
  86. package/dist/utils/token-counter.js +4 -0
  87. package/dist/utils/token-counter.js.map +1 -1
  88. package/dist/utils/usage-tracker.d.ts +19 -0
  89. package/dist/utils/usage-tracker.js +22 -1
  90. package/dist/utils/usage-tracker.js.map +1 -1
  91. package/package.json +1 -1
@@ -0,0 +1,55 @@
1
+ {
2
+ "version": 1,
3
+ "created_at": "2025-11-21T09:17:20.806Z",
4
+ "updated_at": "2025-11-21T09:17:20.806Z",
5
+ "project_root": "/Users/akiralam/code/ax-cli",
6
+ "content_hash": "sha256:e0e29a88f3c707749dcc25f1fb3ce2428fd5a52004652e88c0968d5d5d47d920",
7
+ "source": {
8
+ "directories": [
9
+ {
10
+ "path": "src",
11
+ "max_depth": 3
12
+ },
13
+ {
14
+ "path": "packages",
15
+ "max_depth": 2
16
+ }
17
+ ],
18
+ "files": [
19
+ "README.md",
20
+ "readme.md",
21
+ "package.json",
22
+ "tsconfig.json",
23
+ ".ax-cli/CUSTOM.md"
24
+ ],
25
+ "ignore": [
26
+ "node_modules",
27
+ "dist",
28
+ "build",
29
+ ".git",
30
+ ".next",
31
+ ".nuxt",
32
+ "coverage",
33
+ ".cache",
34
+ ".turbo",
35
+ ".vercel",
36
+ "__pycache__",
37
+ ".pytest_cache",
38
+ "target",
39
+ "vendor",
40
+ "*.log",
41
+ "*.lock",
42
+ ".DS_Store"
43
+ ]
44
+ },
45
+ "context": {
46
+ "formatted": "# Project: ax-cli\n\n\n## Architecture Patterns\n- **Project Type**: cli\n- **Primary Language**: TypeScript\n- **Tech Stack**: React, Vitest, Zod, Commander, Ink, ESM, TypeScript\n- **Package Manager**: npm\n- **Entry Point**: dist/index.js\n- **Module System**: ESM\n- **Test Framework**: vitest\n- **Validation**: zod\n- **Linter**: eslint\n- **Key Directories**: source: src, tests: tests\n\n\n## Directory Structure\n```\nsrc/\n├── agent/\n│ ├── specialized/\n│ │ ├── analysis-agent.ts\n│ │ ├── debug-agent.ts\n│ │ ├── documentation-agent.ts\n│ │ ├── index.ts\n│ │ ├── performance-agent.ts\n│ │ ├── refactoring-agent.ts\n│ │ └── testing-agent.ts\n│ ├── context-manager.ts\n│ ├── context-manager.ts.bak\n│ ├── dependency-resolver.ts\n│ ├── index.ts\n│ ├── llm-agent.ts\n│ ├── llm-agent.ts.backup\n│ ├── subagent-orchestrator.ts\n│ ├── subagent-types.ts\n│ └── subagent.ts\n├── checkpoint/\n│ ├── index.ts\n│ ├── manager.ts\n│ ├── storage.ts\n│ └── types.ts\n├── commands/\n│ ├── init/\n│ │ └── wizard.ts\n│ ├── cache.ts\n│ ├── init.ts\n│ ├── mcp.ts\n│ ├── memory.ts\n│ ├── models.ts\n│ ├── plan.ts\n│ ├── rewind.ts\n│ ├── setup.ts\n│ ├── templates.ts\n│ ├── update.ts\n│ └── usage.ts\n├── hooks/\n│ ├── use-chat-reducer.ts\n│ ├── use-enhanced-input.ts\n│ ├── use-input-handler.ts\n│ └── use-input-history.ts\n├── llm/\n│ ├── client.ts\n│ ├── tools.ts\n│ └── types.ts\n├── mcp/\n│ ├── client.ts\n│ ├── config.ts\n│ └── transports.ts\n├── memory/\n│ ├── context-generator.ts\n│ ├── context-injector.ts\n│ ├── context-store.ts\n│ ├── index.ts\n│ ├── schemas.ts\n│ ├── stats-collector.ts\n│ └── types.ts\n├── planner/\n│ ├── prompts/\n│ │ └── planning-prompt.ts\n│ ├── dependency-resolver.ts\n│ ├── index.ts\n│ ├── plan-generator.ts\n│ ├── plan-storage.ts\n│ ├── task-planner.ts\n│ ├── token-estimator.ts\n│ └── types.ts\n├── schemas/\n│ ├── api-schemas.ts\n│ ├── confirmation-schemas.ts\n│ ├── index-unified.ts\n│ ├── index.ts\n│ ├── README.md\n│ ├── settings-schemas.ts\n│ ├── tool-schemas.ts\n│ └── yaml-schemas.ts\n├── tools/\n│ ├── bash-output.ts\n│ ├── bash.ts\n│ ├── confirmation-tool.ts\n│ ├── index.ts\n│ ├── search.ts\n│ ├── text-editor.ts\n│ └── todo-tool.ts\n├── types/\n│ ├── index.ts\n│ ├── project-analysis.ts\n│ └── template.ts\n├── ui/\n│ ├── components/\n│ │ ├── api-key-input.tsx\n│ │ ├── chat-history.tsx\n│ │ ├── chat-input.tsx\n│ │ ├── chat-interface.tsx\n│ │ ├── collapsible-tool-result.tsx\n│ │ ├── command-suggestions.tsx\n│ │ ├── confirmation-dialog.tsx\n│ │ ├── diff-renderer.tsx\n│ │ ├── index.ts\n│ │ ├── keyboard-hints.tsx\n│ │ ├── loading-spinner.tsx\n│ │ ├── mcp-status.tsx\n│ │ ├── model-selection.tsx\n│ │ ├── phase-progress.tsx\n│ │ ├── quick-actions.tsx\n│ │ ├── reasoning-display.tsx\n│ │ ├── status-bar.tsx\n│ │ ├── subagent-monitor.tsx\n│ │ ├── toast-notification.tsx\n│ │ ├── virtualized-chat-history.tsx\n│ │ └── welcome-panel.tsx\n│ ├── shared/\n│ │ └── max-sized-box.tsx\n│ ├── utils/\n│ │ ├── code-colorizer.tsx\n│ │ ├── colors.ts\n│ │ └── markdown-renderer.tsx\n│ └── app.tsx\n├── utils/\n│ ├── background-task-manager.ts\n│ ├── cache.ts\n│ ├── config-loader.ts\n│ ├── confirmation-service.ts\n│ ├── console-messenger.ts\n│ ├── custom-instructions.ts\n│ ├── error-handler.ts\n│ ├── error-translator.ts\n│ ├── errors.ts\n│ ├── file-cache.ts\n│ ├── history-manager.ts\n│ ├── incremental-analyzer.ts\n│ ├── index.ts\n│ ├── init-previewer.ts\n│ ├── init-validator.ts\n│ ├── instruction-generator.ts\n│ ├── json-utils.ts\n│ ├── llm-optimized-instruction-generator.ts\n│ ├── message-optimizer.ts\n│ ├── onboarding-manager.ts\n│ ├── parallel-analyzer.ts\n│ ├── path-utils.ts\n│ ├── path-validator.ts\n│ ├── performance.ts\n│ ├── progress-tracker.ts\n│ ├── project-analyzer.ts\n│ ├── prompt-builder.ts\n│ ├── settings-manager.ts\n│ ├── settings.ts\n│ ├── setup-validator.ts\n│ └── ... (7 more)\n├── constants.ts\n└── index.ts\npackages/\n└── schemas/\n ├── __tests__/\n ├── scripts/\n ├── src/\n ├── .eslintrc.js\n ├── package-lock.json\n ├── package.json\n ├── README.md\n ├── tsconfig.json\n └── vitest.config.ts\n```\n\n\n## Key Configuration\n\n### README.md\n\n```\n# AX CLI - Enterprise-Class AI CLI\n\n[![Tests](https://img.shields.io/badge/tests-562%20passing-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli/actions/workflows/test.yml)\n[![Coverage](https://img.shields.io/badge/coverage-98.29%25-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli)\n[![npm](https://img.shields.io/npm/dt/@defai.digital/ax-cli?style=flat-square&logo=npm&label=downloads)](https://npm-stat.com/charts.html?package=%40defai.digital%2Fax-cli)\n...\n```\n\n### readme.md\n\n```\n# AX CLI - Enterprise-Class AI CLI\n\n[![Tests](https://img.shields.io/badge/tests-562%20passing-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli/actions/workflows/test.yml)\n[![Coverage](https://img.shields.io/badge/coverage-98.29%25-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli)\n[![npm](https://img.shields.io/npm/dt/@defai.digital/ax-cli?style=flat-square&logo=npm&label=downloads)](https://npm-stat.com/charts.html?package=%40defai.digital%2Fax-cli)\n...\n```\n\n### package.json\n\n- **Name**: @defai.digital/ax-cli\n- **Version**: 3.0.2\n- **Description**: Enterprise-Class AI Command Line Interface - Primary support for GLM (General Language Model) with multi-provider AI orchestration powered by AutomatosX.\n- **Type**: module\n- **CLI**: Yes\n- **Dependencies**: @ax-cli/schemas, @clack/prompts, @modelcontextprotocol/sdk, axios, cfonts, chalk, clipboardy, commander, dotenv, enquirer (+11 more)\n- **Dev Dependencies**: @types/fs-extra, @types/js-yaml, @types/marked-terminal, @types/node, @types/react, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, @vitest/coverage-v8 (+5 more)\n- **Scripts**: build, build:schemas, build:bun, dev, dev:node, start\n\n### tsconfig.json\n\n- **Target**: ES2022\n- **Module**: ESNext\n- **Module Resolution**: Bundler\n- **Strict**: true\n- **Output**: ./dist\n\n### .ax-cli/CUSTOM.md\n\n# @defai.digital/ax-cli - Quick Reference\n\n**Type:** cli | **Lang:** TypeScript | **Ver:** v2.3.1\n**Stack:** React, Vitest, Zod, Commander, Ink, ESM, TypeScript\n\n---\n\n## 🎯 Critical Rules\n\n1. **ESM Imports:** Always use `.js` extension: `import { x } from './y.js'`\n2. **Validation:** Use zod for all external inputs\n3. **Types:** Explicit return types required on all functions\n4. **Testing:** 80%+ coverage, test error paths\n5. **Modules:** Use `import/export` (not `require/module.exports`)\n6. **File Organization:** Follow standardized output paths (see below)\n\n---\n\n## 📁 Project File Organization\n\n### Standard Output Paths\n\nAll AI-generated and project artifacts must follow this structure:\n\n```\nautomatosx/\n├── PRD/ # Product Requirement Documents\n│ ├── features/ # Feature specifications\n│ ├── api/ # API documentation\n│ └── archive/ # Old/deprecated PRDs\n├── REPORT/ # Project reports and analysis\n│ ├── status/ # Status reports\n│ ├\n[...truncated]\n\n\n## README Summary\n\n# AX CLI - Enterprise-Class AI CLI\n\n[![Tests](https://img.shields.io/badge/tests-562%20passing-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli/actions/workflows/test.yml)\n[![Coverage](https://img.shields.io/badge/coverage-98.29%25-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli)\n[![npm](https://img.shields.io/npm/dt/@defai.digital/ax-cli?style=flat-square&logo=npm&label=downloads)](https://npm-stat.com/charts.html?package=%40defai.digital%2Fax-cli)\n[![Node.js Version](https://img.shields.io/badge/node-%3E%3D24.0.0-blue?style=flat-square)](https://nodejs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.9%2B-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)\n[![macOS](https://img.shields.io/badge/macOS-26-blue?style=flat-square&logo=apple)](https://www.apple.com/macos/)\n[![Windows](https://img.shields.io/badge/Windows-11-blue?style=flat-square&logo=windows)](https://www.microsoft.com/windows/)\n[![Ubuntu](https://img.shields.io/badge/Ubuntu-24.04-blue?style=flat-square&logo=ubuntu)](https://ubuntu.com/)\n\n![AX CLI Logo](.github/assets/ax-cli.png)\n\n<p align=\"center\">\n <strong>Enterprise-Grade Architecture • 98%+ Test Coverage • TypeScript & Zod Validation</strong>\n</p>\n\n---\n\n## 🚀 Quick Start\n\n```bash\n# Install globally\nnpm install -g @defai.digital/ax-cli\n\n# Configure your API key\nax-cli setup\n\n# Initialize your project\nax-cli init\n\n# Start interactive mode\nax-cli\n```\n\n## ✨ Features\n\n- **🤖 Multi-Provider Support**: Z.AI (GLM), xAI (Grok), OpenAI, Anthropic (Claude), Ollama (local)\n- **🧠 GLM 4.6 Optimized**: Primary support for General Language Model with advanced reasoning\n - **32K max tokens** (industry-standard, matches Claude Code CLI)\n - 200K context window, 128K max output capability\n - 30% more token efficient than GLM 4.5\n - Optimized for complex code generation and refactoring\n- **🎯 Multi-Phase Task Planner** (NEW in v3.0.0): Intelligent task decomposition for complex requests\n - Automatic complexity detection (57 keyword patterns)\n - LLM-based plan generation with phases and dependencies\n - Phase-by-phase execution with progress tracking\n - File modification tracking and context pruning between phases\n - Plan management commands: `/plans`, `/plan`, `/phases`, `/pause`, `/resume`, `/skip`, `/abandon`\n- **🔄 Session Continuity**: Directory-specific conversation history with `--continue` flag\n - Preserve context across sessions for multi-day development\n - Each project maintains its own independent history\n - Seamlessly resume conversations where you left off\n- **🔌 MCP Integration**: Model Context Protocol for extensible tool support\n- **✅ Production-Ready**: 98%+ test coverage, TypeScript strict mode, Zod validation\n- **🎯 Interactive & Headless**: Chat interface or one-shot commands\n- **📝 Smart Project Init**: Automatic project analysis and custom instructions\n- **🧠 Project Memory** (NEW): Intelligent context caching for z.ai GLM-4.6\n - Automatic project scanning and context generation\n - z.ai implicit caching support (50% token savings on repeated context)\n - Cache statistics tracking and efficiency monitoring\n- **🔄 Auto-Update**: Built-in update checker and installer\n\n### Max Tokens Configuration\n\nAX CLI uses **industry-standard max tokens** based on research of leading AI coding tools:\n\n| Tool | Max Tokens | Notes |\n|------|-----------|-------|\n| **Claude Code CLI** | 16k - 32k | Industry standard |\n| **GitHub Copilot** | 64k | GPT-4o default |\n| **Cursor AI** | 200k | With intelligent pruning |\n| **AX CLI (GLM 4.6)** | **32k** ✅ | Matches Claude Code upper default |\n| **AX CLI (Others)** | 8k | Appropriate for each model |\n\n**Why 32k for GLM 4.6?**\n- Competitive with industry leaders (Claude Code, GitHub Copilot)\n- GLM 4.6 supports up to 128k max output (our 32k is conservative at 25%)\n- Better for complex code generation, large file modifications, and multi-file context\n- Based on o\n\n[...truncated]",
47
+ "token_estimate": 3315,
48
+ "sections": {
49
+ "structure": 1252,
50
+ "readme": 1121,
51
+ "config": 835,
52
+ "patterns": 99
53
+ }
54
+ }
55
+ }
package/README.md CHANGED
@@ -56,6 +56,10 @@ ax-cli
56
56
  - **✅ Production-Ready**: 98%+ test coverage, TypeScript strict mode, Zod validation
57
57
  - **🎯 Interactive & Headless**: Chat interface or one-shot commands
58
58
  - **📝 Smart Project Init**: Automatic project analysis and custom instructions
59
+ - **🧠 Project Memory** (NEW): Intelligent context caching for z.ai GLM-4.6
60
+ - Automatic project scanning and context generation
61
+ - z.ai implicit caching support (50% token savings on repeated context)
62
+ - Cache statistics tracking and efficiency monitoring
59
63
  - **🔄 Auto-Update**: Built-in update checker and installer
60
64
 
61
65
  ### Max Tokens Configuration
@@ -122,6 +126,7 @@ ax-cli # Will prompt for API key on first run
122
126
  - **User Settings**: `~/.ax-cli/config.json`
123
127
  - **Project Settings**: `.ax-cli/settings.json`
124
128
  - **Custom Instructions**: `.ax-cli/CUSTOM.md`
129
+ - **Project Memory**: `.ax-cli/memory.json` (auto-generated)
125
130
 
126
131
  [Configuration Guide →](docs/configuration.md)
127
132
 
@@ -340,6 +345,74 @@ ax-cli mcp remove linear
340
345
 
341
346
  [MCP Integration Guide →](docs/mcp.md)
342
347
 
348
+ ## 🧠 Project Memory (NEW)
349
+
350
+ Project Memory enables intelligent context caching for z.ai GLM-4.6, reducing token costs and improving response consistency:
351
+
352
+ ```bash
353
+ # Initialize project memory (scans codebase)
354
+ ax-cli memory warmup
355
+
356
+ # Output:
357
+ # ✓ Project memory generated (3,305 tokens)
358
+ #
359
+ # 📊 Context breakdown:
360
+ # Structure: 1,252 tokens (38%)
361
+ # README: 1,111 tokens (34%)
362
+ # Config: 835 tokens (25%)
363
+ # Patterns: 99 tokens (3%)
364
+ ```
365
+
366
+ ### How It Works
367
+
368
+ 1. **Warmup**: Scans your project structure, README, configs, and detects architecture patterns
369
+ 2. **Auto-Injection**: Memory context is automatically prepended to system prompts
370
+ 3. **z.ai Caching**: Identical prompt prefixes are automatically cached by z.ai (50% token savings)
371
+ 4. **Statistics**: Track cache efficiency with `ax-cli memory cache-stats`
372
+
373
+ ### Memory Commands
374
+
375
+ ```bash
376
+ ax-cli memory warmup # Create project memory
377
+ ax-cli memory refresh # Update after changes
378
+ ax-cli memory status # Show memory status & token distribution
379
+ ax-cli memory clear # Remove project memory
380
+ ax-cli memory cache-stats # Show cache efficiency statistics
381
+
382
+ # Options
383
+ ax-cli memory warmup -d 5 # Custom scan depth (1-10)
384
+ ax-cli memory warmup -m 12000 # Custom max tokens
385
+ ax-cli memory warmup --dry-run # Preview without saving
386
+ ax-cli memory status --verbose # Show full context
387
+ ax-cli memory status --json # JSON output
388
+ ```
389
+
390
+ ### Token Distribution Visualization
391
+
392
+ ```
393
+ 📊 Token Distribution:
394
+ ████████░░░░░░░░░░░░ Structure (38%)
395
+ ███████░░░░░░░░░░░░░ README (34%)
396
+ █████░░░░░░░░░░░░░░░ Config (25%)
397
+ █░░░░░░░░░░░░░░░░░░░ Patterns (3%)
398
+ ```
399
+
400
+ ### Recommended Workflow
401
+
402
+ ```bash
403
+ # 1. Initialize project (if not done)
404
+ ax-cli init
405
+
406
+ # 2. Create project memory
407
+ ax-cli memory warmup
408
+
409
+ # 3. Use ax-cli normally - memory is auto-injected
410
+ ax-cli -p "refactor authentication module"
411
+
412
+ # 4. After major changes, refresh memory
413
+ ax-cli memory refresh
414
+ ```
415
+
343
416
  ## 🎯 Multi-Phase Task Planner (v3.0.0)
344
417
 
345
418
  AX CLI now includes an intelligent multi-phase task planner that automatically decomposes complex requests:
@@ -404,6 +477,7 @@ AX CLI implements enterprise-grade architecture with:
404
477
  - [Usage](docs/usage.md) - Comprehensive usage guide
405
478
  - [CLI Reference](docs/cli-reference.md) - Command-line interface reference
406
479
  - [MCP Integration](docs/mcp.md) - Model Context Protocol guide
480
+ - [Project Memory](automatosx/prd/project-memory-prd.md) - Project memory feature specification
407
481
  - [Architecture](docs/architecture.md) - Technical architecture details
408
482
  - [Development](docs/development.md) - Development and contribution guide
409
483
  - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions
@@ -1,4 +1,5 @@
1
1
  import { LLMToolCall } from "../llm/client.js";
2
+ import type { SamplingConfig } from "../llm/types.js";
2
3
  import { ToolResult } from "../types/index.js";
3
4
  import { EventEmitter } from "events";
4
5
  import { CheckpointManager } from "../checkpoint/index.js";
@@ -52,10 +53,30 @@ export declare class LLMAgent extends EventEmitter {
52
53
  private taskPlanner;
53
54
  private currentPlan;
54
55
  private planningEnabled;
56
+ /** Sampling configuration for deterministic/reproducible mode */
57
+ private samplingConfig;
55
58
  constructor(apiKey: string, baseURL?: string, model?: string, maxToolRounds?: number);
56
59
  private initializeCheckpointManager;
57
60
  private initializeMCP;
58
61
  private isGrokModel;
62
+ /**
63
+ * Build chat options with sampling configuration included
64
+ * Merges provided options with the agent's sampling config
65
+ */
66
+ private buildChatOptions;
67
+ /**
68
+ * Set sampling configuration for this agent session
69
+ * @param config Sampling configuration to apply
70
+ */
71
+ setSamplingConfig(config: SamplingConfig | undefined): void;
72
+ /**
73
+ * Get current sampling configuration
74
+ */
75
+ getSamplingConfig(): SamplingConfig | undefined;
76
+ /**
77
+ * Check if agent is running in deterministic mode
78
+ */
79
+ isDeterministicMode(): boolean;
59
80
  /**
60
81
  * Detect if a tool call is repetitive (likely causing a loop)
61
82
  * Returns true if the same tool with similar arguments was called multiple times recently
@@ -35,6 +35,8 @@ export class LLMAgent extends EventEmitter {
35
35
  taskPlanner;
36
36
  currentPlan = null;
37
37
  planningEnabled = PLANNER_CONFIG.ENABLED;
38
+ /** Sampling configuration for deterministic/reproducible mode */
39
+ samplingConfig;
38
40
  constructor(apiKey, baseURL, model, maxToolRounds) {
39
41
  super();
40
42
  const manager = getSettingsManager();
@@ -55,6 +57,8 @@ export class LLMAgent extends EventEmitter {
55
57
  this.checkpointManager = getCheckpointManager();
56
58
  this.subagentOrchestrator = new SubagentOrchestrator({ maxConcurrentAgents: 5 });
57
59
  this.taskPlanner = getTaskPlanner();
60
+ // Load sampling configuration from settings (supports env vars, project, and user settings)
61
+ this.samplingConfig = manager.getSamplingSettings();
58
62
  // Wire up checkpoint callback for automatic checkpoint creation
59
63
  this.textEditor.setCheckpointCallback(async (files, description) => {
60
64
  await this.checkpointManager.createCheckpoint({
@@ -77,9 +81,18 @@ export class LLMAgent extends EventEmitter {
77
81
  customInstructions: customInstructions || undefined,
78
82
  });
79
83
  // Initialize with system message
84
+ // OPTIMIZATION: Keep static system prompt separate from dynamic context
85
+ // This maximizes cache hit rates on the xAI API (cached tokens = 50% cost savings)
86
+ // The API automatically caches identical content across requests
80
87
  this.messages.push({
81
88
  role: "system",
82
- content: `${systemPrompt}\n\nCurrent working directory: ${process.cwd()}`,
89
+ content: systemPrompt,
90
+ });
91
+ // Add dynamic context as a separate system message
92
+ // This allows the main system prompt to be cached while context varies
93
+ this.messages.push({
94
+ role: "system",
95
+ content: `Current working directory: ${process.cwd()}\nTimestamp: ${new Date().toISOString().split('T')[0]}`,
83
96
  });
84
97
  }
85
98
  initializeCheckpointManager() {
@@ -125,6 +138,37 @@ export class LLMAgent extends EventEmitter {
125
138
  const currentModel = this.llmClient.getCurrentModel();
126
139
  return currentModel.toLowerCase().includes("grok");
127
140
  }
141
+ /**
142
+ * Build chat options with sampling configuration included
143
+ * Merges provided options with the agent's sampling config
144
+ */
145
+ buildChatOptions(options) {
146
+ const result = { ...options };
147
+ // Include sampling configuration if set and not overridden
148
+ if (this.samplingConfig && !result.sampling) {
149
+ result.sampling = this.samplingConfig;
150
+ }
151
+ return result;
152
+ }
153
+ /**
154
+ * Set sampling configuration for this agent session
155
+ * @param config Sampling configuration to apply
156
+ */
157
+ setSamplingConfig(config) {
158
+ this.samplingConfig = config;
159
+ }
160
+ /**
161
+ * Get current sampling configuration
162
+ */
163
+ getSamplingConfig() {
164
+ return this.samplingConfig;
165
+ }
166
+ /**
167
+ * Check if agent is running in deterministic mode
168
+ */
169
+ isDeterministicMode() {
170
+ return this.samplingConfig?.doSample === false;
171
+ }
128
172
  /**
129
173
  * Detect if a tool call is repetitive (likely causing a loop)
130
174
  * Returns true if the same tool with similar arguments was called multiple times recently
@@ -289,7 +333,7 @@ export class LLMAgent extends EventEmitter {
289
333
  let toolRounds = 0;
290
334
  const maxPhaseRounds = Math.min(this.maxToolRounds, 50); // Limit per phase
291
335
  while (toolRounds < maxPhaseRounds) {
292
- const response = await this.llmClient.chat(this.messages, tools);
336
+ const response = await this.llmClient.chat(this.messages, tools, this.buildChatOptions());
293
337
  const assistantMessage = response.choices[0]?.message;
294
338
  if (!assistantMessage)
295
339
  break;
@@ -431,7 +475,7 @@ export class LLMAgent extends EventEmitter {
431
475
  { role: "system", content: systemPrompt },
432
476
  { role: "user", content: userPrompt },
433
477
  ];
434
- const response = await this.llmClient.chat(planMessages, []);
478
+ const response = await this.llmClient.chat(planMessages, [], this.buildChatOptions());
435
479
  return response.choices[0]?.message?.content || "";
436
480
  }, {
437
481
  projectType: "typescript", // Could be detected
@@ -658,11 +702,11 @@ export class LLMAgent extends EventEmitter {
658
702
  // Load tools safely
659
703
  const tools = await this.loadToolsSafely();
660
704
  // Create chat stream
661
- const stream = this.llmClient.chatStream(this.messages, tools, {
705
+ const stream = this.llmClient.chatStream(this.messages, tools, this.buildChatOptions({
662
706
  searchOptions: this.isGrokModel() && this.shouldUseSearchFor(message)
663
707
  ? { search_parameters: { mode: "auto" } }
664
708
  : { search_parameters: { mode: "off" } }
665
- });
709
+ }));
666
710
  // Process streaming chunks
667
711
  const chunkGen = this.processStreamingChunks(stream, inputTokensRef.value, lastTokenUpdateRef, totalOutputTokensRef);
668
712
  let streamResult;
@@ -765,11 +809,11 @@ export class LLMAgent extends EventEmitter {
765
809
  let toolRounds = 0;
766
810
  try {
767
811
  const tools = await getAllGrokTools();
768
- let currentResponse = await this.llmClient.chat(this.messages, tools, {
812
+ let currentResponse = await this.llmClient.chat(this.messages, tools, this.buildChatOptions({
769
813
  searchOptions: this.isGrokModel() && this.shouldUseSearchFor(message)
770
814
  ? { search_parameters: { mode: "auto" } }
771
815
  : { search_parameters: { mode: "off" } }
772
- });
816
+ }));
773
817
  // Agent loop - continue until no more tool calls or max rounds reached
774
818
  while (toolRounds < maxToolRounds) {
775
819
  const assistantMessage = currentResponse.choices[0]?.message;
@@ -864,11 +908,11 @@ export class LLMAgent extends EventEmitter {
864
908
  this.messages = this.contextManager.pruneMessages(this.messages, this.tokenCounter);
865
909
  }
866
910
  // Get next response - this might contain more tool calls
867
- currentResponse = await this.llmClient.chat(this.messages, tools, {
911
+ currentResponse = await this.llmClient.chat(this.messages, tools, this.buildChatOptions({
868
912
  searchOptions: this.isGrokModel() && this.shouldUseSearchFor(message)
869
913
  ? { search_parameters: { mode: "auto" } }
870
914
  : { search_parameters: { mode: "off" } }
871
- });
915
+ }));
872
916
  }
873
917
  else {
874
918
  // No more tool calls, add final response
@@ -1122,17 +1166,21 @@ export class LLMAgent extends EventEmitter {
1122
1166
  * Add assistant message to history and conversation
1123
1167
  */
1124
1168
  addAssistantMessage(accumulatedMessage) {
1169
+ // Safely extract tool_calls with proper validation
1170
+ const toolCalls = Array.isArray(accumulatedMessage.tool_calls)
1171
+ ? accumulatedMessage.tool_calls
1172
+ : undefined;
1125
1173
  const assistantEntry = {
1126
1174
  type: "assistant",
1127
1175
  content: accumulatedMessage.content || "Using tools to help you...",
1128
1176
  timestamp: new Date(),
1129
- toolCalls: accumulatedMessage.tool_calls || undefined,
1177
+ toolCalls,
1130
1178
  };
1131
1179
  this.chatHistory.push(assistantEntry);
1132
1180
  this.messages.push({
1133
1181
  role: "assistant",
1134
1182
  content: accumulatedMessage.content || "",
1135
- tool_calls: accumulatedMessage.tool_calls,
1183
+ tool_calls: toolCalls,
1136
1184
  });
1137
1185
  // Apply context pruning after adding message to prevent overflow
1138
1186
  // Critical for long assistant responses and tool results
@@ -1240,11 +1288,11 @@ export class LLMAgent extends EventEmitter {
1240
1288
  };
1241
1289
  }
1242
1290
  // Create chat stream
1243
- const stream = this.llmClient.chatStream(this.messages, tools, {
1291
+ const stream = this.llmClient.chatStream(this.messages, tools, this.buildChatOptions({
1244
1292
  searchOptions: this.isGrokModel() && this.shouldUseSearchFor(message)
1245
1293
  ? { search_parameters: { mode: "auto" } }
1246
1294
  : { search_parameters: { mode: "off" } }
1247
- });
1295
+ }));
1248
1296
  // Process streaming chunks
1249
1297
  const chunkGen = this.processStreamingChunks(stream, inputTokensRef.value, lastTokenUpdateRef, totalOutputTokensRef);
1250
1298
  let streamResult;
@@ -1342,14 +1390,15 @@ export class LLMAgent extends EventEmitter {
1342
1390
  * @returns Parsed arguments or error result
1343
1391
  */
1344
1392
  parseToolArguments(toolCall, toolType = 'Tool') {
1345
- if (!toolCall.function.arguments || toolCall.function.arguments.trim() === '') {
1393
+ const argsString = toolCall.function.arguments;
1394
+ if (!argsString || typeof argsString !== 'string' || argsString.trim() === '') {
1346
1395
  return {
1347
1396
  success: false,
1348
1397
  error: `${toolType} ${toolCall.function.name} called with empty arguments`,
1349
1398
  };
1350
1399
  }
1351
1400
  try {
1352
- const args = JSON.parse(toolCall.function.arguments);
1401
+ const args = JSON.parse(argsString);
1353
1402
  // Validate that args is an object (not null, array, or primitive)
1354
1403
  if (typeof args !== 'object' || args === null || Array.isArray(args)) {
1355
1404
  return {