Files
openhuman/scripts/tools-generator/openClaw-formatter.js
T
Steven EnamakelandGitHub bfaabd3b86 fix/rename (#20)
* chore: update AlphaHuman version to 0.49.3 and configure updater plugin in tauri.conf.json

- Bumped the AlphaHuman package version in Cargo.lock to 0.49.3.
- Added updater configuration in tauri.conf.json to enable automatic updates with specified endpoints.

* refactor: rename AlphaHuman to OpenHuman across the codebase

- Updated all instances of "AlphaHuman" to "OpenHuman" in comments, tooltips, and constants to reflect the new branding.
- Adjusted relevant documentation and prompts to ensure consistency with the new name.

* refactor: update documentation and configurations to reflect OpenHuman branding

- Replaced all instances of "AlphaHuman" with "OpenHuman" in documentation, comments, and configuration files to ensure consistency with the new branding.
- Updated deep link URLs and related authentication flows to use the new "openhuman://" scheme.
- Adjusted paths and references in the skills system and other related files to align with the new project name.te

* refactor: standardize OpenHuman references and update configurations

- Replaced all instances of "AlphaHuman" with "OpenHuman" across documentation, comments, and configuration files to maintain branding consistency.
- Updated URLs and paths to reflect the new "openhuman://" scheme.
- Adjusted environment variable names and related settings to align with the new project identity.
- Enhanced documentation for clarity and accuracy regarding the OpenHuman framework.r

* chore: update subproject commit reference in skills directory

* refactor: update backend URL to reflect new service domain

- Changed default backend URL from "https://api.openhuman.xyz" to "https://api.tinyhumans.ai" in both JavaScript and Rust configuration files.
- Ensured consistency across the codebase regarding the new backend service endpoint.

* feat: introduce identity and migration modules for OpenHuman

- Added a new identity module to support AIEOS v1.1 JSON format, including structures for identity, psychology, linguistics, motivations, capabilities, physicality, history, and interests.
- Implemented a migration module to facilitate data migration from OpenClaw memory, including SQLite and Markdown sources, with detailed reporting on migration statistics and warnings.
- Established utility functions for handling multimodal content and image processing within the OpenHuman framework.
- Enhanced the agent system with new dispatcher and classifier functionalities to improve tool management and message classification.

* chore: remove Android project files and configurations

- Deleted various Android project files including .editorconfig, .gitignore, build.gradle.kts, gradle.properties, and others to clean up the project structure.
- Removed all related resources, layouts, and source files from the Android app directory to streamline the codebase.
- This cleanup is part of a larger effort to refactor and simplify the project structure.

* refactor: update login flow and remove Telegram integration

- Removed the TelegramLoginButton component and its references from the OAuthLoginSection, streamlining the login options.
- Updated the AppRoutes to remove the login route, reflecting changes in the authentication flow.
- Enhanced the RotatingTetrahedronCanvas component with improved geometry and lighting effects for better visual presentation.
- Adjusted the TypewriterGreeting component's styling for consistency.
- Cleaned up the Welcome page to integrate the OAuthLoginSection directly, improving user experience.

* chore: update subproject commit reference in skills directory

* chore: update test configurations and improve test assertions

- Modified test scripts in package.json to use a specific Vitest configuration file for consistency.
- Updated assertions in loader tests to ensure loading durations are non-negative.
- Enhanced tool loading tests to clarify expected behavior regarding localStorage and cache management.
- Adjusted agent tool registry tests to improve error handling and ensure accurate statistics.
- Refined device detection tests to reflect updated fallback URLs.

* fix: enhance parameter formatting and remove unused components

- Updated the `formatParameters` function to handle cases where schema properties are empty, returning a more informative response.
- Deleted the `DownloadScreen` component and associated device detection utilities to streamline the codebase and remove unused functionality.
- Adjusted tests to reflect changes in the tool loading and agent tool registry, ensuring accuracy in assertions.

* chore: simplify Vitest configuration by removing unused include patterns

- Updated the Vitest configuration to remove unnecessary test file patterns, streamlining the test setup for better clarity and maintainability.

* refactor: update paths and comments for AI configuration and file watching

- Modified Vite configuration to ignore only the `src-tauri` directory.
- Updated logging messages to reflect the correct path for writing AI configuration files.
- Adjusted fetch calls in the file watcher to use the new path for `TOOLS.md`.
- Revised comments and logic in Rust code to clarify the handling of AI configuration file paths, including legacy fallback options.

* chore: remove unused updater secrets from GitHub Actions workflow

- Deleted UPDATER_GIST_URL and UPDATER_GIST_ID environment variables from the package-and-publish workflow, streamlining the configuration.

* chore: comment out Vitest thresholds for clarity

- Commented out the thresholds section in the Vitest configuration to improve clarity and maintainability, as it is currently not in use.

* ran formatter

* chore: update updater public key in tauri configuration

- Replaced the existing public key in the updater plugin configuration with a new value to ensure proper functionality and security.

* chore: update ESLint configuration and refactor components

- Added `localStorage` and `sessionStorage` as readonly globals in ESLint configuration for better linting support.
- Removed unused imports from `SkillsPanel.tsx` to clean up the code.
- Changed the type of `watcherInterval` in `file-watcher.ts` for improved type safety.
- Refactored toast management logic in `Intelligence.tsx` to enhance clarity and maintainability.
- Simplified import statements in `IntelligenceProvider.tsx` for consistency.
- Streamlined object property shorthand in `agentToolRegistry.ts` for cleaner code.

* refactor: improve error handling and type safety in Intelligence component

- Enhanced toast notification logic to defer state updates, preventing potential issues with setState in effects.
- Updated the source filter dispatch to use a more specific type for improved type safety.

* refactor: enhance type safety across various components and services

- Updated type definitions from `any` to `unknown` in multiple files to improve type safety and prevent potential runtime errors.
- Refactored state management in `TauriCommandsPanel` to use more specific types.
- Adjusted context and parameters in several interfaces to ensure consistent typing.
- Added ESLint directive to `polyfills.ts` for intentional global assignments.
- Streamlined type handling in utility functions and API responses for better clarity and maintainability.

* refactor: streamline import statements and improve code clarity

- Consolidated import statements in `agentToolRegistry.ts` and `intelligenceSlice.ts` for better readability.
- Simplified the `createTestStore` function in `test-utils.tsx` to enhance code conciseness.
- Cleaned up the `isExecutionStepProgressEvent` function in `intelligence-chat-api.ts` for improved clarity and maintainability.
2026-03-26 17:04:46 -07:00

449 lines
15 KiB
JavaScript

#!/usr/bin/env node
/**
* OpenClaw Framework Formatter
*
* Formats discovered tools into OpenClaw-compliant documentation
* with professional presentation, examples, and usage guidelines.
*/
/**
* Environment configurations for OpenClaw compliance
*/
export const ENVIRONMENTS = {
development: {
name: 'Development',
description: 'Local development environment with full access',
accessLevel: 'Full access to all tools',
rateLimits: 'Relaxed for testing',
authentication: 'Development credentials',
logging: 'Verbose logging enabled',
},
production: {
name: 'Production',
description: 'Production environment with security restrictions',
accessLevel: 'Production-safe tools only',
rateLimits: 'Standard API limits enforced',
authentication: 'Production credentials required',
logging: 'Essential logs only',
},
testing: {
name: 'Testing',
description: 'Testing environment for automated validation',
accessLevel: 'Safe tools for automated testing',
rateLimits: 'Testing-specific limits',
authentication: 'Test credentials',
logging: 'Test execution logs',
},
};
/**
* Tool categories for better organization
*/
export const TOOL_CATEGORIES = {
communication: {
name: 'Communication',
description: 'Tools for messaging, email, and social interaction',
skills: ['telegram', 'gmail', 'discord', 'slack'],
},
productivity: {
name: 'Productivity',
description: 'Tools for task management, note-taking, and organization',
skills: ['notion', 'todoist', 'calendar', 'trello'],
},
automation: {
name: 'Automation',
description: 'Tools for workflow automation and task scheduling',
skills: ['zapier', 'ifttt', 'scheduler', 'webhook'],
},
data: {
name: 'Data & Analytics',
description: 'Tools for data processing, analysis, and storage',
skills: ['database', 'csv', 'json', 'analytics'],
},
media: {
name: 'Media & Content',
description: 'Tools for image, video, and content processing',
skills: ['image', 'video', 'audio', 'pdf'],
},
utility: {
name: 'Utilities',
description: 'General-purpose utility tools and helpers',
skills: ['file', 'text', 'crypto', 'converter'],
},
};
/**
* Converts JSON Schema to markdown parameter documentation
* @param {Object} schema - JSON Schema object
* @returns {string} Formatted markdown for parameters
*/
export function formatParameters(schema) {
if (!schema || !schema.properties || Object.keys(schema.properties).length === 0) {
return '- *None*';
}
const params = [];
const required = schema.required || [];
for (const [name, prop] of Object.entries(schema.properties)) {
const isRequired = required.includes(name);
const requiredMark = isRequired ? ' **(required)**' : '';
const type = prop.type || 'any';
const description = prop.description || 'No description available';
let paramLine = `- **${name}** (${type})${requiredMark}: ${description}`;
// Add enum values if present
if (prop.enum) {
paramLine += ` Options: ${prop.enum.map(v => `\`${v}\``).join(', ')}`;
}
// Add format information
if (prop.format) {
paramLine += ` (Format: ${prop.format})`;
}
// Add constraints
if (prop.minLength || prop.maxLength) {
const constraints = [];
if (prop.minLength) constraints.push(`min: ${prop.minLength}`);
if (prop.maxLength) constraints.push(`max: ${prop.maxLength}`);
paramLine += ` [${constraints.join(', ')}]`;
}
params.push(paramLine);
}
return params.join('\n');
}
/**
* Generates example usage for a tool
* @param {Object} tool - Tool definition
* @returns {string} Formatted example
*/
export function generateToolExample(tool) {
const params = {};
const schema = tool.inputSchema;
if (schema && schema.properties) {
// Generate example values for the first few parameters
for (const [name, prop] of Object.entries(schema.properties)) {
if (Object.keys(params).length >= 3) break; // Limit to 3 params for brevity
let exampleValue;
switch (prop.type) {
case 'string':
exampleValue = prop.enum ? prop.enum[0] : `example_${name}`;
break;
case 'number':
exampleValue = prop.default || 10;
break;
case 'boolean':
exampleValue = prop.default || true;
break;
case 'array':
exampleValue = [];
break;
case 'object':
exampleValue = {};
break;
default:
exampleValue = `example_${name}`;
}
params[name] = exampleValue;
}
}
return JSON.stringify({ tool: tool.name, parameters: params }, null, 2);
}
/**
* Groups tools by skill for better organization
* @param {Array} tools - Array of tool objects
* @returns {Object} Grouped tools by skill
*/
export function groupToolsBySkill(tools) {
const grouped = {};
for (const tool of tools) {
const skillId = tool.skillId;
if (!grouped[skillId]) {
grouped[skillId] = {
skillId,
name: formatSkillName(skillId),
category: categorizeSkill(skillId),
tools: [],
};
}
grouped[skillId].tools.push(tool);
}
return grouped;
}
/**
* Formats skill names for display
* @param {string} skillId - Skill identifier
* @returns {string} Formatted name
*/
function formatSkillName(skillId) {
return skillId
.split(/[-_]/)
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
}
/**
* Categorizes a skill based on its ID
* @param {string} skillId - Skill identifier
* @returns {string} Category name
*/
function categorizeSkill(skillId) {
for (const [category, config] of Object.entries(TOOL_CATEGORIES)) {
if (config.skills.some(skill => skillId.includes(skill))) {
return category;
}
}
return 'utility';
}
/**
* Generates environment configuration section
* @returns {string} Environment documentation
*/
export function generateEnvironmentSection() {
let section = '## Environment Configuration\n\n';
section += 'Tools are available in different environments with varying capabilities:\n\n';
for (const [envId, env] of Object.entries(ENVIRONMENTS)) {
section += `### ${env.name} Environment\n\n`;
section += `${env.description}\n\n`;
section += `- **Access Level**: ${env.accessLevel}\n`;
section += `- **Rate Limits**: ${env.rateLimits}\n`;
section += `- **Authentication**: ${env.authentication}\n`;
section += `- **Logging**: ${env.logging}\n\n`;
}
return section;
}
/**
* Generates tool categories section
* @param {Object} groupedTools - Tools grouped by skill
* @returns {string} Categories documentation
*/
export function generateCategoriesSection(groupedTools) {
const categoryCounts = {};
// Count tools by category
for (const skill of Object.values(groupedTools)) {
const category = skill.category;
if (!categoryCounts[category]) {
categoryCounts[category] = { skills: [], toolCount: 0 };
}
categoryCounts[category].skills.push(skill.skillId);
categoryCounts[category].toolCount += skill.tools.length;
}
let section = '## Tool Categories\n\n';
for (const [categoryId, categoryConfig] of Object.entries(TOOL_CATEGORIES)) {
const counts = categoryCounts[categoryId];
if (!counts) continue;
section += `### ${categoryConfig.name}\n\n`;
section += `${categoryConfig.description}\n\n`;
section += `- **Skills**: ${counts.skills.length}\n`;
section += `- **Tools**: ${counts.toolCount}\n`;
section += `- **Available Skills**: ${counts.skills.map(formatSkillName).join(', ')}\n\n`;
}
return section;
}
/**
* Generates complete tools section with skills and tools
* @param {Object} groupedTools - Tools grouped by skill
* @returns {string} Tools documentation
*/
export function generateToolsSection(groupedTools) {
const skillNames = Object.keys(groupedTools).sort();
let section = '## Available Tools\n\n';
for (const skillId of skillNames) {
const skill = groupedTools[skillId];
const categoryConfig = TOOL_CATEGORIES[skill.category];
section += `### ${skill.name} Tools\n\n`;
if (categoryConfig) {
section += `**Category**: ${categoryConfig.name}\n\n`;
}
section += `This skill provides ${skill.tools.length} tool${skill.tools.length === 1 ? '' : 's'} for ${skillId} integration.\n\n`;
for (const tool of skill.tools) {
section += `#### ${tool.name}\n\n`;
section += `**Description**: ${tool.description}\n\n`;
section += `**Parameters**:\n${formatParameters(tool.inputSchema)}\n\n`;
section += `**Usage Context**: Available in all environments\n\n`;
section += `**Example**:\n\`\`\`json\n${generateToolExample(tool)}\n\`\`\`\n\n`;
section += '---\n\n';
}
}
return section;
}
/**
* Generates usage guidelines section
* @returns {string} Guidelines documentation
*/
export function generateGuidelinesSection() {
return `## Tool Usage Guidelines
### Authentication
- All tools require proper authentication setup through the Skills system
- OAuth credentials are managed securely and refreshed automatically
- API keys are stored encrypted in the application keychain
- Test credentials are available for development and testing environments
### Rate Limiting
- Tools automatically respect API rate limits of external services
- Intelligent retry logic handles temporary failures with exponential backoff
- Bulk operations are automatically chunked to avoid hitting limits
- Rate limit status is monitored and reported in real-time
### Error Handling
- All tools return structured error responses with detailed information
- Network failures trigger automatic retry with configurable attempts
- Invalid parameters return clear validation messages with examples
- Tool execution timeouts are handled gracefully with partial results
### Security & Privacy
- Input validation is performed on all parameters using JSON Schema
- Output sanitization prevents injection attacks and data leakage
- Sensitive data is never logged or exposed in error messages
- All API communications use secure protocols (HTTPS/TLS)
### Performance Optimization
- Tool results are cached when appropriate to reduce API calls
- Parallel execution is used for independent operations
- Connection pooling minimizes overhead for repeated API calls
- Background sync keeps data fresh without blocking operations
### Monitoring & Observability
- Tool execution metrics are collected for performance analysis
- Error rates and response times are monitored continuously
- Debug logging is available in development environments
- Tool usage analytics help optimize integration performance
## Skill Management
Tools are provided by Skills, which are JavaScript modules running in a secure V8 runtime:
- **Discovery**: Tools are automatically discovered at build time from running skills
- **Lifecycle**: Skills can be enabled/disabled independently without affecting others
- **Configuration**: Each skill has its own configuration panel with setup wizards
- **Updates**: Skills are updated through Git submodules and the Skills management system
- **Security**: Skills run in sandboxed environments with limited system access
## Integration Architecture
### V8 Runtime
- Skills execute in isolated V8 JavaScript contexts on desktop platforms
- Mobile platforms use lightweight alternatives with server-side execution
- Memory limits and execution timeouts prevent resource exhaustion
- Inter-skill communication is managed through secure message passing
### API Bridge
- Tools communicate with external services through standardized API bridges
- Rate limiting, retry logic, and error handling are implemented at the bridge level
- Authentication tokens are managed centrally and shared across tools
- Response caching and optimization are handled transparently
### Data Flow
1. Tool request received from AI agent
2. Input validation and parameter processing
3. Skill execution in secure V8 context
4. API calls through standardized bridges
5. Response processing and formatting
6. Result delivery to AI agent
`;
}
/**
* Generates footer section with metadata
* @param {Array} tools - Array of all tools
* @returns {string} Footer content
*/
export function generateFooter(tools) {
const skillCount = new Set(tools.map(t => t.skillId)).size;
return `## Support & Troubleshooting
### Common Issues
1. **Tool Not Available**: Check if the associated skill is enabled in Settings → Skills
2. **Authentication Errors**: Verify credentials in the skill's configuration panel
3. **Rate Limit Exceeded**: Wait for the limit to reset or upgrade your API plan
4. **Invalid Parameters**: Review the parameter documentation and examples above
### Getting Help
- **Skill Documentation**: Each skill has detailed setup and usage instructions
- **Debug Logs**: Enable verbose logging in development mode for detailed error information
- **Community Support**: Join our Discord community for help from other users
- **Technical Support**: Contact our support team for critical issues
### Contributing
- **New Tools**: Submit tool requests through our GitHub repository
- **Bug Reports**: Report issues with specific tools and include error logs
- **Improvements**: Suggest enhancements to existing tools and their documentation
---
**Tool Statistics**
- Total Tools: ${tools.length}
- Active Skills: ${skillCount}
- Categories: ${Object.keys(TOOL_CATEGORIES).length}
- Last Updated: ${new Date().toISOString()}
*This file was automatically generated at build time from the V8 skills runtime.*
*For the most up-to-date information, regenerate this file by running \`yarn tools:generate\`.*
`;
}
/**
* Generates complete OpenClaw-compliant TOOLS.md content
* @param {Array} tools - Array of discovered tools
* @returns {string} Complete TOOLS.md content
*/
export function generateOpenClawMarkdown(tools) {
const grouped = groupToolsBySkill(tools);
const skillNames = Object.keys(grouped);
let content = `# OpenHuman Tools
This document lists all available tools that OpenHuman can use to interact with external services and perform actions. Tools are organized by integration and automatically updated during build time.
## Overview
OpenHuman has access to **${tools.length} tools** across **${skillNames.length} integrations** organized into **${Object.keys(TOOL_CATEGORIES).length} categories**.
**Quick Statistics:**
${skillNames.map(skill => `- **${grouped[skill].name}**: ${grouped[skill].tools.length} tools`).join('\n')}
`;
content += generateEnvironmentSection();
content += generateCategoriesSection(grouped);
content += generateToolsSection(grouped);
content += generateGuidelinesSection();
content += generateFooter(tools);
return content;
}