@usejarvis/brain 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +153 -0
- package/README.md +278 -0
- package/bin/jarvis.ts +413 -0
- package/package.json +74 -0
- package/scripts/ensure-bun.cjs +8 -0
- package/src/actions/README.md +421 -0
- package/src/actions/app-control/desktop-controller.test.ts +26 -0
- package/src/actions/app-control/desktop-controller.ts +438 -0
- package/src/actions/app-control/interface.ts +64 -0
- package/src/actions/app-control/linux.ts +273 -0
- package/src/actions/app-control/macos.ts +54 -0
- package/src/actions/app-control/sidecar-launcher.test.ts +23 -0
- package/src/actions/app-control/sidecar-launcher.ts +286 -0
- package/src/actions/app-control/windows.ts +44 -0
- package/src/actions/browser/cdp.ts +138 -0
- package/src/actions/browser/chrome-launcher.ts +252 -0
- package/src/actions/browser/session.ts +437 -0
- package/src/actions/browser/stealth.ts +49 -0
- package/src/actions/index.ts +20 -0
- package/src/actions/terminal/executor.ts +157 -0
- package/src/actions/terminal/wsl-bridge.ts +126 -0
- package/src/actions/test.ts +93 -0
- package/src/actions/tools/agents.ts +321 -0
- package/src/actions/tools/builtin.ts +846 -0
- package/src/actions/tools/commitments.ts +192 -0
- package/src/actions/tools/content.ts +217 -0
- package/src/actions/tools/delegate.ts +147 -0
- package/src/actions/tools/desktop.test.ts +55 -0
- package/src/actions/tools/desktop.ts +305 -0
- package/src/actions/tools/goals.ts +376 -0
- package/src/actions/tools/local-tools-guard.ts +20 -0
- package/src/actions/tools/registry.ts +171 -0
- package/src/actions/tools/research.ts +111 -0
- package/src/actions/tools/sidecar-list.ts +57 -0
- package/src/actions/tools/sidecar-route.ts +105 -0
- package/src/actions/tools/workflows.ts +216 -0
- package/src/agents/agent.ts +132 -0
- package/src/agents/delegation.ts +107 -0
- package/src/agents/hierarchy.ts +113 -0
- package/src/agents/index.ts +19 -0
- package/src/agents/messaging.ts +125 -0
- package/src/agents/orchestrator.ts +576 -0
- package/src/agents/role-discovery.ts +61 -0
- package/src/agents/sub-agent-runner.ts +307 -0
- package/src/agents/task-manager.ts +151 -0
- package/src/authority/approval-delivery.ts +59 -0
- package/src/authority/approval.ts +196 -0
- package/src/authority/audit.ts +158 -0
- package/src/authority/authority.test.ts +519 -0
- package/src/authority/deferred-executor.ts +103 -0
- package/src/authority/emergency.ts +66 -0
- package/src/authority/engine.ts +297 -0
- package/src/authority/index.ts +12 -0
- package/src/authority/learning.ts +111 -0
- package/src/authority/tool-action-map.ts +74 -0
- package/src/awareness/analytics.ts +466 -0
- package/src/awareness/awareness.test.ts +332 -0
- package/src/awareness/capture-engine.ts +305 -0
- package/src/awareness/context-graph.ts +130 -0
- package/src/awareness/context-tracker.ts +349 -0
- package/src/awareness/index.ts +25 -0
- package/src/awareness/intelligence.ts +321 -0
- package/src/awareness/ocr-engine.ts +88 -0
- package/src/awareness/service.ts +528 -0
- package/src/awareness/struggle-detector.ts +342 -0
- package/src/awareness/suggestion-engine.ts +476 -0
- package/src/awareness/types.ts +201 -0
- package/src/cli/autostart.ts +241 -0
- package/src/cli/deps.ts +449 -0
- package/src/cli/doctor.ts +230 -0
- package/src/cli/helpers.ts +401 -0
- package/src/cli/onboard.ts +580 -0
- package/src/comms/README.md +329 -0
- package/src/comms/auth-error.html +48 -0
- package/src/comms/channels/discord.ts +228 -0
- package/src/comms/channels/signal.ts +56 -0
- package/src/comms/channels/telegram.ts +316 -0
- package/src/comms/channels/whatsapp.ts +60 -0
- package/src/comms/channels.test.ts +173 -0
- package/src/comms/desktop-notify.ts +114 -0
- package/src/comms/example.ts +129 -0
- package/src/comms/index.ts +129 -0
- package/src/comms/streaming.ts +142 -0
- package/src/comms/voice.test.ts +152 -0
- package/src/comms/voice.ts +291 -0
- package/src/comms/websocket.test.ts +409 -0
- package/src/comms/websocket.ts +473 -0
- package/src/config/README.md +387 -0
- package/src/config/index.ts +6 -0
- package/src/config/loader.test.ts +137 -0
- package/src/config/loader.ts +142 -0
- package/src/config/types.ts +260 -0
- package/src/daemon/README.md +232 -0
- package/src/daemon/agent-service-interface.ts +9 -0
- package/src/daemon/agent-service.ts +600 -0
- package/src/daemon/api-routes.ts +2119 -0
- package/src/daemon/background-agent-service.ts +396 -0
- package/src/daemon/background-agent.test.ts +78 -0
- package/src/daemon/channel-service.ts +201 -0
- package/src/daemon/commitment-executor.ts +297 -0
- package/src/daemon/event-classifier.ts +239 -0
- package/src/daemon/event-coalescer.ts +123 -0
- package/src/daemon/event-reactor.ts +214 -0
- package/src/daemon/health.ts +220 -0
- package/src/daemon/index.ts +1004 -0
- package/src/daemon/llm-settings.ts +316 -0
- package/src/daemon/observer-service.ts +150 -0
- package/src/daemon/pid.ts +98 -0
- package/src/daemon/research-queue.ts +155 -0
- package/src/daemon/services.ts +175 -0
- package/src/daemon/ws-service.ts +788 -0
- package/src/goals/accountability.ts +240 -0
- package/src/goals/awareness-bridge.ts +185 -0
- package/src/goals/estimator.ts +185 -0
- package/src/goals/events.ts +28 -0
- package/src/goals/goals.test.ts +400 -0
- package/src/goals/integration.test.ts +329 -0
- package/src/goals/nl-builder.test.ts +220 -0
- package/src/goals/nl-builder.ts +256 -0
- package/src/goals/rhythm.test.ts +177 -0
- package/src/goals/rhythm.ts +275 -0
- package/src/goals/service.test.ts +135 -0
- package/src/goals/service.ts +348 -0
- package/src/goals/types.ts +106 -0
- package/src/goals/workflow-bridge.ts +96 -0
- package/src/integrations/google-api.ts +134 -0
- package/src/integrations/google-auth.ts +175 -0
- package/src/llm/README.md +291 -0
- package/src/llm/anthropic.ts +386 -0
- package/src/llm/gemini.ts +371 -0
- package/src/llm/index.ts +19 -0
- package/src/llm/manager.ts +153 -0
- package/src/llm/ollama.ts +307 -0
- package/src/llm/openai.ts +350 -0
- package/src/llm/provider.test.ts +231 -0
- package/src/llm/provider.ts +60 -0
- package/src/llm/test.ts +87 -0
- package/src/observers/README.md +278 -0
- package/src/observers/calendar.ts +113 -0
- package/src/observers/clipboard.ts +136 -0
- package/src/observers/email.ts +109 -0
- package/src/observers/example.ts +58 -0
- package/src/observers/file-watcher.ts +124 -0
- package/src/observers/index.ts +159 -0
- package/src/observers/notifications.ts +197 -0
- package/src/observers/observers.test.ts +203 -0
- package/src/observers/processes.ts +225 -0
- package/src/personality/README.md +61 -0
- package/src/personality/adapter.ts +196 -0
- package/src/personality/index.ts +20 -0
- package/src/personality/learner.ts +209 -0
- package/src/personality/model.ts +132 -0
- package/src/personality/personality.test.ts +236 -0
- package/src/roles/README.md +252 -0
- package/src/roles/authority.ts +119 -0
- package/src/roles/example-usage.ts +198 -0
- package/src/roles/index.ts +42 -0
- package/src/roles/loader.ts +143 -0
- package/src/roles/prompt-builder.ts +194 -0
- package/src/roles/test-multi.ts +102 -0
- package/src/roles/test-role.yaml +77 -0
- package/src/roles/test-utils.ts +93 -0
- package/src/roles/test.ts +106 -0
- package/src/roles/tool-guide.ts +190 -0
- package/src/roles/types.ts +36 -0
- package/src/roles/utils.ts +200 -0
- package/src/scripts/google-setup.ts +168 -0
- package/src/sidecar/connection.ts +179 -0
- package/src/sidecar/index.ts +6 -0
- package/src/sidecar/manager.ts +542 -0
- package/src/sidecar/protocol.ts +85 -0
- package/src/sidecar/rpc.ts +161 -0
- package/src/sidecar/scheduler.ts +136 -0
- package/src/sidecar/types.ts +112 -0
- package/src/sidecar/validator.ts +144 -0
- package/src/vault/README.md +110 -0
- package/src/vault/awareness.ts +341 -0
- package/src/vault/commitments.ts +299 -0
- package/src/vault/content-pipeline.ts +260 -0
- package/src/vault/conversations.ts +173 -0
- package/src/vault/entities.ts +180 -0
- package/src/vault/extractor.test.ts +356 -0
- package/src/vault/extractor.ts +345 -0
- package/src/vault/facts.ts +190 -0
- package/src/vault/goals.ts +477 -0
- package/src/vault/index.ts +87 -0
- package/src/vault/keychain.ts +99 -0
- package/src/vault/observations.ts +115 -0
- package/src/vault/relationships.ts +178 -0
- package/src/vault/retrieval.test.ts +126 -0
- package/src/vault/retrieval.ts +227 -0
- package/src/vault/schema.ts +658 -0
- package/src/vault/settings.ts +38 -0
- package/src/vault/vectors.ts +92 -0
- package/src/vault/workflows.ts +403 -0
- package/src/workflows/auto-suggest.ts +290 -0
- package/src/workflows/engine.ts +366 -0
- package/src/workflows/events.ts +24 -0
- package/src/workflows/executor.ts +207 -0
- package/src/workflows/nl-builder.ts +198 -0
- package/src/workflows/nodes/actions/agent-task.ts +73 -0
- package/src/workflows/nodes/actions/calendar-action.ts +85 -0
- package/src/workflows/nodes/actions/code-execution.ts +73 -0
- package/src/workflows/nodes/actions/discord.ts +77 -0
- package/src/workflows/nodes/actions/file-write.ts +73 -0
- package/src/workflows/nodes/actions/gmail.ts +69 -0
- package/src/workflows/nodes/actions/http-request.ts +117 -0
- package/src/workflows/nodes/actions/notification.ts +85 -0
- package/src/workflows/nodes/actions/run-tool.ts +55 -0
- package/src/workflows/nodes/actions/send-message.ts +82 -0
- package/src/workflows/nodes/actions/shell-command.ts +76 -0
- package/src/workflows/nodes/actions/telegram.ts +60 -0
- package/src/workflows/nodes/builtin.ts +119 -0
- package/src/workflows/nodes/error/error-handler.ts +37 -0
- package/src/workflows/nodes/error/fallback.ts +47 -0
- package/src/workflows/nodes/error/retry.ts +82 -0
- package/src/workflows/nodes/logic/delay.ts +42 -0
- package/src/workflows/nodes/logic/if-else.ts +41 -0
- package/src/workflows/nodes/logic/loop.ts +90 -0
- package/src/workflows/nodes/logic/merge.ts +38 -0
- package/src/workflows/nodes/logic/race.ts +40 -0
- package/src/workflows/nodes/logic/switch.ts +59 -0
- package/src/workflows/nodes/logic/template-render.ts +53 -0
- package/src/workflows/nodes/logic/variable-get.ts +37 -0
- package/src/workflows/nodes/logic/variable-set.ts +59 -0
- package/src/workflows/nodes/registry.ts +99 -0
- package/src/workflows/nodes/transform/aggregate.ts +99 -0
- package/src/workflows/nodes/transform/csv-parse.ts +70 -0
- package/src/workflows/nodes/transform/json-parse.ts +63 -0
- package/src/workflows/nodes/transform/map-filter.ts +84 -0
- package/src/workflows/nodes/transform/regex-match.ts +89 -0
- package/src/workflows/nodes/triggers/calendar.ts +33 -0
- package/src/workflows/nodes/triggers/clipboard.ts +32 -0
- package/src/workflows/nodes/triggers/cron.ts +40 -0
- package/src/workflows/nodes/triggers/email.ts +40 -0
- package/src/workflows/nodes/triggers/file-change.ts +45 -0
- package/src/workflows/nodes/triggers/git.ts +46 -0
- package/src/workflows/nodes/triggers/manual.ts +23 -0
- package/src/workflows/nodes/triggers/poll.ts +81 -0
- package/src/workflows/nodes/triggers/process.ts +44 -0
- package/src/workflows/nodes/triggers/screen-event.ts +37 -0
- package/src/workflows/nodes/triggers/webhook.ts +39 -0
- package/src/workflows/safe-eval.ts +139 -0
- package/src/workflows/template.ts +118 -0
- package/src/workflows/triggers/cron.ts +311 -0
- package/src/workflows/triggers/manager.ts +285 -0
- package/src/workflows/triggers/observer-bridge.ts +172 -0
- package/src/workflows/triggers/poller.ts +201 -0
- package/src/workflows/triggers/screen-condition.ts +218 -0
- package/src/workflows/triggers/triggers.test.ts +740 -0
- package/src/workflows/triggers/webhook.ts +191 -0
- package/src/workflows/types.ts +133 -0
- package/src/workflows/variables.ts +72 -0
- package/src/workflows/workflows.test.ts +383 -0
- package/src/workflows/yaml.ts +104 -0
- package/ui/dist/index-j75njzc1.css +1199 -0
- package/ui/dist/index-p2zh407q.js +80603 -0
- package/ui/dist/index.html +13 -0
- package/ui/public/openwakeword/models/embedding_model.onnx +0 -0
- package/ui/public/openwakeword/models/hey_jarvis_v0.1.onnx +0 -0
- package/ui/public/openwakeword/models/melspectrogram.onnx +0 -0
- package/ui/public/openwakeword/models/silero_vad.onnx +0 -0
- package/ui/public/ort/ort-wasm-simd-threaded.jsep.mjs +106 -0
- package/ui/public/ort/ort-wasm-simd-threaded.jsep.wasm +0 -0
- package/ui/public/ort/ort-wasm-simd-threaded.mjs +59 -0
- package/ui/public/ort/ort-wasm-simd-threaded.wasm +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
id: executive_assistant
|
|
2
|
+
name: Executive Assistant
|
|
3
|
+
description: A highly capable AI assistant that manages your schedule, communications, and daily tasks with proactive intelligence.
|
|
4
|
+
|
|
5
|
+
responsibilities:
|
|
6
|
+
- Monitor user's calendar and proactively suggest optimizations
|
|
7
|
+
- Draft and send emails on behalf of the user (with approval)
|
|
8
|
+
- Track commitments and follow up on pending tasks
|
|
9
|
+
- Provide daily briefings and summaries
|
|
10
|
+
- Research topics and prepare reports
|
|
11
|
+
|
|
12
|
+
autonomous_actions:
|
|
13
|
+
- Read calendar events and emails
|
|
14
|
+
- Send routine status updates to the user
|
|
15
|
+
- Create calendar events for routine activities
|
|
16
|
+
- Log observations and track user preferences
|
|
17
|
+
- Search for information and compile summaries
|
|
18
|
+
|
|
19
|
+
approval_required:
|
|
20
|
+
- Send emails to external contacts
|
|
21
|
+
- Make purchases or financial commitments
|
|
22
|
+
- Modify important settings or configurations
|
|
23
|
+
- Delete important data
|
|
24
|
+
- Cancel or reschedule important meetings
|
|
25
|
+
|
|
26
|
+
kpis:
|
|
27
|
+
- name: Response Time
|
|
28
|
+
metric: Average time to respond to user requests
|
|
29
|
+
target: < 30 seconds
|
|
30
|
+
check_interval: daily
|
|
31
|
+
- name: Task Completion Rate
|
|
32
|
+
metric: Percentage of assigned tasks completed
|
|
33
|
+
target: "> 95%"
|
|
34
|
+
check_interval: weekly
|
|
35
|
+
- name: Proactive Suggestions
|
|
36
|
+
metric: Number of helpful suggestions made per day
|
|
37
|
+
target: "> 5"
|
|
38
|
+
check_interval: daily
|
|
39
|
+
|
|
40
|
+
communication_style:
|
|
41
|
+
tone: Professional yet warm, with occasional wit
|
|
42
|
+
verbosity: adaptive
|
|
43
|
+
formality: adaptive
|
|
44
|
+
|
|
45
|
+
heartbeat_instructions: |
|
|
46
|
+
Every hour, check:
|
|
47
|
+
1. Upcoming calendar events in the next 2 hours
|
|
48
|
+
2. Unread high-priority emails
|
|
49
|
+
3. Pending tasks approaching their deadlines
|
|
50
|
+
4. Any commitments that need follow-up
|
|
51
|
+
|
|
52
|
+
If you find anything requiring attention, proactively notify the user.
|
|
53
|
+
Always include context and suggested actions.
|
|
54
|
+
|
|
55
|
+
sub_roles:
|
|
56
|
+
- role_id: research_specialist
|
|
57
|
+
name: Research Specialist
|
|
58
|
+
description: Deep-dive researcher for complex topics
|
|
59
|
+
spawned_by: executive_assistant
|
|
60
|
+
reports_to: executive_assistant
|
|
61
|
+
max_budget_per_task: 100
|
|
62
|
+
- role_id: email_specialist
|
|
63
|
+
name: Email Specialist
|
|
64
|
+
description: Handles email triage and drafting
|
|
65
|
+
spawned_by: executive_assistant
|
|
66
|
+
reports_to: executive_assistant
|
|
67
|
+
max_budget_per_task: 50
|
|
68
|
+
|
|
69
|
+
tools:
|
|
70
|
+
- calendar_access
|
|
71
|
+
- email_access
|
|
72
|
+
- web_search
|
|
73
|
+
- document_creation
|
|
74
|
+
- note_taking
|
|
75
|
+
- reminder_system
|
|
76
|
+
|
|
77
|
+
authority_level: 6
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Test utility functions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
loadRolesFromDir,
|
|
8
|
+
findRolesWithPermission,
|
|
9
|
+
findMinimalRoleForAction,
|
|
10
|
+
compareRoles,
|
|
11
|
+
getRoleHierarchy,
|
|
12
|
+
validateRoleHierarchy,
|
|
13
|
+
getRoleStats,
|
|
14
|
+
findSpawnersOfRole,
|
|
15
|
+
} from './index.ts';
|
|
16
|
+
|
|
17
|
+
console.log('🧪 Testing Role Utility Functions\n');
|
|
18
|
+
|
|
19
|
+
// Load roles
|
|
20
|
+
import { join } from 'path';
|
|
21
|
+
const roles = loadRolesFromDir(join(import.meta.dir, '../../roles'));
|
|
22
|
+
console.log(`✅ Loaded ${roles.size} roles\n`);
|
|
23
|
+
|
|
24
|
+
// Test 1: Find roles with specific permission
|
|
25
|
+
console.log('Test 1: Find roles that can execute commands');
|
|
26
|
+
const execRoles = findRolesWithPermission(roles, 'execute_command');
|
|
27
|
+
console.log(`Found ${execRoles.length} roles:`);
|
|
28
|
+
execRoles.forEach(r => console.log(` - ${r.name} (level ${r.authority_level})`));
|
|
29
|
+
|
|
30
|
+
// Test 2: Find minimal role for action
|
|
31
|
+
console.log('\nTest 2: Find least privileged role that can send email');
|
|
32
|
+
const minRole = findMinimalRoleForAction(roles, 'send_email');
|
|
33
|
+
if (minRole) {
|
|
34
|
+
console.log(` ✅ ${minRole.name} (level ${minRole.authority_level})`);
|
|
35
|
+
} else {
|
|
36
|
+
console.log(' ❌ No role can send email');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Test 3: Compare two roles
|
|
40
|
+
console.log('\nTest 3: Compare Executive Assistant vs Research Specialist');
|
|
41
|
+
const exec = roles.get('executive_assistant');
|
|
42
|
+
const research = roles.get('research_specialist');
|
|
43
|
+
|
|
44
|
+
if (exec && research) {
|
|
45
|
+
const comparison = compareRoles(exec, research);
|
|
46
|
+
console.log(` Only ${exec.name}:`);
|
|
47
|
+
comparison.onlyInRole1.forEach(a => console.log(` - ${a}`));
|
|
48
|
+
console.log(` Only ${research.name}:`);
|
|
49
|
+
comparison.onlyInRole2.forEach(a => console.log(` - ${a}`));
|
|
50
|
+
console.log(` Both roles:`);
|
|
51
|
+
comparison.inBoth.forEach(a => console.log(` - ${a}`));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Test 4: Role hierarchy
|
|
55
|
+
console.log('\nTest 4: Role hierarchy by authority level');
|
|
56
|
+
console.log(getRoleHierarchy(roles));
|
|
57
|
+
|
|
58
|
+
// Test 5: Validate hierarchy
|
|
59
|
+
console.log('\nTest 5: Validate role hierarchy');
|
|
60
|
+
const validation = validateRoleHierarchy(roles);
|
|
61
|
+
if (validation.valid) {
|
|
62
|
+
console.log(' ✅ Role hierarchy is valid');
|
|
63
|
+
} else {
|
|
64
|
+
console.log(' ❌ Hierarchy errors:');
|
|
65
|
+
validation.errors.forEach(e => console.log(` - ${e}`));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Test 6: Find spawners
|
|
69
|
+
console.log('\nTest 6: Find roles that can spawn research_specialist');
|
|
70
|
+
const spawners = findSpawnersOfRole(roles, 'research_specialist');
|
|
71
|
+
if (spawners.length > 0) {
|
|
72
|
+
console.log(` Found ${spawners.length} spawner(s):`);
|
|
73
|
+
spawners.forEach(r => console.log(` - ${r.name}`));
|
|
74
|
+
} else {
|
|
75
|
+
console.log(' No roles can spawn research_specialist');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Test 7: Statistics
|
|
79
|
+
console.log('\nTest 7: Role collection statistics');
|
|
80
|
+
const stats = getRoleStats(roles);
|
|
81
|
+
console.log(` Total roles: ${stats.totalRoles}`);
|
|
82
|
+
console.log(` Average authority level: ${stats.averageAuthorityLevel.toFixed(1)}`);
|
|
83
|
+
console.log(` Total tools: ${stats.totalTools}`);
|
|
84
|
+
console.log(` Total KPIs: ${stats.totalKPIs}`);
|
|
85
|
+
console.log(` Roles with sub-roles: ${stats.rolesWithSubRoles}`);
|
|
86
|
+
console.log(' Authority distribution:');
|
|
87
|
+
Object.entries(stats.authorityDistribution)
|
|
88
|
+
.sort(([a], [b]) => Number(b) - Number(a))
|
|
89
|
+
.forEach(([level, count]) => {
|
|
90
|
+
console.log(` Level ${level}: ${count} role(s)`);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
console.log('\n✅ All utility tests passed!');
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Test script for the Role Engine
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
loadRole,
|
|
8
|
+
validateRole,
|
|
9
|
+
buildSystemPrompt,
|
|
10
|
+
canPerform,
|
|
11
|
+
listAllowedActions,
|
|
12
|
+
listDeniedActions,
|
|
13
|
+
getRolePermissionsSummary,
|
|
14
|
+
type RoleDefinition,
|
|
15
|
+
type ActionCategory,
|
|
16
|
+
} from './index.ts';
|
|
17
|
+
|
|
18
|
+
console.log('🧪 Testing Role Engine\n');
|
|
19
|
+
|
|
20
|
+
// Test 1: Load a role from YAML
|
|
21
|
+
console.log('Test 1: Loading role from YAML...');
|
|
22
|
+
try {
|
|
23
|
+
const role = loadRole(import.meta.dir + '/test-role.yaml');
|
|
24
|
+
console.log(`✅ Loaded role: ${role.name} (${role.id})`);
|
|
25
|
+
console.log(` Authority Level: ${role.authority_level}`);
|
|
26
|
+
console.log(` Responsibilities: ${role.responsibilities.length}`);
|
|
27
|
+
console.log(` Tools: ${role.tools.length}`);
|
|
28
|
+
console.log(` KPIs: ${role.kpis.length}`);
|
|
29
|
+
console.log(` Sub-roles: ${role.sub_roles.length}`);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('❌ Failed to load role:', error);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Test 2: Validate role
|
|
36
|
+
console.log('\nTest 2: Validating role...');
|
|
37
|
+
const role = loadRole(import.meta.dir + '/test-role.yaml');
|
|
38
|
+
const isValid = validateRole(role);
|
|
39
|
+
console.log(isValid ? '✅ Role is valid' : '❌ Role is invalid');
|
|
40
|
+
|
|
41
|
+
// Test 3: Build system prompt
|
|
42
|
+
console.log('\nTest 3: Building system prompt...');
|
|
43
|
+
const prompt = buildSystemPrompt(role, {
|
|
44
|
+
userName: 'John Doe',
|
|
45
|
+
currentTime: new Date().toLocaleString(),
|
|
46
|
+
activeCommitments: [
|
|
47
|
+
'Finish Q1 report by Friday',
|
|
48
|
+
'Prepare presentation for Monday meeting',
|
|
49
|
+
],
|
|
50
|
+
recentObservations: [
|
|
51
|
+
'User prefers morning meetings',
|
|
52
|
+
'User checks email every 2 hours',
|
|
53
|
+
],
|
|
54
|
+
agentHierarchy: 'Executive Assistant (you) > Research Specialist, Email Specialist',
|
|
55
|
+
});
|
|
56
|
+
console.log('✅ System prompt generated');
|
|
57
|
+
console.log(` Length: ${prompt.length} characters`);
|
|
58
|
+
console.log('\n--- PROMPT PREVIEW ---');
|
|
59
|
+
console.log(prompt.substring(0, 500) + '...\n');
|
|
60
|
+
|
|
61
|
+
// Test 4: Authority checks
|
|
62
|
+
console.log('Test 4: Testing authority system...');
|
|
63
|
+
const permissions = getRolePermissionsSummary(role);
|
|
64
|
+
console.log(`✅ Authority Level: ${permissions.level}/10`);
|
|
65
|
+
console.log(` ${permissions.description}`);
|
|
66
|
+
console.log(` Allowed actions: ${permissions.allowed.length}`);
|
|
67
|
+
console.log(` Denied actions: ${permissions.denied.length}`);
|
|
68
|
+
|
|
69
|
+
// Test specific actions
|
|
70
|
+
const actionsToTest: ActionCategory[] = [
|
|
71
|
+
'read_data',
|
|
72
|
+
'write_data',
|
|
73
|
+
'execute_command',
|
|
74
|
+
'spawn_agent',
|
|
75
|
+
'make_payment',
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
console.log('\nAction Permissions:');
|
|
79
|
+
for (const action of actionsToTest) {
|
|
80
|
+
const can = canPerform(role, action);
|
|
81
|
+
console.log(` ${can ? '✅' : '❌'} ${action}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Test 5: List allowed/denied actions
|
|
85
|
+
console.log('\nTest 5: Listing all permissions...');
|
|
86
|
+
const allowed = listAllowedActions(role);
|
|
87
|
+
const denied = listDeniedActions(role);
|
|
88
|
+
|
|
89
|
+
console.log('\n✅ Allowed Actions:');
|
|
90
|
+
allowed.forEach(action => console.log(` - ${action}`));
|
|
91
|
+
|
|
92
|
+
console.log('\n❌ Denied Actions:');
|
|
93
|
+
denied.forEach(action => console.log(` - ${action}`));
|
|
94
|
+
|
|
95
|
+
// Test 6: Invalid role validation
|
|
96
|
+
console.log('\nTest 6: Testing validation with invalid data...');
|
|
97
|
+
const invalidRole = {
|
|
98
|
+
id: 'test',
|
|
99
|
+
name: 'Test',
|
|
100
|
+
// Missing required fields
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const isInvalid = validateRole(invalidRole);
|
|
104
|
+
console.log(isInvalid ? '❌ Should have been invalid!' : '✅ Correctly rejected invalid role');
|
|
105
|
+
|
|
106
|
+
console.log('\n✅ All tests passed!');
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Guide — Static reference for the AI
|
|
3
|
+
*
|
|
4
|
+
* Explains all available tools and how to use them.
|
|
5
|
+
* Update this file whenever tools are added or changed.
|
|
6
|
+
*
|
|
7
|
+
* When `hasSidecars` is false, sidecar-related content (target params,
|
|
8
|
+
* list_sidecars, sidecar section) is omitted entirely so the AI
|
|
9
|
+
* doesn't waste tokens thinking about remote execution.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export function buildToolGuide(hasSidecars: boolean): string {
|
|
13
|
+
const lines: string[] = [];
|
|
14
|
+
|
|
15
|
+
lines.push('# Tool Guide');
|
|
16
|
+
lines.push('');
|
|
17
|
+
|
|
18
|
+
// --- Tools ---
|
|
19
|
+
lines.push('## Tools');
|
|
20
|
+
lines.push('');
|
|
21
|
+
|
|
22
|
+
if (hasSidecars) {
|
|
23
|
+
lines.push('These tools work locally by default. To run on a remote machine, pass the `target` parameter with a sidecar name or ID.');
|
|
24
|
+
lines.push('');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
lines.push('### run_command');
|
|
28
|
+
lines.push('Execute a shell command. Returns stdout, stderr, and exit code.');
|
|
29
|
+
lines.push('- `command` (required): The shell command to run');
|
|
30
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
31
|
+
lines.push('- `cwd`: Working directory');
|
|
32
|
+
lines.push('- `timeout`: Timeout in ms (default: 30000)');
|
|
33
|
+
lines.push('');
|
|
34
|
+
|
|
35
|
+
lines.push('### read_file');
|
|
36
|
+
lines.push('Read a file\'s contents as text (max 100KB).');
|
|
37
|
+
lines.push('- `path` (required): File path');
|
|
38
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
39
|
+
lines.push('');
|
|
40
|
+
|
|
41
|
+
lines.push('### write_file');
|
|
42
|
+
lines.push('Write content to a file (creates or overwrites).');
|
|
43
|
+
lines.push('- `path` (required): File path');
|
|
44
|
+
lines.push('- `content` (required): Content to write');
|
|
45
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
46
|
+
lines.push('');
|
|
47
|
+
|
|
48
|
+
lines.push('### list_directory');
|
|
49
|
+
lines.push('List directory contents with types and sizes.');
|
|
50
|
+
lines.push('- `path` (required): Directory path');
|
|
51
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
52
|
+
lines.push('');
|
|
53
|
+
|
|
54
|
+
lines.push('### get_clipboard');
|
|
55
|
+
lines.push('Read the clipboard contents.');
|
|
56
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
57
|
+
lines.push('');
|
|
58
|
+
|
|
59
|
+
lines.push('### set_clipboard');
|
|
60
|
+
lines.push('Write text to the clipboard.');
|
|
61
|
+
lines.push('- `content` (required): Text to write');
|
|
62
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
63
|
+
lines.push('');
|
|
64
|
+
|
|
65
|
+
lines.push('### capture_screen');
|
|
66
|
+
lines.push('Take a screenshot of the screen. Returns base64-encoded PNG.');
|
|
67
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
68
|
+
lines.push('');
|
|
69
|
+
|
|
70
|
+
lines.push('### get_system_info');
|
|
71
|
+
lines.push('Get system information (hostname, OS, architecture, CPU count).');
|
|
72
|
+
if (hasSidecars) lines.push('- `target`: Sidecar name or ID for remote execution');
|
|
73
|
+
lines.push('');
|
|
74
|
+
|
|
75
|
+
// --- Browser ---
|
|
76
|
+
lines.push('## Browser');
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push('Control a Chrome browser for web research and interaction. Chrome auto-launches on first use. A persistent profile at ~/.jarvis/browser/profile retains login sessions.');
|
|
79
|
+
lines.push('');
|
|
80
|
+
lines.push('Workflow:');
|
|
81
|
+
lines.push('1. `browser_navigate` to a URL — returns page text + interactive elements with [id] numbers');
|
|
82
|
+
lines.push('2. `browser_click` / `browser_type` to interact using element [id]s');
|
|
83
|
+
lines.push('3. `browser_snapshot` to see the page after an action');
|
|
84
|
+
lines.push('4. `browser_scroll` to reveal content below the fold');
|
|
85
|
+
lines.push('5. `browser_evaluate` for advanced JavaScript interactions');
|
|
86
|
+
lines.push('6. `browser_screenshot` for visual capture');
|
|
87
|
+
lines.push('');
|
|
88
|
+
lines.push('Rules:');
|
|
89
|
+
lines.push('- For READ-ONLY tasks, `browser_navigate` already returns content. Don\'t snapshot just to read.');
|
|
90
|
+
lines.push('- For INTERACTIVE tasks, snapshot after each action to verify.');
|
|
91
|
+
lines.push('- Fill forms FIRST, verify in snapshot, THEN submit.');
|
|
92
|
+
lines.push('- If an element isn\'t visible, scroll down first.');
|
|
93
|
+
lines.push('- Modern SPAs may need `browser_evaluate` for custom components.');
|
|
94
|
+
lines.push('');
|
|
95
|
+
|
|
96
|
+
// --- Sidecars ---
|
|
97
|
+
if (hasSidecars) {
|
|
98
|
+
lines.push('## Sidecars (Remote Machines)');
|
|
99
|
+
lines.push('');
|
|
100
|
+
lines.push('Sidecars are the user\'s other machines (laptops, servers, desktops) connected to the brain. They allow you to run commands, read/write files, and more on remote devices.');
|
|
101
|
+
lines.push('');
|
|
102
|
+
lines.push('### How to use sidecars');
|
|
103
|
+
lines.push('1. Call `list_sidecars` to see which machines are available and their connection status');
|
|
104
|
+
lines.push('2. Use any compatible tool with the `target` parameter set to the sidecar\'s name or ID');
|
|
105
|
+
lines.push('3. If the sidecar is offline or doesn\'t support the required capability, you\'ll get a clear error');
|
|
106
|
+
lines.push('');
|
|
107
|
+
lines.push('### list_sidecars');
|
|
108
|
+
lines.push('Query live sidecar status. Always call this before targeting a remote machine.');
|
|
109
|
+
lines.push('- `filter`: Optional string to filter by name or ID (case-insensitive)');
|
|
110
|
+
lines.push('- Returns: connection status, hostname, OS, capabilities, last seen time');
|
|
111
|
+
lines.push('');
|
|
112
|
+
lines.push('### Capabilities');
|
|
113
|
+
lines.push('Each sidecar advertises what it can do:');
|
|
114
|
+
lines.push('- `terminal` — supports `run_command`');
|
|
115
|
+
lines.push('- `filesystem` — supports `read_file`, `write_file`, `list_directory`');
|
|
116
|
+
lines.push('- `clipboard` — supports `get_clipboard`, `set_clipboard`');
|
|
117
|
+
lines.push('- `screenshot` — supports `capture_screen`');
|
|
118
|
+
lines.push('- `system_info` — supports `get_system_info`');
|
|
119
|
+
lines.push('- `desktop`, `browser` — supports desktop/browser automation tools');
|
|
120
|
+
lines.push('');
|
|
121
|
+
lines.push('If a capability is listed as unavailable (with a reason), do NOT try to work around it with `run_command`. The required system tool is missing and shell commands will fail the same way.');
|
|
122
|
+
lines.push('');
|
|
123
|
+
lines.push('### Example workflow');
|
|
124
|
+
lines.push('User: "Check disk space on my server"');
|
|
125
|
+
lines.push('1. Call `list_sidecars` → see "home-server" is CONNECTED with terminal capability');
|
|
126
|
+
lines.push('2. Call `run_command` with target="home-server", command="df -h"');
|
|
127
|
+
lines.push('3. Report results to user');
|
|
128
|
+
lines.push('');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// --- Desktop ---
|
|
132
|
+
lines.push('## Desktop Automation');
|
|
133
|
+
lines.push('');
|
|
134
|
+
lines.push('Control desktop applications on any platform (Windows, macOS, Linux). Works like browser tools but for native desktop apps. The same tools work on all platforms — the sidecar handles OS-specific details internally.');
|
|
135
|
+
lines.push('');
|
|
136
|
+
lines.push('Workflow:');
|
|
137
|
+
lines.push('1. `desktop_list_windows` to see available windows with PIDs');
|
|
138
|
+
lines.push('2. `desktop_snapshot` to get the UI element tree with [id] numbers (like browser_snapshot)');
|
|
139
|
+
lines.push('3. `desktop_click` / `desktop_type` to interact using element [id]s');
|
|
140
|
+
lines.push('4. `desktop_snapshot` again to verify the result');
|
|
141
|
+
lines.push('');
|
|
142
|
+
lines.push('Tools:');
|
|
143
|
+
lines.push('- `desktop_list_windows` — list all visible windows (titles, PIDs, positions)');
|
|
144
|
+
lines.push('- `desktop_snapshot` — get the UI element tree of a window. Each element has an [id]. Optional `depth` param to control tree depth (default: 8).');
|
|
145
|
+
lines.push('- `desktop_click` — click or interact with an element by [id]. Optional `action` param: click (default), double_click, right_click, invoke, toggle, set_value, get_value, expand, collapse, focus. Optional `value` param for set_value.');
|
|
146
|
+
lines.push('- `desktop_type` — type text into the focused element. Optional `element_id` to click-focus first.');
|
|
147
|
+
lines.push('- `desktop_press_keys` — press key combos (e.g., "ctrl,s", "alt,f4", "enter")');
|
|
148
|
+
lines.push('- `desktop_find_element` — search for elements by property (name, control_type, class_name, automation_id) without scanning the full tree');
|
|
149
|
+
lines.push('- `desktop_launch_app` — launch an application by name or path');
|
|
150
|
+
lines.push('- `desktop_focus_window` — bring a window to the foreground by PID');
|
|
151
|
+
lines.push('- `desktop_screenshot` — visual capture of the desktop or a specific window');
|
|
152
|
+
lines.push('');
|
|
153
|
+
lines.push('Rules:');
|
|
154
|
+
lines.push('- Always `desktop_list_windows` first to get the PID, then `desktop_snapshot` with that PID.');
|
|
155
|
+
lines.push('- After clicking or typing, snapshot again to verify the updated state.');
|
|
156
|
+
lines.push('- Use `desktop_find_element` when you know the element name/type — faster than scanning the full tree.');
|
|
157
|
+
lines.push('- The `action` param on `desktop_click` supports richer interactions on Windows (invoke, toggle, set_value, expand, collapse). On macOS/Linux, only click, double_click, right_click, and focus are supported.');
|
|
158
|
+
lines.push('- `automation_id` in `desktop_find_element` is Windows-only; it is ignored on other platforms.');
|
|
159
|
+
lines.push('');
|
|
160
|
+
|
|
161
|
+
// --- Task Management ---
|
|
162
|
+
lines.push('## Task Management');
|
|
163
|
+
lines.push('');
|
|
164
|
+
lines.push('### manage_goals');
|
|
165
|
+
lines.push('OKR-style goal management (create, list, score, decompose, morning plan, evening review).');
|
|
166
|
+
lines.push('');
|
|
167
|
+
lines.push('### manage_workflow');
|
|
168
|
+
lines.push('Create and run automation workflows from natural language.');
|
|
169
|
+
lines.push('');
|
|
170
|
+
lines.push('### delegate_task');
|
|
171
|
+
lines.push('Send a task to a specialist sub-agent (research analyst, software engineer, etc.). The specialist works independently and returns results.');
|
|
172
|
+
lines.push('');
|
|
173
|
+
lines.push('### manage_agents');
|
|
174
|
+
lines.push('Manage persistent background agents for long-running tasks.');
|
|
175
|
+
lines.push('');
|
|
176
|
+
|
|
177
|
+
// --- Other ---
|
|
178
|
+
lines.push('## Other Tools');
|
|
179
|
+
lines.push('');
|
|
180
|
+
lines.push('### research_queue');
|
|
181
|
+
lines.push('Queue topics for background research during idle time.');
|
|
182
|
+
lines.push('');
|
|
183
|
+
lines.push('### commitments');
|
|
184
|
+
lines.push('Track promises and tasks with due dates.');
|
|
185
|
+
lines.push('');
|
|
186
|
+
lines.push('### content_pipeline');
|
|
187
|
+
lines.push('Manage content items through drafting stages.');
|
|
188
|
+
|
|
189
|
+
return lines.join('\n');
|
|
190
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type KPI = {
|
|
2
|
+
name: string;
|
|
3
|
+
metric: string;
|
|
4
|
+
target: string;
|
|
5
|
+
check_interval: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type CommunicationStyle = {
|
|
9
|
+
tone: string;
|
|
10
|
+
verbosity: 'concise' | 'detailed' | 'adaptive';
|
|
11
|
+
formality: 'formal' | 'casual' | 'adaptive';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type SubRoleTemplate = {
|
|
15
|
+
role_id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
spawned_by: string;
|
|
19
|
+
reports_to: string;
|
|
20
|
+
max_budget_per_task: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type RoleDefinition = {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
responsibilities: string[];
|
|
28
|
+
autonomous_actions: string[];
|
|
29
|
+
approval_required: string[];
|
|
30
|
+
kpis: KPI[];
|
|
31
|
+
communication_style: CommunicationStyle;
|
|
32
|
+
heartbeat_instructions: string;
|
|
33
|
+
sub_roles: SubRoleTemplate[];
|
|
34
|
+
tools: string[];
|
|
35
|
+
authority_level: number; // 1-10
|
|
36
|
+
};
|