mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 15:03:57 +00:00
Refactor formatting and improve code consistency
Updated function and parameter formatting for better readability and maintainability. Improved documentation clarity in `TOOLS.md` and ensured code consistency across files by aligning indentation and syntax styles.
This commit is contained in:
+27
-19
@@ -7,6 +7,7 @@ This document lists all available tools that AlphaHuman can use to interact with
|
||||
AlphaHuman has access to **4 tools** across **3 integrations** organized into **6 categories**.
|
||||
|
||||
**Quick Statistics:**
|
||||
|
||||
- **Telegram**: 2 tools
|
||||
- **Notion**: 1 tools
|
||||
- **Gmail**: 1 tools
|
||||
@@ -73,6 +74,7 @@ This skill provides 1 tool for gmail integration.
|
||||
**Description**: Send an email via Gmail
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **body** (string) **(required)**: Email body content
|
||||
- **subject** (string) **(required)**: Email subject line
|
||||
- **to** (string) **(required)**: Recipient email address
|
||||
@@ -80,14 +82,11 @@ This skill provides 1 tool for gmail integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "send_email",
|
||||
"parameters": {
|
||||
"body": "example_body",
|
||||
"subject": "example_subject",
|
||||
"to": "example_to"
|
||||
}
|
||||
"parameters": { "body": "example_body", "subject": "example_subject", "to": "example_to" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -104,6 +103,7 @@ This skill provides 1 tool for notion integration.
|
||||
**Description**: Create a new page in Notion workspace
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **content** (array): Page content blocks
|
||||
- **parent_id** (string) **(required)**: Parent database or page ID
|
||||
- **title** (string) **(required)**: Page title
|
||||
@@ -111,14 +111,11 @@ This skill provides 1 tool for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "create_page",
|
||||
"parameters": {
|
||||
"content": [],
|
||||
"parent_id": "example_parent_id",
|
||||
"title": "example_title"
|
||||
}
|
||||
"parameters": { "content": [], "parent_id": "example_parent_id", "title": "example_title" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -135,6 +132,7 @@ This skill provides 2 tools for telegram integration.
|
||||
**Description**: Send a message to a Telegram chat or user
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **chat_id** (string) **(required)**: Telegram chat ID or username
|
||||
- **message** (string) **(required)**: Message text to send
|
||||
- **parse_mode** (string): Message formatting mode
|
||||
@@ -142,6 +140,7 @@ This skill provides 2 tools for telegram integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "send_message",
|
||||
@@ -160,20 +159,16 @@ This skill provides 2 tools for telegram integration.
|
||||
**Description**: Retrieve message history from a Telegram chat
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **chat_id** (string) **(required)**: Telegram chat ID or username
|
||||
- **limit** (number): Number of messages to retrieve
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "get_chat_history",
|
||||
"parameters": {
|
||||
"chat_id": "example_chat_id",
|
||||
"limit": 10
|
||||
}
|
||||
}
|
||||
{ "tool": "get_chat_history", "parameters": { "chat_id": "example_chat_id", "limit": 10 } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -181,36 +176,42 @@ This skill provides 2 tools for telegram integration.
|
||||
## 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
|
||||
@@ -229,18 +230,21 @@ Tools are provided by Skills, which are JavaScript modules running in a secure V
|
||||
## 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
|
||||
@@ -251,18 +255,21 @@ Tools are provided by Skills, which are JavaScript modules running in a secure V
|
||||
## 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
|
||||
@@ -270,10 +277,11 @@ Tools are provided by Skills, which are JavaScript modules running in a secure V
|
||||
---
|
||||
|
||||
**Tool Statistics**
|
||||
|
||||
- Total Tools: 4
|
||||
- Active Skills: 3
|
||||
- Categories: 6
|
||||
- Last Updated: 2026-03-11T23:23:47.633Z
|
||||
|
||||
*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`.*
|
||||
_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`._
|
||||
|
||||
+1
-1
Submodule skills updated: e6dd1730eb...8168045b0b
@@ -1,9 +1,10 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { skillManager } from '../../lib/skills/manager';
|
||||
import { persistor } from '../../store';
|
||||
import SettingsHeader from './components/SettingsHeader';
|
||||
import SettingsMenuItem from './components/SettingsMenuItem';
|
||||
import { useSettingsNavigation } from './hooks/useSettingsNavigation';
|
||||
import { persistor } from '../../store';
|
||||
import { skillManager } from '../../lib/skills/manager';
|
||||
|
||||
const SettingsHome = () => {
|
||||
const { navigateToSettings } = useSettingsNavigation();
|
||||
@@ -31,7 +32,7 @@ const SettingsHome = () => {
|
||||
|
||||
// Complete reset - redirect to login for fresh start
|
||||
window.location.href = '/login';
|
||||
}
|
||||
};
|
||||
|
||||
const handleLogoutAndClearData = async () => {
|
||||
try {
|
||||
@@ -42,7 +43,7 @@ const SettingsHome = () => {
|
||||
setError('Failed to clear data and logout. Please try again.');
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// const handleViewEncryptionKey = () => {
|
||||
// // TODO: Show encryption key in a secure modal
|
||||
@@ -281,11 +282,16 @@ const SettingsHome = () => {
|
||||
description: 'Sign out and permanently clear all local data',
|
||||
icon: (
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
onClick: () => setShowLogoutAndClearModal(true),
|
||||
dangerous: true
|
||||
dangerous: true,
|
||||
},
|
||||
{
|
||||
id: 'logout',
|
||||
@@ -352,8 +358,17 @@ const SettingsHome = () => {
|
||||
<div className="bg-stone-900 rounded-2xl max-w-md w-full p-6 border border-stone-700/50">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="w-10 h-10 rounded-lg bg-amber-500/20 flex items-center justify-center">
|
||||
<svg className="w-5 h-5 text-amber-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
|
||||
<svg
|
||||
className="w-5 h-5 text-amber-400"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
@@ -363,13 +378,11 @@ const SettingsHome = () => {
|
||||
|
||||
<div className="mb-6">
|
||||
<p className="text-stone-300 text-sm leading-relaxed">
|
||||
This will sign you out and permanently delete ALL data including:
|
||||
• App settings and conversations
|
||||
• Email data from Gmail
|
||||
• Chat history from Telegram
|
||||
• Cached files from Notion
|
||||
• All other skills data
|
||||
<br /><br />
|
||||
This will sign you out and permanently delete ALL data including: • App settings and
|
||||
conversations • Email data from Gmail • Chat history from Telegram • Cached files
|
||||
from Notion • All other skills data
|
||||
<br />
|
||||
<br />
|
||||
This action cannot be undone and may take a few moments to complete.
|
||||
</p>
|
||||
|
||||
@@ -387,19 +400,28 @@ const SettingsHome = () => {
|
||||
setError(null);
|
||||
}}
|
||||
disabled={isLoading}
|
||||
className="flex-1 px-4 py-2 rounded-lg border border-stone-600 text-stone-300 hover:bg-stone-800 transition-colors disabled:opacity-50"
|
||||
>
|
||||
className="flex-1 px-4 py-2 rounded-lg border border-stone-600 text-stone-300 hover:bg-stone-800 transition-colors disabled:opacity-50">
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={handleLogoutAndClearData}
|
||||
disabled={isLoading}
|
||||
className="flex-1 px-4 py-2 rounded-lg bg-amber-600 hover:bg-amber-500 text-white transition-colors disabled:opacity-50 flex items-center justify-center gap-2"
|
||||
>
|
||||
className="flex-1 px-4 py-2 rounded-lg bg-amber-600 hover:bg-amber-500 text-white transition-colors disabled:opacity-50 flex items-center justify-center gap-2">
|
||||
{isLoading && (
|
||||
<svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
||||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
|
||||
<circle
|
||||
className="opacity-25"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
strokeWidth="4"
|
||||
/>
|
||||
<path
|
||||
className="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
{isLoading ? 'Clearing All Data...' : 'Log Out & Clear Everything'}
|
||||
|
||||
@@ -337,7 +337,9 @@ const Conversations = () => {
|
||||
}
|
||||
|
||||
// Snapshot history for AI request (excluding the just-added user message since we'll add it manually)
|
||||
const historySnapshot = messages.filter(m => !m.id.startsWith('optimistic-') && m.id !== userMessage.id);
|
||||
const historySnapshot = messages.filter(
|
||||
m => !m.id.startsWith('optimistic-') && m.id !== userMessage.id
|
||||
);
|
||||
|
||||
setInputValue('');
|
||||
setSendError(null);
|
||||
@@ -529,7 +531,9 @@ const Conversations = () => {
|
||||
// Remove the user message from persistent storage on error
|
||||
// We'll use a thunk-like approach to access current state
|
||||
dispatch((dispatch, getState) => {
|
||||
const state = getState() as { thread: { messagesByThreadId: Record<string, ThreadMessage[]> } };
|
||||
const state = getState() as {
|
||||
thread: { messagesByThreadId: Record<string, ThreadMessage[]> };
|
||||
};
|
||||
const persistedMessages = state.thread.messagesByThreadId[sendingThreadId] || [];
|
||||
const currentMessages = persistedMessages.filter(m => m.id !== userMessage.id);
|
||||
dispatch(updateMessagesForThread({ threadId: sendingThreadId, messages: currentMessages }));
|
||||
@@ -978,7 +982,9 @@ const Conversations = () => {
|
||||
key={i}
|
||||
type="button"
|
||||
onClick={() => handleSendMessage(s.text)}
|
||||
disabled={isSending || !!(activeThreadId && activeThreadId !== selectedThreadId)}
|
||||
disabled={
|
||||
isSending || !!(activeThreadId && activeThreadId !== selectedThreadId)
|
||||
}
|
||||
className="flex-shrink-0 px-3 py-1.5 rounded-lg text-[12px] whitespace-nowrap bg-white/5 text-stone-400 hover:bg-white/10 transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
{s.text}
|
||||
</button>
|
||||
@@ -993,7 +999,8 @@ const Conversations = () => {
|
||||
{activeThreadId && activeThreadId !== selectedThreadId && (
|
||||
<div className="mb-3 p-2 rounded-lg bg-amber-500/10 border border-amber-500/20">
|
||||
<p className="text-xs text-amber-400">
|
||||
Another conversation is active. Please wait for it to complete before sending messages here.
|
||||
Another conversation is active. Please wait for it to complete before sending
|
||||
messages here.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -1039,14 +1046,22 @@ const Conversations = () => {
|
||||
value={inputValue}
|
||||
onChange={e => setInputValue(e.target.value)}
|
||||
onKeyDown={handleInputKeyDown}
|
||||
placeholder={activeThreadId && activeThreadId !== selectedThreadId ? "Another conversation is active..." : "Type a message..."}
|
||||
placeholder={
|
||||
activeThreadId && activeThreadId !== selectedThreadId
|
||||
? 'Another conversation is active...'
|
||||
: 'Type a message...'
|
||||
}
|
||||
rows={1}
|
||||
disabled={!!(activeThreadId && activeThreadId !== selectedThreadId)}
|
||||
className="flex-1 resize-none bg-white/5 border border-white/10 rounded-xl px-4 py-2.5 text-sm placeholder:text-stone-500 focus:outline-none focus:ring-1 focus:ring-primary-500/50 focus:border-primary-500/50 transition-all max-h-32 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
/>
|
||||
<button
|
||||
onClick={() => handleSendMessage()}
|
||||
disabled={!inputValue.trim() || isSending || !!(activeThreadId && activeThreadId !== selectedThreadId)}
|
||||
disabled={
|
||||
!inputValue.trim() ||
|
||||
isSending ||
|
||||
!!(activeThreadId && activeThreadId !== selectedThreadId)
|
||||
}
|
||||
className="p-2.5 rounded-xl bg-primary-600 hover:bg-primary-500 disabled:opacity-40 disabled:cursor-not-allowed transition-colors flex-shrink-0">
|
||||
{isSending ? (
|
||||
<svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
|
||||
|
||||
+6
-2
@@ -50,7 +50,11 @@ export interface IAgentToolRegistry {
|
||||
/**
|
||||
* Execute a tool using the skill system
|
||||
*/
|
||||
executeTool(skillId: string, toolName: string, toolArguments: string): Promise<AgentToolExecution>;
|
||||
executeTool(
|
||||
skillId: string,
|
||||
toolName: string,
|
||||
toolArguments: string
|
||||
): Promise<AgentToolExecution>;
|
||||
|
||||
/**
|
||||
* Get a specific tool by name
|
||||
@@ -61,4 +65,4 @@ export interface IAgentToolRegistry {
|
||||
* Get all available tools
|
||||
*/
|
||||
getAllTools(): AgentToolSchema[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import {invoke, isTauri as coreIsTauri} from '@tauri-apps/api/core';
|
||||
import {getCurrent, onOpenUrl} from '@tauri-apps/plugin-deep-link';
|
||||
import { isTauri as coreIsTauri, invoke } from '@tauri-apps/api/core';
|
||||
import { getCurrent, onOpenUrl } from '@tauri-apps/plugin-deep-link';
|
||||
|
||||
import {skillManager} from '../lib/skills/manager';
|
||||
import {consumeLoginToken, fetchIntegrationTokens} from '../services/api/authApi';
|
||||
import {buildManualSentryEvent, enqueueError} from '../services/errorReportQueue';
|
||||
import {store} from '../store';
|
||||
import {setToken} from '../store/authSlice';
|
||||
import {setSkillState} from '../store/skillsSlice';
|
||||
import {decryptIntegrationTokens, hexToBase64, type IntegrationTokensPayload,} from './integrationTokensCrypto';
|
||||
import { skillManager } from '../lib/skills/manager';
|
||||
import { consumeLoginToken, fetchIntegrationTokens } from '../services/api/authApi';
|
||||
import { buildManualSentryEvent, enqueueError } from '../services/errorReportQueue';
|
||||
import { store } from '../store';
|
||||
import { setToken } from '../store/authSlice';
|
||||
import { setSkillState } from '../store/skillsSlice';
|
||||
import {
|
||||
decryptIntegrationTokens,
|
||||
hexToBase64,
|
||||
type IntegrationTokensPayload,
|
||||
} from './integrationTokensCrypto';
|
||||
|
||||
function getCurrentUserId(): string | null {
|
||||
const state = store.getState();
|
||||
@@ -42,7 +46,6 @@ const handleAuthDeepLink = async (parsed: URL) => {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
console.log('[DeepLink] Received auth token');
|
||||
|
||||
try {
|
||||
@@ -59,8 +62,6 @@ const handleAuthDeepLink = async (parsed: URL) => {
|
||||
store.dispatch(setToken(jwtToken));
|
||||
window.location.hash = '/onboarding';
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user