BREAKING CHANGE(aidoc): migrate agent orchestration to new runAgent API and filesystem tools; refactor model handling and update README and tests

This commit is contained in:
2026-03-11 18:58:48 +00:00
parent 883985dbc0
commit 6b2957b272
11 changed files with 834 additions and 3270 deletions

View File

@@ -1,5 +1,17 @@
# Changelog # Changelog
## 2026-03-11 - 2.0.0 - BREAKING CHANGE(aidoc)
migrate agent orchestration to new runAgent API and filesystem tools; refactor model handling and update README and tests
- Replace DualAgentOrchestrator with plugins.smartagent.runAgent and scoped filesystem tools
- Introduce smartagentTools export and use filesystemTool for agents
- Replace smartAiInstance with model via plugins.smartai.getModel() and remove previous lifecycle methods (breaking API change)
- Normalize agent output property from result to text and standardize log messages (removed emojis)
- Update changelog/README/description generation flows to use new agent interface
- Bump several devDependencies and dependencies (tsbuild, tstest, @types/node, tspublish, push.rocks packages, typedoc, typescript)
- Change test entry to export default tap.start()
- Revise README content and structure
## 2026-01-04 - 1.12.0 - feat(commit) ## 2026-01-04 - 1.12.0 - feat(commit)
add token budgeting and dynamic diff token calculation to avoid OpenAI context limit issues add token budgeting and dynamic diff token calculation to avoid OpenAI context limit issues

View File

