@everworker/oneringai 0.4.7 → 0.5.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.
Files changed (32) hide show
  1. package/README.md +425 -45
  2. package/dist/{ImageModel-1uP-2vk7.d.ts → ImageModel-CV8OuP3Z.d.ts} +10 -4
  3. package/dist/{ImageModel-BDI37OED.d.cts → ImageModel-OjV5NvLY.d.cts} +10 -4
  4. package/dist/capabilities/agents/index.cjs +17 -0
  5. package/dist/capabilities/agents/index.cjs.map +1 -1
  6. package/dist/capabilities/agents/index.d.cts +1 -1
  7. package/dist/capabilities/agents/index.d.ts +1 -1
  8. package/dist/capabilities/agents/index.js +17 -0
  9. package/dist/capabilities/agents/index.js.map +1 -1
  10. package/dist/capabilities/images/index.cjs +273 -16
  11. package/dist/capabilities/images/index.cjs.map +1 -1
  12. package/dist/capabilities/images/index.d.cts +1 -1
  13. package/dist/capabilities/images/index.d.ts +1 -1
  14. package/dist/capabilities/images/index.js +273 -16
  15. package/dist/capabilities/images/index.js.map +1 -1
  16. package/dist/index-BlEwczd4.d.ts +320 -0
  17. package/dist/index-DrJYI_0l.d.cts +320 -0
  18. package/dist/{index-Blci0FEd.d.ts → index-hmTj59TM.d.ts} +543 -36
  19. package/dist/{index-D8RCwpK9.d.cts → index-t4cRhBZW.d.cts} +543 -36
  20. package/dist/index.cjs +19916 -7155
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +7807 -5065
  23. package/dist/index.d.ts +7807 -5065
  24. package/dist/index.js +19377 -6645
  25. package/dist/index.js.map +1 -1
  26. package/dist/shared/index.cjs +596 -7
  27. package/dist/shared/index.cjs.map +1 -1
  28. package/dist/shared/index.d.cts +2 -284
  29. package/dist/shared/index.d.ts +2 -284
  30. package/dist/shared/index.js +596 -7
  31. package/dist/shared/index.js.map +1 -1
  32. package/package.json +1 -1
