@framers/agentos 0.1.14 → 0.1.16

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 (55) hide show
  1. package/README.md +303 -518
  2. package/dist/config/VectorStoreConfiguration.d.ts +2 -1
  3. package/dist/config/VectorStoreConfiguration.d.ts.map +1 -1
  4. package/dist/config/VectorStoreConfiguration.js.map +1 -1
  5. package/dist/core/observability/otel.d.ts +21 -0
  6. package/dist/core/observability/otel.d.ts.map +1 -1
  7. package/dist/core/observability/otel.js +20 -0
  8. package/dist/core/observability/otel.js.map +1 -1
  9. package/dist/core/safety/ActionDeduplicator.d.ts +33 -0
  10. package/dist/core/safety/ActionDeduplicator.d.ts.map +1 -0
  11. package/dist/core/safety/ActionDeduplicator.js +70 -0
  12. package/dist/core/safety/ActionDeduplicator.js.map +1 -0
  13. package/dist/core/safety/CircuitBreaker.d.ts +58 -0
  14. package/dist/core/safety/CircuitBreaker.d.ts.map +1 -0
  15. package/dist/core/safety/CircuitBreaker.js +131 -0
  16. package/dist/core/safety/CircuitBreaker.js.map +1 -0
  17. package/dist/core/safety/CostGuard.d.ts +60 -0
  18. package/dist/core/safety/CostGuard.d.ts.map +1 -0
  19. package/dist/core/safety/CostGuard.js +140 -0
  20. package/dist/core/safety/CostGuard.js.map +1 -0
  21. package/dist/core/safety/StuckDetector.d.ts +38 -0
  22. package/dist/core/safety/StuckDetector.d.ts.map +1 -0
  23. package/dist/core/safety/StuckDetector.js +125 -0
  24. package/dist/core/safety/StuckDetector.js.map +1 -0
  25. package/dist/core/safety/ToolExecutionGuard.d.ts +51 -0
  26. package/dist/core/safety/ToolExecutionGuard.d.ts.map +1 -0
  27. package/dist/core/safety/ToolExecutionGuard.js +153 -0
  28. package/dist/core/safety/ToolExecutionGuard.js.map +1 -0
  29. package/dist/core/safety/index.d.ts +16 -0
  30. package/dist/core/safety/index.d.ts.map +1 -0
  31. package/dist/core/safety/index.js +11 -0
  32. package/dist/core/safety/index.js.map +1 -0
  33. package/dist/index.d.ts +2 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/logging/PinoLogger.d.ts.map +1 -1
  38. package/dist/logging/PinoLogger.js +83 -5
  39. package/dist/logging/PinoLogger.js.map +1 -1
  40. package/dist/rag/VectorStoreManager.d.ts.map +1 -1
  41. package/dist/rag/VectorStoreManager.js +4 -0
  42. package/dist/rag/VectorStoreManager.js.map +1 -1
  43. package/dist/rag/implementations/vector_stores/QdrantVectorStore.d.ts +73 -0
  44. package/dist/rag/implementations/vector_stores/QdrantVectorStore.d.ts.map +1 -0
  45. package/dist/rag/implementations/vector_stores/QdrantVectorStore.js +631 -0
  46. package/dist/rag/implementations/vector_stores/QdrantVectorStore.js.map +1 -0
  47. package/dist/rag/implementations/vector_stores/index.d.ts +1 -0
  48. package/dist/rag/implementations/vector_stores/index.d.ts.map +1 -1
  49. package/dist/rag/implementations/vector_stores/index.js +2 -0
  50. package/dist/rag/implementations/vector_stores/index.js.map +1 -1
  51. package/dist/rag/index.d.ts +1 -0
  52. package/dist/rag/index.d.ts.map +1 -1
  53. package/dist/rag/index.js +1 -0
  54. package/dist/rag/index.js.map +1 -1
  55. package/package.json +2 -1