@@ -19,30 +19,30 @@
"buildDocs": "tsdoc" "buildDocs": "tsdoc"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^4.0.2", "@git.zone/tsbuild": "^4.3.0",
"@git.zone/tsrun": "^2.0.1", "@git.zone/tsrun": "^2.0.1",
"@git.zone/tstest": "^3.1.4", "@git.zone/tstest": "^3.3.2",
"@types/node": "^25.0.3" "@types/node": "^25.4.0"
}, },
"dependencies": { "dependencies": {
"@git.zone/tspublish": "^1.11.0", "@git.zone/tspublish": "^1.11.2",
"@push.rocks/early": "^4.0.4", "@push.rocks/early": "^4.0.4",
"@push.rocks/npmextra": "^5.3.3", "@push.rocks/npmextra": "^5.3.3",
"@push.rocks/qenv": "^6.1.3", "@push.rocks/qenv": "^6.1.3",
"@push.rocks/smartagent": "1.2.5", "@push.rocks/smartagent": "^3.0.2",
"@push.rocks/smartai": "^0.8.0", "@push.rocks/smartai": "^2.0.0",
"@push.rocks/smartcli": "^4.0.19", "@push.rocks/smartcli": "^4.0.20",
"@push.rocks/smartdelay": "^3.0.5", "@push.rocks/smartdelay": "^3.0.5",
"@push.rocks/smartfile": "^13.1.2", "@push.rocks/smartfile": "^13.1.2",
"@push.rocks/smartfs": "^1.3.1", "@push.rocks/smartfs": "^1.5.0",
"@push.rocks/smartgit": "^3.3.1", "@push.rocks/smartgit": "^3.3.1",
"@push.rocks/smartinteract": "^2.0.16", "@push.rocks/smartinteract": "^2.0.16",
"@push.rocks/smartlog": "^3.1.10", "@push.rocks/smartlog": "^3.2.1",
"@push.rocks/smartlog-destination-local": "^9.0.2", "@push.rocks/smartlog-destination-local": "^9.0.2",
"@push.rocks/smartpath": "^6.0.0", "@push.rocks/smartpath": "^6.0.0",
"@push.rocks/smartshell": "^3.3.0", "@push.rocks/smartshell": "^3.3.7",
"@push.rocks/smarttime": "^4.1.1", "@push.rocks/smarttime": "^4.2.3",
"typedoc": "^0.28.15", "typedoc": "^0.28.17",
"typescript": "^5.9.3" "typescript": "^5.9.3"
}, },
"files": [ "files": [

3174
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

492
readme.md
View File

@@ -1,4 +1,4 @@
# @git.zone/tsdoc 🚀 # @git.zone/tsdoc
AI-Powered Documentation for TypeScript Projects AI-Powered Documentation for TypeScript Projects
@@ -6,402 +6,226 @@ AI-Powered Documentation for TypeScript Projects
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly. For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
## What is tsdoc? ## Install
`@git.zone/tsdoc` is a next-generation documentation CLI tool that combines traditional TypeDoc generation with cutting-edge AI to create comprehensive, intelligent documentation for your TypeScript projects. It reads your code, understands it, and writes documentation that actually makes sense.
### ✨ Key Features
- **🤖 AI-Enhanced Documentation** - Leverages AI to generate contextual READMEs
- **🧠 Smart Context Building** - Intelligent file prioritization with dependency analysis and caching
- **📚 TypeDoc Integration** - Classic API documentation generation when you need it
- **💬 Smart Commit Messages** - AI analyzes your changes and suggests meaningful commit messages
- **🎯 Context Optimization** - Advanced token management with 40-60% reduction in usage
- **⚡ Performance Optimized** - 3-5x faster with lazy loading and parallel processing
- **📦 Zero Config** - Works out of the box with sensible defaults
- **🔧 Highly Configurable** - Customize every aspect when needed
## Installation
```bash ```bash
# Global installation (recommended) # Global installation (recommended for CLI usage)
pnpm add -g @git.zone/tsdoc pnpm add -g @git.zone/tsdoc
# Or use with npx # Or use with npx
npx @git.zone/tsdoc npx @git.zone/tsdoc
# Or install locally as a dependency
pnpm add @git.zone/tsdoc
``` ```
## Quick Start ## Usage
### Generate AI-Powered Documentation `@git.zone/tsdoc` is a comprehensive TypeScript documentation tool that combines traditional TypeDoc API documentation generation with AI-powered documentation workflows. It uses OpenAI models via the Vercel AI SDK to generate READMEs, project descriptions, keywords, and semantic commit messages by intelligently exploring your project with agentic tool use.
### CLI Commands
| Command | Description |
|---------|-------------|
| `tsdoc` | Auto-detects project type and runs TypeDoc |
| `tsdoc aidoc` | Generates AI-powered README + description/keywords |
| `tsdoc readme` | Generates AI-powered README only |
| `tsdoc description` | Generates AI-powered description and keywords only |
| `tsdoc commit` | Generates a semantic commit message from uncommitted changes |
| `tsdoc typedoc` | Generates traditional TypeDoc API documentation |
### Generating AI-Powered Documentation
The `aidoc` command combines README generation and description/keyword generation in one step:
```bash ```bash
# In your project root # In your project root
tsdoc aidoc tsdoc aidoc
``` ```
That's it! tsdoc will analyze your entire codebase and generate: This will:
- A comprehensive README.md 1. Analyze your codebase using an AI agent with filesystem access
- Updated package.json description and keywords 2. Generate a comprehensive `readme.md`
- Smart documentation based on your actual code structure 3. Update `package.json` and `npmextra.json` with an AI-generated description and keywords
### Generate Traditional TypeDoc You can also run these separately:
```bash ```bash
tsdoc typedoc --publicSubdir docs # Generate only the README
tsdoc readme
# Generate only the description and keywords
tsdoc description
``` ```
### Get Smart Commit Messages ### Generating Commit Messages
The `commit` command analyzes your uncommitted changes and produces a structured commit object:
```bash ```bash
tsdoc commit tsdoc commit
``` ```
## CLI Commands Output is a JSON object following conventional commits:
| Command | Description | ```json
|---------|-------------| {
| `tsdoc` | Auto-detects and runs appropriate documentation | "recommendedNextVersionLevel": "feat",
| `tsdoc aidoc` | Generate AI-enhanced documentation | "recommendedNextVersionScope": "core",
| `tsdoc typedoc` | Generate TypeDoc documentation | "recommendedNextVersionMessage": "add new feature for better documentation",
| `tsdoc commit` | Generate smart commit message | "recommendedNextVersionDetails": [
| `tsdoc tokens` | Analyze token usage for AI context | "implemented X",
"refactored Y"
### Token Analysis ],
"recommendedNextVersion": "1.13.0",
Understanding token usage helps optimize AI costs: "changelog": "# Changelog\n\n## 2026-03-11 - 1.13.0 - core\n..."
}
```bash
# Show token count for current project
tsdoc tokens
# Show detailed stats for all task types
tsdoc tokens --all
# Show detailed breakdown with file listing
tsdoc tokens --detailed --listFiles
``` ```
### Command Options The commit command includes intelligent diff processing that:
- Excludes lock files, build artifacts, IDE directories, and caches from the diff
- Prioritizes source files over build artifacts
- Samples large diffs with head/tail extraction to stay within token budgets
- Automatically generates or updates the changelog
#### tsdoc aidoc ### Generating TypeDoc
- `--tokens` / `--showTokens` - Show token count before generating
- `--tokensOnly` - Only show token count, don't generate
#### tsdoc typedoc For traditional API documentation via TypeDoc:
- `--publicSubdir <dir>` - Output subdirectory within public folder
#### tsdoc tokens ```bash
- `--task <type>` - Specify task type: `readme`, `commit`, or `description` # Generate to default ./public directory
- `--all` - Show stats for all task types tsdoc typedoc
- `--detailed` - Show detailed token usage and costs
- `--listFiles` - List all files included in context # Generate to a specific subdirectory
- `--model <name>` - Show usage for specific model (`gpt4`, `gpt35`) tsdoc typedoc --publicSubdir docs
```
### Monorepo Support
When generating READMEs, tsdoc automatically detects monorepo submodules via `@git.zone/tspublish` conventions. Each submodule directory with a `tspublish.json` gets its own generated README.
### Programmatic API
You can also use tsdoc programmatically:
```typescript
import { AiDoc } from '@git.zone/tsdoc';
const aidoc = new AiDoc();
await aidoc.start(); // Initializes the AI model (prompts for OpenAI token if needed)
// Generate a README
await aidoc.buildReadme('/path/to/project');
// Generate description and keywords
await aidoc.buildDescription('/path/to/project');
// Generate a commit message object
const commitObj = await aidoc.buildNextCommitObject('/path/to/project');
console.log(commitObj);
// Get project context information
const context = await aidoc.getProjectContext('/path/to/project');
// Get token count for a project
const tokenCount = await aidoc.getProjectContextTokenCount('/path/to/project');
// Estimate tokens in arbitrary text
const tokens = aidoc.countTokens('some text here');
await aidoc.stop();
```
## Configuration ## Configuration
Configure tsdoc via `npmextra.json`: ### OpenAI Token
An OpenAI API key is required for all AI features. It can be provided in three ways:
1. **Environment variable**: `OPENAI_TOKEN`
2. **Interactive prompt**: On first run, tsdoc will prompt for the token and persist it
3. **Constructor argument**: Pass `{ OPENAI_TOKEN: 'sk-...' }` to `new AiDoc()`
The token is persisted at `~/.npmextra/kv/@git.zone/tsdoc.json` for subsequent runs.
### npmextra.json
tsdoc uses `npmextra.json` for project metadata. The `tsdoc` key holds legal information that gets appended to generated READMEs:
```json ```json
{ {
"@git.zone/tsdoc": { "tsdoc": {
"legal": "## License and Legal Information\n\n...", "legal": "\n## License and Legal Information\n\n..."
"context": { },
"maxTokens": 190000, "gitzone": {
"defaultMode": "trimmed", "module": {
"cache": { "githost": "gitlab.com",
"enabled": true, "gitscope": "gitzone",
"ttl": 3600, "gitrepo": "tsdoc",
"maxSize": 100 "npmPackagename": "@git.zone/tsdoc",
}, "description": "...",
"analyzer": { "keywords": ["..."]
"useAIRefinement": false
},
"prioritization": {
"dependencyWeight": 0.3,
"relevanceWeight": 0.4,
"efficiencyWeight": 0.2,
"recencyWeight": 0.1
},
"tiers": {
"essential": { "minScore": 0.8, "trimLevel": "none" },
"important": { "minScore": 0.5, "trimLevel": "light" },
"optional": { "minScore": 0.2, "trimLevel": "aggressive" }
},
"taskSpecificSettings": {
"readme": {
"mode": "trimmed",
"includePaths": ["ts/", "src/"],
"excludePaths": ["test/", "node_modules/"]
},
"commit": {
"mode": "trimmed",
"focusOnChangedFiles": true
}
},
"trimming": {
"removeImplementations": true,
"preserveInterfaces": true,
"preserveJSDoc": true,
"maxFunctionLines": 5,
"removeComments": true
}
} }
} }
} }
``` ```
### Configuration Options
#### Context Settings
- **maxTokens** - Maximum tokens for AI context (default: 190000)
- **defaultMode** - Default context mode: 'full', 'trimmed', or 'summarized'
- **cache** - Caching configuration for improved performance
- **analyzer** - Smart file analysis and prioritization settings
- **prioritization** - Weights for file importance scoring
- **tiers** - Tier thresholds and trimming levels
#### Cache Configuration
- **enabled** - Enable/disable file caching (default: true)
- **ttl** - Time-to-live in seconds (default: 3600)
- **maxSize** - Maximum cache size in MB (default: 100)
- **directory** - Cache directory path (default: .nogit/context-cache)
## How It Works
### 🚀 Smart Context Building Pipeline
1. **📊 Fast Metadata Scanning** - Lazy loading scans files without reading contents
2. **🧬 Dependency Analysis** - Builds dependency graph from import statements
3. **🎯 Intelligent Scoring** - Multi-factor importance scoring:
- **Relevance**: Task-specific file importance (e.g., index.ts for READMEs)
- **Centrality**: How many files depend on this file
- **Efficiency**: Information density (tokens vs. value)
- **Recency**: Recently changed files (for commits)
4. **🏆 Smart Prioritization** - Files sorted by combined importance score
5. **🎭 Tier-Based Trimming** - Adaptive trimming based on importance:
- **Essential** (score ≥ 0.8): No trimming
- **Important** (score ≥ 0.5): Light trimming
- **Optional** (score ≥ 0.2): Aggressive trimming
6. **💾 Intelligent Caching** - Cache results with file change detection
7. **🧠 AI Processing** - Send optimized context to AI for documentation
### Context Optimization Benefits
The smart context system delivers significant improvements:
| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| **Token Usage** | ~190k (limit) | ~110-130k | ⬇️ 40-60% reduction |
| **Build Time** | 4-6 seconds | 1-2 seconds | ⚡ 3-5x faster |
| **Memory Usage** | All files loaded | Metadata + selected | 📉 80%+ reduction |
| **Relevance** | Alphabetical sorting | Smart scoring | 🎯 90%+ relevant |
| **Cache Hits** | None | 70-80% | 🚀 Major speedup |
## Environment Variables
| Variable | Description |
|----------|-------------|
| `OPENAI_TOKEN` | Your OpenAI API key for AI features (required) |
The token can also be provided interactively on first run - it will be persisted in `~/.npmextra/kv/@git.zone/tsdoc.json`.
## Use Cases
### 🚀 Continuous Integration
```yaml
# .github/workflows/docs.yml
name: Documentation
on: [push]
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Generate Documentation
env:
OPENAI_TOKEN: ${{ secrets.OPENAI_TOKEN }}
run: |
npm install -g @git.zone/tsdoc
tsdoc aidoc
- name: Commit Changes
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add readme.md package.json
git commit -m "docs: update documentation [skip ci]" || exit 0
git push
```
### 🔄 Pre-Commit Hooks
```bash
# .git/hooks/prepare-commit-msg
#!/bin/bash
tsdoc commit > .git/COMMIT_EDITMSG
```
### 📦 Package Publishing
```json
{
"scripts": {
"prepublishOnly": "tsdoc aidoc",
"version": "tsdoc aidoc && git add readme.md"
}
}
```
## Requirements
- **Node.js** >= 18.0.0
- **TypeScript** project
- **OpenAI API key** (for AI features)
## Troubleshooting
### Token Limit Exceeded
If you hit token limits, try:
```bash
# Check token usage details
tsdoc tokens --all --detailed
```
Or configure stricter limits in `npmextra.json`:
```json
{
"@git.zone/tsdoc": {
"context": {
"maxTokens": 100000,
"tiers": {
"essential": { "minScore": 0.9, "trimLevel": "none" },
"important": { "minScore": 0.7, "trimLevel": "aggressive" },
"optional": { "minScore": 0.5, "trimLevel": "aggressive" }
}
}
}
}
```
### Missing API Key
Set your OpenAI key:
```bash
export OPENAI_TOKEN="your-key-here"
tsdoc aidoc
```
### Slow Performance
Enable caching and adjust settings in `npmextra.json`:
```json
{
"@git.zone/tsdoc": {
"context": {
"cache": {
"enabled": true,
"ttl": 7200,
"maxSize": 200
}
}
}
}
```
### Cache Issues
Clear the cache if needed:
```bash
rm -rf .nogit/context-cache
```
## Why tsdoc?
### 🎯 Actually Understands Your Code
Not just parsing, but real comprehension through AI. The smart context system ensures AI sees the most relevant parts of your codebase.
### ⏱️ Saves Hours
Generate complete, accurate documentation in seconds. The intelligent caching system makes subsequent runs even faster.
### 🔄 Always Up-to-Date
Regenerate documentation with every change. Smart dependency analysis ensures nothing important is missed.
### 🎨 Beautiful Output
Clean, professional documentation every time. AI understands your code's purpose and explains it clearly.
### 💰 Cost-Effective
Smart context optimization reduces AI API costs by 40-60% without sacrificing quality.
## Architecture ## Architecture
### Core Components ### Core Components
``` ```
@git.zone/tsdoc @git.zone/tsdoc
├── AiDoc # Main AI documentation orchestrator ├── AiDoc # Main orchestrator - manages AI model and delegates to task classes
├── TypeDoc # Traditional TypeDoc integration ├── TypeDoc # Traditional TypeDoc API documentation generation
├── Context System # Smart context building ├── ProjectContext # Gathers project files for context (package.json, ts/, test/)
│ ├── EnhancedContext # Main context builder ├── DiffProcessor # Intelligent git diff processing with prioritization and sampling
│ ├── LazyFileLoader # Efficient file loading ├── Readme # AI-powered README generation using runAgent with filesystem tools
├── ContextCache # Performance caching ├── Commit # AI-powered commit message generation with diff analysis
│ ├── ContextAnalyzer # Intelligent file analysis ├── Description # AI-powered description and keyword generation
│ ├── ContextTrimmer # Adaptive code trimming └── CLI # Command-line interface built on @push.rocks/smartcli
│ ├── DiffProcessor # Git diff optimization
│ ├── ConfigManager # Configuration management
│ └── TaskContextFactory # Task-specific contexts
└── CLI # Command-line interface
``` ```
### Data Flow ### AI Agent Architecture
``` tsdoc uses `@push.rocks/smartagent`'s `runAgent()` function with `@push.rocks/smartai`'s `getModel()` for all AI tasks. Each documentation task (readme, commit, description) runs an autonomous AI agent that:
Project Files
1. Receives a system prompt defining its role and constraints
LazyFileLoader (metadata scan) 2. Gets access to scoped filesystem tools (read-only, limited to project directory)
3. Explores the project structure autonomously using tool calls
ContextAnalyzer (scoring & prioritization) 4. Produces the final output (README markdown, commit JSON, or description JSON)
ContextCache (check cache) ### Diff Processing
File Loading (parallel, on-demand) The `DiffProcessor` class handles large git diffs intelligently:
ContextTrimmer (tier-based) - **Small files** (< 300 lines): Included in full
- **Medium files** (< 800 lines): Head/tail sampling with context
Token Budget (enforcement) - **Large files**: Metadata only (filepath, lines added/removed)
- Files are prioritized by importance: source > test > config > docs > build artifacts
AI Model - Token budget is enforced dynamically based on OpenAI's context limits
Generated Documentation ## Requirements
```
- **Node.js** >= 18.0.0
- **TypeScript** project with `ts/` source directory
- **OpenAI API key** (for AI features)
## License and Legal Information ## License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file. This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file. **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
### Trademarks ### Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein. This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
### Company Information ### Company Information
Task Venture Capital GmbH Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task.vc. For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

View File

@@ -39,4 +39,4 @@ tap.test('should stop AIdocs', async () => {
await aidocs.stop(); await aidocs.stop();
}); });
tap.start(); export default tap.start();

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@git.zone/tsdoc', name: '@git.zone/tsdoc',
version: '1.12.0', version: '2.0.0',
description: 'A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.' description: 'A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.'
} }

View File

@@ -103,7 +103,7 @@ export class Commit {
const totalChars = diffStringArray.join('\n\n').length; const totalChars = diffStringArray.join('\n\n').length;
const estimatedTokens = Math.ceil(totalChars / 4); const estimatedTokens = Math.ceil(totalChars / 4);
console.log(`📊 Raw git diff statistics:`); console.log(`Raw git diff statistics:`);
console.log(` Files changed: ${diffStringArray.length}`); console.log(` Files changed: ${diffStringArray.length}`);
console.log(` Total characters: ${totalChars.toLocaleString()}`); console.log(` Total characters: ${totalChars.toLocaleString()}`);
console.log(` Estimated tokens: ${estimatedTokens.toLocaleString()}`); console.log(` Estimated tokens: ${estimatedTokens.toLocaleString()}`);
@@ -111,7 +111,7 @@ export class Commit {
// Calculate available tokens for diff based on total budget // Calculate available tokens for diff based on total budget
const maxDiffTokens = calculateMaxDiffTokens(); const maxDiffTokens = calculateMaxDiffTokens();
console.log(`📊 Token budget: ${maxDiffTokens.toLocaleString()} tokens for diff (limit: ${TOKEN_BUDGET.OPENAI_CONTEXT_LIMIT.toLocaleString()}, overhead: ${(TOKEN_BUDGET.SMARTAGENT_OVERHEAD + TOKEN_BUDGET.TASK_PROMPT_OVERHEAD).toLocaleString()})`); console.log(`Token budget: ${maxDiffTokens.toLocaleString()} tokens for diff (limit: ${TOKEN_BUDGET.OPENAI_CONTEXT_LIMIT.toLocaleString()}, overhead: ${(TOKEN_BUDGET.SMARTAGENT_OVERHEAD + TOKEN_BUDGET.TASK_PROMPT_OVERHEAD).toLocaleString()})`);
// Use DiffProcessor to intelligently handle large diffs // Use DiffProcessor to intelligently handle large diffs
const diffProcessor = new DiffProcessor({ const diffProcessor = new DiffProcessor({
@@ -125,14 +125,14 @@ export class Commit {
const processedDiff = diffProcessor.processDiffs(diffStringArray); const processedDiff = diffProcessor.processDiffs(diffStringArray);
processedDiffString = diffProcessor.formatForContext(processedDiff); processedDiffString = diffProcessor.formatForContext(processedDiff);
console.log(`📝 Processed diff statistics:`); console.log(`Processed diff statistics:`);
console.log(` Full diffs: ${processedDiff.fullDiffs.length} files`); console.log(` Full diffs: ${processedDiff.fullDiffs.length} files`);
console.log(` Summarized: ${processedDiff.summarizedDiffs.length} files`); console.log(` Summarized: ${processedDiff.summarizedDiffs.length} files`);
console.log(` Metadata only: ${processedDiff.metadataOnly.length} files`); console.log(` Metadata only: ${processedDiff.metadataOnly.length} files`);
console.log(` Final tokens: ${processedDiff.totalTokens.toLocaleString()}`); console.log(` Final tokens: ${processedDiff.totalTokens.toLocaleString()}`);
if (estimatedTokens > 50000) { if (estimatedTokens > 50000) {
console.log(`DiffProcessor reduced token usage: ${estimatedTokens.toLocaleString()} ${processedDiff.totalTokens.toLocaleString()}`); console.log(`DiffProcessor reduced token usage: ${estimatedTokens.toLocaleString()} -> ${processedDiff.totalTokens.toLocaleString()}`);
} }
// Validate total tokens won't exceed limit // Validate total tokens won't exceed limit
@@ -141,71 +141,44 @@ export class Commit {
+ TOKEN_BUDGET.TASK_PROMPT_OVERHEAD; + TOKEN_BUDGET.TASK_PROMPT_OVERHEAD;
if (totalEstimatedTokens > TOKEN_BUDGET.OPENAI_CONTEXT_LIMIT - TOKEN_BUDGET.SAFETY_MARGIN) { if (totalEstimatedTokens > TOKEN_BUDGET.OPENAI_CONTEXT_LIMIT - TOKEN_BUDGET.SAFETY_MARGIN) {
console.log(`⚠️ Warning: Estimated tokens (${totalEstimatedTokens.toLocaleString()}) approaching limit`); console.log(`Warning: Estimated tokens (${totalEstimatedTokens.toLocaleString()}) approaching limit`);
console.log(` Consider splitting into smaller commits`); console.log(` Consider splitting into smaller commits`);
} }
} else { } else {
processedDiffString = 'No changes.'; processedDiffString = 'No changes.';
} }
// Use DualAgentOrchestrator for commit message generation // Use runAgent for commit message generation with filesystem tool
const commitOrchestrator = new plugins.smartagent.DualAgentOrchestrator({ const fsTools = plugins.smartagentTools.filesystemTool({ rootDir: this.projectDir });
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
logPrefix: '[Commit]',
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
guardianPolicyPrompt: `
You validate commit messages for semantic versioning compliance.
APPROVE tool calls for: const commitSystemPrompt = `
- Reading package.json or source files to understand project context You create commit messages for git commits following semantic versioning conventions.
- Using tree to see project structure
- Listing directory contents
REJECT tool calls for: You have access to filesystem tools to explore the project if needed.
- Reading files outside the project directory
- Writing, deleting, or modifying any files
- Any destructive operations
APPROVE final output if: IMPORTANT RULES:
- Version level (fix/feat/BREAKING CHANGE) matches the scope of changes in the diff - Only READ files (package.json, source files) for context
- Commit message is clear, professional, and follows conventional commit conventions - Do NOT write, delete, or modify any files
- No personal information, licensing details, or AI mentions (Claude/Codex) included - Version level (fix/feat/BREAKING CHANGE) must match the scope of changes
- JSON structure is valid with all required fields - Commit message must be clear, professional, and follow conventional commit conventions
- Scope accurately reflects the changed modules/files - Do NOT include personal information, licensing details, or AI mentions (Claude/Codex)
- JSON structure must be valid with all required fields
REJECT final output if: - Scope must accurately reflect the changed modules/files
- Version level doesn't match the scope of changes (e.g., "feat" for a typo fix should be "fix") `;
- Message is vague, unprofessional, or contains sensitive information
- JSON is malformed or missing required fields
`,
});
// Register scoped filesystem tool for agent exploration
commitOrchestrator.registerScopedFilesystemTool(this.projectDir, [
'.nogit/**',
'node_modules/**',
'.git/**',
'dist/**',
'dist_*/**',
]);
await commitOrchestrator.start();
const commitTaskPrompt = ` const commitTaskPrompt = `
You create a commit message for a git commit.
Project directory: ${this.projectDir} Project directory: ${this.projectDir}
You have access to a filesystem tool to explore the project if needed: You have access to filesystem tools to explore the project if needed:
- Use tree to see project structure - Use list_directory to see project structure
- Use read to read package.json or source files for context - Use read_file to read package.json or source files for context
Analyze the git diff below to understand what changed and generate a commit message. Analyze the git diff below to understand what changed and generate a commit message.
You should not include any licensing information or personal information. You should not include any licensing information or personal information.
Never mention CLAUDE code, or codex. Never mention CLAUDE code, or codex.
Your final output (inside the task_complete tags) must be ONLY valid JSON - the raw JSON object, nothing else. Your final response must be ONLY valid JSON - the raw JSON object, nothing else.
No explanations, no summaries, no markdown - just the JSON object that can be parsed with JSON.parse(). No explanations, no summaries, no markdown - just the JSON object that can be parsed with JSON.parse().
Here is the structure of the JSON you must return: Here is the structure of the JSON you must return:
@@ -227,15 +200,19 @@ ${processedDiffString}
Analyze these changes and output the JSON commit message object. Analyze these changes and output the JSON commit message object.
`; `;
const commitResult = await commitOrchestrator.run(commitTaskPrompt); logger.log('info', 'Starting commit message generation with agent...');
await commitOrchestrator.stop();
if (!commitResult.success) { const commitResult = await plugins.smartagent.runAgent({
throw new Error(`Commit message generation failed: ${commitResult.status}`); model: this.aiDocsRef.model,
} prompt: commitTaskPrompt,
system: commitSystemPrompt,
tools: fsTools,
maxSteps: 10,
onToolCall: (toolName) => logger.log('info', `[Commit] Tool call: ${toolName}`),
});
// Extract JSON from result - handle cases where AI adds text around it // Extract JSON from result - handle cases where AI adds text around it
let jsonString = commitResult.result let jsonString = commitResult.text
.replace(/```json\n?/gi, '') .replace(/```json\n?/gi, '')
.replace(/```\n?/gi, ''); .replace(/```\n?/gi, '');
@@ -259,30 +236,16 @@ Analyze these changes and output the JSON commit message object.
const commitMessages = await gitRepo.getAllCommitMessages(); const commitMessages = await gitRepo.getAllCommitMessages();
console.log(JSON.stringify(commitMessages, null, 2)); console.log(JSON.stringify(commitMessages, null, 2));
// Use DualAgentOrchestrator for changelog generation with Guardian validation const changelogSystemPrompt = `
const changelogOrchestrator = new plugins.smartagent.DualAgentOrchestrator({ You generate changelog.md files for software projects.
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
logPrefix: '[Changelog]',
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
guardianPolicyPrompt: `
You validate changelog generation.
APPROVE if: RULES:
- Changelog follows proper markdown format with ## headers for each version - Changelog must follow proper markdown format with ## headers for each version
- Entries are chronologically ordered (newest first) - Entries must be chronologically ordered (newest first)
- Version ranges for trivial commits are properly summarized - Version ranges for trivial commits should be properly summarized
- No duplicate or empty entries - No duplicate or empty entries
- Format matches: ## yyyy-mm-dd - x.x.x - scope - Format: ## yyyy-mm-dd - x.x.x - scope
`;
REJECT with feedback if:
- Markdown formatting is incorrect
- Entries are not meaningful or helpful
- Dates or versions are malformed
`,
});
await changelogOrchestrator.start();
const changelogTaskPrompt = ` const changelogTaskPrompt = `
You are building a changelog.md file for the project. You are building a changelog.md file for the project.
@@ -291,7 +254,7 @@ Omit commits and versions that lack relevant changes, but make sure to mention t
A changelog entry should look like this: A changelog entry should look like this:
## yyyy-mm-dd - x.x.x - scope here ## yyyy-mm-dd - x.x.x - scope here
main descriptiom here main description here
- detailed bullet points follow - detailed bullet points follow
@@ -305,16 +268,17 @@ Here are the commit messages:
${JSON.stringify(commitMessages, null, 2)} ${JSON.stringify(commitMessages, null, 2)}
`; `;
const changelogResult = await changelogOrchestrator.run(changelogTaskPrompt); const changelogResult = await plugins.smartagent.runAgent({
await changelogOrchestrator.stop(); model: this.aiDocsRef.model,
prompt: changelogTaskPrompt,
if (!changelogResult.success) { system: changelogSystemPrompt,
throw new Error(`Changelog generation failed: ${changelogResult.status}`); maxSteps: 1,
} onToolCall: (toolName) => logger.log('info', `[Changelog] Tool call: ${toolName}`),
});
previousChangelog = plugins.smartfileFactory.fromString( previousChangelog = plugins.smartfileFactory.fromString(
previousChangelogPath, previousChangelogPath,
changelogResult.result.replaceAll('```markdown', '').replaceAll('```', ''), changelogResult.text.replaceAll('```markdown', '').replaceAll('```', ''),
'utf8' 'utf8'
); );
} }

View File

@@ -19,53 +19,29 @@ export class Description {
} }
public async build() { public async build() {
// Use DualAgentOrchestrator with filesystem tool for agent-driven exploration // Use runAgent with filesystem tool for agent-driven exploration
const descriptionOrchestrator = new plugins.smartagent.DualAgentOrchestrator({ const fsTools = plugins.smartagentTools.filesystemTool({ rootDir: this.projectDir });
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
maxIterations: 15,
maxResultChars: 10000, // Limit tool output to prevent token explosion
maxHistoryMessages: 15, // Limit history window
logPrefix: '[Description]',
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
guardianPolicyPrompt: `
You validate description generation tool calls and outputs.
APPROVE tool calls for: const descriptionSystemPrompt = `
- Reading package.json, npmextra.json, or source files in the ts/ directory You create project descriptions and keywords for npm packages.
- Listing directory contents to understand project structure
- Using tree to see project structure
REJECT tool calls for: You have access to filesystem tools to explore the project.
- Reading files outside the project directory
- Writing, deleting, or modifying any files
- Any destructive operations
For final output, APPROVE if: IMPORTANT RULES:
- JSON is valid and parseable - Only READ files (package.json, npmextra.json, source files in ts/)
- Description is a clear, concise one-sentence summary - Do NOT write, delete, or modify any files
- Keywords are relevant to the project's use cases - Your final response must be valid JSON only
- Both description and keywords fields are present - Description must be a clear, concise one-sentence summary
- Keywords must be relevant to the project's use cases
REJECT final output if: - Both description and keywords fields must be present
- JSON is malformed or wrapped in markdown code blocks - Do NOT wrap JSON in markdown code blocks
- Description is too long or vague `;
- Keywords are irrelevant or generic
`,
});
// Register scoped filesystem tool for agent exploration
descriptionOrchestrator.registerScopedFilesystemTool(this.projectDir);
await descriptionOrchestrator.start();
const descriptionTaskPrompt = ` const descriptionTaskPrompt = `
You create a project description and keywords for an npm package.
PROJECT DIRECTORY: ${this.projectDir} PROJECT DIRECTORY: ${this.projectDir}
Use the filesystem tool to explore the project and understand what it does: Use the filesystem tools to explore the project and understand what it does:
1. First, use tree to see the project structure 1. First, use list_directory to see the project structure
2. Read package.json to understand the package name and current description 2. Read package.json to understand the package name and current description
3. Read npmextra.json if it exists for additional metadata 3. Read npmextra.json if it exists for additional metadata
4. Read key source files in ts/ directory to understand the implementation 4. Read key source files in ts/ directory to understand the implementation
@@ -83,16 +59,20 @@ Your answer should be parseable with JSON.parse() without modifying anything.
Don't wrap the JSON in \`\`\`json\`\`\` - just return the raw JSON object. Don't wrap the JSON in \`\`\`json\`\`\` - just return the raw JSON object.
`; `;
const descriptionResult = await descriptionOrchestrator.run(descriptionTaskPrompt); logger.log('info', 'Starting description generation with agent...');
await descriptionOrchestrator.stop();
if (!descriptionResult.success) { const descriptionResult = await plugins.smartagent.runAgent({
throw new Error(`Description generation failed: ${descriptionResult.status}`); model: this.aiDocsRef.model,
} prompt: descriptionTaskPrompt,
system: descriptionSystemPrompt,
tools: fsTools,
maxSteps: 15,
onToolCall: (toolName) => logger.log('info', `[Description] Tool call: ${toolName}`),
});
console.log(descriptionResult.result); console.log(descriptionResult.text);
const resultObject: IDescriptionInterface = JSON.parse( const resultObject: IDescriptionInterface = JSON.parse(
descriptionResult.result.replace('```json', '').replace('```', ''), descriptionResult.text.replace('```json', '').replace('```', ''),
); );
// Use ProjectContext to get file handles for writing // Use ProjectContext to get file handles for writing
@@ -120,6 +100,6 @@ Don't wrap the JSON in \`\`\`json\`\`\` - just return the raw JSON object.
console.log(`\n======================\n`); console.log(`\n======================\n`);
console.log(JSON.stringify(resultObject, null, 2)); console.log(JSON.stringify(resultObject, null, 2));
console.log(`\n======================\n`); console.log(`\n======================\n`);
return descriptionResult.result; return descriptionResult.text;
} }
} }

View File

@@ -28,55 +28,31 @@ export class Readme {
console.log(error); console.log(error);
} }
// Use DualAgentOrchestrator with filesystem tool for agent-driven exploration // Use runAgent with filesystem tool for agent-driven exploration
const readmeOrchestrator = new plugins.smartagent.DualAgentOrchestrator({ const fsTools = plugins.smartagentTools.filesystemTool({ rootDir: this.projectDir });
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
maxIterations: 25,
maxResultChars: 15000, // Limit tool output to prevent token explosion
maxHistoryMessages: 20, // Limit history window
logPrefix: '[README]',
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
guardianPolicyPrompt: `
You validate README generation tool calls and outputs.
APPROVE tool calls for: const readmeSystemPrompt = `
- Reading any files within the project directory (package.json, ts/*.ts, readme.md, etc.)
- Using tree to see project structure
- Using glob to find source files
- Listing directory contents
REJECT tool calls for:
- Reading files outside the project directory
- Writing, deleting, or modifying any files
- Any destructive operations
For final README output, APPROVE if:
- README follows proper markdown format
- Contains Install and Usage sections
- Code examples are correct TypeScript/ESM syntax
- Documentation is comprehensive and helpful
REJECT final output if:
- README is incomplete or poorly formatted
- Contains licensing information (added separately)
- Uses CommonJS syntax instead of ESM
- Contains "in conclusion" or similar filler
`,
});
// Register scoped filesystem tool for agent exploration
readmeOrchestrator.registerScopedFilesystemTool(this.projectDir);
await readmeOrchestrator.start();
const readmeTaskPrompt = `
You create markdown READMEs for npm projects. You only output the markdown readme. You create markdown READMEs for npm projects. You only output the markdown readme.
You have access to filesystem tools to explore the project. Use them to understand the codebase.
IMPORTANT RULES:
- Only READ files within the project directory
- Do NOT write, delete, or modify any files
- README must follow proper markdown format
- Must contain Install and Usage sections
- Code examples must use correct TypeScript/ESM syntax
- Documentation must be comprehensive and helpful
- Do NOT include licensing information (added separately)
- Do NOT use CommonJS syntax - only ESM
- Do NOT include "in conclusion" or similar filler
`;
const readmeTaskPrompt = `
PROJECT DIRECTORY: ${this.projectDir} PROJECT DIRECTORY: ${this.projectDir}
Use the filesystem tool to explore the project and understand what it does: Use the filesystem tools to explore the project and understand what it does:
1. First, use tree to see the project structure (maxDepth: 3) 1. First, use list_directory to see the project structure
2. Read package.json to understand the package name, description, and dependencies 2. Read package.json to understand the package name, description, and dependencies
3. Read the existing readme.md if it exists (use it as a base, improve and expand) 3. Read the existing readme.md if it exists (use it as a base, improve and expand)
4. Read readme.hints.md if it exists (contains hints for documentation) 4. Read readme.hints.md if it exists (contains hints for documentation)
@@ -106,15 +82,19 @@ Then generate a comprehensive README following this template:
] ]
`; `;
const readmeResult = await readmeOrchestrator.run(readmeTaskPrompt); logger.log('info', 'Starting README generation with agent...');
await readmeOrchestrator.stop();
if (!readmeResult.success) { const readmeResult = await plugins.smartagent.runAgent({
throw new Error(`README generation failed: ${readmeResult.status}`); model: this.aiDocsRef.model,
} prompt: readmeTaskPrompt,
system: readmeSystemPrompt,
tools: fsTools,
maxSteps: 25,
onToolCall: (toolName) => logger.log('info', `[README] Tool call: ${toolName}`),
});
// Clean up markdown formatting if wrapped in code blocks // Clean up markdown formatting if wrapped in code blocks
let resultMessage = readmeResult.result let resultMessage = readmeResult.text
.replace(/^```markdown\n?/i, '') .replace(/^```markdown\n?/i, '')
.replace(/\n?```$/i, ''); .replace(/\n?```$/i, '');
@@ -142,40 +122,19 @@ Then generate a comprehensive README following this template:
.encoding('utf8') .encoding('utf8')
.read(); .read();
// Create a new orchestrator with filesystem tool for each submodule const subModuleFsTools = plugins.smartagentTools.filesystemTool({ rootDir: subModulePath });
const subModuleOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
smartAiInstance: this.aiDocsRef.smartAiInstance,
defaultProvider: 'openai',
maxIterations: 20,
maxResultChars: 12000,
maxHistoryMessages: 15,
logPrefix: `[README:${subModule}]`,
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
guardianPolicyPrompt: `
You validate README generation for submodules.
APPROVE tool calls for: const subModuleSystemPrompt = `
- Reading any files within the submodule directory You create markdown READMEs for npm projects. You only output the markdown readme.
- Using tree to see structure
- Using glob to find source files
REJECT tool calls for: IMPORTANT RULES:
- Reading files outside the submodule directory - Only READ files within the submodule directory
- Writing, deleting, or modifying any files - Do NOT write, delete, or modify any files
- Any destructive operations - README must be comprehensive, well-formatted markdown with ESM TypeScript examples
- Do NOT include licensing information (added separately)
APPROVE final README if comprehensive, well-formatted markdown with ESM TypeScript examples. `;
REJECT incomplete READMEs or those with licensing info.
`,
});
// Register scoped filesystem tool for the submodule directory
subModuleOrchestrator.registerScopedFilesystemTool(subModulePath);
await subModuleOrchestrator.start();
const subModulePrompt = ` const subModulePrompt = `
You create markdown READMEs for npm projects. You only output the markdown readme.
SUB MODULE: ${subModule} SUB MODULE: ${subModule}
SUB MODULE DIRECTORY: ${subModulePath} SUB MODULE DIRECTORY: ${subModulePath}
@@ -183,8 +142,8 @@ IMPORTANT: YOU ARE CREATING THE README FOR THIS SUB MODULE: ${subModule}
The Sub Module will be published with: The Sub Module will be published with:
${JSON.stringify(tspublishData, null, 2)} ${JSON.stringify(tspublishData, null, 2)}
Use the filesystem tool to explore the submodule: Use the filesystem tools to explore the submodule:
1. Use tree to see the submodule structure 1. Use list_directory to see the submodule structure
2. Read package.json to understand the submodule 2. Read package.json to understand the submodule
3. Read source files in ts/ directory to understand the implementation 3. Read source files in ts/ directory to understand the implementation
@@ -208,21 +167,23 @@ Generate a README following the template:
Don't use \`\`\` at the beginning or end. Only for code blocks. Don't use \`\`\` at the beginning or end. Only for code blocks.
`; `;
const subModuleResult = await subModuleOrchestrator.run(subModulePrompt); const subModuleResult = await plugins.smartagent.runAgent({
await subModuleOrchestrator.stop(); model: this.aiDocsRef.model,
prompt: subModulePrompt,
system: subModuleSystemPrompt,
tools: subModuleFsTools,
maxSteps: 20,
onToolCall: (toolName) => logger.log('info', `[README:${subModule}] Tool call: ${toolName}`),
});
if (subModuleResult.success) { const subModuleReadmeString = subModuleResult.text
const subModuleReadmeString = subModuleResult.result .replace(/^```markdown\n?/i, '')
.replace(/^```markdown\n?/i, '') .replace(/\n?```$/i, '') + '\n' + legalInfo;
.replace(/\n?```$/i, '') + '\n' + legalInfo; await plugins.fsInstance
await plugins.fsInstance .file(plugins.path.join(subModulePath, 'readme.md'))
.file(plugins.path.join(subModulePath, 'readme.md')) .encoding('utf8')
.encoding('utf8') .write(subModuleReadmeString);
.write(subModuleReadmeString); logger.log('success', `Built readme for ${subModule}`);
logger.log('success', `Built readme for ${subModule}`);
} else {
logger.log('error', `Failed to build readme for ${subModule}: ${subModuleResult.status}`);
}
} }
return resultMessage; return resultMessage;

View File

@@ -8,7 +8,7 @@ export class AiDoc {
public npmextraKV: plugins.npmextra.KeyValueStore; public npmextraKV: plugins.npmextra.KeyValueStore;
public qenvInstance: plugins.qenv.Qenv; public qenvInstance: plugins.qenv.Qenv;
public aidocInteract: plugins.smartinteract.SmartInteract; public aidocInteract: plugins.smartinteract.SmartInteract;
public smartAiInstance: plugins.smartai.SmartAi; public model: plugins.smartai.LanguageModelV3;
argvArg: any; argvArg: any;
@@ -84,27 +84,16 @@ export class AiDoc {
this.openaiToken = await this.npmextraKV.readKey('OPENAI_TOKEN'); this.openaiToken = await this.npmextraKV.readKey('OPENAI_TOKEN');
} }
// lets assume we have an OPENAI_Token now // Create model using getModel()
this.smartAiInstance = new plugins.smartai.SmartAi({ this.model = plugins.smartai.getModel({
openaiToken: this.openaiToken, provider: 'openai',
model: 'gpt-5.4',
apiKey: this.openaiToken,
}); });
await this.smartAiInstance.start();
} }
public async stop() { public async stop() {
if (this.smartAiInstance) { // No lifecycle management needed with getModel() API
await this.smartAiInstance.stop();
}
// No explicit cleanup needed for npmextraKV or aidocInteract
// They don't keep event loop alive
}
/**
* Get the OpenAI provider for direct chat calls
* This is a convenience getter to access the provider from SmartAi
*/
public get openaiProvider(): plugins.smartai.OpenAiProvider {
return this.smartAiInstance.openaiProvider;
} }
public getOpenaiToken(): string { public getOpenaiToken(): string {

View File

@@ -7,6 +7,7 @@ export { path };
import * as npmextra from '@push.rocks/npmextra'; import * as npmextra from '@push.rocks/npmextra';
import * as qenv from '@push.rocks/qenv'; import * as qenv from '@push.rocks/qenv';
import * as smartagent from '@push.rocks/smartagent'; import * as smartagent from '@push.rocks/smartagent';
import * as smartagentTools from '@push.rocks/smartagent/tools';
import * as smartai from '@push.rocks/smartai'; import * as smartai from '@push.rocks/smartai';
import * as smartcli from '@push.rocks/smartcli'; import * as smartcli from '@push.rocks/smartcli';
import * as smartdelay from '@push.rocks/smartdelay'; import * as smartdelay from '@push.rocks/smartdelay';
@@ -24,6 +25,7 @@ export {
npmextra, npmextra,
qenv, qenv,
smartagent, smartagent,
smartagentTools,
smartai, smartai,
smartcli, smartcli,
smartdelay, smartdelay,