@hera-al/server 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +325 -0
- package/bundled/apple-notes/SKILL.md +77 -0
- package/bundled/apple-reminders/SKILL.md +96 -0
- package/bundled/blogwatcher/SKILL.md +69 -0
- package/bundled/camsnap/SKILL.md +45 -0
- package/bundled/discord/SKILL.md +578 -0
- package/bundled/gemini/SKILL.md +43 -0
- package/bundled/gifgrep/SKILL.md +79 -0
- package/bundled/github/SKILL.md +77 -0
- package/bundled/gog/SKILL.md +116 -0
- package/bundled/goplaces/SKILL.md +52 -0
- package/bundled/himalaya/SKILL.md +257 -0
- package/bundled/himalaya/references/configuration.md +184 -0
- package/bundled/himalaya/references/message-composition.md +199 -0
- package/bundled/homebrew/SKILL.md +82 -0
- package/bundled/local-places/SERVER_README.md +101 -0
- package/bundled/local-places/SKILL.md +102 -0
- package/bundled/local-places/pyproject.toml +21 -0
- package/bundled/local-places/src/local_places/__init__.py +2 -0
- package/bundled/local-places/src/local_places/google_places.py +314 -0
- package/bundled/local-places/src/local_places/main.py +65 -0
- package/bundled/local-places/src/local_places/schemas.py +107 -0
- package/bundled/markitdown/SKILL.md +96 -0
- package/bundled/mcporter/SKILL.md +61 -0
- package/bundled/merge-pr/SKILL.md +187 -0
- package/bundled/merge-pr/agents/openai.yaml +4 -0
- package/bundled/nano-banana-pro/SKILL.md +58 -0
- package/bundled/nano-banana-pro/scripts/generate_image.py +184 -0
- package/bundled/nano-pdf/SKILL.md +38 -0
- package/bundled/open-prose/README.md +25 -0
- package/bundled/open-prose/index.ts +5 -0
- package/bundled/open-prose/openclaw.plugin.json +11 -0
- package/bundled/open-prose/package.json +15 -0
- package/bundled/open-prose/skills/prose/LICENSE +21 -0
- package/bundled/open-prose/skills/prose/SKILL.md +323 -0
- package/bundled/open-prose/skills/prose/alt-borges.md +141 -0
- package/bundled/open-prose/skills/prose/alts/arabian-nights.md +358 -0
- package/bundled/open-prose/skills/prose/alts/borges.md +360 -0
- package/bundled/open-prose/skills/prose/alts/folk.md +322 -0
- package/bundled/open-prose/skills/prose/alts/homer.md +346 -0
- package/bundled/open-prose/skills/prose/alts/kafka.md +373 -0
- package/bundled/open-prose/skills/prose/compiler.md +2971 -0
- package/bundled/open-prose/skills/prose/examples/01-hello-world.prose +4 -0
- package/bundled/open-prose/skills/prose/examples/02-research-and-summarize.prose +6 -0
- package/bundled/open-prose/skills/prose/examples/03-code-review.prose +17 -0
- package/bundled/open-prose/skills/prose/examples/04-write-and-refine.prose +14 -0
- package/bundled/open-prose/skills/prose/examples/05-debug-issue.prose +20 -0
- package/bundled/open-prose/skills/prose/examples/06-explain-codebase.prose +17 -0
- package/bundled/open-prose/skills/prose/examples/07-refactor.prose +20 -0
- package/bundled/open-prose/skills/prose/examples/08-blog-post.prose +20 -0
- package/bundled/open-prose/skills/prose/examples/09-research-with-agents.prose +25 -0
- package/bundled/open-prose/skills/prose/examples/10-code-review-agents.prose +32 -0
- package/bundled/open-prose/skills/prose/examples/11-skills-and-imports.prose +27 -0
- package/bundled/open-prose/skills/prose/examples/12-secure-agent-permissions.prose +43 -0
- package/bundled/open-prose/skills/prose/examples/13-variables-and-context.prose +51 -0
- package/bundled/open-prose/skills/prose/examples/14-composition-blocks.prose +48 -0
- package/bundled/open-prose/skills/prose/examples/15-inline-sequences.prose +23 -0
- package/bundled/open-prose/skills/prose/examples/16-parallel-reviews.prose +19 -0
- package/bundled/open-prose/skills/prose/examples/17-parallel-research.prose +19 -0
- package/bundled/open-prose/skills/prose/examples/18-mixed-parallel-sequential.prose +36 -0
- package/bundled/open-prose/skills/prose/examples/19-advanced-parallel.prose +71 -0
- package/bundled/open-prose/skills/prose/examples/20-fixed-loops.prose +20 -0
- package/bundled/open-prose/skills/prose/examples/21-pipeline-operations.prose +35 -0
- package/bundled/open-prose/skills/prose/examples/22-error-handling.prose +51 -0
- package/bundled/open-prose/skills/prose/examples/23-retry-with-backoff.prose +63 -0
- package/bundled/open-prose/skills/prose/examples/24-choice-blocks.prose +86 -0
- package/bundled/open-prose/skills/prose/examples/25-conditionals.prose +114 -0
- package/bundled/open-prose/skills/prose/examples/26-parameterized-blocks.prose +100 -0
- package/bundled/open-prose/skills/prose/examples/27-string-interpolation.prose +105 -0
- package/bundled/open-prose/skills/prose/examples/28-automated-pr-review.prose +37 -0
- package/bundled/open-prose/skills/prose/examples/28-gas-town.prose +1572 -0
- package/bundled/open-prose/skills/prose/examples/29-captains-chair.prose +218 -0
- package/bundled/open-prose/skills/prose/examples/30-captains-chair-simple.prose +42 -0
- package/bundled/open-prose/skills/prose/examples/31-captains-chair-with-memory.prose +145 -0
- package/bundled/open-prose/skills/prose/examples/33-pr-review-autofix.prose +168 -0
- package/bundled/open-prose/skills/prose/examples/34-content-pipeline.prose +204 -0
- package/bundled/open-prose/skills/prose/examples/35-feature-factory.prose +296 -0
- package/bundled/open-prose/skills/prose/examples/36-bug-hunter.prose +237 -0
- package/bundled/open-prose/skills/prose/examples/37-the-forge.prose +1474 -0
- package/bundled/open-prose/skills/prose/examples/38-skill-scan.prose +455 -0
- package/bundled/open-prose/skills/prose/examples/39-architect-by-simulation.prose +277 -0
- package/bundled/open-prose/skills/prose/examples/40-rlm-self-refine.prose +32 -0
- package/bundled/open-prose/skills/prose/examples/41-rlm-divide-conquer.prose +38 -0
- package/bundled/open-prose/skills/prose/examples/42-rlm-filter-recurse.prose +46 -0
- package/bundled/open-prose/skills/prose/examples/43-rlm-pairwise.prose +50 -0
- package/bundled/open-prose/skills/prose/examples/44-run-endpoint-ux-test.prose +261 -0
- package/bundled/open-prose/skills/prose/examples/45-plugin-release.prose +159 -0
- package/bundled/open-prose/skills/prose/examples/45-run-endpoint-ux-test-with-remediation.prose +637 -0
- package/bundled/open-prose/skills/prose/examples/46-run-endpoint-ux-test-fast.prose +148 -0
- package/bundled/open-prose/skills/prose/examples/46-workflow-crystallizer.prose +225 -0
- package/bundled/open-prose/skills/prose/examples/47-language-self-improvement.prose +356 -0
- package/bundled/open-prose/skills/prose/examples/48-habit-miner.prose +445 -0
- package/bundled/open-prose/skills/prose/examples/49-prose-run-retrospective.prose +210 -0
- package/bundled/open-prose/skills/prose/examples/README.md +391 -0
- package/bundled/open-prose/skills/prose/examples/roadmap/README.md +22 -0
- package/bundled/open-prose/skills/prose/examples/roadmap/iterative-refinement.prose +20 -0
- package/bundled/open-prose/skills/prose/examples/roadmap/parallel-review.prose +18 -0
- package/bundled/open-prose/skills/prose/examples/roadmap/simple-pipeline.prose +17 -0
- package/bundled/open-prose/skills/prose/examples/roadmap/syntax/open-prose-syntax.prose +223 -0
- package/bundled/open-prose/skills/prose/guidance/antipatterns.md +951 -0
- package/bundled/open-prose/skills/prose/guidance/patterns.md +700 -0
- package/bundled/open-prose/skills/prose/guidance/system-prompt.md +180 -0
- package/bundled/open-prose/skills/prose/help.md +144 -0
- package/bundled/open-prose/skills/prose/lib/README.md +108 -0
- package/bundled/open-prose/skills/prose/lib/calibrator.prose +215 -0
- package/bundled/open-prose/skills/prose/lib/cost-analyzer.prose +174 -0
- package/bundled/open-prose/skills/prose/lib/error-forensics.prose +250 -0
- package/bundled/open-prose/skills/prose/lib/inspector.prose +196 -0
- package/bundled/open-prose/skills/prose/lib/profiler.prose +460 -0
- package/bundled/open-prose/skills/prose/lib/program-improver.prose +275 -0
- package/bundled/open-prose/skills/prose/lib/project-memory.prose +118 -0
- package/bundled/open-prose/skills/prose/lib/user-memory.prose +93 -0
- package/bundled/open-prose/skills/prose/lib/vm-improver.prose +243 -0
- package/bundled/open-prose/skills/prose/primitives/session.md +593 -0
- package/bundled/open-prose/skills/prose/prose.md +1237 -0
- package/bundled/open-prose/skills/prose/state/filesystem.md +498 -0
- package/bundled/open-prose/skills/prose/state/in-context.md +384 -0
- package/bundled/open-prose/skills/prose/state/postgres.md +880 -0
- package/bundled/open-prose/skills/prose/state/sqlite.md +574 -0
- package/bundled/peekaboo/SKILL.md +190 -0
- package/bundled/prepare-pr/SKILL.md +277 -0
- package/bundled/prepare-pr/agents/openai.yaml +4 -0
- package/bundled/review-pr/SKILL.md +228 -0
- package/bundled/review-pr/agents/openai.yaml +4 -0
- package/bundled/sag/SKILL.md +87 -0
- package/bundled/skill-creator/SKILL.md +370 -0
- package/bundled/skill-creator/license.txt +202 -0
- package/bundled/skill-creator/scripts/init_skill.py +378 -0
- package/bundled/skill-creator/scripts/package_skill.py +111 -0
- package/bundled/skill-creator/scripts/quick_validate.py +101 -0
- package/bundled/spotify-player/SKILL.md +64 -0
- package/bundled/ssh/SKILL.md +119 -0
- package/bundled/summarize/SKILL.md +87 -0
- package/bundled/video-frames/SKILL.md +46 -0
- package/bundled/video-frames/scripts/frame.sh +81 -0
- package/bundled/voice-call/SKILL.md +45 -0
- package/bundled/wacli/SKILL.md +72 -0
- package/bundled/weather/SKILL.md +54 -0
- package/dist/agent/agent-service.d.ts +88 -0
- package/dist/agent/agent-service.js +1 -0
- package/dist/agent/message-queue.d.ts +24 -0
- package/dist/agent/message-queue.js +1 -0
- package/dist/agent/prompt-builder.d.ts +58 -0
- package/dist/agent/prompt-builder.js +1 -0
- package/dist/agent/session-agent.d.ts +197 -0
- package/dist/agent/session-agent.js +1 -0
- package/dist/agent/session-db.d.ts +26 -0
- package/dist/agent/session-db.js +1 -0
- package/dist/agent/session-error-handler.d.ts +37 -0
- package/dist/agent/session-error-handler.js +1 -0
- package/dist/agent/session-manager.d.ts +19 -0
- package/dist/agent/session-manager.js +1 -0
- package/dist/agent/workspace-files.d.ts +51 -0
- package/dist/agent/workspace-files.js +1 -0
- package/dist/auth/auth-middleware.d.ts +9 -0
- package/dist/auth/auth-middleware.js +1 -0
- package/dist/auth/node-signature-db.d.ts +30 -0
- package/dist/auth/node-signature-db.js +1 -0
- package/dist/auth/token-db.d.ts +38 -0
- package/dist/auth/token-db.js +1 -0
- package/dist/browser/browser-service.d.ts +9 -0
- package/dist/browser/browser-service.js +1 -0
- package/dist/channels/channel.d.ts +2 -0
- package/dist/channels/channel.js +1 -0
- package/dist/channels/responses.d.ts +21 -0
- package/dist/channels/responses.js +1 -0
- package/dist/commands/clear.d.ts +7 -0
- package/dist/commands/clear.js +1 -0
- package/dist/commands/cmd.d.ts +7 -0
- package/dist/commands/cmd.js +1 -0
- package/dist/commands/coder.d.ts +12 -0
- package/dist/commands/coder.js +1 -0
- package/dist/commands/command-registry.d.ts +12 -0
- package/dist/commands/command-registry.js +1 -0
- package/dist/commands/command.d.ts +22 -0
- package/dist/commands/command.js +1 -0
- package/dist/commands/compact.d.ts +7 -0
- package/dist/commands/compact.js +1 -0
- package/dist/commands/customsubagents.d.ts +15 -0
- package/dist/commands/customsubagents.js +1 -0
- package/dist/commands/help.d.ts +9 -0
- package/dist/commands/help.js +1 -0
- package/dist/commands/mcp.d.ts +9 -0
- package/dist/commands/mcp.js +1 -0
- package/dist/commands/model.d.ts +22 -0
- package/dist/commands/model.js +1 -0
- package/dist/commands/models.d.ts +11 -0
- package/dist/commands/models.js +1 -0
- package/dist/commands/new.d.ts +7 -0
- package/dist/commands/new.js +1 -0
- package/dist/commands/plugin.d.ts +7 -0
- package/dist/commands/plugin.js +1 -0
- package/dist/commands/sandbox.d.ts +12 -0
- package/dist/commands/sandbox.js +1 -0
- package/dist/commands/showtool.d.ts +12 -0
- package/dist/commands/showtool.js +1 -0
- package/dist/commands/status.d.ts +24 -0
- package/dist/commands/status.js +1 -0
- package/dist/commands/stop.d.ts +10 -0
- package/dist/commands/stop.js +1 -0
- package/dist/commands/subagents.d.ts +12 -0
- package/dist/commands/subagents.js +1 -0
- package/dist/commands/usage.d.ts +25 -0
- package/dist/commands/usage.js +1 -0
- package/dist/commands/useplugin.d.ts +7 -0
- package/dist/commands/useplugin.js +1 -0
- package/dist/config-watcher.d.ts +14 -0
- package/dist/config-watcher.js +1 -0
- package/dist/config.d.ts +267 -0
- package/dist/config.js +1 -0
- package/dist/cron/cron-service.d.ts +57 -0
- package/dist/cron/cron-service.js +1 -0
- package/dist/cron/heartbeat-token.d.ts +29 -0
- package/dist/cron/heartbeat-token.js +1 -0
- package/dist/cron/schedule.d.ts +3 -0
- package/dist/cron/schedule.js +1 -0
- package/dist/cron/store.d.ts +4 -0
- package/dist/cron/store.js +1 -0
- package/dist/cron/types.d.ts +47 -0
- package/dist/cron/types.js +1 -0
- package/dist/gateway/bridge.d.ts +38 -0
- package/dist/gateway/bridge.js +1 -0
- package/dist/gateway/channel-manager.d.ts +45 -0
- package/dist/gateway/channel-manager.js +1 -0
- package/dist/gateway/channels/qr-image.d.ts +5 -0
- package/dist/gateway/channels/qr-image.js +1 -0
- package/dist/gateway/channels/telegram.d.ts +39 -0
- package/dist/gateway/channels/telegram.js +1 -0
- package/dist/gateway/channels/webchat.d.ts +51 -0
- package/dist/gateway/channels/webchat.js +1 -0
- package/dist/gateway/channels/whatsapp.d.ts +40 -0
- package/dist/gateway/channels/whatsapp.js +1 -0
- package/dist/gateway/node-registry.d.ts +38 -0
- package/dist/gateway/node-registry.js +1 -0
- package/dist/heracli/index.d.ts +3 -0
- package/dist/heracli/index.js +2 -0
- package/dist/heracli/logs.d.ts +13 -0
- package/dist/heracli/logs.js +1 -0
- package/dist/heracli/security/audit.d.ts +17 -0
- package/dist/heracli/security/audit.js +1 -0
- package/dist/heracli/security/checks/channel-policies.d.ts +6 -0
- package/dist/heracli/security/checks/channel-policies.js +1 -0
- package/dist/heracli/security/checks/credentials.d.ts +6 -0
- package/dist/heracli/security/checks/credentials.js +1 -0
- package/dist/heracli/security/checks/fs-permissions.d.ts +6 -0
- package/dist/heracli/security/checks/fs-permissions.js +1 -0
- package/dist/heracli/security/checks/network.d.ts +4 -0
- package/dist/heracli/security/checks/network.js +1 -0
- package/dist/heracli/security/report.d.ts +4 -0
- package/dist/heracli/security/report.js +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/installer/hera.d.ts +3 -0
- package/dist/installer/hera.js +2 -0
- package/dist/media/message-processor.d.ts +23 -0
- package/dist/media/message-processor.js +1 -0
- package/dist/memory/memory-manager.d.ts +21 -0
- package/dist/memory/memory-manager.js +1 -0
- package/dist/memory/memory-provider.d.ts +22 -0
- package/dist/memory/memory-provider.js +1 -0
- package/dist/memory/memory-search.d.ts +102 -0
- package/dist/memory/memory-search.js +1 -0
- package/dist/memory/recall-strategies.d.ts +2 -0
- package/dist/memory/recall-strategies.js +1 -0
- package/dist/nostromo/auth.d.ts +29 -0
- package/dist/nostromo/auth.js +1 -0
- package/dist/nostromo/nostromo.d.ts +23 -0
- package/dist/nostromo/nostromo.js +1 -0
- package/dist/nostromo/ui-html-layout.d.ts +3 -0
- package/dist/nostromo/ui-html-layout.js +1 -0
- package/dist/nostromo/ui-html-modals.d.ts +3 -0
- package/dist/nostromo/ui-html-modals.js +1 -0
- package/dist/nostromo/ui-js-agent.d.ts +3 -0
- package/dist/nostromo/ui-js-agent.js +1 -0
- package/dist/nostromo/ui-js-channels.d.ts +3 -0
- package/dist/nostromo/ui-js-channels.js +1 -0
- package/dist/nostromo/ui-js-competences.d.ts +3 -0
- package/dist/nostromo/ui-js-competences.js +1 -0
- package/dist/nostromo/ui-js-config.d.ts +3 -0
- package/dist/nostromo/ui-js-config.js +1 -0
- package/dist/nostromo/ui-js-core.d.ts +3 -0
- package/dist/nostromo/ui-js-core.js +1 -0
- package/dist/nostromo/ui-js-ops.d.ts +3 -0
- package/dist/nostromo/ui-js-ops.js +1 -0
- package/dist/nostromo/ui-js-prompts.d.ts +3 -0
- package/dist/nostromo/ui-js-prompts.js +1 -0
- package/dist/nostromo/ui-styles.d.ts +3 -0
- package/dist/nostromo/ui-styles.js +1 -0
- package/dist/nostromo/ui.d.ts +2 -0
- package/dist/nostromo/ui.js +1 -0
- package/dist/server.d.ts +80 -0
- package/dist/server.js +1 -0
- package/dist/stt/local-whisper.d.ts +9 -0
- package/dist/stt/local-whisper.js +1 -0
- package/dist/stt/openai-whisper.d.ts +14 -0
- package/dist/stt/openai-whisper.js +1 -0
- package/dist/stt/stt-loader.d.ts +4 -0
- package/dist/stt/stt-loader.js +1 -0
- package/dist/stt/stt-provider.d.ts +4 -0
- package/dist/stt/stt-provider.js +1 -0
- package/dist/tools/browser-tools.d.ts +9 -0
- package/dist/tools/browser-tools.js +1 -0
- package/dist/tools/cron-tools.d.ts +4 -0
- package/dist/tools/cron-tools.js +1 -0
- package/dist/tools/memory-tools.d.ts +3 -0
- package/dist/tools/memory-tools.js +1 -0
- package/dist/tools/message-tools.d.ts +5 -0
- package/dist/tools/message-tools.js +1 -0
- package/dist/tools/node-tools.d.ts +3 -0
- package/dist/tools/node-tools.js +1 -0
- package/dist/tools/server-tools.d.ts +2 -0
- package/dist/tools/server-tools.js +1 -0
- package/dist/tools/tts-tools.d.ts +3 -0
- package/dist/tools/tts-tools.js +1 -0
- package/dist/tts/tts-service.d.ts +19 -0
- package/dist/tts/tts-service.js +1 -0
- package/dist/utils/chunk.d.ts +3 -0
- package/dist/utils/chunk.js +1 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.js +1 -0
- package/dist/utils/markdown/fences.d.ts +11 -0
- package/dist/utils/markdown/fences.js +1 -0
- package/dist/utils/markdown/ir.d.ts +33 -0
- package/dist/utils/markdown/ir.js +1 -0
- package/dist/utils/markdown/render.d.ts +19 -0
- package/dist/utils/markdown/render.js +1 -0
- package/dist/utils/markdown/tables.d.ts +3 -0
- package/dist/utils/markdown/tables.js +1 -0
- package/dist/utils/media-response.d.ts +29 -0
- package/dist/utils/media-response.js +1 -0
- package/dist/utils/package-paths.d.ts +5 -0
- package/dist/utils/package-paths.js +1 -0
- package/dist/utils/telegram-format.d.ts +13 -0
- package/dist/utils/telegram-format.js +1 -0
- package/installationPkg/.env.example +26 -0
- package/installationPkg/AGENTS.md +143 -0
- package/installationPkg/BOOTSTRAP.md +45 -0
- package/installationPkg/CBINT.json +16 -0
- package/installationPkg/HEARTBEAT.md +5 -0
- package/installationPkg/IDENTITY.md +7 -0
- package/installationPkg/SOUL.md +36 -0
- package/installationPkg/SYSTEM_PROMPT.md +55 -0
- package/installationPkg/SYSTEM_PROMPT_SUBAGENT.md +40 -0
- package/installationPkg/TOOLS.md +36 -0
- package/installationPkg/USER.md +11 -0
- package/installationPkg/config.example.yaml +291 -0
- package/package.json +95 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ssh
|
|
3
|
+
description: Manage SSH connections, run remote commands, transfer files, and manage keys. Use when working with remote servers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SSH Manager
|
|
7
|
+
|
|
8
|
+
Manage SSH connections, execute remote commands, transfer files, and handle SSH keys.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
- Running commands on remote servers
|
|
12
|
+
- Transferring files to/from remote machines
|
|
13
|
+
- Managing SSH keys and config
|
|
14
|
+
- Setting up tunnels and port forwarding
|
|
15
|
+
- Debugging connection issues
|
|
16
|
+
|
|
17
|
+
## Remote Commands
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
ssh user@host "command" # Run single command
|
|
21
|
+
ssh user@host "cd /app && git pull && pm2 restart all" # Chained commands
|
|
22
|
+
ssh -p 2222 user@host "command" # Custom port
|
|
23
|
+
ssh -i ~/.ssh/mykey user@host "command" # Specific key
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## File Transfer (SCP)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
scp file.txt user@host:/remote/path/ # Upload file
|
|
30
|
+
scp user@host:/remote/path/file.txt ./ # Download file
|
|
31
|
+
scp -r ./folder user@host:/remote/path/ # Upload directory
|
|
32
|
+
scp -P 2222 file.txt user@host:/path/ # Custom port
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## File Transfer (rsync - preferred for large transfers)
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
rsync -avz ./local/ user@host:/remote/ # Sync local to remote
|
|
39
|
+
rsync -avz user@host:/remote/ ./local/ # Sync remote to local
|
|
40
|
+
rsync -avz --delete ./local/ user@host:/remote/ # Mirror (delete extra files)
|
|
41
|
+
rsync -avz --progress ./large-file user@host:/path/ # With progress
|
|
42
|
+
rsync -avz -e "ssh -p 2222" ./local/ user@host:/remote/ # Custom port
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## SSH Config (~/.ssh/config)
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
Host myserver
|
|
49
|
+
HostName 192.168.1.100
|
|
50
|
+
User admin
|
|
51
|
+
Port 22
|
|
52
|
+
IdentityFile ~/.ssh/mykey
|
|
53
|
+
|
|
54
|
+
Host jump
|
|
55
|
+
HostName bastion.example.com
|
|
56
|
+
User jumpuser
|
|
57
|
+
|
|
58
|
+
Host internal
|
|
59
|
+
HostName 10.0.0.5
|
|
60
|
+
User admin
|
|
61
|
+
ProxyJump jump
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
After config, simply: `ssh myserver`
|
|
65
|
+
|
|
66
|
+
## Key Management
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
ssh-keygen -t ed25519 -C "comment" # Generate key (preferred)
|
|
70
|
+
ssh-keygen -t rsa -b 4096 -C "comment" # Generate RSA key
|
|
71
|
+
ssh-copy-id user@host # Copy public key to server
|
|
72
|
+
ssh-add ~/.ssh/mykey # Add key to agent
|
|
73
|
+
ssh-add -l # List keys in agent
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Tunnels & Port Forwarding
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Local forward: access remote service on local port
|
|
80
|
+
ssh -L 8080:localhost:3000 user@host # local:8080 -> remote:3000
|
|
81
|
+
|
|
82
|
+
# Remote forward: expose local service on remote port
|
|
83
|
+
ssh -R 9090:localhost:3000 user@host # remote:9090 -> local:3000
|
|
84
|
+
|
|
85
|
+
# SOCKS proxy
|
|
86
|
+
ssh -D 1080 user@host # SOCKS proxy on local:1080
|
|
87
|
+
|
|
88
|
+
# Background tunnel (no shell)
|
|
89
|
+
ssh -fN -L 8080:localhost:3000 user@host
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Troubleshooting
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
ssh -v user@host # Verbose (debug level 1)
|
|
96
|
+
ssh -vv user@host # More verbose
|
|
97
|
+
ssh -vvv user@host # Maximum verbosity
|
|
98
|
+
ssh -o ConnectTimeout=5 user@host # Set timeout
|
|
99
|
+
ssh -o StrictHostKeyChecking=no user@host # Skip host key check (use carefully!)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Server Health Checks
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
ssh user@host "uptime" # Load average
|
|
106
|
+
ssh user@host "df -h" # Disk usage
|
|
107
|
+
ssh user@host "free -h" # Memory usage
|
|
108
|
+
ssh user@host "top -bn1 | head -20" # Process list
|
|
109
|
+
ssh user@host "systemctl status nginx" # Service status
|
|
110
|
+
ssh user@host "tail -n 50 /var/log/syslog" # Recent logs
|
|
111
|
+
ssh user@host "docker ps" # Running containers
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Notes
|
|
115
|
+
- Always prefer ed25519 keys over RSA for new setups
|
|
116
|
+
- Use SSH config file to avoid typing long commands
|
|
117
|
+
- Use `rsync` over `scp` for large or repeated transfers
|
|
118
|
+
- Never disable StrictHostKeyChecking in production
|
|
119
|
+
- Use ProxyJump for bastion/jump host setups
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: summarize
|
|
3
|
+
description: Summarize or extract text/transcripts from URLs, podcasts, and local files (great fallback for “transcribe this YouTube/video”).
|
|
4
|
+
homepage: https://summarize.sh
|
|
5
|
+
metadata:
|
|
6
|
+
{
|
|
7
|
+
"openclaw":
|
|
8
|
+
{
|
|
9
|
+
"emoji": "🧾",
|
|
10
|
+
"requires": { "bins": ["summarize"] },
|
|
11
|
+
"install":
|
|
12
|
+
[
|
|
13
|
+
{
|
|
14
|
+
"id": "brew",
|
|
15
|
+
"kind": "brew",
|
|
16
|
+
"formula": "steipete/tap/summarize",
|
|
17
|
+
"bins": ["summarize"],
|
|
18
|
+
"label": "Install summarize (brew)",
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Summarize
|
|
26
|
+
|
|
27
|
+
Fast CLI to summarize URLs, local files, and YouTube links.
|
|
28
|
+
|
|
29
|
+
## When to use (trigger phrases)
|
|
30
|
+
|
|
31
|
+
Use this skill immediately when the user asks any of:
|
|
32
|
+
|
|
33
|
+
- “use summarize.sh”
|
|
34
|
+
- “what’s this link/video about?”
|
|
35
|
+
- “summarize this URL/article”
|
|
36
|
+
- “transcribe this YouTube/video” (best-effort transcript extraction; no `yt-dlp` needed)
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
summarize "https://example.com" --model google/gemini-3-flash-preview
|
|
42
|
+
summarize "/path/to/file.pdf" --model google/gemini-3-flash-preview
|
|
43
|
+
summarize "https://youtu.be/dQw4w9WgXcQ" --youtube auto
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## YouTube: summary vs transcript
|
|
47
|
+
|
|
48
|
+
Best-effort transcript (URLs only):
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
summarize "https://youtu.be/dQw4w9WgXcQ" --youtube auto --extract-only
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
If the user asked for a transcript but it’s huge, return a tight summary first, then ask which section/time range to expand.
|
|
55
|
+
|
|
56
|
+
## Model + keys
|
|
57
|
+
|
|
58
|
+
Set the API key for your chosen provider:
|
|
59
|
+
|
|
60
|
+
- OpenAI: `OPENAI_API_KEY`
|
|
61
|
+
- Anthropic: `ANTHROPIC_API_KEY`
|
|
62
|
+
- xAI: `XAI_API_KEY`
|
|
63
|
+
- Google: `GEMINI_API_KEY` (aliases: `GOOGLE_GENERATIVE_AI_API_KEY`, `GOOGLE_API_KEY`)
|
|
64
|
+
|
|
65
|
+
Default model is `google/gemini-3-flash-preview` if none is set.
|
|
66
|
+
|
|
67
|
+
## Useful flags
|
|
68
|
+
|
|
69
|
+
- `--length short|medium|long|xl|xxl|<chars>`
|
|
70
|
+
- `--max-output-tokens <count>`
|
|
71
|
+
- `--extract-only` (URLs only)
|
|
72
|
+
- `--json` (machine readable)
|
|
73
|
+
- `--firecrawl auto|off|always` (fallback extraction)
|
|
74
|
+
- `--youtube auto` (Apify fallback if `APIFY_API_TOKEN` set)
|
|
75
|
+
|
|
76
|
+
## Config
|
|
77
|
+
|
|
78
|
+
Optional config file: `~/.summarize/config.json`
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{ "model": "openai/gpt-5.2" }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Optional services:
|
|
85
|
+
|
|
86
|
+
- `FIRECRAWL_API_KEY` for blocked sites
|
|
87
|
+
- `APIFY_API_TOKEN` for YouTube fallback
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: video-frames
|
|
3
|
+
description: Extract frames or short clips from videos using ffmpeg.
|
|
4
|
+
homepage: https://ffmpeg.org
|
|
5
|
+
metadata:
|
|
6
|
+
{
|
|
7
|
+
"openclaw":
|
|
8
|
+
{
|
|
9
|
+
"emoji": "🎞️",
|
|
10
|
+
"requires": { "bins": ["ffmpeg"] },
|
|
11
|
+
"install":
|
|
12
|
+
[
|
|
13
|
+
{
|
|
14
|
+
"id": "brew",
|
|
15
|
+
"kind": "brew",
|
|
16
|
+
"formula": "ffmpeg",
|
|
17
|
+
"bins": ["ffmpeg"],
|
|
18
|
+
"label": "Install ffmpeg (brew)",
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Video Frames (ffmpeg)
|
|
26
|
+
|
|
27
|
+
Extract a single frame from a video, or create quick thumbnails for inspection.
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
First frame:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
{baseDir}/scripts/frame.sh /path/to/video.mp4 --out /tmp/frame.jpg
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
At a timestamp:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
{baseDir}/scripts/frame.sh /path/to/video.mp4 --time 00:00:10 --out /tmp/frame-10s.jpg
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
|
|
45
|
+
- Prefer `--time` for “what is happening around here?”.
|
|
46
|
+
- Use a `.jpg` for quick share; use `.png` for crisp UI frames.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
usage() {
|
|
5
|
+
cat >&2 <<'EOF'
|
|
6
|
+
Usage:
|
|
7
|
+
frame.sh <video-file> [--time HH:MM:SS] [--index N] --out /path/to/frame.jpg
|
|
8
|
+
|
|
9
|
+
Examples:
|
|
10
|
+
frame.sh video.mp4 --out /tmp/frame.jpg
|
|
11
|
+
frame.sh video.mp4 --time 00:00:10 --out /tmp/frame-10s.jpg
|
|
12
|
+
frame.sh video.mp4 --index 0 --out /tmp/frame0.png
|
|
13
|
+
EOF
|
|
14
|
+
exit 2
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if [[ "${1:-}" == "" || "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
18
|
+
usage
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
in="${1:-}"
|
|
22
|
+
shift || true
|
|
23
|
+
|
|
24
|
+
time=""
|
|
25
|
+
index=""
|
|
26
|
+
out=""
|
|
27
|
+
|
|
28
|
+
while [[ $# -gt 0 ]]; do
|
|
29
|
+
case "$1" in
|
|
30
|
+
--time)
|
|
31
|
+
time="${2:-}"
|
|
32
|
+
shift 2
|
|
33
|
+
;;
|
|
34
|
+
--index)
|
|
35
|
+
index="${2:-}"
|
|
36
|
+
shift 2
|
|
37
|
+
;;
|
|
38
|
+
--out)
|
|
39
|
+
out="${2:-}"
|
|
40
|
+
shift 2
|
|
41
|
+
;;
|
|
42
|
+
*)
|
|
43
|
+
echo "Unknown arg: $1" >&2
|
|
44
|
+
usage
|
|
45
|
+
;;
|
|
46
|
+
esac
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
if [[ ! -f "$in" ]]; then
|
|
50
|
+
echo "File not found: $in" >&2
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
if [[ "$out" == "" ]]; then
|
|
55
|
+
echo "Missing --out" >&2
|
|
56
|
+
usage
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
mkdir -p "$(dirname "$out")"
|
|
60
|
+
|
|
61
|
+
if [[ "$index" != "" ]]; then
|
|
62
|
+
ffmpeg -hide_banner -loglevel error -y \
|
|
63
|
+
-i "$in" \
|
|
64
|
+
-vf "select=eq(n\\,${index})" \
|
|
65
|
+
-vframes 1 \
|
|
66
|
+
"$out"
|
|
67
|
+
elif [[ "$time" != "" ]]; then
|
|
68
|
+
ffmpeg -hide_banner -loglevel error -y \
|
|
69
|
+
-ss "$time" \
|
|
70
|
+
-i "$in" \
|
|
71
|
+
-frames:v 1 \
|
|
72
|
+
"$out"
|
|
73
|
+
else
|
|
74
|
+
ffmpeg -hide_banner -loglevel error -y \
|
|
75
|
+
-i "$in" \
|
|
76
|
+
-vf "select=eq(n\\,0)" \
|
|
77
|
+
-vframes 1 \
|
|
78
|
+
"$out"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
echo "$out"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: voice-call
|
|
3
|
+
description: Start voice calls via the OpenClaw voice-call plugin.
|
|
4
|
+
metadata:
|
|
5
|
+
{
|
|
6
|
+
"openclaw":
|
|
7
|
+
{
|
|
8
|
+
"emoji": "📞",
|
|
9
|
+
"skillKey": "voice-call",
|
|
10
|
+
"requires": { "config": ["plugins.entries.voice-call.enabled"] },
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Voice Call
|
|
16
|
+
|
|
17
|
+
Use the voice-call plugin to start or inspect calls (Twilio, Telnyx, Plivo, or mock).
|
|
18
|
+
|
|
19
|
+
## CLI
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"
|
|
23
|
+
openclaw voicecall status --call-id <id>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Tool
|
|
27
|
+
|
|
28
|
+
Use `voice_call` for agent-initiated calls.
|
|
29
|
+
|
|
30
|
+
Actions:
|
|
31
|
+
|
|
32
|
+
- `initiate_call` (message, to?, mode?)
|
|
33
|
+
- `continue_call` (callId, message)
|
|
34
|
+
- `speak_to_user` (callId, message)
|
|
35
|
+
- `end_call` (callId)
|
|
36
|
+
- `get_status` (callId)
|
|
37
|
+
|
|
38
|
+
Notes:
|
|
39
|
+
|
|
40
|
+
- Requires the voice-call plugin to be enabled.
|
|
41
|
+
- Plugin config lives under `plugins.entries.voice-call.config`.
|
|
42
|
+
- Twilio config: `provider: "twilio"` + `twilio.accountSid/authToken` + `fromNumber`.
|
|
43
|
+
- Telnyx config: `provider: "telnyx"` + `telnyx.apiKey/connectionId` + `fromNumber`.
|
|
44
|
+
- Plivo config: `provider: "plivo"` + `plivo.authId/authToken` + `fromNumber`.
|
|
45
|
+
- Dev fallback: `provider: "mock"` (no network).
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wacli
|
|
3
|
+
description: Send WhatsApp messages to other people or search/sync WhatsApp history via the wacli CLI (not for normal user chats).
|
|
4
|
+
homepage: https://wacli.sh
|
|
5
|
+
metadata:
|
|
6
|
+
{
|
|
7
|
+
"openclaw":
|
|
8
|
+
{
|
|
9
|
+
"emoji": "📱",
|
|
10
|
+
"requires": { "bins": ["wacli"] },
|
|
11
|
+
"install":
|
|
12
|
+
[
|
|
13
|
+
{
|
|
14
|
+
"id": "brew",
|
|
15
|
+
"kind": "brew",
|
|
16
|
+
"formula": "steipete/tap/wacli",
|
|
17
|
+
"bins": ["wacli"],
|
|
18
|
+
"label": "Install wacli (brew)",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "go",
|
|
22
|
+
"kind": "go",
|
|
23
|
+
"module": "github.com/steipete/wacli/cmd/wacli@latest",
|
|
24
|
+
"bins": ["wacli"],
|
|
25
|
+
"label": "Install wacli (go)",
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# wacli
|
|
33
|
+
|
|
34
|
+
Use `wacli` only when the user explicitly asks you to message someone else on WhatsApp or when they ask to sync/search WhatsApp history.
|
|
35
|
+
Do NOT use `wacli` for normal user chats; OpenClaw routes WhatsApp conversations automatically.
|
|
36
|
+
If the user is chatting with you on WhatsApp, you should not reach for this tool unless they ask you to contact a third party.
|
|
37
|
+
|
|
38
|
+
Safety
|
|
39
|
+
|
|
40
|
+
- Require explicit recipient + message text.
|
|
41
|
+
- Confirm recipient + message before sending.
|
|
42
|
+
- If anything is ambiguous, ask a clarifying question.
|
|
43
|
+
|
|
44
|
+
Auth + sync
|
|
45
|
+
|
|
46
|
+
- `wacli auth` (QR login + initial sync)
|
|
47
|
+
- `wacli sync --follow` (continuous sync)
|
|
48
|
+
- `wacli doctor`
|
|
49
|
+
|
|
50
|
+
Find chats + messages
|
|
51
|
+
|
|
52
|
+
- `wacli chats list --limit 20 --query "name or number"`
|
|
53
|
+
- `wacli messages search "query" --limit 20 --chat <jid>`
|
|
54
|
+
- `wacli messages search "invoice" --after 2025-01-01 --before 2025-12-31`
|
|
55
|
+
|
|
56
|
+
History backfill
|
|
57
|
+
|
|
58
|
+
- `wacli history backfill --chat <jid> --requests 2 --count 50`
|
|
59
|
+
|
|
60
|
+
Send
|
|
61
|
+
|
|
62
|
+
- Text: `wacli send text --to "+14155551212" --message "Hello! Are you free at 3pm?"`
|
|
63
|
+
- Group: `wacli send text --to "1234567890-123456789@g.us" --message "Running 5 min late."`
|
|
64
|
+
- File: `wacli send file --to "+14155551212" --file /path/agenda.pdf --caption "Agenda"`
|
|
65
|
+
|
|
66
|
+
Notes
|
|
67
|
+
|
|
68
|
+
- Store dir: `~/.wacli` (override with `--store`).
|
|
69
|
+
- Use `--json` for machine-readable output when parsing.
|
|
70
|
+
- Backfill requires your phone online; results are best-effort.
|
|
71
|
+
- WhatsApp CLI is not needed for routine user chats; it’s for messaging other people.
|
|
72
|
+
- JIDs: direct chats look like `<number>@s.whatsapp.net`; groups look like `<id>@g.us` (use `wacli chats list` to find).
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: weather
|
|
3
|
+
description: Get current weather and forecasts (no API key required).
|
|
4
|
+
homepage: https://wttr.in/:help
|
|
5
|
+
metadata: { "openclaw": { "emoji": "🌤️", "requires": { "bins": ["curl"] } } }
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Weather
|
|
9
|
+
|
|
10
|
+
Two free services, no API keys needed.
|
|
11
|
+
|
|
12
|
+
## wttr.in (primary)
|
|
13
|
+
|
|
14
|
+
Quick one-liner:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
curl -s "wttr.in/London?format=3"
|
|
18
|
+
# Output: London: ⛅️ +8°C
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Compact format:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
curl -s "wttr.in/London?format=%l:+%c+%t+%h+%w"
|
|
25
|
+
# Output: London: ⛅️ +8°C 71% ↙5km/h
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Full forecast:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
curl -s "wttr.in/London?T"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Format codes: `%c` condition · `%t` temp · `%h` humidity · `%w` wind · `%l` location · `%m` moon
|
|
35
|
+
|
|
36
|
+
Tips:
|
|
37
|
+
|
|
38
|
+
- URL-encode spaces: `wttr.in/New+York`
|
|
39
|
+
- Airport codes: `wttr.in/JFK`
|
|
40
|
+
- Units: `?m` (metric) `?u` (USCS)
|
|
41
|
+
- Today only: `?1` · Current only: `?0`
|
|
42
|
+
- PNG: `curl -s "wttr.in/Berlin.png" -o /tmp/weather.png`
|
|
43
|
+
|
|
44
|
+
## Open-Meteo (fallback, JSON)
|
|
45
|
+
|
|
46
|
+
Free, no key, good for programmatic use:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -s "https://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12¤t_weather=true"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Find coordinates for a city, then query. Returns JSON with temp, windspeed, weathercode.
|
|
53
|
+
|
|
54
|
+
Docs: https://open-meteo.com/en/docs
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { AppConfig } from "../config.js";
|
|
2
|
+
import type { BuiltPrompt } from "./prompt-builder.js";
|
|
3
|
+
import type { NodeRegistry } from "../gateway/node-registry.js";
|
|
4
|
+
import type { ChannelManager } from "../gateway/channel-manager.js";
|
|
5
|
+
import { type AgentResult } from "./session-agent.js";
|
|
6
|
+
import type { UsageData } from "../commands/usage.js";
|
|
7
|
+
import { createServerToolsServer } from "../tools/server-tools.js";
|
|
8
|
+
import { createTTSToolsServer } from "../tools/tts-tools.js";
|
|
9
|
+
export type QueryResult = AgentResult;
|
|
10
|
+
export declare class AgentService {
|
|
11
|
+
private config;
|
|
12
|
+
private agents;
|
|
13
|
+
private usageBySession;
|
|
14
|
+
private nodeToolsServer;
|
|
15
|
+
private messageToolsServer;
|
|
16
|
+
private serverToolsServer;
|
|
17
|
+
private cronToolsServer;
|
|
18
|
+
private ttsToolsServer;
|
|
19
|
+
private memoryToolsServer;
|
|
20
|
+
private browserToolsServer;
|
|
21
|
+
private channelManager;
|
|
22
|
+
private showToolUseGetter;
|
|
23
|
+
constructor(config: AppConfig, nodeRegistry?: NodeRegistry, channelManager?: ChannelManager, serverToolsServer?: ReturnType<typeof createServerToolsServer>, cronToolsServer?: unknown, sessionDb?: import("./session-db.js").SessionDB, ttsToolsServer?: ReturnType<typeof createTTSToolsServer>, memoryToolsServer?: unknown, showToolUseGetter?: (sessionKey: string) => boolean, browserToolsServer?: unknown);
|
|
24
|
+
/**
|
|
25
|
+
* Send a message to the agent for a given session.
|
|
26
|
+
* Creates a long-lived SessionAgent on first call; subsequent messages for
|
|
27
|
+
* the same session key are queued and processed sequentially by the SDK.
|
|
28
|
+
*/
|
|
29
|
+
sendMessage(sessionKey: string, prompt: BuiltPrompt, sessionId: string | undefined, systemPrompt: string, subagentSystemPrompt: string, modelOverride?: string, coderSkill?: boolean, subagentsEnabled?: boolean, customSubAgentsEnabled?: boolean, sandboxEnabled?: boolean): Promise<QueryResult>;
|
|
30
|
+
hasNodeTools(): boolean;
|
|
31
|
+
hasMessageTools(): boolean;
|
|
32
|
+
/** Return all active MCP tool server instances for introspection. */
|
|
33
|
+
getToolServers(): Array<{
|
|
34
|
+
name: string;
|
|
35
|
+
instance: unknown;
|
|
36
|
+
}>;
|
|
37
|
+
private getOrCreateAgent;
|
|
38
|
+
interrupt(sessionKey: string): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Check if the agent for a session is currently processing a request.
|
|
41
|
+
*/
|
|
42
|
+
isBusy(sessionKey: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Check if a session has a pending interactive permission request.
|
|
45
|
+
*/
|
|
46
|
+
hasPendingPermission(sessionKey: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a pending interactive permission request for a session.
|
|
49
|
+
*/
|
|
50
|
+
resolvePermission(sessionKey: string, approved: boolean): void;
|
|
51
|
+
/**
|
|
52
|
+
* Check if a session has a pending AskUserQuestion waiting for user input.
|
|
53
|
+
*/
|
|
54
|
+
hasPendingQuestion(sessionKey: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Resolve a pending AskUserQuestion for a session.
|
|
57
|
+
*/
|
|
58
|
+
resolveQuestion(sessionKey: string, answer: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Destroy a session's agent (e.g. on /new command).
|
|
61
|
+
* The next sendMessage call will create a fresh agent.
|
|
62
|
+
*/
|
|
63
|
+
destroySession(sessionKey: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Close all active session agents (e.g. during server reconfiguration).
|
|
66
|
+
* Pending responses will be rejected with a "SessionAgent closed" error.
|
|
67
|
+
*/
|
|
68
|
+
destroyAll(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get list of active session keys
|
|
71
|
+
*/
|
|
72
|
+
getActiveSessions(): string[];
|
|
73
|
+
/**
|
|
74
|
+
* Get count of active sessions
|
|
75
|
+
*/
|
|
76
|
+
getActiveSessionCount(): number;
|
|
77
|
+
/**
|
|
78
|
+
* Get SDK slash commands discovered from any active agent's init message.
|
|
79
|
+
* Returns the first non-empty list found (commands are the same across agents).
|
|
80
|
+
*/
|
|
81
|
+
getUsage(sessionKey: string): UsageData | undefined;
|
|
82
|
+
getSdkSlashCommands(): string[];
|
|
83
|
+
listModels(): Promise<Array<{
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
}>>;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=agent-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{query as e}from"@anthropic-ai/claude-agent-sdk";import{SessionAgent as s}from"./session-agent.js";import{createNodeToolsServer as t}from"../tools/node-tools.js";import{createMessageToolsServer as o}from"../tools/message-tools.js";import{createLogger as r}from"../utils/logger.js";const n=r("AgentService");export class AgentService{config;agents=new Map;usageBySession=new Map;nodeToolsServer=null;messageToolsServer=null;serverToolsServer=null;cronToolsServer=null;ttsToolsServer=null;memoryToolsServer=null;browserToolsServer=null;channelManager=null;showToolUseGetter=null;constructor(e,s,r,n,i,a,l,g,h,c){this.config=e,r&&(this.channelManager=r),s&&(this.nodeToolsServer=t(s)),r&&a&&(this.messageToolsServer=o(r,()=>this.config,a)),n&&(this.serverToolsServer=n),i&&(this.cronToolsServer=i),l&&(this.ttsToolsServer=l),g&&(this.memoryToolsServer=g),c&&(this.browserToolsServer=c),h&&(this.showToolUseGetter=h)}async sendMessage(e,s,t,o,r,i,a,l,g,h){const c=this.getOrCreateAgent(e,t,o,r,i,a,l,g,h);if(i&&i!==c.getModel()){const t=e=>{const s=this.config.models.find(s=>s.id===e);return!(!s?.proxy||"not-used"===s.proxy)},d=t(c.getModel()),u=t(i);if(d||u){n.info(`[${e}] Proxy config change detected (old=${d}, new=${u}), restarting session`),this.destroySession(e);const t=this.getOrCreateAgent(e,void 0,o,r,i,a,l,g,h);return await t.send(s)}await c.setModel(i)}try{return await c.send(s)}catch(d){const u=d instanceof Error?d.message:String(d);if(u.includes("INVALID_ARGUMENT")||/API Error: 400/.test(u)){n.warn(`[${e}] Transient API 400 error, retrying once: ${u.slice(0,120)}`),this.agents.delete(e),c.close();const d=this.getOrCreateAgent(e,t,o,r,i,a,l,g,h);try{return await d.send(s)}catch(s){n.error(`[${e}] Retry also failed: ${s}`),this.agents.delete(e),d.close();const o=s instanceof Error?s.message:String(s);if(t)return{response:o.includes("SessionAgent closed")?"[AGENT_CLOSED]":"",sessionId:"",sessionReset:!0};throw s}}if(this.agents.delete(e),c.close(),t)return n.warn(`Session agent failed for ${e}: ${d}`),{response:u.includes("SessionAgent closed")?"[AGENT_CLOSED]":"",sessionId:"",sessionReset:!0};throw d}}hasNodeTools(){return null!==this.nodeToolsServer}hasMessageTools(){return null!==this.messageToolsServer}getToolServers(){const e=[];return this.nodeToolsServer&&e.push(this.nodeToolsServer),this.messageToolsServer&&e.push(this.messageToolsServer),this.serverToolsServer&&e.push(this.serverToolsServer),this.cronToolsServer&&e.push(this.cronToolsServer),this.ttsToolsServer&&e.push(this.ttsToolsServer),this.memoryToolsServer&&e.push(this.memoryToolsServer),this.browserToolsServer&&e.push(this.browserToolsServer),e}getOrCreateAgent(e,t,o,r,n,i,a,l,g){const h=this.agents.get(e);if(h&&h.isActive())return h;h&&(h.close(),this.agents.delete(e));const c=new s(e,this.config,o,r,t,n,this.nodeToolsServer??void 0,this.messageToolsServer??void 0,this.serverToolsServer??void 0,this.cronToolsServer??void 0,i,a,l,this.ttsToolsServer??void 0,this.memoryToolsServer??void 0,this.browserToolsServer??void 0,g);if(this.channelManager){const e=this.channelManager;if(c.setChannelSender(async(s,t,o,r)=>{r&&r.length>0?await e.sendButtons(s,t,o,r):await e.sendToChannel(s,t,o)}),this.showToolUseGetter){const s=this.showToolUseGetter;c.setToolUseNotifier(async(t,o,r)=>{if(!s(`${t}:${o}`))return;const n=`⚙️ Using ${r.replace(/^mcp__[^_]+__/,"")}`;await e.sendToChannel(t,o,n),await e.setTyping(t,o)})}c.setTypingSetter(async(s,t)=>{await e.setTyping(s,t)}),c.setTypingClearer(async(s,t)=>{await e.clearTyping(s,t)}),c.setTextBlockStreamer(async(s,t,o)=>{await e.sendResponse(s,t,o)})}return c.setUsageRecorder((e,s,t,o,r)=>{this.usageBySession.set(e,{totalCostUsd:s,durationMs:t,numTurns:o,modelUsage:r,recordedAt:Date.now()})}),this.agents.set(e,c),c}async interrupt(e){const s=this.agents.get(e);return!!s&&s.interrupt()}isBusy(e){const s=this.agents.get(e);return!!s&&s.isBusy()}hasPendingPermission(e){const s=this.agents.get(e);return!!s&&s.hasPendingPermission()}resolvePermission(e,s){const t=this.agents.get(e);t&&t.resolvePermission(s)}hasPendingQuestion(e){const s=this.agents.get(e);return!!s&&s.hasPendingQuestion()}resolveQuestion(e,s){const t=this.agents.get(e);t&&t.resolveQuestion(s)}destroySession(e){const s=this.agents.get(e);s&&(s.close(),this.agents.delete(e),n.info(`Session agent destroyed: ${e}`))}destroyAll(){for(const[e,s]of this.agents)s.close(),n.info(`Session agent destroyed (reconfigure): ${e}`);this.agents.clear()}getActiveSessions(){return Array.from(this.agents.keys()).filter(e=>{const s=this.agents.get(e);return s&&s.isActive()})}getActiveSessionCount(){return this.getActiveSessions().length}getUsage(e){return this.usageBySession.get(e)}getSdkSlashCommands(){for(const e of this.agents.values()){const s=e.getSdkSlashCommands();if(s.length>0)return s}return[]}async listModels(){try{const s=e({prompt:"list models",options:{maxTurns:0}}),t=await s.supportedModels();for await(const e of s)break;return t.map(e=>({id:e.id??e.name??String(e),name:e.name??e.id??String(e)}))}catch(e){return n.error(`Failed to list models: ${e}`),[{id:"claude-sonnet-4-6",name:"Claude Sonnet 4.6"},{id:"claude-opus-4-6",name:"Claude Opus 4.6"},{id:"claude-haiku-3-5-20241022",name:"Claude Haiku 3.5"}]}}}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async iterable message queue for the Claude Agent SDK.
|
|
3
|
+
*
|
|
4
|
+
* Messages are pushed via push() and consumed sequentially via async iteration.
|
|
5
|
+
* Used as the `prompt` input to the SDK's query() function, enabling a single
|
|
6
|
+
* long-lived query per session with multiple user messages over time.
|
|
7
|
+
*/
|
|
8
|
+
export interface QueueMessage {
|
|
9
|
+
type: "user";
|
|
10
|
+
message: {
|
|
11
|
+
role: "user";
|
|
12
|
+
content: string | Array<Record<string, unknown>>;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export declare class MessageQueue {
|
|
16
|
+
private messages;
|
|
17
|
+
private waitingResolve;
|
|
18
|
+
private closed;
|
|
19
|
+
push(msg: QueueMessage): void;
|
|
20
|
+
close(): void;
|
|
21
|
+
get pending(): number;
|
|
22
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<QueueMessage>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=message-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class MessageQueue{messages=[];waitingResolve=null;closed=!1;push(s){if(!this.closed)if(this.waitingResolve){const e=this.waitingResolve;this.waitingResolve=null,e(s)}else this.messages.push(s)}close(){if(this.closed=!0,this.waitingResolve){const s=this.waitingResolve;this.waitingResolve=null,s(null)}}get pending(){return this.messages.length}async*[Symbol.asyncIterator](){for(;!this.closed;)if(this.messages.length>0)yield this.messages.shift();else{const s=await new Promise(s=>{this.waitingResolve=s});if(null===s)break;yield s}}}
|