package/README.md CHANGED
@@ -14,130 +14,33 @@
14
14
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.4+-3178c6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
15
15
  [![License](https://img.shields.io/badge/License-Apache_2.0-blue?style=flat-square)](https://opensource.org/licenses/Apache-2.0)
16
16
 
17
- [Website](https://agentos.sh) · [Documentation](https://agentos.sh/docs) · [npm](https://www.npmjs.com/package/@framers/agentos) · [GitHub](https://github.com/framersai/agentos)
17
+ [Website](https://agentos.sh) · [Documentation](https://docs.agentos.sh) · [npm](https://www.npmjs.com/package/@framers/agentos) · [GitHub](https://github.com/framersai/agentos)
18
18
 
19
19
  </div>
20
20
 
21
21
  ---
22
22
 
23
- ## Table of Contents
24
-
25
- - [Overview](#overview)
26
- - [Features](#features)
27
- - [Installation](#installation)
28
- - [Quick Start](#quick-start)
29
- - [Architecture](#architecture)
30
- - [Documentation](#documentation)
31
- - [Examples](#examples)
32
- - [Roadmap](#roadmap)
33
- - [Contributing](#contributing)
34
- - [License](#license)
35
-
36
- ---
37
-
38
- ## Overview
39
-
40
- AgentOS is a TypeScript-first orchestration runtime for building **adaptive, emergent AI agents**. Unlike traditional agent frameworks that treat agents as stateless functions, AgentOS introduces **Generalized Mind Instances (GMIs)** — context-aware entities that learn, evolve, and maintain coherent personalities across interactions.
41
-
42
- ```bash
43
- npm install @framers/agentos
44
- ```
45
-
46
- ---
47
-
48
- ## Features
49
-
50
- <table>
51
- <tr>
52
- <td width="50%">
53
-
54
- ### ◆ Adaptive Intelligence
55
- - **GMI Architecture** — Persistent agent identities with working memory
56
- - **Dynamic Personas** — Contextual personality adaptation
57
- - **Multi-model Support** — OpenAI, Anthropic, local models
58
-
59
- </td>
60
- <td width="50%">
61
-
62
- ### ◆ Streaming-First Runtime
63
- - **Token-level streaming** — Real-time response delivery
64
- - **Async generators** — Native TypeScript patterns
65
- - **WebSocket & SSE** — Multiple transport protocols
66
-
67
- </td>
68
- </tr>
69
- <tr>
70
- <td width="50%">
71
-
72
- ### ◆ Tool Orchestration
73
- - **Permission management** — Fine-grained access control
74
- - **Dynamic registration** — Runtime tool discovery
75
- - **Guardrails** — Safety constraints and validation
76
-
77
- </td>
78
- <td width="50%">
79
-
80
- ### ◆ RAG & Memory
81
- - **Vector storage** — Semantic memory retrieval
82
- - **SQL adapters** — SQLite, PostgreSQL support
83
- - **Context optimization** — Automatic window management
84
-
85
- </td>
86
- </tr>
87
- <tr>
88
- <td width="50%">
89
-
90
- ### ◆ Multi-Agent Coordination
91
- - **Agency system** — Agent hierarchies and teams
92
- - **Message bus** — Inter-agent communication
93
- - **Handoffs** — Context transfer between agents
94
-
95
- </td>
96
- <td width="50%">
97
-
98
- ### ◆ Human-in-the-Loop
99
- - **Approval workflows** — High-risk action gates
100
- - **Clarification requests** — Ambiguity resolution
101
- - **Escalation handling** — Human takeover paths
102
-
103
- </td>
104
- </tr>
105
- </table>
106
-
107
- ---
108
-
109
- ## Installation
23
+ ## Quick Start
110
24
 
111
25
  ```bash
112
- # npm
113
26
  npm install @framers/agentos
114
-
115
- # pnpm
116
- pnpm add @framers/agentos
117
-
118
- # yarn
119
- yarn add @framers/agentos
120
27
  ```
121
28
 
122
29
  **Requirements:** Node.js 18+ · TypeScript 5.0+
123
30
 
124
- ---
125
-
126
- ## Quick Start
31
+ ### Streaming Chat
127
32
 
128
33
  ```typescript
129
34
  import { AgentOS, AgentOSResponseChunkType } from '@framers/agentos';
130
35
  import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
131
36
 
132
- // Initialize (local/dev defaults)
133
37
  const agent = new AgentOS();
134
38
  await agent.initialize(await createTestAgentOSConfig());
135
39
 
136
- // Process requests with streaming
137
40
  for await (const chunk of agent.processRequest({
138
- userId: 'user-123',
139
- sessionId: 'session-123',
140
- textInput: 'Help me analyze this data',
41
+ userId: 'user-1',
42
+ sessionId: 'session-1',
43
+ textInput: 'Explain how TCP handshakes work',
141
44
  })) {
142
45
  if (chunk.type === AgentOSResponseChunkType.TEXT_DELTA) {
143
46
  process.stdout.write(chunk.textDelta);
@@ -145,7 +48,9 @@ for await (const chunk of agent.processRequest({
145
48
  }
146
49
  ```
147
50
 
148
- ### With Tools (Extension Packs)
51
+ ### Adding Tools
52
+
53
+ Tools are registered via extension packs and called automatically by the model:
149
54
 
150
55
  ```typescript
151
56
  import {
@@ -158,284 +63,227 @@ import {
158
63
  } from '@framers/agentos';
159
64
  import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
160
65
 
161
- const helloTool: ITool = {
162
- id: 'hello-tool',
163
- name: 'hello',
164
- displayName: 'Hello',
165
- description: 'Return a greeting.',
66
+ const weatherTool: ITool = {
67
+ id: 'get-weather',
68
+ name: 'get_weather',
69
+ displayName: 'Get Weather',
70
+ description: 'Returns current weather for a city.',
166
71
  category: 'utility',
167
72
  hasSideEffects: false,
168
73
  inputSchema: {
169
74
  type: 'object',
170
- properties: { name: { type: 'string' } },
171
- required: ['name'],
172
- },
173
- execute: async (args, _ctx) => {
174
- const name = typeof args.name === 'string' ? args.name : String(args.name);
175
- return { success: true, output: { text: `Hello, ${name}!` } };
75
+ properties: { city: { type: 'string', description: 'City name' } },
76
+ required: ['city'],
176
77
  },
78
+ execute: async (args) => ({
79
+ success: true,
80
+ output: { text: `Weather in ${args.city}: 22°C, partly cloudy` },
81
+ }),
177
82
  };
178
83
 
179
84
  const manifest: ExtensionManifest = {
180
- packs: [
181
- {
182
- factory: async () =>
183
- ({
184
- name: 'local-tools',
185
- descriptors: [{ id: helloTool.id, kind: EXTENSION_KIND_TOOL, payload: helloTool }],
186
- }) satisfies ExtensionPack,
187
- },
188
- ],
85
+ packs: [{
86
+ factory: async () => ({
87
+ name: 'my-tools',
88
+ descriptors: [{ id: weatherTool.id, kind: EXTENSION_KIND_TOOL, payload: weatherTool }],
89
+ } satisfies ExtensionPack),
90
+ }],
189
91
  };
190
92
 
191
93
  const agent = new AgentOS();
192
- const base = await createTestAgentOSConfig();
193
- await agent.initialize({ ...base, extensionManifest: manifest });
94
+ const config = await createTestAgentOSConfig();
95
+ await agent.initialize({ ...config, extensionManifest: manifest });
194
96
 
195
- // Tools are called automatically when the model decides to use them
196
97
  for await (const chunk of agent.processRequest({
197
- userId: 'user-123',
198
- sessionId: 'session-123',
199
- textInput: 'Say hello to Ada.',
98
+ userId: 'user-1',
99
+ sessionId: 'session-1',
100
+ textInput: 'What is the weather in Tokyo?',
200
101
  })) {
201
- if (chunk.type === AgentOSResponseChunkType.TEXT_DELTA) process.stdout.write(chunk.textDelta);
102
+ switch (chunk.type) {
103
+ case AgentOSResponseChunkType.TEXT_DELTA:
104
+ process.stdout.write(chunk.textDelta);
105
+ break;
106
+ case AgentOSResponseChunkType.TOOL_CALL_REQUEST:
107
+ console.log('Tool calls:', chunk.toolCalls);
108
+ break;
109
+ case AgentOSResponseChunkType.TOOL_RESULT_EMISSION:
110
+ console.log('Tool result:', chunk.toolResult);
111
+ break;
112
+ }
202
113
  }
203
114
  ```
204
115
 
205
- ### Multiple Providers
116
+ ---
206
117
 
207
- ```typescript
208
- import { AgentOS } from '@framers/agentos';
209
- import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
118
+ ## Features
210
119
 
211
- const agent = new AgentOS();
212
- const base = await createTestAgentOSConfig();
120
+ ### LLM Providers
121
+ - **Multi-provider** OpenAI, Anthropic, Azure, Google, Ollama, OpenRouter, and more
122
+ - **Model switching** — Change providers/models per request via `ProcessingOptions`
123
+ - **Streaming-first** — Token-level async generator responses with backpressure
124
+
125
+ ### Tools & Extensions
126
+ - **Extension packs** — Register tools, guardrails, workflows, personas, and channel adapters
127
+ - **12 extension kinds** — `tool`, `guardrail`, `workflow`, `persona`, `messaging-channel`, `planning-strategy`, `hitl-handler`, `memory-provider`, and more
128
+ - **Permission management** — Fine-grained tool access control per user/role
129
+ - **Dynamic registration** — Add/remove tools at runtime
130
+
131
+ ### Agent Intelligence
132
+ - **Persistent agents (GMIs)** — Working memory, persona adaptation, learning across sessions
133
+ - **Contextual prompting** — Dynamic prompt elements selected by user context and task
134
+ - **Mood adaptation** — Tone shifts based on conversation sentiment
135
+
136
+ ### Planning & Human-in-the-Loop
137
+ - **Task planning** — Multi-step plan generation with ReAct reasoning
138
+ - **Approval workflows** — Gate high-risk actions with human review
139
+ - **Clarification requests** — Agents ask for missing information
140
+ - **Escalation** — Automatic handoff to human operators
141
+
142
+ ### Multi-Agent Coordination
143
+ - **Agency registry** — Register and manage agent teams
144
+ - **Communication bus** — Inter-agent message passing and handoffs
145
+ - **Shared memory** — Agency-level memory with vector search
146
+
147
+ ### Memory & RAG
148
+ - **Vector retrieval** — Embedding-based semantic search (SQL-backed)
149
+ - **Conversation persistence** — Rolling summaries and long-term memory
150
+ - **Multiple data sources** — Configure separate vector stores per domain
151
+
152
+ ### Safety & Guardrails
153
+ - **Input/output guardrails** — Block, modify, or escalate based on content
154
+ - **Cost ceiling** — Per-request token budget enforcement
155
+ - **Cross-agent guardrails** — Monitor agent-to-agent interactions
156
+ - **Circuit breaker** — Automatic backoff on provider failures
157
+
158
+ ### Structured Output
159
+ - **JSON schema validation** — Extract typed data from unstructured text
160
+ - **Parallel function calls** — Multiple tool invocations in one turn
161
+ - **Entity extraction** — Named entity recognition with schema constraints
213
162
 
214
- await agent.initialize({
215
- ...base,
216
- modelProviderManagerConfig: {
217
- providers: [
218
- { providerId: 'openai', enabled: true, isDefault: true, config: { apiKey: process.env.OPENAI_API_KEY } },
219
- { providerId: 'openrouter', enabled: true, config: { apiKey: process.env.OPENROUTER_API_KEY } },
220
- { providerId: 'ollama', enabled: true, config: { baseUrl: 'http://localhost:11434' } },
221
- ],
222
- },
223
- gmiManagerConfig: {
224
- ...base.gmiManagerConfig,
225
- defaultGMIBaseConfigDefaults: {
226
- ...(base.gmiManagerConfig.defaultGMIBaseConfigDefaults ?? {}),
227
- defaultLlmProviderId: 'openai',
228
- defaultLlmModelId: 'gpt-4o',
229
- },
230
- },
231
- });
232
- ```
163
+ ### Messaging Channels
164
+ - **13+ platforms** — Telegram, WhatsApp, Discord, Slack, Signal, Teams, Matrix, and more
165
+ - **Bidirectional adapters** — Unified `IChannelAdapter` interface for all platforms
166
+ - **Channel routing** — Inbound/outbound message routing with `ChannelRouter`
167
+
168
+ ### Operations
169
+ - **OpenTelemetry** Opt-in tracing, metrics, and structured logging
170
+ - **Provenance** — Optional immutability policies, signed event ledger, external anchoring
171
+ - **Cost tracking** — Token usage monitoring and optimization
233
172
 
234
- ### RAG (RetrievalAugmentor)
173
+ ---
235
174
 
236
- AgentOS supports embedding-based retrieval via `IRetrievalAugmentor` (vector RAG, optional GraphRAG). You can either:
175
+ ## Configuration
237
176
 
238
- - pass a ready augmentor via `AgentOSConfig.retrievalAugmentor`, or
239
- - let AgentOS initialize it via `AgentOSConfig.ragConfig`
177
+ ### Development (Quick Start)
240
178
 
241
- See `docs/RAG_MEMORY_CONFIGURATION.md` for full setup details.
179
+ `createTestAgentOSConfig()` provides sensible defaults for local development:
242
180
 
243
- ```ts
181
+ ```typescript
244
182
  import { AgentOS } from '@framers/agentos';
245
183
  import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
246
184
 
247
- const agentos = new AgentOS();
248
- const base = await createTestAgentOSConfig();
249
- await agentos.initialize({
250
- ...base,
251
- ragConfig: {
252
- embeddingManagerConfig: {
253
- embeddingModels: [
254
- { modelId: 'text-embedding-3-small', providerId: 'openai', dimension: 1536, isDefault: true },
255
- ],
256
- },
257
- vectorStoreManagerConfig: {
258
- managerId: 'rag-vsm',
259
- providers: [{ id: 'sql-store', type: 'sql', storage: { filePath: './data/agentos_vectors.db' } }],
260
- defaultProviderId: 'sql-store',
261
- defaultEmbeddingDimension: 1536,
262
- },
263
- dataSourceConfigs: [
264
- {
265
- dataSourceId: 'voice_conversation_summaries',
266
- displayName: 'Conversation Summaries',
267
- vectorStoreProviderId: 'sql-store',
268
- actualNameInProvider: 'voice_conversation_summaries',
269
- embeddingDimension: 1536,
270
- },
271
- ],
272
- retrievalAugmentorConfig: {
273
- defaultDataSourceId: 'voice_conversation_summaries',
274
- categoryBehaviors: [],
275
- },
276
- },
277
- });
185
+ const agent = new AgentOS();
186
+ await agent.initialize(await createTestAgentOSConfig());
278
187
  ```
279
188
 
280
- ### Immutability & Provenance (Optional)
189
+ ### Production
281
190
 
282
- AgentOS includes an optional provenance system that can:
283
- - enforce storage immutability policies (`mutable`, `revisioned`, `sealed`)
284
- - record a signed, tamper-evident event ledger
285
- - optionally anchor Merkle roots to external systems (WORM, Rekor, OpenTimestamps, Ethereum, Solana)
191
+ `createAgentOSConfig()` reads from environment variables:
286
192
 
287
- ```typescript
288
- import { profiles } from '@framers/agentos/provenance';
289
- import { createProvenancePack } from '@framers/agentos/extensions/packs/provenance-pack';
290
-
291
- // Pick a profile:
292
- // - mutableDev(): normal app semantics, no signing
293
- // - revisionedVerified(): edits allowed, but revisions/tombstones are tracked + signed
294
- // - sealedAutonomous(): append-only storage policy for protected tables + signed ledger
295
- const provenanceConfig = profiles.sealedAutonomous();
296
-
297
- const provenancePack = createProvenancePack(
298
- provenanceConfig,
299
- storageAdapter,
300
- 'agent-001', // signing identity
301
- 'agentos_', // optional table prefix
302
- );
303
-
304
- // Add the pack to your extension manifest, then initialize AgentOS.
193
+ ```bash
194
+ # Required
195
+ DATABASE_URL=file:./data/agentos.db
196
+ JWT_SECRET=your-secret
197
+ API_KEY_ENCRYPTION_KEY_HEX=64-char-hex
198
+
199
+ # LLM Providers (at least one)
200
+ OPENAI_API_KEY=sk-...
201
+ ANTHROPIC_API_KEY=sk-ant-...
202
+ OPENROUTER_API_KEY=sk-or-...
203
+ OLLAMA_BASE_URL=http://localhost:11434
305
204
  ```
306
205
 
307
- **Key rotation:** keep tool API keys out of the immutable spec (env vars or a secret store). Rotate keys and restart without changing the agent identity/history.
206
+ ```typescript
207
+ import { AgentOS } from '@framers/agentos';
208
+ import { createAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
308
209
 
309
- **Sealed conversation persistence:** when using `sealed` storage policy with SQL conversation persistence, set `ConversationManagerConfig.appendOnlyPersistence=true` so conversation history remains append-only (no UPDATE/DELETE/UPSERT on protected tables).
210
+ const agent = new AgentOS();
211
+ await agent.initialize(await createAgentOSConfig());
212
+ ```
310
213
 
311
- **Toolset pinning (recommended):** treat the enabled toolset as part of the sealed spec. Disable dynamic tool registration and (optionally) store a toolset manifest hash at seal time so you can verify you’re running the same tools/versions later.
214
+ ### Multiple Providers
312
215
 
313
- **“Forgetting” memory in sealed mode:** avoid hard deletes. Prefer append-only **redaction/tombstone** events that remove items from retrieval while keeping an auditable trail.
216
+ Configure multiple LLM providers with fallback:
314
217
 
315
- ---
218
+ ```typescript
219
+ const agent = new AgentOS();
220
+ const config = await createTestAgentOSConfig();
316
221
 
317
- ## Architecture
222
+ await agent.initialize({
223
+ ...config,
224
+ modelProviderManagerConfig: {
225
+ providers: [
226
+ { providerId: 'openai', enabled: true, isDefault: true, config: { apiKey: process.env.OPENAI_API_KEY } },
227
+ { providerId: 'anthropic', enabled: true, config: { apiKey: process.env.ANTHROPIC_API_KEY } },
228
+ { providerId: 'ollama', enabled: true, config: { baseUrl: 'http://localhost:11434' } },
229
+ ],
230
+ },
231
+ gmiManagerConfig: {
232
+ ...config.gmiManagerConfig,
233
+ defaultGMIBaseConfigDefaults: {
234
+ ...(config.gmiManagerConfig.defaultGMIBaseConfigDefaults ?? {}),
235
+ defaultLlmProviderId: 'openai',
236
+ defaultLlmModelId: 'gpt-4o',
237
+ },
238
+ },
239
+ });
318
240
 
319
- ```
320
- ┌─────────────────────────────────────────────────────────────────┐
321
- │ AgentOS Runtime │
322
- ├─────────────────────────────────────────────────────────────────┤
323
- ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
324
- │ Request │ │ Prompt │ │ Streaming │ │
325
- │ │ Router │→ │ Engine │→ │ Manager │ │
326
- │ └─────────────┘ └─────────────┘ └─────────────┘ │
327
- │ ↓ ↓ ↓ │
328
- │ ┌─────────────────────────────────────────────────────────┐ │
329
- │ │ GMI Manager │ │
330
- │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
331
- │ │ │ Working │ │ Context │ │ Persona │ │Learning │ │ │
332
- │ │ │ Memory │ │ Manager │ │ Overlay │ │ Module │ │ │
333
- │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
334
- │ └─────────────────────────────────────────────────────────┘ │
335
- │ ↓ ↓ ↓ │
336
- │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
337
- │ │ Tool │ │ RAG │ │ Planning │ │
338
- │ │Orchestrator │ │ Memory │ │ Engine │ │
339
- │ └─────────────┘ └─────────────┘ └─────────────┘ │
340
- │ ↓ ↓ ↓ │
341
- │ ┌─────────────────────────────────────────────────────────┐ │
342
- │ │ LLM Provider Manager │ │
343
- │ │ OpenAI │ Anthropic │ Azure │ Local Models │ │
344
- │ └─────────────────────────────────────────────────────────┘ │
345
- └─────────────────────────────────────────────────────────────────┘
241
+ // Override per request:
242
+ for await (const chunk of agent.processRequest({
243
+ userId: 'user-1',
244
+ sessionId: 'session-1',
245
+ textInput: 'Hello',
246
+ options: { preferredProviderId: 'anthropic', preferredModelId: 'claude-sonnet-4-5-20250929' },
247
+ })) { /* ... */ }
346
248
  ```
347
249
 
348
250
  ---
349
251
 
350
- ## Documentation
351
-
352
- ### Core Concepts
353
-
354
- | Guide | Description |
355
- |-------|-------------|
356
- | [Architecture](./docs/ARCHITECTURE.md) | System design and component overview |
357
- | [Guardrails](./docs/GUARDRAILS_USAGE.md) | Safety controls and mid-stream intervention |
358
- | [Extensions](./docs/RFC_EXTENSION_STANDARDS.md) | Extension system and standards |
359
- | [Ecosystem](./docs/ECOSYSTEM.md) | Related repos and packages |
360
-
361
- ### Messaging Channels
362
-
363
- | Guide | Description |
364
- |-------|-------------|
365
- | [Channel Types](./src/channels/types.ts) | `ChannelPlatform`, `ChannelMessage`, `MessageContent`, `ChannelCapability` |
366
- | [IChannelAdapter](./src/channels/IChannelAdapter.ts) | Adapter interface for external messaging platforms |
367
- | [ChannelRouter](./src/channels/ChannelRouter.ts) | Inbound/outbound message routing |
252
+ ## Examples
368
253
 
369
- AgentOS v0.1.3+ introduces `EXTENSION_KIND_MESSAGING_CHANNEL` for external human-facing messaging platforms. Channel extensions register an `IChannelAdapter` that handles bidirectional messaging:
254
+ ### Multi-Agent Collaboration
370
255
 
371
256
  ```typescript
372
- import type { IChannelAdapter, ChannelMessage, MessageContent } from '@framers/agentos';
373
-
374
- // Channel adapters are registered via extension packs:
375
- // { id: 'telegramChannel', kind: 'messaging-channel', payload: adapter }
376
- ```
377
-
378
- Supported platforms: `telegram`, `whatsapp`, `discord`, `slack`, `webchat`, `signal`, `imessage`, `google_chat`, `teams`, `matrix`, `zalo`, `email`, `sms`.
379
-
380
- ### Agent Features
381
-
382
- | Guide | Description |
383
- |-------|-------------|
384
- | [Planning Engine](./docs/PLANNING_ENGINE.md) | Multi-step task planning and execution |
385
- | [Human-in-the-Loop](./docs/HUMAN_IN_THE_LOOP.md) | Approval workflows and oversight |
386
- | [Agent Communication](./docs/AGENT_COMMUNICATION.md) | Inter-agent messaging patterns |
387
- | [Self-Building Agents](./docs/RECURSIVE_SELF_BUILDING_AGENTS.md) | Recursive agent construction |
388
- | [Structured Output](./docs/STRUCTURED_OUTPUT.md) | JSON schema validation |
389
- | [Evaluation Framework](./docs/EVALUATION_FRAMEWORK.md) | Testing and quality assurance |
390
-
391
- ### Storage & Memory
392
-
393
- | Guide | Description |
394
- |-------|-------------|
395
- | [RAG Configuration](./docs/RAG_MEMORY_CONFIGURATION.md) | Memory and retrieval setup |
396
- | [SQL Storage](./docs/SQL_STORAGE_QUICKSTART.md) | SQLite/PostgreSQL setup |
397
- | [Client-Side Storage](./docs/CLIENT_SIDE_STORAGE.md) | Browser storage options |
398
-
399
- ### Operations
257
+ import { AgentOS, AgencyRegistry, AgentCommunicationBus } from '@framers/agentos';
258
+ import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
400
259
 
401
- | Guide | Description |
402
- |-------|-------------|
403
- | [Cost Optimization](./docs/COST_OPTIMIZATION.md) | Token usage and cost management |
404
- | [Observability](./docs/OBSERVABILITY.md) | OpenTelemetry spans and trace/log correlation (opt-in) |
405
- | [Platform Support](./docs/PLATFORM_SUPPORT.md) | Supported platforms and environments |
406
- | [Releasing](./docs/RELEASING.md) | How to publish new versions |
407
- | [API Reference](./docs/api/index.html) | TypeDoc-generated API docs |
408
- ---
260
+ const config = await createTestAgentOSConfig();
409
261
 
410
- ## Examples
262
+ const researcher = new AgentOS();
263
+ await researcher.initialize(config);
411
264
 
412
- ### Structured Data Extraction
265
+ const writer = new AgentOS();
266
+ await writer.initialize(config);
413
267
 
414
- ```typescript
415
- import { AgentOS, StructuredOutputManager } from '@framers/agentos';
268
+ const agency = new AgencyRegistry();
269
+ const bus = new AgentCommunicationBus();
270
+ agency.register('researcher', researcher, { bus });
271
+ agency.register('writer', writer, { bus });
416
272
 
417
- const agent = new AgentOS();
418
- await agent.initialize({
419
- llmProvider: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o' }
273
+ // Agents coordinate via message passing
274
+ bus.on('research:complete', async ({ findings }) => {
275
+ for await (const chunk of writer.processRequest({
276
+ userId: 'system',
277
+ sessionId: 'collab-1',
278
+ textInput: `Write documentation based on: ${JSON.stringify(findings)}`,
279
+ })) { /* handle chunks */ }
420
280
  });
421
281
 
422
- // Extract typed data from unstructured text
423
- const structured = new StructuredOutputManager({ llmProviderManager: agent.llmProviderManager });
424
- const contact = await structured.generate({
425
- prompt: 'Extract: "Meeting with Sarah Chen (sarah@startup.io) on Jan 15 re: Series A"',
426
- schema: {
427
- type: 'object',
428
- properties: {
429
- name: { type: 'string' },
430
- email: { type: 'string', format: 'email' },
431
- date: { type: 'string' },
432
- topic: { type: 'string' }
433
- },
434
- required: ['name', 'email']
435
- },
436
- schemaName: 'ContactInfo'
437
- });
438
- // → { name: 'Sarah Chen', email: 'sarah@startup.io', date: 'Jan 15', topic: 'Series A' }
282
+ for await (const chunk of researcher.processRequest({
283
+ userId: 'system',
284
+ sessionId: 'collab-1',
285
+ textInput: 'Analyze the authentication module',
286
+ })) { /* handle chunks */ }
439
287
  ```
440
288
 
441
289
  ### Human-in-the-Loop Approvals
@@ -443,20 +291,19 @@ const contact = await structured.generate({
443
291
  ```typescript
444
292
  import { HumanInteractionManager } from '@framers/agentos';
445
293
 
446
- const hitl = new HumanInteractionManager({ defaultTimeoutMs: 300000 });
294
+ const hitl = new HumanInteractionManager({ defaultTimeoutMs: 300_000 });
447
295
 
448
- // Gate high-risk operations with human approval
449
296
  const decision = await hitl.requestApproval({
450
297
  action: {
451
298
  type: 'database_mutation',
452
299
  description: 'Archive 50K inactive accounts older than 2 years',
453
300
  severity: 'high',
454
- metadata: { affectedRows: 50000, table: 'users' }
301
+ metadata: { affectedRows: 50_000, table: 'users' },
455
302
  },
456
303
  alternatives: [
457
- { action: 'soft_delete', description: 'Mark as inactive instead of archiving' },
458
- { action: 'export_first', description: 'Export to CSV before archiving' }
459
- ]
304
+ { action: 'soft_delete', description: 'Mark as inactive instead' },
305
+ { action: 'export_first', description: 'Export to CSV before archiving' },
306
+ ],
460
307
  });
461
308
 
462
309
  if (decision.approved) {
@@ -466,241 +313,181 @@ if (decision.approved) {
466
313
  }
467
314
  ```
468
315
 
469
- ### Autonomous Task Planning
316
+ ### Structured Data Extraction
470
317
 
471
318
  ```typescript
472
- import { AgentOS, PlanningEngine } from '@framers/agentos';
319
+ import { AgentOS, StructuredOutputManager } from '@framers/agentos';
320
+ import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
473
321
 
474
322
  const agent = new AgentOS();
475
- await agent.initialize({
476
- llmProvider: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o' }
477
- });
478
-
479
- const planner = new PlanningEngine({ llmProvider: agent.llmProviderManager, strategy: 'react' });
323
+ await agent.initialize(await createTestAgentOSConfig());
480
324
 
481
- // Decompose complex goals into executable steps with ReAct reasoning
482
- const plan = await planner.generatePlan({
483
- goal: 'Migrate authentication from sessions to JWT',
484
- constraints: ['Zero downtime', 'Backwards compatible for 30 days', 'Audit logging required'],
485
- context: { currentStack: 'Express + Redis sessions', userCount: '50K' }
325
+ const structured = new StructuredOutputManager({
326
+ llmProviderManager: agent.llmProviderManager,
486
327
  });
487
328
 
488
- for await (const step of planner.executePlan(plan.id)) {
489
- console.log(`[${step.status}] ${step.action}`);
490
- if (step.requiresHumanApproval) {
491
- const approved = await promptUser(step.description);
492
- if (!approved) break;
493
- }
494
- }
495
- ```
496
-
497
- ### Multi-Agent Collaboration
498
-
499
- ```typescript
500
- import { AgentOS, AgencyRegistry, AgentCommunicationBus } from '@framers/agentos';
501
-
502
- // Create specialized agents
503
- const researcher = new AgentOS();
504
- await researcher.initialize({ llmProvider: llmConfig, persona: 'Research analyst' });
505
-
506
- const writer = new AgentOS();
507
- await writer.initialize({ llmProvider: llmConfig, persona: 'Technical writer' });
508
-
509
- // Register in agency with shared communication
510
- const agency = new AgencyRegistry();
511
- const bus = new AgentCommunicationBus();
512
- agency.register('researcher', researcher, { bus });
513
- agency.register('writer', writer, { bus });
514
-
515
- // Agents coordinate via message passing
516
- bus.on('research:complete', async ({ findings }) => {
517
- await writer.processRequest({
518
- message: `Write documentation based on: ${JSON.stringify(findings)}`
519
- });
329
+ const contact = await structured.generate({
330
+ prompt: 'Extract: "Meeting with Sarah Chen (sarah@startup.io) on Jan 15 re: Series A"',
331
+ schema: {
332
+ type: 'object',
333
+ properties: {
334
+ name: { type: 'string' },
335
+ email: { type: 'string', format: 'email' },
336
+ date: { type: 'string' },
337
+ topic: { type: 'string' },
338
+ },
339
+ required: ['name', 'email'],
340
+ },
341
+ schemaName: 'ContactInfo',
520
342
  });
521
-
522
- await researcher.processRequest({ message: 'Analyze the authentication module' });
343
+ // → { name: 'Sarah Chen', email: 'sarah@startup.io', date: 'Jan 15', topic: 'Series A' }
523
344
  ```
524
345
 
525
- ### Guardrails: Mid-Stream Decision Override
346
+ ### RAG Memory
526
347
 
527
348
  ```typescript
528
349
  import { AgentOS } from '@framers/agentos';
529
- import { CostCeilingGuardrail } from './guardrails/CostCeilingGuardrail';
530
-
531
- const costGuard = new CostCeilingGuardrail({
532
- maxCostUsd: 0.05, // 5 cents per request
533
- inputTokenPricePer1k: 0.0001,
534
- outputTokenPricePer1k: 0.0002,
535
- budgetExceededText: 'Response exceeded cost ceiling. Please refine your request.'
536
- });
350
+ import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
537
351
 
538
352
  const agent = new AgentOS();
539
- await agent.initialize({
540
- llmProvider: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY },
541
- guardrailService: costGuard
542
- });
543
-
544
- // Agent generates expensive response → guardrail intercepts → substitutes budget message
545
- // Agents can "change their mind" before delivery based on cost, content policy, or quality checks
546
- ```
547
-
548
- See [Guardrails Usage Guide](./docs/GUARDRAILS_USAGE.md) for complete documentation.
549
-
550
- ### Non-Streaming Response
353
+ const config = await createTestAgentOSConfig();
551
354
 
552
- ```typescript
553
- import { AgentOS } from '@framers/agentos';
554
-
555
- const agent = new AgentOS();
556
355
  await agent.initialize({
557
- llmProvider: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o' }
356
+ ...config,
357
+ ragConfig: {
358
+ embeddingManagerConfig: {
359
+ embeddingModels: [
360
+ { modelId: 'text-embedding-3-small', providerId: 'openai', dimension: 1536, isDefault: true },
361
+ ],
362
+ },
363
+ vectorStoreManagerConfig: {
364
+ managerId: 'rag-vsm',
365
+ providers: [{ id: 'sql-store', type: 'sql', storage: { filePath: './data/vectors.db' } }],
366
+ defaultProviderId: 'sql-store',
367
+ defaultEmbeddingDimension: 1536,
368
+ },
369
+ dataSourceConfigs: [{
370
+ dataSourceId: 'conversations',
371
+ displayName: 'Conversation Memory',
372
+ vectorStoreProviderId: 'sql-store',
373
+ actualNameInProvider: 'conversations',
374
+ embeddingDimension: 1536,
375
+ }],
376
+ retrievalAugmentorConfig: {
377
+ defaultDataSourceId: 'conversations',
378
+ categoryBehaviors: [],
379
+ },
380
+ },
558
381
  });
559
382
 
560
- // Collect full response without streaming
561
- const chunks = [];
562
- for await (const chunk of agent.processRequest({ message: 'Explain OAuth 2.0 briefly' })) {
563
- if (chunk.type === 'content') {
564
- chunks.push(chunk.content);
565
- }
566
- }
567
- const fullResponse = chunks.join('');
383
+ // Agent now retrieves relevant context from vector memory before responding
568
384
  ```
569
385
 
570
- ### Mood-Adaptive Responses
386
+ ### Guardrails
571
387
 
572
388
  ```typescript
573
- import { AgentOS, GMIMood } from '@framers/agentos';
389
+ import {
390
+ AgentOS,
391
+ type IGuardrailService,
392
+ type GuardrailContext,
393
+ GuardrailAction,
394
+ } from '@framers/agentos';
395
+ import { createTestAgentOSConfig } from '@framers/agentos/config/AgentOSConfig';
574
396
 
575
- const agent = new AgentOS();
576
- await agent.initialize({
577
- llmProvider: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o' },
578
- persona: {
579
- name: 'Support Agent',
580
- moodAdaptation: {
581
- enabled: true,
582
- defaultMood: GMIMood.EMPATHETIC,
583
- allowedMoods: [GMIMood.EMPATHETIC, GMIMood.FOCUSED, GMIMood.ANALYTICAL],
584
- sensitivityFactor: 0.7,
585
- // Mood-specific prompt modifiers
586
- moodPrompts: {
587
- [GMIMood.EMPATHETIC]: 'Prioritize understanding and emotional support.',
588
- [GMIMood.FRUSTRATED]: 'Acknowledge difficulty, offer step-by-step guidance.',
589
- [GMIMood.ANALYTICAL]: 'Provide detailed technical explanations with examples.'
590
- }
397
+ // Guardrails intercept responses before delivery
398
+ const costGuard: IGuardrailService = {
399
+ async evaluateOutput(context: GuardrailContext) {
400
+ const tokens = context.usage?.totalTokens ?? 0;
401
+ if (tokens > 10_000) {
402
+ return {
403
+ action: GuardrailAction.MODIFY,
404
+ modifiedContent: 'Response exceeded token budget. Please ask a more specific question.',
405
+ reason: `Token count ${tokens} exceeds limit`,
406
+ };
591
407
  }
592
- }
593
- });
408
+ return { action: GuardrailAction.ALLOW };
409
+ },
410
+ };
594
411
 
595
- // Agent automatically adapts tone based on conversation context
596
- for await (const chunk of agent.processRequest({
597
- message: 'This is so frustrating, nothing works!'
598
- })) {
599
- // Response adapts with empathetic tone, mood shifts to EMPATHETIC
600
- }
412
+ const agent = new AgentOS();
413
+ const config = await createTestAgentOSConfig();
414
+ await agent.initialize({ ...config, guardrailService: costGuard });
601
415
  ```
602
416
 
603
- ### Contextual Prompt Adaptation
604
-
605
- ```typescript
606
- import { AgentOS } from '@framers/agentos';
417
+ ---
607
418
 
608
- const agent = new AgentOS();
609
- await agent.initialize({
610
- llmProvider: llmConfig,
611
- persona: {
612
- name: 'Adaptive Tutor',
613
- // Dynamic prompt elements injected based on runtime context
614
- contextualPromptElements: [
615
- {
616
- id: 'beginner-guidance',
617
- type: 'SYSTEM_INSTRUCTION_ADDON',
618
- content: 'Explain concepts simply, avoid jargon, use analogies.',
619
- criteria: { userSkillLevel: ['novice', 'beginner'] },
620
- priority: 10
621
- },
622
- {
623
- id: 'expert-mode',
624
- type: 'SYSTEM_INSTRUCTION_ADDON',
625
- content: 'Assume deep technical knowledge, be concise, skip basics.',
626
- criteria: { userSkillLevel: ['expert', 'advanced'] },
627
- priority: 10
628
- },
629
- {
630
- id: 'debugging-context',
631
- type: 'FEW_SHOT_EXAMPLE',
632
- content: { role: 'assistant', content: 'Let\'s trace through step by step...' },
633
- criteria: { taskHint: ['debugging', 'troubleshooting'] }
634
- }
635
- ],
636
- // Meta-prompts for self-reflection and planning
637
- metaPrompts: [
638
- {
639
- id: 'mid-conversation-check',
640
- trigger: 'every_n_turns',
641
- triggerConfig: { n: 5 },
642
- prompt: 'Assess: Is the user making progress? Should I adjust my approach?'
643
- }
644
- ]
645
- }
646
- });
419
+ ## Architecture
647
420
 
648
- // Prompts automatically adapt based on user context and task
649
- await agent.updateUserContext({ skillLevel: 'expert' });
650
- for await (const chunk of agent.processRequest({ message: 'Explain monads' })) {
651
- // Uses expert-mode prompt element, skips beginner explanations
652
- }
421
+ ```
422
+ ┌─────────────────────────────────────────────────────────────────┐
423
+ │ AgentOS Runtime │
424
+ ├─────────────────────────────────────────────────────────────────┤
425
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
426
+ │ │ Request │ │ Prompt │ │ Streaming │ │
427
+ │ │ Router │→ │ Engine │→ │ Manager │ │
428
+ │ └─────────────┘ └─────────────┘ └─────────────┘ │
429
+ │ ↓ ↓ ↓ │
430
+ │ ┌─────────────────────────────────────────────────────────┐ │
431
+ │ │ GMI Manager │ │
432
+ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
433
+ │ │ │ Working │ │ Context │ │ Persona │ │Learning │ │ │
434
+ │ │ │ Memory │ │ Manager │ │ Overlay │ │ Module │ │ │
435
+ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
436
+ │ └─────────────────────────────────────────────────────────┘ │
437
+ │ ↓ ↓ ↓ │
438
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
439
+ │ │ Tool │ │ RAG │ │ Planning │ │
440
+ │ │Orchestrator │ │ Memory │ │ Engine │ │
441
+ │ └─────────────┘ └─────────────┘ └─────────────┘ │
442
+ │ ↓ ↓ ↓ │
443
+ │ ┌─────────────────────────────────────────────────────────┐ │
444
+ │ │ LLM Provider Manager │ │
445
+ │ │ OpenAI │ Anthropic │ Azure │ Ollama │ ... │ │
446
+ │ └─────────────────────────────────────────────────────────┘ │
447
+ └─────────────────────────────────────────────────────────────────┘
653
448
  ```
654
449
 
655
450
  ---
656
451
 
657
- ## Roadmap
452
+ ## Documentation
658
453
 
659
- | Version | Status | Features |
660
- |---------|--------|----------|
661
- | 0.1 | ✓ | Core runtime, GMI, streaming, tools, RAG |
662
- | 0.2 | → | Knowledge graphs, marketplace, visual planning |
663
- | 0.3 | ○ | Distributed agents, edge deployment |
664
- | 1.0 | ○ | Production hardening, enterprise features |
454
+ Full documentation at **[docs.agentos.sh](https://docs.agentos.sh)**
665
455
 
666
- See [CHANGELOG.md](./CHANGELOG.md) for release history.
456
+ | Topic | Description |
457
+ |-------|-------------|
458
+ | [System Architecture](https://docs.agentos.sh/docs/architecture/system-architecture) | Core design and component internals |
459
+ | [Planning Engine](https://docs.agentos.sh/docs/features/planning-engine) | Multi-step task planning and execution |
460
+ | [Human-in-the-Loop](https://docs.agentos.sh/docs/features/human-in-the-loop) | Approval workflows and oversight |
461
+ | [Guardrails](https://docs.agentos.sh/docs/features/guardrails) | Safety constraints and content filtering |
462
+ | [RAG Memory](https://docs.agentos.sh/docs/features/rag-memory) | Vector storage and retrieval configuration |
463
+ | [Extensions](https://docs.agentos.sh/docs/extensions/overview) | Extension system, official extensions catalog |
464
+ | [Structured Output](https://docs.agentos.sh/docs/features/structured-output) | JSON schema validation and entity extraction |
465
+ | [Agent Communication](https://docs.agentos.sh/docs/features/agent-communication) | Inter-agent messaging and handoffs |
466
+ | [Observability](https://docs.agentos.sh/docs/architecture/observability) | OpenTelemetry traces, metrics, and logging |
467
+ | [Cost Optimization](https://docs.agentos.sh/docs/features/cost-optimization) | Token usage monitoring and caching |
468
+ | [API Reference](https://docs.agentos.sh/docs/api/) | Auto-generated TypeDoc API docs |
667
469
 
668
470
  ---
669
471
 
670
472
  ## Contributing
671
473
 
672
- We welcome contributions. See our [Contributing Guide](https://github.com/framersai/agentos/blob/master/CONTRIBUTING.md) for details.
673
-
674
474
  ```bash
675
- # Clone and setup
676
475
  git clone https://github.com/framersai/agentos.git
677
476
  cd agentos
678
477
  pnpm install
679
-
680
- # Development
681
- pnpm run build # Build the package
682
- pnpm run test # Run tests
683
- pnpm run docs # Generate documentation
478
+ pnpm run build
479
+ pnpm run test
684
480
  ```
685
481
 
686
- ### Commit Convention
482
+ We use [Conventional Commits](https://www.conventionalcommits.org/): `feat:` (minor), `fix:` (patch), `BREAKING CHANGE:` (major).
687
483
 
688
- We use [Conventional Commits](https://www.conventionalcommits.org/):
689
-
690
- ```
691
- feat: New features → minor version bump
692
- fix: Bug fixes → patch version bump
693
- docs: Documentation only
694
- BREAKING CHANGE: → major version bump
695
- ```
484
+ See the [Contributing Guide](https://github.com/framersai/agentos/blob/master/CONTRIBUTING.md) for details.
696
485
 
697
486
  ---
698
487
 
699
488
  ## License
700
489
 
701
- [Apache 2.0](./LICENSE) © [Framers](https://frame.dev)
702
-
703
- ---
490
+ [Apache 2.0](./LICENSE) [Frame.dev](https://frame.dev)
704
491
 
705
492
  <div align="center">
706
493
 
@@ -714,6 +501,4 @@ BREAKING CHANGE: → major version bump
714
501
 
715
502
  **Built by [Frame.dev](https://frame.dev)** · [@framersai](https://github.com/framersai)
716
503
 
717
- [Website](https://agentos.sh) · [Documentation](https://agentos.sh/docs) · [Twitter](https://twitter.com/framersai)
718
-
719
504
  </div>