package/README.md CHANGED
@@ -35,6 +35,10 @@
35
35
  - [21. External API Integration](#21-external-api-integration) — Scoped Registry, Vendor Templates, Tool Discovery
36
36
  - [22. Microsoft Graph Connector Tools](#22-microsoft-graph-connector-tools-new) — Email, calendar, meetings, and Teams transcripts
37
37
  - [23. Tool Catalog](#23-tool-catalog-new) — Dynamic tool loading/unloading for agents with 100+ tools
38
+ - [24. Async (Non-Blocking) Tools](#24-async-non-blocking-tools-new) — Background tool execution with auto-continuation
39
+ - [25. Long-Running Sessions (Suspend/Resume)](#25-long-running-sessions-suspendresume-new) — Suspend agent loops waiting for external input, resume days later
40
+ - [26. Agent Registry](#26-agent-registry-new) — Global tracking, deep inspection, parent/child hierarchy, event fan-in, external control
41
+ - [27. Agent Orchestrator](#27-agent-orchestrator-new) — Multi-agent teams with shared workspace, async turns, and parallel execution
38
42
  - [MCP Integration](#mcp-model-context-protocol-integration)
39
43
  - [Documentation](#documentation)
40
44
  - [Examples](#examples)
@@ -65,7 +69,7 @@
65
69
  **Part 1**. [Your AI Agent Forgets Everything. Here’s How We Fixed It.](https://medium.com/superstringtheory/your-ai-agent-forgets-everything-heres-how-we-fixed-it-276b39aedbb3): context management plugins
66
70
 
67
71
 
68
- ## HOSEA APP
72
+ ## EVERWORKER DESKTOP APP
69
73
  We realize that library alone in these times is not enough to get you excited, so we built a FREE FOREVER desktop app on top of this library to showcase its power! It's as easy to start using as cloning this library's repo, and then `cd apps/hosea` and then `npm install` and then `npm run dev`. Or watch the video first:
70
74
 
71
75
  [![Watch the demo](https://img.youtube.com/vi/_LzDiuOQD8Y/maxresdefault.jpg)](https://www.youtube.com/watch?v=_LzDiuOQD8Y)
@@ -91,6 +95,7 @@ Showcasing another amazing "built with oneringai": ["no saas" agentic business t
91
95
  - 🎛️ **Dynamic Tool Management** - Enable/disable tools at runtime, namespaces, priority-based selection
92
96
  - 🔌 **Tool Execution Plugins** - NEW: Pluggable pipeline for logging, analytics, UI updates, custom behavior
93
97
  - 💾 **Session Persistence** - Save and resume conversations with full state restoration
98
+ - ⏸️ **Long-Running Sessions** - NEW: Suspend agent loops via `SuspendSignal`, resume hours/days later with `Agent.hydrate()`
94
99
  - 👤 **Multi-User Support** - Set `userId` once, flows automatically to all tool executions and session metadata
95
100
  - 🔒 **Auth Identities** - Restrict agents to specific connectors (and accounts), composable with access policies
96
101
  - 🤖 **Universal Agent** - ⚠️ *Deprecated* - Use `Agent` with plugins instead
@@ -117,6 +122,8 @@ Showcasing another amazing "built with oneringai": ["no saas" agentic business t
117
122
  - 📊 **Execution Recording** - NEW: Persist full routine execution history with `createExecutionRecorder()` — replaces manual hook wiring
118
123
  - ⏰ **Scheduling & Triggers** - NEW: `SimpleScheduler` for interval/one-time schedules, `EventEmitterTrigger` for webhook/queue-driven execution
119
124
  - 📦 **Tool Catalog** - NEW: Dynamic tool loading/unloading — agents discover and load only the categories they need at runtime
125
+ - **Async Tools** - NEW: Non-blocking tool execution — long-running tools run in background while the agent continues reasoning, with auto-continuation when results arrive
126
+ - 📡 **Agent Registry** - NEW: Global tracking of all active agents — deep inspection, parent/child hierarchy, event fan-in, external control
120
127
  - 🔄 **Streaming** - Real-time responses with event streams
121
128
  - 📝 **TypeScript** - Full type safety and IntelliSense support
122
129
 
@@ -602,7 +609,126 @@ const plugin = agent.tools.executionPipeline.get('plugin-name');
602
609
  const plugins = agent.tools.executionPipeline.list();
603
610
  ```
604
611
 
605
- ### 4. Session Persistence
612
+ ### 4. Tool Permissions (NEW)
613
+
614
+ Policy-based permission system with per-user rules, argument inspection, and pluggable storage. Permissions are enforced at the ToolManager pipeline level -- **all tool execution paths are gated**.
615
+
616
+ #### Zero-Config (Backward Compatible)
617
+
618
+ Existing code works unchanged. Safe tools (read-only, memory, catalog) are auto-allowed; all others default to prompting:
619
+
620
+ ```typescript
621
+ const agent = Agent.create({ connector: 'openai', model: 'gpt-4', tools: [readFile, bash] });
622
+
623
+ // read_file executes immediately (in DEFAULT_ALLOWLIST)
624
+ // bash triggers approval flow (write/shell tools require approval by default)
625
+ ```
626
+
627
+ #### Per-User Permission Rules
628
+
629
+ User rules have the **highest priority** -- they override all built-in policies. Rules support argument inspection with conditions:
630
+
631
+ ```typescript
632
+ import { PermissionPolicyManager } from '@everworker/oneringai';
633
+
634
+ const manager = new PermissionPolicyManager({
635
+ userRules: [
636
+ // Allow bash, but only in the project directory
637
+ {
638
+ id: '1', toolName: 'bash', action: 'allow', enabled: true,
639
+ createdBy: 'user', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
640
+ conditions: [{ argName: 'command', operator: 'not_contains', value: 'rm -rf' }],
641
+ },
642
+ // Block all web tools unconditionally
643
+ {
644
+ id: '2', toolName: 'web_fetch', action: 'deny', enabled: true, unconditional: true,
645
+ createdBy: 'admin', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
646
+ },
647
+ ],
648
+ });
649
+ ```
650
+
651
+ Condition operators: `starts_with`, `not_starts_with`, `contains`, `not_contains`, `equals`, `not_equals`, `matches` (regex), `not_matches`.
652
+
653
+ #### Built-in Policies
654
+
655
+ Eight composable policies evaluated in priority order (`deny` short-circuits):
656
+
657
+ | Policy | Description |
658
+ |--------|-------------|
659
+ | **AllowlistPolicy** | Auto-allow tools in the allowlist (read-only, memory, catalog) |
660
+ | **BlocklistPolicy** | Hard-block tools in the blocklist (no approval possible) |
661
+ | **SessionApprovalPolicy** | Cache approvals per-session with optional argument-scoped keys |
662
+ | **PathRestrictionPolicy** | Restrict file tools to allowed directory roots |
663
+ | **BashFilterPolicy** | Block/flag dangerous shell commands by pattern |
664
+ | **UrlAllowlistPolicy** | Restrict web tools to allowed URL domains |
665
+ | **RolePolicy** | Role-based access control (map user roles to tool permissions) |
666
+ | **RateLimitPolicy** | Limit tool invocations per time window |
667
+
668
+ ```typescript
669
+ import { PathRestrictionPolicy, BashFilterPolicy } from '@everworker/oneringai';
670
+
671
+ const agent = Agent.create({
672
+ connector: 'openai', model: 'gpt-4',
673
+ permissions: {
674
+ policies: [
675
+ new PathRestrictionPolicy({ allowedPaths: ['/workspace'] }),
676
+ new BashFilterPolicy({ blockedPatterns: ['rm -rf', 'sudo'] }),
677
+ ],
678
+ },
679
+ });
680
+ ```
681
+
682
+ #### Approval Dialog Integration
683
+
684
+ When a tool needs approval, the `onApprovalRequired` callback fires. Return a `createRule` to persist the decision:
685
+
686
+ ```typescript
687
+ const agent = Agent.create({
688
+ connector: 'openai', model: 'gpt-4',
689
+ permissions: {
690
+ onApprovalRequired: async (ctx) => {
691
+ const userChoice = await showApprovalDialog(ctx.toolName, ctx.args);
692
+
693
+ return {
694
+ approved: userChoice.allow,
695
+ // Persist as a user rule so it won't ask again
696
+ createRule: userChoice.remember ? {
697
+ description: `Auto-allow ${ctx.toolName}`,
698
+ conditions: [{ argName: 'path', operator: 'starts_with', value: '/workspace' }],
699
+ } : undefined,
700
+ };
701
+ },
702
+ },
703
+ });
704
+ ```
705
+
706
+ #### Tool Self-Declaration
707
+
708
+ Tool authors declare permission defaults on the tool definition. App developers can override at registration:
709
+
710
+ ```typescript
711
+ const myTool: ToolFunction = {
712
+ definition: { type: 'function', function: { name: 'deploy', description: '...', parameters: {...} } },
713
+ execute: async (args) => { /* ... */ },
714
+ // Author-declared defaults
715
+ permission: {
716
+ scope: 'once',
717
+ riskLevel: 'high',
718
+ approvalMessage: 'This will deploy to production',
719
+ sensitiveArgs: ['environment', 'version'],
720
+ },
721
+ };
722
+
723
+ // App developer can override at registration
724
+ agent.tools.register(myTool, {
725
+ permission: { scope: 'session' }, // Relax to session-level approval
726
+ });
727
+ ```
728
+
729
+ For complete documentation, see the [User Guide](./USER_GUIDE.md#tool-permissions).
730
+
731
+ ### 5. Session Persistence
606
732
 
607
733
  Save and resume full context state including conversation history and plugin states:
608
734
 
@@ -672,7 +798,7 @@ const agent = Agent.create({ connector: 'openai', model: 'gpt-4' });
672
798
 
673
799
  See the [User Guide](./USER_GUIDE.md#centralized-storage-registry) for full documentation.
674
800
 
675
- ### 5. Working Memory
801
+ ### 6. Working Memory
676
802
 
677
803
  Use the `WorkingMemoryPluginNextGen` for agents that need to store and retrieve data:
678
804
 
@@ -688,7 +814,7 @@ const agent = Agent.create({
688
814
  },
689
815
  });
690
816
 
691
- // Agent now has memory_store, memory_retrieve, memory_delete, memory_query tools
817
+ // Agent now has unified store_get, store_set, store_delete, store_list, store_action tools
692
818
  await agent.run('Check weather for SF and remember the result');
693
819
  ```
694
820
 
@@ -698,7 +824,7 @@ await agent.run('Check weather for SF and remember the result');
698
824
  - 🧠 **Context Management** - Automatic handling of context limits
699
825
  - 💾 **Session Persistence** - Save/load via `ctx.save()` and `ctx.load()`
700
826
 
701
- ### 6. Research with Search Tools
827
+ ### 7. Research with Search Tools
702
828
 
703
829
  Use `Agent` with search tools and `WorkingMemoryPluginNextGen` for research workflows:
704
830
 
@@ -734,7 +860,7 @@ await agent.run('Research AI developments in 2026 and store key findings');
734
860
  - 📝 **Working Memory** - Store findings with priority-based eviction
735
861
  - 🏗️ **Tiered Memory** - Raw → Summary → Findings pattern
736
862
 
737
- ### 7. Context Management
863
+ ### 8. Context Management
738
864
 
739
865
  **AgentContextNextGen** is the modern, plugin-based context manager. It provides clean separation of concerns with composable plugins:
740
866
 
@@ -796,11 +922,12 @@ const agent = Agent.create({
796
922
  **Available Features:**
797
923
  | Feature | Default | Plugin | Associated Tools |
798
924
  |---------|---------|--------|------------------|
799
- | `workingMemory` | `true` | WorkingMemoryPluginNextGen | `memory_store/retrieve/delete/query/cleanup_raw` |
800
- | `inContextMemory` | `false` | InContextMemoryPluginNextGen | `context_set/delete/list` |
801
- | `persistentInstructions` | `false` | PersistentInstructionsPluginNextGen | `instructions_set/remove/list/clear` |
802
- | `userInfo` | `false` | UserInfoPluginNextGen | `user_info_set/get/remove/clear`, `todo_add/update/remove` |
925
+ | `workingMemory` | `true` | WorkingMemoryPluginNextGen | Unified `store_*` tools (store="memory"). Actions: cleanup_raw, query |
926
+ | `inContextMemory` | `false` | InContextMemoryPluginNextGen | Unified `store_*` tools (store="context") |
927
+ | `persistentInstructions` | `false` | PersistentInstructionsPluginNextGen | Unified `store_*` tools (store="instructions"). Actions: clear |
928
+ | `userInfo` | `false` | UserInfoPluginNextGen | Unified `store_*` tools (store="user_info") + `todo_add/update/remove` |
803
929
  | `toolCatalog` | `false` | ToolCatalogPluginNextGen | `tool_catalog_search/load/unload` |
930
+ | `sharedWorkspace` | `false` | SharedWorkspacePluginNextGen | Unified `store_*` tools (store="workspace"). Actions: log, history, archive, clear |
804
931
 
805
932
  **AgentContextNextGen architecture:**
806
933
  - **Plugin-first design** - All features are composable plugins
@@ -820,7 +947,7 @@ console.log(budget.available); // Remaining tokens
820
947
  console.log(budget.utilizationPercent); // Usage percentage
821
948
  ```
822
949
 
823
- ### 8. InContextMemory
950
+ ### 9. InContextMemory
824
951
 
825
952
  Store key-value pairs **directly in context** for instant LLM access without retrieval calls:
826
953
 
@@ -845,20 +972,20 @@ plugin.set('user_prefs', 'User preferences', { verbose: true }, 'high');
845
972
  // Store data with UI display - shown in the host app's sidebar panel
846
973
  plugin.set('dashboard', 'Progress dashboard', '## Progress\n- [x] Step 1\n- [ ] Step 2', 'normal', true);
847
974
 
848
- // LLM can use context_set/context_delete/context_list tools
975
+ // LLM uses unified store tools: store_set("context", ...), store_get("context", ...), etc.
849
976
  // Or access directly via plugin API
850
977
  const state = plugin.get('current_state'); // { step: 2, status: 'active' }
851
978
  ```
852
979
 
853
980
  **Key Difference from WorkingMemory:**
854
- - **WorkingMemory**: External storage + index → requires `memory_retrieve()` for values
981
+ - **WorkingMemory**: External storage + index → requires `store_get("memory", key)` for values
855
982
  - **InContextMemory**: Full values in context → instant access, no retrieval needed
856
983
 
857
- **UI Display (`showInUI`):** Entries with `showInUI: true` are displayed in the host application's sidebar panel with full markdown rendering (code blocks, tables, charts, diagrams, etc.). The LLM sets this via the `context_set` tool. Users can also pin specific entries to always display them regardless of the agent's setting. See the [User Guide](./USER_GUIDE.md#ui-display-showInUI) for details.
984
+ **UI Display (`showInUI`):** Entries with `showInUI: true` are displayed in the host application's sidebar panel with full markdown rendering (code blocks, tables, charts, diagrams, etc.). The LLM sets this via `store_set("context", key, { ..., showInUI: true })`. Users can also pin specific entries to always display them regardless of the agent's setting. See the [User Guide](./USER_GUIDE.md#ui-display-showInUI) for details.
858
985
 
859
986
  **Use cases:** Session state, user preferences, counters, flags, small accumulated results, live dashboards.
860
987
 
861
- ### 9. Persistent Instructions
988
+ ### 10. Persistent Instructions
862
989
 
863
990
  Store agent-level custom instructions that persist across sessions on disk:
864
991
 
@@ -876,7 +1003,7 @@ const agent = Agent.create({
876
1003
  },
877
1004
  });
878
1005
 
879
- // LLM can now use instructions_set/remove/list/clear tools
1006
+ // LLM uses unified store tools: store_set("instructions", ...), store_delete("instructions", ...), etc.
880
1007
  // Instructions persist to ~/.oneringai/agents/my-assistant/custom_instructions.json
881
1008
  ```
882
1009
 
@@ -886,15 +1013,15 @@ const agent = Agent.create({
886
1013
  - 🔄 **Auto-Load** - Instructions loaded automatically on agent start
887
1014
  - 🛡️ **Never Compacted** - Critical instructions always preserved in context
888
1015
 
889
- **Available Tools:**
890
- - `instructions_set` - Add or update a single instruction by key
891
- - `instructions_remove` - Remove a single instruction by key
892
- - `instructions_list` - List all instructions with keys and content
893
- - `instructions_clear` - Remove all instructions (requires confirmation)
1016
+ **Store Tools (via unified `store_*` interface):**
1017
+ - `store_set("instructions", key, { content })` - Add or update a single instruction by key
1018
+ - `store_delete("instructions", key)` - Remove a single instruction by key
1019
+ - `store_list("instructions")` - List all instructions with keys and content
1020
+ - `store_action("instructions", "clear", { confirm: true })` - Remove all instructions
894
1021
 
895
1022
  **Use cases:** Agent personality/behavior, user preferences, learned rules, tool usage patterns.
896
1023
 
897
- ### 10. User Info
1024
+ ### 11. User Info
898
1025
 
899
1026
  Store user-specific preferences and context that are automatically injected into the LLM system message:
900
1027
 
@@ -912,9 +1039,9 @@ const agent = Agent.create({
912
1039
  },
913
1040
  });
914
1041
 
915
- // LLM can now use user_info_set/get/remove/clear tools
1042
+ // LLM uses unified store tools: store_set("user_info", ...), store_get("user_info", ...), etc.
916
1043
  // Data persists to ~/.oneringai/users/alice/user_info.json
917
- // All entries are automatically shown in context — no need to call user_info_get each turn
1044
+ // All entries are automatically shown in context — no need to call store_get each turn
918
1045
  ```
919
1046
 
920
1047
  **Key Features:**
@@ -923,11 +1050,11 @@ const agent = Agent.create({
923
1050
  - 👥 **User-Scoped** - Data is per-user, not per-agent — different agents share the same user data
924
1051
  - 🔧 **LLM-Modifiable** - Agent can update user info during execution
925
1052
 
926
- **User Info Tools:**
927
- - `user_info_set` - Store/update user information by key (`key`, `value`, `description?`)
928
- - `user_info_get` - Retrieve one entry by key, or all entries if no key
929
- - `user_info_remove` - Remove a specific entry
930
- - `user_info_clear` - Clear all entries (requires confirmation)
1053
+ **Store Tools (via unified `store_*` interface):**
1054
+ - `store_set("user_info", key, { value, description? })` - Store/update user information
1055
+ - `store_get("user_info", key?)` - Retrieve one entry or all entries
1056
+ - `store_delete("user_info", key)` - Remove a specific entry
1057
+ - `store_action("user_info", "clear", { confirm: true })` - Clear all entries
931
1058
 
932
1059
  **TODO Tools** (built into the same plugin):
933
1060
  - `todo_add` - Create a TODO (`title`, `description?`, `people?`, `dueDate?`, `tags?`)
@@ -938,7 +1065,7 @@ TODOs are stored alongside user info and rendered in a separate **"Current TODOs
938
1065
 
939
1066
  **Use cases:** User preferences (theme, language, timezone), user context (role, location), accumulated knowledge about the user, task/TODO tracking with deadlines and people.
940
1067
 
941
- ### 11. Direct LLM Access
1068
+ ### 12. Direct LLM Access
942
1069
 
943
1070
  Bypass all context management for simple, stateless LLM calls:
944
1071
 
@@ -984,7 +1111,7 @@ for await (const event of agent.streamDirect('Tell me a story')) {
984
1111
 
985
1112
  **Use cases:** Quick one-off queries, embeddings-like simplicity, testing, hybrid workflows.
986
1113
 
987
- ### 12. Audio Capabilities
1114
+ ### 13. Audio Capabilities
988
1115
 
989
1116
  Text-to-Speech and Speech-to-Text with multiple providers:
990
1117
 
@@ -1049,7 +1176,7 @@ for await (const event of voice.wrap(agent.stream('Tell me a story'))) { ... }
1049
1176
  - **TTS**: OpenAI (`tts-1`, `tts-1-hd`, `gpt-4o-mini-tts`), Google (`gemini-tts`)
1050
1177
  - **STT**: OpenAI (`whisper-1`, `gpt-4o-transcribe`), Groq (`whisper-large-v3` - 12x cheaper!)
1051
1178
 
1052
- ### 13. Model Registry
1179
+ ### 14. Model Registry
1053
1180
 
1054
1181
  Complete metadata for 23+ models:
1055
1182
 
@@ -1078,7 +1205,7 @@ console.log(`Cached: $${cachedCost}`); // $0.0293 (90% discount)
1078
1205
  - **Google (7)**: Gemini 3, Gemini 2.5
1079
1206
  - **Grok (9)**: Grok 4.1, Grok 4, Grok Code, Grok 3, Grok 2 Vision
1080
1207
 
1081
- ### 14. Streaming
1208
+ ### 15. Streaming
1082
1209
 
1083
1210
  Real-time responses:
1084
1211
 
@@ -1090,7 +1217,7 @@ for await (const text of StreamHelpers.textOnly(agent.stream('Hello'))) {
1090
1217
  }
1091
1218
  ```
1092
1219
 
1093
- ### 15. OAuth for External APIs
1220
+ ### 16. OAuth for External APIs
1094
1221
 
1095
1222
  ```typescript
1096
1223
  import { OAuthManager, FileStorage } from '@everworker/oneringai';
@@ -1107,7 +1234,7 @@ const oauth = new OAuthManager({
1107
1234
  const authUrl = await oauth.startAuthFlow('user123');
1108
1235
  ```
1109
1236
 
1110
- ### 16. Developer Tools
1237
+ ### 17. Developer Tools
1111
1238
 
1112
1239
  File system and shell tools for building coding assistants:
1113
1240
 
@@ -1149,9 +1276,9 @@ await agent.run('Run npm test and report any failures');
1149
1276
  - Timeout protection (default 2 min)
1150
1277
  - Output truncation for large outputs
1151
1278
 
1152
- ### 17. Custom Tool Generation (NEW)
1279
+ ### 18. Custom Tool Generation (NEW)
1153
1280
 
1154
- Let agents **create their own tools** at runtime — draft, test, iterate, save, and reuse. The agent writes JavaScript code, validates it, tests it in the VM sandbox, and persists it for future use. All 6 meta-tools are auto-registered and visible in Hosea.
1281
+ Let agents **create their own tools** at runtime — draft, test, iterate, save, and reuse. The agent writes JavaScript code, validates it, tests it in the VM sandbox, and persists it for future use. All 6 meta-tools are auto-registered and visible in Everworker Desktop.
1155
1282
 
1156
1283
  ```typescript
1157
1284
  import { createCustomToolMetaTools, hydrateCustomTool } from '@everworker/oneringai';
@@ -1184,7 +1311,7 @@ agent.tools.register(weatherTool, { source: 'custom', tags: ['weather', 'api'] }
1184
1311
 
1185
1312
  > See the [User Guide](./USER_GUIDE.md#custom-tool-generation) for the complete workflow, sandbox API reference, and examples.
1186
1313
 
1187
- ### 18. Desktop Automation Tools (NEW)
1314
+ ### 19. Desktop Automation Tools (NEW)
1188
1315
 
1189
1316
  OS-level desktop automation for building "computer use" agents — screenshot the screen, send to a vision model, receive tool calls (click, type, etc.), execute them, repeat:
1190
1317
 
@@ -1220,7 +1347,7 @@ await agent.run('Open Safari and search for "weather forecast"');
1220
1347
  - Screenshots use the `__images` convention for automatic multimodal handling across all providers (Anthropic, OpenAI, Google)
1221
1348
  - Requires `@nut-tree-fork/nut-js` as an optional peer dependency: `npm install @nut-tree-fork/nut-js`
1222
1349
 
1223
- ### 19. Document Reader
1350
+ ### 20. Document Reader
1224
1351
 
1225
1352
  Universal file-to-LLM-content converter. Reads arbitrary document formats and produces clean markdown text with optional image extraction:
1226
1353
 
@@ -1285,7 +1412,7 @@ await agent.run([
1285
1412
 
1286
1413
  See the [User Guide](./USER_GUIDE.md#document-reader) for complete API reference and configuration options.
1287
1414
 
1288
- ### 20. Routine Execution (NEW)
1415
+ ### 21. Routine Execution (NEW)
1289
1416
 
1290
1417
  Execute multi-step AI workflows where tasks run in dependency order with automatic validation:
1291
1418
 
@@ -1327,7 +1454,7 @@ console.log(execution.status); // 'completed' | 'failed'
1327
1454
 
1328
1455
  **Key Features:**
1329
1456
  - **Task Dependencies** - DAG-based ordering via `dependsOn`
1330
- - **Memory Bridging** - In-context memory (`context_set`) + working memory (`memory_store`) persist across tasks while conversation is cleared
1457
+ - **Memory Bridging** - In-context memory (`store_set("context", ...)`) + working memory (`store_set("memory", ...)`) persist across tasks while conversation is cleared
1331
1458
  - **LLM Validation** - Self-reflection against completion criteria with configurable score thresholds
1332
1459
  - **Retry Logic** - Configurable `maxAttempts` per task with automatic retry on validation failure
1333
1460
  - **Smart Error Classification** - Permanent errors (auth, config, model-not-found) skip retry; transient errors retry normally
@@ -1410,7 +1537,7 @@ const all = await storage.list(undefined, { tags: ['daily'] });
1410
1537
 
1411
1538
  > See the [User Guide](./USER_GUIDE.md#routine-execution) for the complete API reference, architecture details, and examples.
1412
1539
 
1413
- ### 21. External API Integration
1540
+ ### 22. External API Integration
1414
1541
 
1415
1542
  Connect your AI agents to 35+ external services with enterprise-grade resilience:
1416
1543
 
@@ -1617,7 +1744,7 @@ for (const tool of allTools) {
1617
1744
  }
1618
1745
  ```
1619
1746
 
1620
- ### 22. Microsoft Graph Connector Tools (NEW)
1747
+ ### 23. Microsoft Graph Connector Tools (NEW)
1621
1748
 
1622
1749
  6 dedicated tools for Microsoft Graph API — email, calendar, meetings, and Teams transcripts. Auto-registered for connectors with `serviceType: 'microsoft'` or `baseURL` matching `graph.microsoft.com`.
1623
1750
 
@@ -1658,7 +1785,7 @@ await agent.run('Find available meeting slots for alice and bob this week');
1658
1785
 
1659
1786
  Supports both **delegated** (`/me` — user signs in) and **application** (`/users/{id}` — app-only) permission modes. See the [User Guide](./USER_GUIDE.md#microsoft-graph-connector-tools) for full parameter reference.
1660
1787
 
1661
- ### 23. Tool Catalog
1788
+ ### 24. Tool Catalog
1662
1789
 
1663
1790
  When agents have 100+ available tools, sending all definitions to the LLM wastes tokens and degrades performance. The Tool Catalog lets agents discover and load only the categories they need:
1664
1791
 
@@ -1708,6 +1835,259 @@ await agent.run('Search for information about quantum computing');
1708
1835
 
1709
1836
  See the [User Guide](./USER_GUIDE.md#tool-catalog) for full documentation.
1710
1837
 
1838
+ ### 25. Async (Non-Blocking) Tools
1839
+
1840
+ Some tools take seconds or minutes to complete (web scraping, data analysis, API calls). With async tools, the agent doesn't wait — it continues reasoning and receives results later:
1841
+
1842
+ ```typescript
1843
+ import { Agent, ToolFunction } from '@everworker/oneringai';
1844
+
1845
+ // Define a long-running tool as non-blocking
1846
+ const analyzeData: ToolFunction = {
1847
+ definition: {
1848
+ type: 'function',
1849
+ function: {
1850
+ name: 'analyze_dataset',
1851
+ description: 'Run statistical analysis on a dataset (takes ~30s)',
1852
+ parameters: {
1853
+ type: 'object',
1854
+ properties: { dataset: { type: 'string' } },
1855
+ required: ['dataset'],
1856
+ },
1857
+ },
1858
+ blocking: false, // <-- This makes it async
1859
+ },
1860
+ execute: async (args) => {
1861
+ // Long-running work happens here
1862
+ const result = await runAnalysis(args.dataset);
1863
+ return { summary: result.summary, score: result.score };
1864
+ },
1865
+ };
1866
+
1867
+ // Auto-continue mode (default): agent handles everything
1868
+ const agent = Agent.create({
1869
+ connector: 'anthropic',
1870
+ model: 'claude-sonnet-4-6',
1871
+ asyncTools: {
1872
+ autoContinue: true, // Re-enter agentic loop when results arrive (default)
1873
+ batchWindowMs: 1000, // Batch results arriving within 1s (default: 500ms)
1874
+ asyncTimeout: 300000, // 5 min timeout per async tool (default)
1875
+ },
1876
+ tools: [analyzeData, readFile], // Mix async and blocking tools
1877
+ });
1878
+
1879
+ const response = await agent.run('Analyze the sales dataset and summarize');
1880
+ // response.pendingAsyncTools lists any still-running async tools
1881
+ // When results arrive, agent auto-continues and processes them
1882
+
1883
+ // Manual mode: caller controls when to continue
1884
+ const agent2 = Agent.create({
1885
+ connector: 'anthropic',
1886
+ model: 'claude-sonnet-4-6',
1887
+ asyncTools: { autoContinue: false },
1888
+ tools: [analyzeData],
1889
+ });
1890
+
1891
+ agent2.on('async:tool:complete', (event) => {
1892
+ console.log(`${event.toolName} finished in ${event.duration}ms`);
1893
+ });
1894
+
1895
+ const response2 = await agent2.run('Analyze the dataset');
1896
+ if (agent2.hasPendingAsyncTools()) {
1897
+ // Do other work while waiting, then:
1898
+ const continuation = await agent2.continueWithAsyncResults();
1899
+ console.log(continuation.output_text);
1900
+ }
1901
+ ```
1902
+
1903
+ **How It Works:**
1904
+ 1. LLM calls a `blocking: false` tool
1905
+ 2. Tool starts executing in background; LLM gets placeholder: *"Tool is executing asynchronously..."*
1906
+ 3. Agentic loop continues — LLM can call other tools, reason, or produce text
1907
+ 4. When the real result arrives, it's injected as a user message with the full result
1908
+ 5. If `autoContinue: true`, the agent re-enters the agentic loop to process the result
1909
+
1910
+ **Key Features:**
1911
+ - **Mixed execution** — Blocking and async tools work together in the same iteration
1912
+ - **Result batching** — Multiple async results arriving close together are delivered in one message
1913
+ - **Timeout protection** — Configurable per-tool timeout (default 5 min)
1914
+ - **5 events** — `async:tool:started`, `async:tool:complete`, `async:tool:error`, `async:tool:timeout`, `async:continuation:start`
1915
+ - **Public API** — `hasPendingAsyncTools()`, `getPendingAsyncTools()`, `cancelAsyncTool(id)`, `cancelAllAsyncTools()`
1916
+ - **Clean cleanup** — `agent.destroy()` cancels all pending async tools
1917
+
1918
+ See the [User Guide](./USER_GUIDE.md#async-non-blocking-tools) for the full guide.
1919
+
1920
+ ### 26. Long-Running Sessions (Suspend/Resume)
1921
+
1922
+ Some workflows span hours or days — an agent sends an email, then waits for a reply. With `SuspendSignal`, tools can pause the agent loop, and external events resume it later:
1923
+
1924
+ ```typescript
1925
+ import { Agent, SuspendSignal, ToolFunction } from '@everworker/oneringai';
1926
+
1927
+ // Tool that suspends the agent loop
1928
+ const presentToUser: ToolFunction = {
1929
+ definition: {
1930
+ type: 'function',
1931
+ function: {
1932
+ name: 'send_results_email',
1933
+ description: 'Email analysis results to the user and wait for their reply',
1934
+ parameters: {
1935
+ type: 'object',
1936
+ properties: { to: { type: 'string' }, body: { type: 'string' } },
1937
+ required: ['to', 'body'],
1938
+ },
1939
+ },
1940
+ },
1941
+ execute: async (args) => {
1942
+ const { messageId } = await emailService.send(args.to, args.body);
1943
+ return SuspendSignal.create({
1944
+ result: `Email sent to ${args.to}. Waiting for reply.`,
1945
+ correlationId: `email:${messageId}`,
1946
+ metadata: { messageId },
1947
+ });
1948
+ },
1949
+ };
1950
+
1951
+ // Run agent — it suspends when the tool returns SuspendSignal
1952
+ const response = await agent.run('Analyze data and email results to user@example.com');
1953
+ // response.status === 'suspended'
1954
+ // response.suspension.correlationId === 'email:msg_123'
1955
+ // response.suspension.sessionId — saved automatically
1956
+
1957
+ // --- Days later: email reply arrives via webhook ---
1958
+
1959
+ // Resolve which session to resume
1960
+ const ref = await correlationStorage.resolve('email:msg_123');
1961
+
1962
+ // Reconstruct agent from stored definition + session
1963
+ const resumedAgent = await Agent.hydrate(ref.sessionId, { agentId: ref.agentId });
1964
+
1965
+ // Customize before running (add hooks, tools, etc.)
1966
+ resumedAgent.tools.register(presentToUser);
1967
+
1968
+ // Continue with user's reply — may complete or suspend again!
1969
+ const result = await resumedAgent.run('Thanks, but also look at Q2 data');
1970
+ ```
1971
+
1972
+ **How It Works:**
1973
+ 1. Tool returns `SuspendSignal.create({ result, correlationId })` instead of a normal result
1974
+ 2. Agent loop adds the `result` as normal tool output, does a final wrap-up LLM call (no tools)
1975
+ 3. Session is saved automatically; correlation mapping stored for routing
1976
+ 4. `AgentResponse` has `status: 'suspended'` with full `suspension` metadata
1977
+ 5. Later, `Agent.hydrate()` reconstructs from stored definition + session
1978
+ 6. Caller customizes (hooks, tools), then `run(input)` continues the loop
1979
+
1980
+ **Key Features:**
1981
+ - **Zero LLM awareness** — The LLM just calls tools; suspension is handled by the loop
1982
+ - **Multi-step workflows** — Resume can lead to another suspension (natural chains)
1983
+ - **Configurable TTL** — Default 7 days, per-signal via `ttl` option
1984
+ - **Correlation storage** — Pluggable via `StorageRegistry.set('correlations', myStorage)`
1985
+ - **Full state restoration** — Conversation history + all plugin states (memory, instructions, etc.)
1986
+
1987
+ See the [User Guide](./USER_GUIDE.md#long-running-sessions-suspendresume) for the full guide.
1988
+
1989
+ ### 27. Agent Registry
1990
+
1991
+ Every `Agent` automatically registers with `AgentRegistry` on creation and unregisters on destroy. Query, inspect, and control all agents from one place:
1992
+
1993
+ ```typescript
1994
+ import { Agent, AgentRegistry } from '@everworker/oneringai';
1995
+
1996
+ // Agents auto-register — no setup needed
1997
+ const researcher = Agent.create({ connector: 'openai', model: 'gpt-4', name: 'researcher' });
1998
+ const coder = Agent.create({ connector: 'anthropic', model: 'claude-sonnet-4-6', name: 'coder' });
1999
+
2000
+ // Query
2001
+ AgentRegistry.count; // 2
2002
+ AgentRegistry.getByName('researcher'); // [researcher]
2003
+ AgentRegistry.filter({ status: 'idle' }); // [researcher, coder]
2004
+
2005
+ // Aggregate stats
2006
+ AgentRegistry.getStats();
2007
+ // { total: 2, byStatus: { idle: 2, ... }, byModel: { 'gpt-4': 1, ... }, ... }
2008
+
2009
+ // Deep inspection — full context, conversation, plugins, tools, metrics
2010
+ const inspection = await AgentRegistry.inspect(researcher.registryId);
2011
+ // inspection.context.plugins — all plugin states (working memory, etc.)
2012
+ // inspection.context.tools — all registered tools with call counts
2013
+ // inspection.conversation — full InputItem[] array
2014
+ // inspection.execution.metrics — tokens, tool calls, errors, durations
2015
+
2016
+ // Parent/child hierarchy (for agent-spawns-agent patterns)
2017
+ const child = Agent.create({
2018
+ connector: 'openai', model: 'gpt-4',
2019
+ parentAgentId: researcher.registryId, // link to parent
2020
+ });
2021
+ AgentRegistry.getChildren(researcher.registryId); // [child]
2022
+ AgentRegistry.getTree(researcher.registryId); // recursive tree
2023
+
2024
+ // Event fan-in — all events from all agents through one listener
2025
+ AgentRegistry.onAgentEvent((agentId, name, event, data) => {
2026
+ console.log(`[${name}] ${event}`); // "[researcher] execution:start"
2027
+ });
2028
+
2029
+ // External control
2030
+ AgentRegistry.pauseAgent(researcher.registryId);
2031
+ AgentRegistry.cancelAll('shutting down');
2032
+ AgentRegistry.destroyMatching({ model: 'gpt-4' });
2033
+ ```
2034
+
2035
+ See the [User Guide](./USER_GUIDE.md#agent-registry) for the full API reference.
2036
+
2037
+ ### 28. Agent Orchestrator (NEW)
2038
+
2039
+ Create autonomous agent teams that coordinate through a shared workspace:
2040
+
2041
+ ```typescript
2042
+ import { createOrchestrator, Connector, Vendor } from '@everworker/oneringai';
2043
+
2044
+ Connector.create({ name: 'openai', vendor: Vendor.OpenAI, auth: { type: 'api_key', apiKey: process.env.OPENAI_API_KEY! } });
2045
+
2046
+ const orchestrator = createOrchestrator({
2047
+ connector: 'openai',
2048
+ model: 'gpt-4',
2049
+ agentTypes: {
2050
+ architect: {
2051
+ systemPrompt: 'You are a senior software architect. Design clean, scalable systems.',
2052
+ tools: [readFile, writeFile],
2053
+ },
2054
+ critic: {
2055
+ systemPrompt: 'You are a thorough code reviewer. Find issues and suggest improvements.',
2056
+ tools: [readFile, grep],
2057
+ },
2058
+ developer: {
2059
+ systemPrompt: 'You are a senior developer. Write clean, tested code.',
2060
+ tools: [readFile, writeFile, editFile, bash],
2061
+ },
2062
+ },
2063
+ });
2064
+
2065
+ // The orchestrator LLM decides the workflow
2066
+ const result = await orchestrator.run('Build an auth module with JWT support');
2067
+ ```
2068
+
2069
+ **How it works:**
2070
+ - The orchestrator is a regular Agent with 7 coordination tools
2071
+ - Workers are persistent Agent instances that remember reasoning across turns
2072
+ - All agents share a workspace (bulletin board) for artifacts and status
2073
+ - Workers receive "what changed since your last turn" at each turn start
2074
+
2075
+ **Orchestration tools:**
2076
+
2077
+ | Tool | Type | Purpose |
2078
+ |------|------|---------|
2079
+ | `create_agent(name, type)` | blocking | Spawn a worker from predefined types |
2080
+ | `assign_turn(agent, instruction)` | blocking | Give agent a task, wait for result |
2081
+ | `assign_turn_async(agent, instruction)` | **non-blocking** | Start agent in background, result delivered later |
2082
+ | `assign_parallel([{agent, instruction}...])` | blocking | Fan-out to multiple agents, wait for all |
2083
+ | `send_message(agent, message)` | blocking | Inject message into running/idle agent |
2084
+ | `list_agents()` | blocking | See team status |
2085
+ | `destroy_agent(name)` | blocking | Remove a worker |
2086
+
2087
+ **Async turns** leverage the existing async tools infrastructure — the orchestrator continues planning while workers execute in the background.
2088
+
2089
+ See the [User Guide](./USER_GUIDE.md#agent-orchestrator) for detailed examples including iterative review cycles, parallel research, and custom workflows.
2090
+
1711
2091
  ---
1712
2092
 
1713
2093
  ## MCP (Model Context Protocol) Integration
@@ -1856,4 +2236,4 @@ MIT License - See [LICENSE](./LICENSE) file.
1856
2236
 
1857
2237
  ---
1858
2238
 
1859
- **Version:** 0.4.7 | **Last Updated:** 2026-03-10 | **[User Guide](./USER_GUIDE.md)** | **[API Reference](./API_REFERENCE.md)** | **[Changelog](./CHANGELOG.md)**
2239
+ **Version:** 0.5.0 | **Last Updated:** 2026-03-17 | **[User Guide](./USER_GUIDE.md)** | **[API Reference](./API_REFERENCE.md)** | **[Changelog](./CHANGELOG.md)**