├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs
├── api-reference.md
├── assets
│ ├── README.md
│ ├── orbit-architecture.png
│ └── orbit-logo.png
├── core-concepts.md
├── getting-started.md
├── security.md
└── troubleshooting.md
├── package.json
├── packages
├── blockchain
│ ├── package.json
│ └── src
│ │ ├── index.ts
│ │ ├── protocols
│ │ ├── aave.ts
│ │ └── uniswap.ts
│ │ ├── providers
│ │ └── ethereum-provider.ts
│ │ └── types.ts
├── context
│ ├── package.json
│ └── src
│ │ ├── context-provider.ts
│ │ ├── index.ts
│ │ └── types.ts
├── core
│ ├── package.json
│ ├── src
│ │ ├── agent
│ │ │ ├── base-agent.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── index.ts
│ │ ├── interfaces
│ │ │ ├── agent.interface.ts
│ │ │ ├── context.interface.ts
│ │ │ ├── index.ts
│ │ │ ├── orchestrator.interface.ts
│ │ │ └── tool.interface.ts
│ │ ├── orchestrator
│ │ │ ├── index.ts
│ │ │ ├── orchestrator.ts
│ │ │ └── types.ts
│ │ ├── stack
│ │ │ ├── constructs
│ │ │ │ ├── agent.ts
│ │ │ │ ├── api.ts
│ │ │ │ └── database.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── tool
│ │ │ └── base-tool.ts
│ │ └── utils
│ │ │ ├── config.ts
│ │ │ └── logger.ts
│ └── tsconfig.json
├── security
│ ├── package.json
│ └── src
│ │ ├── index.ts
│ │ ├── providers
│ │ └── default-provider.ts
│ │ └── types.ts
└── tools
│ ├── package.json
│ ├── src
│ ├── agent
│ │ ├── bedrock-agent.ts
│ │ ├── claude-agent.ts
│ │ ├── index.ts
│ │ └── openai-agent.ts
│ ├── base-tool.ts
│ ├── index.ts
│ ├── social
│ │ ├── index.ts
│ │ └── x-tool.ts
│ └── web3
│ │ ├── index.ts
│ │ └── web3-tool.ts
│ └── tsconfig.json
└── turbo.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules
3 | .pnp
4 | .pnp.js
5 | .yarn/install-state.gz
6 |
7 | # Testing
8 | coverage
9 |
10 | # Next.js
11 | .next/
12 | out/
13 | build
14 |
15 | # Misc
16 | .DS_Store
17 | *.pem
18 |
19 | # Debug
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
24 | # Local env files
25 | .env*.local
26 |
27 | # TypeScript
28 | *.tsbuildinfo
29 |
30 | # Turbo
31 | .turbo
32 |
33 | # Build
34 | dist/
35 |
36 | # IDE
37 | .idea
38 | .vscode
39 | *.swp
40 | *.swo
41 |
42 | # Logs
43 | logs
44 | *.log
45 |
46 | # Cache
47 | .cache
48 | .npm
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to O.R.B.I.T.
2 |
3 | First off, thank you for considering contributing to O.R.B.I.T.! It's people like you that make O.R.B.I.T. such a great tool.
4 |
5 | ## Code of Conduct
6 |
7 | This project and everyone participating in it is governed by the O.R.B.I.T. Code of Conduct. By participating, you are expected to uphold this code.
8 |
9 | ## How Can I Contribute?
10 |
11 | ### Reporting Bugs
12 |
13 | This section guides you through submitting a bug report for O.R.B.I.T. Following these guidelines helps maintainers and the community understand your report.
14 |
15 | Before creating bug reports, please check the issue list as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible:
16 |
17 | * Use a clear and descriptive title
18 | * Describe the exact steps which reproduce the problem
19 | * Provide specific examples to demonstrate the steps
20 | * Describe the behavior you observed after following the steps
21 | * Explain which behavior you expected to see instead and why
22 | * Include screenshots and animated GIFs if possible
23 |
24 | ### Suggesting Enhancements
25 |
26 | This section guides you through submitting an enhancement suggestion for O.R.B.I.T., including completely new features and minor improvements to existing functionality.
27 |
28 | Before creating enhancement suggestions, please check the issue list as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please include as many details as possible:
29 |
30 | * Use a clear and descriptive title
31 | * Provide a step-by-step description of the suggested enhancement
32 | * Provide specific examples to demonstrate the steps
33 | * Describe the current behavior and explain which behavior you expected to see instead
34 | * Explain why this enhancement would be useful
35 |
36 | ### Pull Requests
37 |
38 | * Fill in the required template
39 | * Do not include issue numbers in the PR title
40 | * Follow the TypeScript styleguide
41 | * Include screenshots and animated GIFs in your pull request whenever possible
42 | * Document new code
43 | * End all files with a newline
44 |
45 | ## Development Process
46 |
47 | 1. Fork the repo
48 | 2. Create a new branch from `main`
49 | 3. Make your changes
50 | 4. Run the tests
51 | 5. Push to your fork and submit a pull request
52 |
53 | ### Setting up your environment
54 |
55 | 1. Install Node.js (v18 or higher)
56 | 2. Install Yarn (v4.0.2 or higher)
57 | 3. Clone your fork
58 | 4. Install dependencies: `yarn install`
59 | 5. Build the packages: `yarn build`
60 |
61 | ### Running Tests
62 |
63 | ```bash
64 | # Run all tests
65 | yarn test
66 |
67 | # Run tests for a specific package
68 | yarn workspace @orbit/core test
69 | ```
70 |
71 | ### Style Guide
72 |
73 | * Use TypeScript
74 | * Use Prettier for formatting
75 | * Follow the existing code style
76 | * Write meaningful commit messages
77 |
78 | ## Community
79 |
80 | * Follow us on [Twitter](https://twitter.com/metroslabs)
81 | * Join our [Discord](https://discord.gg/metroslabs)
82 | * Visit our [Website](https://metroslabs.xyz)
83 |
84 | ## Questions?
85 |
86 | Feel free to open an issue or reach out to the maintainers at [Metros Labs](https://github.com/metros-org).
87 |
88 | ## License
89 |
90 | By contributing to O.R.B.I.T., you agree that your contributions will be licensed under its MIT License.
91 |
92 | ---
93 |
94 | Copyright (c) 2025 Metros Labs
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Metros Labs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # O.R.B.I.T.
2 |
3 |
4 |

5 |
Orchestrated Responsive Business Intelligence Toolkit
6 |
An open-source multi-agent orchestration framework for building intelligent, collaborative ecosystems.
7 |
8 |
9 | ## 🌟 Overview
10 |
11 | O.R.B.I.T. is a part of the Metros Labs platform, bridging AI and blockchain to enable developers to create adaptive, tokenized environments for business innovation, automation, and execution. Built with TypeScript and designed for enterprise-grade applications, O.R.B.I.T. provides a robust foundation for building next-generation multi-agent systems.
12 |
13 |
14 |

15 |
16 |
17 | ## 🚀 Key Features
18 |
19 | - **Advanced Orchestration**: Intelligent coordination of agents for complex, multi-faceted tasks
20 | - **Blockchain Integration**: Seamless integration with DeFi protocols, NFT ecosystems, and cross-chain operations
21 | - **Adaptive Intelligence**: Real-time adaptability with context-aware decision-making
22 | - **Enterprise-Grade Security**: Built-in security features and audit trails
23 | - **Developer-Friendly**: Comprehensive documentation and examples
24 |
25 | ## 🛠 Core Components
26 |
27 | ### 1. Orchestration Core Engine (OCE)
28 |
29 | - Central hub for managing agent collaboration
30 | - Dynamic orchestration and role allocation
31 | - Extensible API for diverse agent integration
32 |
33 | ### 2. Responsive Context Handler (RCH)
34 |
35 | - Real-time context management
36 | - Environment monitoring
37 | - Predictive task modeling
38 |
39 | ### 3. Blockchain Orchestration Layer (BOL)
40 |
41 | - Native blockchain protocol integration
42 | - Cross-chain transaction management
43 | - Smart contract automation
44 |
45 | ### 4. Secure Communication Layer (SCL)
46 |
47 | - End-to-end encrypted messaging
48 | - Low-latency agent communication
49 | - Flexible synchronization patterns
50 |
51 | ## 📦 Installation
52 |
53 | 1. Clone the repository:
54 |
55 | ```bash
56 | git clone https://github.com/metros-org/orbit-framework.git
57 | cd orbit-framework
58 | ```
59 |
60 | 2. Install dependencies:
61 |
62 | ```bash
63 | yarn install
64 | ```
65 |
66 | 3. Build the packages:
67 |
68 | ```bash
69 | yarn build
70 | ```
71 |
72 | ## 🔧 Quick Start
73 |
74 | Add the orbit-framework as a git dependency in your package.json:
75 |
76 | ```json
77 | {
78 | "dependencies": {
79 | "@orbit/core": "git+https://github.com/metros-org/orbit-framework.git#main",
80 | "@orbit/tools": "git+https://github.com/metros-org/orbit-framework.git#main"
81 | }
82 | }
83 | ```
84 |
85 | Then use it in your code:
86 |
87 | ```typescript
88 | import { Orchestrator, BedrockAgent, ClaudeAgent } from "@orbit/core";
89 | import { Web3Tool, UniswapTool } from "@orbit/tools";
90 |
91 | // Initialize the orchestrator
92 | const orchestrator = new Orchestrator({
93 | agents: [
94 | new BedrockAgent({ name: "market-analyzer" }),
95 | new ClaudeAgent({ name: "strategy-planner" }),
96 | ],
97 | tools: [new Web3Tool(), new UniswapTool()],
98 | });
99 |
100 | // Start a workflow
101 | await orchestrator.execute({
102 | task: "analyze-market-opportunity",
103 | input: {
104 | token: "ETH",
105 | timeframe: "24h",
106 | },
107 | });
108 | ```
109 |
110 | ## 🌐 Use Cases
111 |
112 | - **DeFi Automation**: Liquidity management, yield farming, portfolio optimization
113 | - **NFT Operations**: Creation, metadata management, marketplace automation
114 | - **DAO Governance**: Voting mechanisms, treasury operations, community engagement
115 | - **AI-Powered Business**: Workflow automation, data analysis, decision-making
116 | - **Cross-Chain Solutions**: Asset bridging, cross-chain task execution
117 |
118 | ## 📚 Documentation
119 |
120 | - [Getting Started](docs/getting-started.md)
121 | - [Core Concepts](docs/core-concepts.md)
122 | - [API Reference](docs/api-reference.md)
123 | - [Examples](examples/README.md)
124 | - [Contributing Guide](CONTRIBUTING.md)
125 |
126 | ## 🤝 Contributing
127 |
128 | We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
129 |
130 | 1. Fork the repository
131 | 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
132 | 3. Commit your changes (`git commit -m 'Add amazing feature'`)
133 | 4. Push to the branch (`git push origin feature/amazing-feature`)
134 | 5. Open a Pull Request
135 |
136 | ## 📄 License
137 |
138 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
139 |
140 | ## 🏢 About
141 |
142 | O.R.B.I.T. is developed and maintained by [Metros Labs](https://github.com/metros-org).
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/docs/api-reference.md:
--------------------------------------------------------------------------------
1 | # API Reference
2 |
3 | ## Core Package (@orbit/core)
4 |
5 | ### Orchestrator
6 |
7 | The main orchestration engine that manages agents and tasks.
8 |
9 | ```typescript
10 | class Orchestrator implements IOrchestrator {
11 | constructor(config: OrchestratorConfig);
12 |
13 | // Core methods
14 | initialize(): Promise;
15 | shutdown(): Promise;
16 |
17 | // Agent management
18 | addAgent(agent: IAgent): void;
19 | removeAgent(agentName: string): void;
20 |
21 | // Tool management
22 | addTool(tool: Tool): void;
23 | removeTool(toolName: string): void;
24 |
25 | // Task management
26 | submitTask(task: TaskDefinition): Promise;
27 | cancelTask(taskId: string): Promise;
28 | getTaskStatus(taskId: string): Promise;
29 |
30 | // Metrics
31 | getMetrics(): IOrchestratorMetrics;
32 | }
33 | ```
34 |
35 | #### Configuration
36 |
37 | ```typescript
38 | interface OrchestratorConfig {
39 | agents?: IAgent[];
40 | tools?: Tool[];
41 | maxConcurrentTasks?: number;
42 | defaultTimeout?: number;
43 | retryStrategy?: RetryStrategy;
44 | }
45 |
46 | interface RetryStrategy {
47 | maxAttempts: number;
48 | backoff: 'linear' | 'exponential';
49 | initialDelay: number;
50 | }
51 | ```
52 |
53 | ### Agents
54 |
55 | Base agent implementation and types.
56 |
57 | ```typescript
58 | abstract class BaseAgent implements IAgent {
59 | constructor(config: AgentConfig);
60 |
61 | // Lifecycle methods
62 | abstract initialize(): Promise;
63 | abstract execute(input: string, options?: AgentExecuteOptions): Promise;
64 | abstract stop(): Promise;
65 |
66 | // Tool management
67 | addTool(tool: Tool): void;
68 | removeTool(toolName: string): void;
69 |
70 | // Status and metrics
71 | getStatus(): 'idle' | 'busy' | 'error' | 'stopped';
72 | getMetrics(): AgentMetrics;
73 | }
74 | ```
75 |
76 | #### Agent Types
77 |
78 | ```typescript
79 | interface AgentConfig {
80 | name: string;
81 | description?: string;
82 | modelId?: string;
83 | maxTokens?: number;
84 | temperature?: number;
85 | tools?: Tool[];
86 | metadata?: Record;
87 | }
88 |
89 | interface AgentCapabilities {
90 | canStream: boolean;
91 | supportedTools: string[];
92 | maxConcurrentTasks: number;
93 | supportedModels: string[];
94 | }
95 |
96 | interface AgentMetrics {
97 | totalTasks: number;
98 | successfulTasks: number;
99 | failedTasks: number;
100 | averageResponseTime: number;
101 | lastActive: Date;
102 | }
103 | ```
104 |
105 | ### Tools
106 |
107 | Base tool implementation and types.
108 |
109 | ```typescript
110 | abstract class BaseTool implements Tool {
111 | constructor(options: ToolOptions);
112 |
113 | // Core methods
114 | abstract execute(...args: any[]): Promise;
115 | abstract validate?(...args: any[]): Promise;
116 | abstract getSchema(): ToolSchema;
117 |
118 | // Metadata
119 | getMetadata(): Record;
120 | }
121 | ```
122 |
123 | #### Tool Types
124 |
125 | ```typescript
126 | interface ToolOptions {
127 | name: string;
128 | description: string;
129 | version: string;
130 | category?: string;
131 | metadata?: Record;
132 | }
133 |
134 | interface ToolSchema {
135 | name: string;
136 | description: string;
137 | parameters: {
138 | type: 'object';
139 | properties: Record;
140 | required?: string[];
141 | };
142 | returns: {
143 | type: string;
144 | description: string;
145 | };
146 | }
147 | ```
148 |
149 | ## Context Package (@orbit/context)
150 |
151 | ### Context Provider
152 |
153 | Manages task context and memory.
154 |
155 | ```typescript
156 | class DefaultContextProvider implements ContextProvider {
157 | constructor(config: ContextProviderConfig);
158 |
159 | // Core methods
160 | get(key: string): Promise;
161 | set(key: string, value: any): Promise;
162 | delete(key: string): Promise;
163 | clear(): Promise;
164 |
165 | // Memory management
166 | getMemory(taskId: string): Promise;
167 | updateMemory(taskId: string, memory: Partial): Promise;
168 |
169 | // Event handling
170 | subscribe(event: string, callback: (data: any) => void): void;
171 | unsubscribe(event: string, callback: (data: any) => void): void;
172 |
173 | // Cleanup
174 | dispose(): Promise;
175 | }
176 | ```
177 |
178 | ## Blockchain Package (@orbit/blockchain)
179 |
180 | ### Ethereum Provider
181 |
182 | Manages Ethereum blockchain interactions.
183 |
184 | ```typescript
185 | class EthereumProvider implements BlockchainProvider {
186 | constructor(network: NetworkConfig);
187 |
188 | // Connection
189 | connect(): Promise;
190 | disconnect(): Promise;
191 |
192 | // Basic operations
193 | getBalance(address: string): Promise;
194 | getBlock(blockHashOrNumber: string | number): Promise;
195 | getTransaction(hash: string): Promise;
196 | getTransactionCount(address: string): Promise;
197 |
198 | // Transaction handling
199 | sendTransaction(config: TransactionConfig): Promise;
200 | estimateGas(config: TransactionConfig): Promise;
201 |
202 | // Contract interaction
203 | call(contract: ContractConfig, method: string, args: any[]): Promise;
204 | estimateContractGas(contract: ContractConfig, method: string, args: any[]): Promise;
205 | }
206 | ```
207 |
208 | ### DeFi Protocols
209 |
210 | #### Uniswap Integration
211 |
212 | ```typescript
213 | class UniswapProtocol {
214 | constructor(provider: BlockchainProvider, config: UniswapConfig);
215 |
216 | // Pool operations
217 | getPool(tokenA: string, tokenB: string, fee: number): Promise;
218 | getPoolData(poolAddress: string): Promise;
219 |
220 | // Trading operations
221 | quoteExactInputSingle(tokenIn: string, tokenOut: string, fee: number, amountIn: BigNumberish): Promise;
222 | swap(params: SwapParams): Promise;
223 |
224 | // Liquidity operations
225 | addLiquidity(tokenA: string, tokenB: string, fee: number, ...params: any[]): Promise;
226 | }
227 | ```
228 |
229 | #### Aave Integration
230 |
231 | ```typescript
232 | class AaveProtocol {
233 | constructor(provider: BlockchainProvider, config: AaveConfig);
234 |
235 | // Market data
236 | getReserveData(asset: string): Promise;
237 | getUserAccountData(user: string): Promise;
238 |
239 | // Lending operations
240 | supply(asset: string, amount: BigNumberish, onBehalfOf: string, referralCode?: number): Promise;
241 | borrow(asset: string, amount: BigNumberish, ...params: any[]): Promise;
242 | repay(asset: string, amount: BigNumberish, ...params: any[]): Promise;
243 | withdraw(asset: string, amount: BigNumberish, to: string): Promise;
244 | }
245 | ```
246 |
247 | ## Security Package (@orbit/security)
248 |
249 | ### Security Provider
250 |
251 | Handles secure communication and encryption.
252 |
253 | ```typescript
254 | class DefaultSecurityProvider implements SecurityProvider {
255 | constructor(config: SecurityConfig);
256 |
257 | // Key generation
258 | generateEncryptionKey(): Promise;
259 | generateSigningKey(): Promise;
260 |
261 | // Encryption
262 | encrypt(message: string, recipientPublicKey: string): Promise;
263 | decrypt(message: EncryptedMessage, privateKey: string): Promise;
264 |
265 | // Signing
266 | sign(message: string | EncryptedMessage, privateKey: string): Promise;
267 | verify(signedMessage: SignedMessage): Promise;
268 |
269 | // Key exchange
270 | deriveSharedSecret(privateKey: string, publicKey: string): Promise;
271 | }
--------------------------------------------------------------------------------
/docs/assets/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/orbit-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metros-org/orbit-framework/77cdf1e81a99434e9f1197e6d6bb2f5c1377abe6/docs/assets/orbit-architecture.png
--------------------------------------------------------------------------------
/docs/assets/orbit-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metros-org/orbit-framework/77cdf1e81a99434e9f1197e6d6bb2f5c1377abe6/docs/assets/orbit-logo.png
--------------------------------------------------------------------------------
/docs/core-concepts.md:
--------------------------------------------------------------------------------
1 | # Core Concepts
2 |
3 | ## Overview
4 |
5 | O.R.B.I.T. (Orchestrated Responsive Blockchain Integration Technology) is a framework designed for building and managing autonomous agents that can interact with blockchain networks and execute complex tasks. This document outlines the core concepts and architecture of the framework.
6 |
7 | ## Architecture Components
8 |
9 | ### 1. Orchestration Core Engine (OCE)
10 |
11 | The OCE is the central component responsible for managing agents, tasks, and system resources.
12 |
13 | #### Key Features:
14 | - Task scheduling and distribution
15 | - Agent lifecycle management
16 | - Resource allocation and monitoring
17 | - State management and persistence
18 | - Error handling and recovery
19 |
20 | ```typescript
21 | interface IOrchestrator {
22 | // Agent Management
23 | addAgent(agent: IAgent): void;
24 | removeAgent(agentName: string): void;
25 | getAgent(agentName: string): IAgent;
26 |
27 | // Task Management
28 | submitTask(task: TaskDefinition): Promise;
29 | cancelTask(taskId: string): Promise;
30 | getTaskStatus(taskId: string): Promise;
31 |
32 | // System Management
33 | initialize(): Promise;
34 | shutdown(): Promise;
35 | getMetrics(): SystemMetrics;
36 | }
37 | ```
38 |
39 | ### 2. Responsive Context Handler (RCH)
40 |
41 | The RCH manages agent memory and context, enabling intelligent decision-making and learning.
42 |
43 | #### Memory Types:
44 | - Short-term memory (temporary task data)
45 | - Long-term memory (persistent knowledge)
46 | - Episodic memory (historical interactions)
47 |
48 | ```typescript
49 | interface ContextProvider {
50 | // Memory Operations
51 | get(key: string): Promise;
52 | set(key: string, value: any): Promise;
53 | delete(key: string): Promise;
54 |
55 | // Memory Management
56 | getMemory(taskId: string): Promise;
57 | updateMemory(taskId: string, memory: Partial): Promise;
58 | clearMemory(taskId: string): Promise;
59 | }
60 |
61 | interface TaskMemory {
62 | shortTerm: Map;
63 | longTerm: Map;
64 | episodic: Array;
65 | }
66 | ```
67 |
68 | ### 3. Blockchain Orchestration Layer (BOL)
69 |
70 | The BOL handles all blockchain-related operations and integrations.
71 |
72 | #### Capabilities:
73 | - Multi-chain support
74 | - Transaction management
75 | - Smart contract interaction
76 | - DeFi protocol integration
77 |
78 | ```typescript
79 | interface BlockchainProvider {
80 | // Connection
81 | connect(): Promise;
82 | disconnect(): Promise;
83 |
84 | // Basic Operations
85 | getBalance(address: string): Promise;
86 | getTransaction(hash: string): Promise;
87 |
88 | // Contract Interaction
89 | call(contract: ContractConfig, method: string, args: any[]): Promise;
90 | estimateGas(config: TransactionConfig): Promise;
91 | }
92 | ```
93 |
94 | ### 4. Secure Communication Layer (SCL)
95 |
96 | The SCL ensures secure communication between components and external systems.
97 |
98 | #### Security Features:
99 | - End-to-end encryption
100 | - Message authentication
101 | - Access control
102 | - Key management
103 |
104 | ```typescript
105 | interface SecurityProvider {
106 | // Encryption
107 | encrypt(message: string, recipientPublicKey: string): Promise;
108 | decrypt(message: EncryptedMessage, privateKey: string): Promise;
109 |
110 | // Authentication
111 | sign(message: string, privateKey: string): Promise;
112 | verify(signedMessage: SignedMessage): Promise;
113 | }
114 | ```
115 |
116 | ## Core Concepts
117 |
118 | ### 1. Agents
119 |
120 | Agents are autonomous entities that can execute tasks and interact with the system.
121 |
122 | #### Agent Types:
123 | - Task-specific agents
124 | - General-purpose agents
125 | - Specialized blockchain agents
126 |
127 | ```typescript
128 | interface IAgent {
129 | // Properties
130 | name: string;
131 | description: string;
132 | capabilities: AgentCapabilities;
133 |
134 | // Lifecycle
135 | initialize(): Promise;
136 | execute(input: string, options?: AgentExecuteOptions): Promise;
137 | stop(): Promise;
138 |
139 | // Tool Management
140 | addTool(tool: Tool): void;
141 | removeTool(toolName: string): void;
142 | }
143 | ```
144 |
145 | ### 2. Tools
146 |
147 | Tools are reusable components that provide specific functionality to agents.
148 |
149 | #### Tool Categories:
150 | - Blockchain operations
151 | - Data processing
152 | - External integrations
153 | - Utility functions
154 |
155 | ```typescript
156 | interface Tool {
157 | name: string;
158 | description: string;
159 | version: string;
160 |
161 | execute(...args: any[]): Promise;
162 | validate?(...args: any[]): Promise;
163 | getSchema(): ToolSchema;
164 | }
165 | ```
166 |
167 | ### 3. Tasks
168 |
169 | Tasks represent units of work that can be executed by agents.
170 |
171 | #### Task Properties:
172 | - Input parameters
173 | - Execution context
174 | - Success criteria
175 | - Error handling
176 |
177 | ```typescript
178 | interface TaskDefinition {
179 | agent: string;
180 | input: any;
181 | options?: TaskOptions;
182 | context?: TaskContext;
183 | timeout?: number;
184 | retryStrategy?: RetryStrategy;
185 | }
186 |
187 | interface TaskResult {
188 | taskId: string;
189 | status: TaskStatus;
190 | output: any;
191 | error?: Error;
192 | metrics: TaskMetrics;
193 | }
194 | ```
195 |
196 | ### 4. Context
197 |
198 | Context provides the environment and state for task execution.
199 |
200 | #### Context Elements:
201 | - Task-specific data
202 | - Agent memory
203 | - System state
204 | - External data
205 |
206 | ```typescript
207 | interface TaskContext {
208 | // Task Information
209 | taskId: string;
210 | parentTaskId?: string;
211 | startTime: Date;
212 |
213 | // Memory Access
214 | memory: TaskMemory;
215 |
216 | // State Management
217 | state: Map;
218 |
219 | // External Data
220 | externalData?: Map;
221 | }
222 | ```
223 |
224 | ## Design Principles
225 |
226 | ### 1. Modularity
227 | - Components are loosely coupled
228 | - Easy to extend and customize
229 | - Plugin architecture
230 |
231 | ### 2. Scalability
232 | - Horizontal scaling
233 | - Load balancing
234 | - Resource optimization
235 |
236 | ### 3. Reliability
237 | - Error recovery
238 | - State persistence
239 | - Transaction safety
240 |
241 | ### 4. Security
242 | - Secure by design
243 | - Defense in depth
244 | - Privacy preservation
245 |
246 | ## Best Practices
247 |
248 | ### 1. Agent Design
249 | - Single responsibility principle
250 | - Clear input/output contracts
251 | - Proper error handling
252 | - Resource cleanup
253 |
254 | ### 2. Tool Development
255 | - Reusable components
256 | - Comprehensive documentation
257 | - Version compatibility
258 | - Testing coverage
259 |
260 | ### 3. Task Organization
261 | - Atomic operations
262 | - Clear dependencies
263 | - Proper timeout handling
264 | - Retry strategies
265 |
266 | ### 4. State Management
267 | - Immutable when possible
268 | - Clear ownership
269 | - Proper synchronization
270 | - Backup strategies
271 |
272 | ## Advanced Concepts
273 |
274 | ### 1. Agent Collaboration
275 | - Task delegation
276 | - Resource sharing
277 | - Communication protocols
278 | - Conflict resolution
279 |
280 | ### 2. State Management
281 | - Distributed state
282 | - Consistency models
283 | - State synchronization
284 | - Recovery mechanisms
285 |
286 | ### 3. Error Handling
287 | - Error classification
288 | - Recovery strategies
289 | - Fallback mechanisms
290 | - Error reporting
291 |
292 | ### 4. System Monitoring
293 | - Performance metrics
294 | - Health checks
295 | - Alert systems
296 | - Debugging tools
297 |
298 | ## Next Steps
299 |
300 | 1. Review the API Reference for detailed implementation
301 | 2. Explore examples for practical usage
302 | 3. Check security guidelines for best practices
303 | 4. Join the community for support and collaboration
--------------------------------------------------------------------------------
/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting Started with O.R.B.I.T.
2 |
3 | This guide will help you get started with the O.R.B.I.T. framework.
4 |
5 | ## Prerequisites
6 |
7 | - Node.js v18 or higher
8 | - yarn v4.0.2 or higher
9 | - Basic understanding of TypeScript
10 | - Basic understanding of blockchain concepts
11 |
12 | ## Installation
13 |
14 | 1. Clone the repository:
15 |
16 | ```bash
17 | git clone https://github.com/metros-org/orbit-framework.git
18 | cd orbit-framework
19 | ```
20 |
21 | 2. Install dependencies:
22 |
23 | ```bash
24 | yarn install
25 | ```
26 |
27 | 3. Build the packages:
28 |
29 | ```bash
30 | yarn build
31 | ```
32 |
33 | ## Using in Your Project
34 |
35 | 1. Create a new TypeScript project:
36 |
37 | ```bash
38 | mkdir my-orbit-project
39 | cd my-orbit-project
40 | yarn init -y
41 | yarn add typescript @types/node --dev
42 | yarn tsc --init
43 | ```
44 |
45 | 2. Add the orbit-framework as a git dependency in your package.json:
46 |
47 | ```json
48 | {
49 | "dependencies": {
50 | "@orbit/core": "git+https://github.com/metros-org/orbit-framework.git#main",
51 | "@orbit/tools": "git+https://github.com/metros-org/orbit-framework.git#main"
52 | }
53 | }
54 | ```
55 |
56 | 3. Install optional packages based on your needs:
57 |
58 | ```json
59 | {
60 | "dependencies": {
61 | "@orbit/blockchain": "git+https://github.com/metros-org/orbit-framework.git#main",
62 | "@orbit/context": "git+https://github.com/metros-org/orbit-framework.git#main",
63 | "@orbit/security": "git+https://github.com/metros-org/orbit-framework.git#main"
64 | }
65 | }
66 | ```
67 |
68 | ## Basic Setup
69 |
70 | 1. Create a new TypeScript project:
71 |
72 | ```bash
73 | mkdir my-orbit-project
74 | cd my-orbit-project
75 | npm init -y
76 | npm install typescript @types/node --save-dev
77 | npx tsc --init
78 | ```
79 |
80 | 2. Create your first orchestrator:
81 |
82 | ```typescript
83 | // src/index.ts
84 | import { Orchestrator, BedrockAgent } from '@orbit/core';
85 | import { Web3Tool } from '@orbit/tools';
86 |
87 | async function main() {
88 | // Initialize the orchestrator
89 | const orchestrator = new Orchestrator({
90 | agents: [
91 | new BedrockAgent({
92 | name: 'data-analyzer',
93 | modelId: 'anthropic.claude-v2'
94 | })
95 | ],
96 | tools: [new Web3Tool()]
97 | });
98 |
99 | // Initialize the system
100 | await orchestrator.initialize();
101 |
102 | // Submit a task
103 | const result = await orchestrator.submitTask({
104 | id: 'analyze-data-1',
105 | type: 'analysis',
106 | input: {
107 | data: 'Your data here',
108 | parameters: {
109 | // Your parameters
110 | }
111 | }
112 | });
113 |
114 | console.log('Task result:', result);
115 | }
116 |
117 | main().catch(console.error);
118 | ```
119 |
120 | ## Configuration
121 |
122 | ### Core Configuration
123 |
124 | ```typescript
125 | import { OrchestratorConfig } from '@orbit/core';
126 |
127 | const config: OrchestratorConfig = {
128 | maxConcurrentTasks: 5,
129 | defaultTimeout: 30000, // 30 seconds
130 | retryStrategy: {
131 | maxAttempts: 3,
132 | backoff: 'exponential',
133 | initialDelay: 1000
134 | }
135 | };
136 | ```
137 |
138 | ### Blockchain Integration
139 |
140 | ```typescript
141 | import { EthereumProvider } from '@orbit/blockchain';
142 |
143 | const provider = new EthereumProvider({
144 | chainId: 1,
145 | name: 'Ethereum Mainnet',
146 | rpcUrl: 'YOUR_RPC_URL',
147 | nativeCurrency: {
148 | name: 'Ether',
149 | symbol: 'ETH',
150 | decimals: 18
151 | }
152 | });
153 | ```
154 |
155 | ### Context Management
156 |
157 | ```typescript
158 | import { DefaultContextProvider } from '@orbit/context';
159 |
160 | const contextProvider = new DefaultContextProvider({
161 | redis: {
162 | host: 'localhost',
163 | port: 6379
164 | },
165 | ttl: 3600 // 1 hour
166 | });
167 | ```
168 |
169 | ### Security Setup
170 |
171 | ```typescript
172 | import { DefaultSecurityProvider } from '@orbit/security';
173 |
174 | const securityProvider = new DefaultSecurityProvider({
175 | encryptionAlgorithm: 'ECDH-ES+A256KW',
176 | signatureAlgorithm: 'EdDSA'
177 | });
178 | ```
179 |
180 | ## Next Steps
181 |
182 | - Read the [Core Concepts](core-concepts.md) guide to understand the framework's architecture
183 | - Check out the [Examples](../examples) directory for more advanced use cases
184 | - Review the [API Reference](api-reference.md) for detailed documentation
185 |
186 | ## Common Patterns
187 |
188 | ### Task Orchestration
189 |
190 | ```typescript
191 | // Define task dependencies
192 | const task = {
193 | id: 'complex-task',
194 | type: 'workflow',
195 | input: {
196 | data: 'input data'
197 | },
198 | dependencies: ['task-1', 'task-2']
199 | };
200 |
201 | // Submit task with context
202 | const result = await orchestrator.submitTask({
203 | ...task,
204 | context: {
205 | variables: {
206 | key: 'value'
207 | },
208 | memory: {
209 | shortTerm: {},
210 | longTerm: {},
211 | episodic: []
212 | }
213 | }
214 | });
215 | ```
216 |
217 | ### Agent Communication
218 |
219 | ```typescript
220 | // Set up agent communication
221 | agent1.on('message', (message) => {
222 | console.log('Agent 1 received:', message);
223 | });
224 |
225 | agent2.on('message', (message) => {
226 | console.log('Agent 2 received:', message);
227 | });
228 |
229 | // Send messages between agents
230 | await agent1.send(agent2.name, {
231 | type: 'request',
232 | content: 'Hello from Agent 1'
233 | });
234 | ```
235 |
236 | ### Error Handling
237 |
238 | ```typescript
239 | try {
240 | const result = await orchestrator.submitTask(task);
241 | } catch (error) {
242 | if (error.code === 'TASK_TIMEOUT') {
243 | // Handle timeout
244 | } else if (error.code === 'AGENT_ERROR') {
245 | // Handle agent error
246 | } else {
247 | // Handle other errors
248 | }
249 | }
250 | ```
251 |
252 | ## Best Practices
253 |
254 | 1. **Task Granularity**: Keep tasks focused and atomic
255 | 2. **Error Handling**: Implement comprehensive error handling
256 | 3. **Resource Management**: Monitor and manage system resources
257 | 4. **Security**: Always use secure communication channels
258 | 5. **Monitoring**: Implement logging and monitoring
259 | 6. **Testing**: Write unit tests for critical components
260 |
261 | ## Troubleshooting
262 |
263 | Common issues and their solutions:
264 |
265 | 1. **Connection Issues**
266 | - Check network connectivity
267 | - Verify RPC endpoints
268 | - Check Redis connection (if using)
269 |
270 | 2. **Performance Issues**
271 | - Monitor task queue size
272 | - Check agent load
273 | - Verify system resources
274 |
275 | 3. **Memory Issues**
276 | - Monitor memory usage
277 | - Clear context cache regularly
278 | - Implement garbage collection
279 |
280 | For more help, check the [examples](../examples) or open an issue on GitHub.
--------------------------------------------------------------------------------
/docs/security.md:
--------------------------------------------------------------------------------
1 | # Security Guidelines
2 |
3 | ## Overview
4 |
5 | The O.R.B.I.T. framework implements comprehensive security measures to protect agent communications, blockchain interactions, and sensitive data. This document outlines security best practices and implementation guidelines.
6 |
7 | ## Core Security Features
8 |
9 | ### 1. Encryption
10 |
11 | All sensitive communications are encrypted using industry-standard algorithms:
12 |
13 | ```typescript
14 | // Example of secure message encryption
15 | const securityProvider = new DefaultSecurityProvider({
16 | algorithm: 'aes-256-gcm',
17 | keyDerivation: 'pbkdf2',
18 | hashAlgorithm: 'sha256'
19 | });
20 |
21 | // Encrypt message
22 | const encryptedMessage = await securityProvider.encrypt(
23 | message,
24 | recipientPublicKey
25 | );
26 |
27 | // Decrypt message
28 | const decryptedMessage = await securityProvider.decrypt(
29 | encryptedMessage,
30 | privateKey
31 | );
32 | ```
33 |
34 | ### 2. Authentication
35 |
36 | Agent authentication using digital signatures:
37 |
38 | ```typescript
39 | // Generate signing keys
40 | const { publicKey, privateKey } = await securityProvider.generateSigningKey();
41 |
42 | // Sign message
43 | const signedMessage = await securityProvider.sign(message, privateKey);
44 |
45 | // Verify signature
46 | const isValid = await securityProvider.verify(signedMessage);
47 | ```
48 |
49 | ### 3. Access Control
50 |
51 | Role-based access control for agents and tools:
52 |
53 | ```typescript
54 | const accessControl = new AccessControlProvider({
55 | roles: ['admin', 'agent', 'tool'],
56 | permissions: {
57 | 'admin': ['*'],
58 | 'agent': ['execute', 'read'],
59 | 'tool': ['execute']
60 | }
61 | });
62 |
63 | // Check permissions
64 | const canExecute = await accessControl.checkPermission(
65 | agentId,
66 | 'execute',
67 | resourceId
68 | );
69 | ```
70 |
71 | ## Secure Configuration
72 |
73 | ### 1. Environment Variables
74 |
75 | Sensitive configuration should be stored in environment variables:
76 |
77 | ```typescript
78 | // Load configuration securely
79 | const config = {
80 | apiKey: process.env.ORBIT_API_KEY,
81 | privateKey: process.env.ORBIT_PRIVATE_KEY,
82 | nodeUrl: process.env.ORBIT_NODE_URL
83 | };
84 | ```
85 |
86 | ### 2. Network Security
87 |
88 | Configure secure network connections:
89 |
90 | ```typescript
91 | const networkConfig = {
92 | ssl: true,
93 | cert: process.env.SSL_CERT,
94 | key: process.env.SSL_KEY,
95 | ca: process.env.SSL_CA,
96 | rejectUnauthorized: true
97 | };
98 | ```
99 |
100 | ## Blockchain Security
101 |
102 | ### 1. Transaction Signing
103 |
104 | Secure transaction signing process:
105 |
106 | ```typescript
107 | // Sign transaction
108 | const signedTx = await provider.signTransaction({
109 | to: recipient,
110 | value: amount,
111 | nonce: await provider.getTransactionCount(sender),
112 | gasLimit: estimatedGas,
113 | gasPrice: await provider.getGasPrice()
114 | });
115 | ```
116 |
117 | ### 2. Key Management
118 |
119 | Secure storage and handling of blockchain keys:
120 |
121 | ```typescript
122 | const keyManager = new KeyManager({
123 | storage: 'encrypted',
124 | encryptionKey: process.env.ENCRYPTION_KEY,
125 | backupEnabled: true,
126 | backupLocation: process.env.BACKUP_LOCATION
127 | });
128 |
129 | // Store private key
130 | await keyManager.storeKey(keyId, privateKey);
131 |
132 | // Retrieve private key
133 | const key = await keyManager.getKey(keyId);
134 | ```
135 |
136 | ## Data Protection
137 |
138 | ### 1. Sensitive Data Handling
139 |
140 | Guidelines for handling sensitive data:
141 |
142 | ```typescript
143 | class SensitiveDataHandler {
144 | // Mask sensitive data
145 | static maskData(data: string): string {
146 | return data.replace(/\d{12,}/g, '************');
147 | }
148 |
149 | // Sanitize input
150 | static sanitizeInput(input: string): string {
151 | return input.replace(/[<>]/g, '');
152 | }
153 |
154 | // Secure data storage
155 | static async storeSecurely(data: any): Promise {
156 | const encrypted = await securityProvider.encrypt(
157 | JSON.stringify(data),
158 | storagePublicKey
159 | );
160 | await storage.set(encrypted);
161 | }
162 | }
163 | ```
164 |
165 | ### 2. Memory Security
166 |
167 | Secure memory management:
168 |
169 | ```typescript
170 | class SecureMemoryManager {
171 | // Clear sensitive data
172 | static clearSensitiveData(): void {
173 | process.memoryUsage();
174 | global.gc();
175 | }
176 |
177 | // Secure memory allocation
178 | static allocateSecureBuffer(size: number): Buffer {
179 | return Buffer.alloc(size, 0, 'secure');
180 | }
181 | }
182 | ```
183 |
184 | ## Security Best Practices
185 |
186 | 1. **Input Validation**
187 | - Validate all inputs
188 | - Sanitize data before processing
189 | - Use parameterized queries
190 |
191 | 2. **Output Encoding**
192 | - Encode all output
193 | - Use appropriate encoding for context
194 | - Implement content security policies
195 |
196 | 3. **Error Handling**
197 | - Do not expose sensitive information in errors
198 | - Log security events securely
199 | - Implement proper error recovery
200 |
201 | 4. **Session Management**
202 | - Use secure session handling
203 | - Implement proper timeout mechanisms
204 | - Validate session tokens
205 |
206 | 5. **Audit Logging**
207 | - Log security events
208 | - Maintain audit trails
209 | - Secure log storage
210 |
211 | ## Security Checklist
212 |
213 | ### Development
214 | - [ ] Use secure dependencies
215 | - [ ] Implement input validation
216 | - [ ] Enable security headers
217 | - [ ] Use secure configurations
218 | - [ ] Implement proper error handling
219 |
220 | ### Deployment
221 | - [ ] Secure environment variables
222 | - [ ] Enable SSL/TLS
223 | - [ ] Configure firewalls
224 | - [ ] Set up monitoring
225 | - [ ] Regular security updates
226 |
227 | ### Operation
228 | - [ ] Monitor security events
229 | - [ ] Regular security audits
230 | - [ ] Incident response plan
231 | - [ ] Backup procedures
232 | - [ ] Access control review
233 |
234 | ## Incident Response
235 |
236 | 1. **Detection**
237 | - Monitor security events
238 | - Analyze suspicious activities
239 | - Alert on security breaches
240 |
241 | 2. **Response**
242 | - Isolate affected systems
243 | - Investigate root cause
244 | - Document incident details
245 |
246 | 3. **Recovery**
247 | - Restore from secure backups
248 | - Patch vulnerabilities
249 | - Update security measures
250 |
251 | 4. **Prevention**
252 | - Update security policies
253 | - Enhance monitoring
254 | - Implement additional controls
--------------------------------------------------------------------------------
/docs/troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Error Handling & Troubleshooting
2 |
3 | ## Common Error Types
4 |
5 | ### Orchestrator Errors
6 |
7 | ```typescript
8 | class OrchestratorError extends Error {
9 | code: string;
10 | details: Record;
11 | }
12 | ```
13 |
14 | | Error Code | Description | Resolution |
15 | |------------|-------------|------------|
16 | | `INIT_FAILED` | Orchestrator initialization failed | Check configuration and ensure all required services are available |
17 | | `AGENT_NOT_FOUND` | Specified agent does not exist | Verify agent name and ensure it's properly registered |
18 | | `TOOL_NOT_FOUND` | Specified tool does not exist | Verify tool name and ensure it's properly registered |
19 | | `TASK_TIMEOUT` | Task execution exceeded timeout | Adjust timeout settings or optimize task execution |
20 | | `MAX_RETRIES_EXCEEDED` | Task retry limit reached | Check task configuration and underlying service health |
21 |
22 | ### Agent Errors
23 |
24 | ```typescript
25 | class AgentError extends Error {
26 | agentName: string;
27 | code: string;
28 | details: Record;
29 | }
30 | ```
31 |
32 | | Error Code | Description | Resolution |
33 | |------------|-------------|------------|
34 | | `EXECUTION_FAILED` | Agent failed to execute task | Check agent logs and task input validity |
35 | | `INVALID_TOOL_CALL` | Invalid tool usage by agent | Verify tool schema and agent implementation |
36 | | `CONTEXT_ACCESS_DENIED` | Agent lacks required context access | Check agent permissions and context configuration |
37 | | `MODEL_ERROR` | Language model error | Verify API keys and model availability |
38 |
39 | ### Blockchain Errors
40 |
41 | ```typescript
42 | class BlockchainError extends Error {
43 | code: string;
44 | network: string;
45 | details: Record;
46 | }
47 | ```
48 |
49 | | Error Code | Description | Resolution |
50 | |------------|-------------|------------|
51 | | `NETWORK_ERROR` | Failed to connect to blockchain network | Check network configuration and connectivity |
52 | | `INSUFFICIENT_FUNDS` | Insufficient balance for transaction | Ensure account has required funds |
53 | | `CONTRACT_ERROR` | Smart contract interaction failed | Verify contract address and ABI |
54 | | `TRANSACTION_FAILED` | Transaction execution failed | Check gas settings and transaction parameters |
55 |
56 | ## Debugging Strategies
57 |
58 | ### 1. Logging
59 |
60 | Configure logging levels in your application:
61 |
62 | ```typescript
63 | const config: OrchestratorConfig = {
64 | logging: {
65 | level: 'debug', // 'error' | 'warn' | 'info' | 'debug' | 'trace'
66 | format: 'json',
67 | transports: ['console', 'file'],
68 | filename: 'orbit.log'
69 | }
70 | };
71 | ```
72 |
73 | ### 2. Task Tracing
74 |
75 | Enable detailed task execution tracing:
76 |
77 | ```typescript
78 | const taskConfig: TaskConfig = {
79 | tracing: {
80 | enabled: true,
81 | detailed: true,
82 | includeToolCalls: true,
83 | includeMemoryOperations: true
84 | }
85 | };
86 | ```
87 |
88 | ### 3. Memory Inspection
89 |
90 | Monitor agent memory usage:
91 |
92 | ```typescript
93 | const memory = await orchestrator.getAgentMemory(agentName);
94 | console.log('Memory Usage:', {
95 | shortTerm: memory.shortTerm.size,
96 | longTerm: memory.longTerm.size,
97 | episodic: memory.episodic.length
98 | });
99 | ```
100 |
101 | ### 4. Network Monitoring
102 |
103 | Monitor blockchain network status:
104 |
105 | ```typescript
106 | const networkStatus = await provider.getNetworkStatus();
107 | console.log('Network Status:', {
108 | blockNumber: networkStatus.blockNumber,
109 | gasPrice: networkStatus.gasPrice,
110 | peers: networkStatus.peers,
111 | syncing: networkStatus.syncing
112 | });
113 | ```
114 |
115 | ## Best Practices
116 |
117 | 1. **Error Recovery**
118 | - Implement proper error handling for all async operations
119 | - Use retry mechanisms with exponential backoff
120 | - Maintain transaction atomicity in blockchain operations
121 |
122 | 2. **Monitoring**
123 | - Set up alerts for critical errors
124 | - Monitor system resource usage
125 | - Track agent performance metrics
126 |
127 | 3. **Testing**
128 | - Write comprehensive unit tests
129 | - Perform integration testing with mock services
130 | - Test error scenarios and recovery mechanisms
131 |
132 | 4. **Security**
133 | - Validate all inputs
134 | - Implement proper access controls
135 | - Use secure communication channels
136 | - Handle sensitive data appropriately
137 |
138 | ## Common Issues and Solutions
139 |
140 | ### Agent Communication Issues
141 |
142 | **Problem**: Agents fail to communicate or exchange messages.
143 |
144 | **Solution**:
145 | 1. Check network connectivity
146 | 2. Verify message format and encryption
147 | 3. Ensure proper authentication
148 | 4. Check for rate limiting
149 |
150 | ### Task Execution Failures
151 |
152 | **Problem**: Tasks fail to execute or timeout.
153 |
154 | **Solution**:
155 | 1. Review task configuration
156 | 2. Check agent availability
157 | 3. Verify tool dependencies
158 | 4. Adjust timeout settings
159 |
160 | ### Memory Management Issues
161 |
162 | **Problem**: Memory leaks or excessive memory usage.
163 |
164 | **Solution**:
165 | 1. Implement proper cleanup
166 | 2. Use memory limits
167 | 3. Monitor memory usage
168 | 4. Optimize data structures
169 |
170 | ### Blockchain Integration Issues
171 |
172 | **Problem**: Failed blockchain transactions or interactions.
173 |
174 | **Solution**:
175 | 1. Check network status
176 | 2. Verify account balance
177 | 3. Adjust gas settings
178 | 4. Handle nonce management
179 |
180 | ## Support Resources
181 |
182 | For additional support:
183 |
184 | 1. Check the API Reference documentation
185 | 2. Review example implementations
186 | 3. Examine system logs
187 | 4. Use debugging tools and monitoring systems
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "orbit-framework",
3 | "private": true,
4 | "workspaces": [
5 | "packages/*"
6 | ],
7 | "scripts": {
8 | "build": "turbo run build",
9 | "dev": "turbo run dev",
10 | "lint": "turbo run lint",
11 | "test": "turbo run test",
12 | "clean": "turbo run clean",
13 | "format": "prettier --write \"**/*.{ts,tsx,md}\""
14 | },
15 | "devDependencies": {
16 | "prettier": "^3.2.4",
17 | "turbo": "^1.11.3",
18 | "typescript": "^5.3.3"
19 | },
20 | "packageManager": "yarn@4.0.2",
21 | "engines": {
22 | "node": ">=18.0.0"
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "git+https://github.com/metros-org/orbit-framework.git"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/packages/blockchain/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@orbit/blockchain",
3 | "version": "0.1.0",
4 | "description": "Blockchain Orchestration Layer for O.R.B.I.T Framework",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "scripts": {
8 | "build": "tsc",
9 | "test": "jest",
10 | "lint": "eslint src/**/*.ts"
11 | },
12 | "dependencies": {
13 | "@orbit/core": "^0.1.0",
14 | "ethers": "^6.11.0",
15 | "web3": "^4.5.0",
16 | "@uniswap/sdk-core": "^4.0.9",
17 | "@aave/core-v3": "^1.18.0",
18 | "curve-js": "^1.0.0"
19 | },
20 | "devDependencies": {
21 | "@types/node": "^22.10.6",
22 | "@types/jest": "^29.5.14",
23 | "typescript": "^5.7.3",
24 | "jest": "^29.7.0",
25 | "ts-jest": "^29.2.5"
26 | },
27 | "repository": {
28 | "type": "git",
29 | "url": "git+https://github.com/metros-org/orbit-framework.git",
30 | "directory": "packages/blockchain"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/blockchain/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types';
2 | export * from './providers/ethereum-provider';
3 | export * from './protocols/uniswap';
4 | export * from './protocols/aave';
--------------------------------------------------------------------------------
/packages/blockchain/src/protocols/aave.ts:
--------------------------------------------------------------------------------
1 | import { BigNumberish } from 'ethers';
2 | import { Logger } from '@orbit/core';
3 | import { BlockchainProvider, ContractConfig } from '../types';
4 |
5 | export interface AaveConfig {
6 | poolAddress: string;
7 | poolAbi: any[];
8 | dataProviderAddress: string;
9 | dataProviderAbi: any[];
10 | }
11 |
12 | export interface ReserveData {
13 | configuration: {
14 | ltv: number;
15 | liquidationThreshold: number;
16 | liquidationBonus: number;
17 | decimals: number;
18 | active: boolean;
19 | frozen: boolean;
20 | paused: boolean;
21 | };
22 | liquidityRate: BigNumberish;
23 | variableBorrowRate: BigNumberish;
24 | stableBorrowRate: BigNumberish;
25 | totalAToken: BigNumberish;
26 | totalStableDebt: BigNumberish;
27 | totalVariableDebt: BigNumberish;
28 | availableLiquidity: BigNumberish;
29 | utilizationRate: BigNumberish;
30 | }
31 |
32 | export interface UserAccountData {
33 | totalCollateralETH: BigNumberish;
34 | totalDebtETH: BigNumberish;
35 | availableBorrowsETH: BigNumberish;
36 | currentLiquidationThreshold: BigNumberish;
37 | ltv: BigNumberish;
38 | healthFactor: BigNumberish;
39 | }
40 |
41 | export class AaveProtocol {
42 | private readonly logger: Logger;
43 | private readonly provider: BlockchainProvider;
44 | private readonly config: AaveConfig;
45 |
46 | constructor(provider: BlockchainProvider, config: AaveConfig) {
47 | this.logger = new Logger('AaveProtocol');
48 | this.provider = provider;
49 | this.config = config;
50 | }
51 |
52 | public async getReserveData(asset: string): Promise {
53 | const dataProvider: ContractConfig = {
54 | address: this.config.dataProviderAddress,
55 | abi: this.config.dataProviderAbi
56 | };
57 |
58 | const data = await this.provider.call(dataProvider, 'getReserveData', [asset]);
59 |
60 | return {
61 | configuration: {
62 | ltv: data.configuration.ltv.toNumber(),
63 | liquidationThreshold: data.configuration.liquidationThreshold.toNumber(),
64 | liquidationBonus: data.configuration.liquidationBonus.toNumber(),
65 | decimals: data.configuration.decimals.toNumber(),
66 | active: data.configuration.active,
67 | frozen: data.configuration.frozen,
68 | paused: data.configuration.paused
69 | },
70 | liquidityRate: data.liquidityRate,
71 | variableBorrowRate: data.variableBorrowRate,
72 | stableBorrowRate: data.stableBorrowRate,
73 | totalAToken: data.totalAToken,
74 | totalStableDebt: data.totalStableDebt,
75 | totalVariableDebt: data.totalVariableDebt,
76 | availableLiquidity: data.availableLiquidity,
77 | utilizationRate: data.utilizationRate
78 | };
79 | }
80 |
81 | public async getUserAccountData(user: string): Promise {
82 | const pool: ContractConfig = {
83 | address: this.config.poolAddress,
84 | abi: this.config.poolAbi
85 | };
86 |
87 | const data = await this.provider.call(pool, 'getUserAccountData', [user]);
88 |
89 | return {
90 | totalCollateralETH: data.totalCollateralETH,
91 | totalDebtETH: data.totalDebtETH,
92 | availableBorrowsETH: data.availableBorrowsETH,
93 | currentLiquidationThreshold: data.currentLiquidationThreshold,
94 | ltv: data.ltv,
95 | healthFactor: data.healthFactor
96 | };
97 | }
98 |
99 | public async supply(
100 | asset: string,
101 | amount: BigNumberish,
102 | onBehalfOf: string,
103 | referralCode: number = 0
104 | ): Promise {
105 | const pool: ContractConfig = {
106 | address: this.config.poolAddress,
107 | abi: this.config.poolAbi
108 | };
109 |
110 | const tx = await this.provider.call(pool, 'supply', [
111 | asset,
112 | amount,
113 | onBehalfOf,
114 | referralCode
115 | ]);
116 |
117 | return tx.hash;
118 | }
119 |
120 | public async borrow(
121 | asset: string,
122 | amount: BigNumberish,
123 | interestRateMode: number,
124 | referralCode: number,
125 | onBehalfOf: string
126 | ): Promise {
127 | const pool: ContractConfig = {
128 | address: this.config.poolAddress,
129 | abi: this.config.poolAbi
130 | };
131 |
132 | const tx = await this.provider.call(pool, 'borrow', [
133 | asset,
134 | amount,
135 | interestRateMode,
136 | referralCode,
137 | onBehalfOf
138 | ]);
139 |
140 | return tx.hash;
141 | }
142 |
143 | public async repay(
144 | asset: string,
145 | amount: BigNumberish,
146 | interestRateMode: number,
147 | onBehalfOf: string
148 | ): Promise {
149 | const pool: ContractConfig = {
150 | address: this.config.poolAddress,
151 | abi: this.config.poolAbi
152 | };
153 |
154 | const tx = await this.provider.call(pool, 'repay', [
155 | asset,
156 | amount,
157 | interestRateMode,
158 | onBehalfOf
159 | ]);
160 |
161 | return tx.hash;
162 | }
163 |
164 | public async withdraw(
165 | asset: string,
166 | amount: BigNumberish,
167 | to: string
168 | ): Promise {
169 | const pool: ContractConfig = {
170 | address: this.config.poolAddress,
171 | abi: this.config.poolAbi
172 | };
173 |
174 | const tx = await this.provider.call(pool, 'withdraw', [
175 | asset,
176 | amount,
177 | to
178 | ]);
179 |
180 | return tx.hash;
181 | }
182 | }
--------------------------------------------------------------------------------
/packages/blockchain/src/protocols/uniswap.ts:
--------------------------------------------------------------------------------
1 | import { ethers, BigNumberish } from 'ethers';
2 | import { Logger } from '@orbit/core';
3 | import { BlockchainProvider, ContractConfig } from '../types';
4 |
5 | export interface UniswapConfig {
6 | factoryAddress: string;
7 | routerAddress: string;
8 | quoterAddress: string;
9 | factoryAbi: any[];
10 | routerAbi: any[];
11 | quoterAbi: any[];
12 | }
13 |
14 | export interface SwapParams {
15 | tokenIn: string;
16 | tokenOut: string;
17 | fee: number;
18 | recipient: string;
19 | deadline: number;
20 | amountIn: BigNumberish;
21 | amountOutMinimum: BigNumberish;
22 | sqrtPriceLimitX96: BigNumberish;
23 | }
24 |
25 | export interface Pool {
26 | token0: string;
27 | token1: string;
28 | fee: number;
29 | tickSpacing: number;
30 | liquidity: BigNumberish;
31 | sqrtPriceX96: BigNumberish;
32 | tick: number;
33 | }
34 |
35 | export class UniswapProtocol {
36 | private readonly logger: Logger;
37 | private readonly provider: BlockchainProvider;
38 | private readonly config: UniswapConfig;
39 |
40 | constructor(provider: BlockchainProvider, config: UniswapConfig) {
41 | this.logger = new Logger('UniswapProtocol');
42 | this.provider = provider;
43 | this.config = config;
44 | }
45 |
46 | public async getPool(tokenA: string, tokenB: string, fee: number): Promise {
47 | const factory: ContractConfig = {
48 | address: this.config.factoryAddress,
49 | abi: this.config.factoryAbi
50 | };
51 |
52 | return await this.provider.call(factory, 'getPool', [tokenA, tokenB, fee]);
53 | }
54 |
55 | public async getPoolData(poolAddress: string): Promise {
56 | const poolAbi = [
57 | 'function token0() view returns (address)',
58 | 'function token1() view returns (address)',
59 | 'function fee() view returns (uint24)',
60 | 'function tickSpacing() view returns (int24)',
61 | 'function liquidity() view returns (uint128)',
62 | 'function slot0() view returns (uint160 sqrtPriceX96, int24 tick, ...)'
63 | ];
64 |
65 | const poolContract: ContractConfig = {
66 | address: poolAddress,
67 | abi: poolAbi
68 | };
69 |
70 | const [token0, token1, fee, tickSpacing, liquidity, slot0] = await Promise.all([
71 | this.provider.call(poolContract, 'token0', []),
72 | this.provider.call(poolContract, 'token1', []),
73 | this.provider.call(poolContract, 'fee', []),
74 | this.provider.call(poolContract, 'tickSpacing', []),
75 | this.provider.call(poolContract, 'liquidity', []),
76 | this.provider.call(poolContract, 'slot0', [])
77 | ]);
78 |
79 | return {
80 | token0,
81 | token1,
82 | fee,
83 | tickSpacing,
84 | liquidity,
85 | sqrtPriceX96: slot0[0],
86 | tick: slot0[1]
87 | };
88 | }
89 |
90 | public async quoteExactInputSingle(
91 | tokenIn: string,
92 | tokenOut: string,
93 | fee: number,
94 | amountIn: BigNumberish
95 | ): Promise {
96 | const quoter: ContractConfig = {
97 | address: this.config.quoterAddress,
98 | abi: this.config.quoterAbi
99 | };
100 |
101 | return await this.provider.call(quoter, 'quoteExactInputSingle', [
102 | tokenIn,
103 | tokenOut,
104 | fee,
105 | amountIn,
106 | 0 // sqrtPriceLimitX96
107 | ]);
108 | }
109 |
110 | public async swap(params: SwapParams): Promise {
111 | const router: ContractConfig = {
112 | address: this.config.routerAddress,
113 | abi: this.config.routerAbi
114 | };
115 |
116 | const exactInputParams = {
117 | tokenIn: params.tokenIn,
118 | tokenOut: params.tokenOut,
119 | fee: params.fee,
120 | recipient: params.recipient,
121 | deadline: params.deadline,
122 | amountIn: params.amountIn,
123 | amountOutMinimum: params.amountOutMinimum,
124 | sqrtPriceLimitX96: params.sqrtPriceLimitX96
125 | };
126 |
127 | const tx = await this.provider.call(router, 'exactInputSingle', [exactInputParams]);
128 | return tx.hash;
129 | }
130 |
131 | public async addLiquidity(
132 | tokenA: string,
133 | tokenB: string,
134 | fee: number,
135 | amount0Desired: BigNumberish,
136 | amount1Desired: BigNumberish,
137 | amount0Min: BigNumberish,
138 | amount1Min: BigNumberish,
139 | recipient: string,
140 | deadline: number
141 | ): Promise {
142 | const router: ContractConfig = {
143 | address: this.config.routerAddress,
144 | abi: this.config.routerAbi
145 | };
146 |
147 | const mintParams = {
148 | token0: tokenA,
149 | token1: tokenB,
150 | fee: fee,
151 | tickLower: -887272, // TODO: Calculate based on price range
152 | tickUpper: 887272, // TODO: Calculate based on price range
153 | amount0Desired,
154 | amount1Desired,
155 | amount0Min,
156 | amount1Min,
157 | recipient,
158 | deadline
159 | };
160 |
161 | const tx = await this.provider.call(router, 'mint', [mintParams]);
162 | return tx.hash;
163 | }
164 | }
--------------------------------------------------------------------------------
/packages/blockchain/src/providers/ethereum-provider.ts:
--------------------------------------------------------------------------------
1 | import { ethers, BigNumberish } from 'ethers';
2 | import { Logger } from '@orbit/core';
3 | import {
4 | BlockchainProvider,
5 | NetworkConfig,
6 | ContractConfig,
7 | TransactionConfig,
8 | TransactionResponse,
9 | EventFilter,
10 | EventLog
11 | } from '../types';
12 |
13 | export class EthereumProvider implements BlockchainProvider {
14 | private readonly logger: Logger;
15 | private provider: ethers.JsonRpcProvider;
16 | private signer?: ethers.Signer;
17 |
18 | public readonly chainId: number;
19 | public readonly network: NetworkConfig;
20 |
21 | constructor(network: NetworkConfig) {
22 | this.logger = new Logger(`EthereumProvider:${network.name}`);
23 | this.network = network;
24 | this.chainId = network.chainId;
25 | this.provider = new ethers.JsonRpcProvider(network.rpcUrl);
26 | }
27 |
28 | public async connect(): Promise {
29 | try {
30 | await this.provider.getNetwork();
31 | this.logger.info('Connected to network', {
32 | chainId: this.chainId,
33 | name: this.network.name
34 | });
35 | } catch (error) {
36 | this.logger.error('Failed to connect to network:', error);
37 | throw error;
38 | }
39 | }
40 |
41 | public async disconnect(): Promise {
42 | // Clean up any subscriptions or connections
43 | this.provider.removeAllListeners();
44 | }
45 |
46 | public async getBalance(address: string): Promise {
47 | return await this.provider.getBalance(address);
48 | }
49 |
50 | public async getBlock(blockHashOrNumber: string | number): Promise {
51 | return await this.provider.getBlock(blockHashOrNumber);
52 | }
53 |
54 | public async getTransaction(hash: string): Promise {
55 | const tx = await this.provider.getTransaction(hash);
56 | if (!tx) throw new Error(`Transaction not found: ${hash}`);
57 |
58 | const receipt = await tx.wait();
59 |
60 | return {
61 | hash: tx.hash,
62 | from: tx.from,
63 | to: tx.to!,
64 | value: tx.value,
65 | gasLimit: tx.gasLimit,
66 | gasPrice: tx.gasPrice || 0,
67 | nonce: tx.nonce,
68 | data: tx.data,
69 | chainId: tx.chainId,
70 | status: receipt ? (receipt.status ? 'confirmed' : 'failed') : 'pending',
71 | receipt: receipt ? {
72 | blockNumber: receipt.blockNumber,
73 | blockHash: receipt.blockHash,
74 | transactionIndex: receipt.index,
75 | status: receipt.status === 1,
76 | gasUsed: receipt.gasUsed,
77 | effectiveGasPrice: receipt.gasPrice,
78 | logs: receipt.logs
79 | } : undefined
80 | };
81 | }
82 |
83 | public async getTransactionCount(address: string): Promise {
84 | return await this.provider.getTransactionCount(address);
85 | }
86 |
87 | public async sendTransaction(config: TransactionConfig): Promise {
88 | if (!this.signer) {
89 | throw new Error('No signer available');
90 | }
91 |
92 | const tx = await this.signer.sendTransaction({
93 | to: config.to,
94 | data: config.data,
95 | value: config.value,
96 | gasLimit: config.gasLimit,
97 | gasPrice: config.gasPrice,
98 | maxFeePerGas: config.maxFeePerGas,
99 | maxPriorityFeePerGas: config.maxPriorityFeePerGas,
100 | nonce: config.nonce
101 | });
102 |
103 | return this.getTransaction(tx.hash);
104 | }
105 |
106 | public async estimateGas(config: TransactionConfig): Promise {
107 | return await this.provider.estimateGas({
108 | to: config.to,
109 | data: config.data,
110 | value: config.value
111 | });
112 | }
113 |
114 | public on(event: string | EventFilter, listener: (log: EventLog) => void): void {
115 | if (typeof event === 'string') {
116 | this.provider.on(event, listener);
117 | } else {
118 | this.provider.on(event, listener);
119 | }
120 | }
121 |
122 | public off(event: string | EventFilter, listener: (log: EventLog) => void): void {
123 | if (typeof event === 'string') {
124 | this.provider.off(event, listener);
125 | } else {
126 | this.provider.off(event, listener);
127 | }
128 | }
129 |
130 | public async call(contract: ContractConfig, method: string, args: any[]): Promise {
131 | const ethersContract = new ethers.Contract(
132 | contract.address,
133 | contract.abi,
134 | this.provider
135 | );
136 |
137 | return await ethersContract[method](...args);
138 | }
139 |
140 | public async estimateContractGas(
141 | contract: ContractConfig,
142 | method: string,
143 | args: any[]
144 | ): Promise {
145 | const ethersContract = new ethers.Contract(
146 | contract.address,
147 | contract.abi,
148 | this.provider
149 | );
150 |
151 | return await ethersContract[method].estimateGas(...args);
152 | }
153 |
154 | public setSigner(signer: ethers.Signer): void {
155 | this.signer = signer;
156 | }
157 |
158 | public getSigner(): ethers.Signer | undefined {
159 | return this.signer;
160 | }
161 | }
--------------------------------------------------------------------------------
/packages/blockchain/src/types.ts:
--------------------------------------------------------------------------------
1 | import { BigNumberish } from 'ethers';
2 |
3 | export interface NetworkConfig {
4 | chainId: number;
5 | name: string;
6 | rpcUrl: string;
7 | explorerUrl?: string;
8 | nativeCurrency: {
9 | name: string;
10 | symbol: string;
11 | decimals: number;
12 | };
13 | }
14 |
15 | export interface ContractConfig {
16 | address: string;
17 | abi: any[];
18 | name?: string;
19 | version?: string;
20 | }
21 |
22 | export interface TransactionConfig {
23 | to: string;
24 | data?: string;
25 | value?: BigNumberish;
26 | gasLimit?: BigNumberish;
27 | gasPrice?: BigNumberish;
28 | maxFeePerGas?: BigNumberish;
29 | maxPriorityFeePerGas?: BigNumberish;
30 | nonce?: number;
31 | }
32 |
33 | export interface TransactionResponse {
34 | hash: string;
35 | from: string;
36 | to: string;
37 | value: BigNumberish;
38 | gasLimit: BigNumberish;
39 | gasPrice: BigNumberish;
40 | nonce: number;
41 | data: string;
42 | chainId: number;
43 | timestamp?: number;
44 | status?: 'pending' | 'confirmed' | 'failed';
45 | receipt?: {
46 | blockNumber: number;
47 | blockHash: string;
48 | transactionIndex: number;
49 | status: boolean;
50 | gasUsed: BigNumberish;
51 | effectiveGasPrice: BigNumberish;
52 | logs: any[];
53 | };
54 | }
55 |
56 | export interface EventFilter {
57 | address?: string;
58 | topics?: (string | string[])[];
59 | fromBlock?: number | string;
60 | toBlock?: number | string;
61 | }
62 |
63 | export interface EventLog {
64 | address: string;
65 | topics: string[];
66 | data: string;
67 | blockNumber: number;
68 | blockHash: string;
69 | transactionHash: string;
70 | transactionIndex: number;
71 | logIndex: number;
72 | removed: boolean;
73 | }
74 |
75 | export interface BlockchainProvider {
76 | readonly chainId: number;
77 | readonly network: NetworkConfig;
78 |
79 | connect(): Promise;
80 | disconnect(): Promise;
81 |
82 | getBalance(address: string): Promise;
83 | getBlock(blockHashOrNumber: string | number): Promise;
84 | getTransaction(hash: string): Promise;
85 | getTransactionCount(address: string): Promise;
86 |
87 | sendTransaction(config: TransactionConfig): Promise;
88 | estimateGas(config: TransactionConfig): Promise;
89 |
90 | on(event: string | EventFilter, listener: (log: EventLog) => void): void;
91 | off(event: string | EventFilter, listener: (log: EventLog) => void): void;
92 |
93 | call(contract: ContractConfig, method: string, args: any[]): Promise;
94 | estimateContractGas(contract: ContractConfig, method: string, args: any[]): Promise;
95 | }
--------------------------------------------------------------------------------
/packages/context/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@orbit/context",
3 | "version": "0.1.0",
4 | "description": "Responsive Context Handler for O.R.B.I.T Framework",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "scripts": {
8 | "build": "tsc",
9 | "test": "jest",
10 | "lint": "eslint src/**/*.ts"
11 | },
12 | "dependencies": {
13 | "@orbit/core": "^0.1.0",
14 | "ioredis": "^5.3.2",
15 | "node-cache": "^5.1.2",
16 | "rxjs": "^7.8.1",
17 | "winston": "^3.11.0"
18 | },
19 | "devDependencies": {
20 | "@types/node": "^22.10.6",
21 | "@types/jest": "^29.5.14",
22 | "typescript": "^5.7.3",
23 | "jest": "^29.7.0",
24 | "ts-jest": "^29.2.5"
25 | },
26 | "repository": {
27 | "type": "git",
28 | "url": "git+https://github.com/metros-org/orbit-framework.git",
29 | "directory": "packages/context"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/context/src/context-provider.ts:
--------------------------------------------------------------------------------
1 | import Redis from 'ioredis';
2 | import NodeCache from 'node-cache';
3 | import { Subject } from 'rxjs';
4 | import { Logger } from '@orbit/core';
5 | import { ContextProvider, TaskMemory } from './types';
6 |
7 | export interface ContextProviderConfig {
8 | redis?: {
9 | host: string;
10 | port: number;
11 | password?: string;
12 | };
13 | ttl?: number;
14 | checkPeriod?: number;
15 | }
16 |
17 | export class DefaultContextProvider implements ContextProvider {
18 | private readonly logger: Logger;
19 | private readonly redis?: Redis;
20 | private readonly cache: NodeCache;
21 | private readonly events: Map>;
22 | private readonly prefix: string = 'orbit:context:';
23 |
24 | constructor(config: ContextProviderConfig = {}) {
25 | this.logger = new Logger('ContextProvider');
26 | this.events = new Map();
27 |
28 | // Initialize Redis if configured
29 | if (config.redis) {
30 | this.redis = new Redis({
31 | host: config.redis.host,
32 | port: config.redis.port,
33 | password: config.redis.password,
34 | retryStrategy: (times) => Math.min(times * 50, 2000)
35 | });
36 |
37 | this.redis.on('error', (error) => {
38 | this.logger.error('Redis connection error:', error);
39 | });
40 | }
41 |
42 | // Initialize local cache
43 | this.cache = new NodeCache({
44 | stdTTL: config.ttl || 3600,
45 | checkperiod: config.checkPeriod || 600,
46 | useClones: false
47 | });
48 | }
49 |
50 | public async get(key: string): Promise {
51 | const fullKey = this.getFullKey(key);
52 |
53 | // Try local cache first
54 | const localValue = this.cache.get(fullKey);
55 | if (localValue !== undefined) {
56 | return localValue;
57 | }
58 |
59 | // Try Redis if available
60 | if (this.redis) {
61 | try {
62 | const value = await this.redis.get(fullKey);
63 | if (value) {
64 | const parsed = JSON.parse(value);
65 | this.cache.set(fullKey, parsed);
66 | return parsed;
67 | }
68 | } catch (error) {
69 | this.logger.error(`Error getting key ${key} from Redis:`, error);
70 | }
71 | }
72 |
73 | return null;
74 | }
75 |
76 | public async set(key: string, value: any): Promise {
77 | const fullKey = this.getFullKey(key);
78 | const serialized = JSON.stringify(value);
79 |
80 | // Set in local cache
81 | this.cache.set(fullKey, value);
82 |
83 | // Set in Redis if available
84 | if (this.redis) {
85 | try {
86 | await this.redis.set(fullKey, serialized);
87 | } catch (error) {
88 | this.logger.error(`Error setting key ${key} in Redis:`, error);
89 | }
90 | }
91 | }
92 |
93 | public async delete(key: string): Promise {
94 | const fullKey = this.getFullKey(key);
95 |
96 | // Delete from local cache
97 | this.cache.del(fullKey);
98 |
99 | // Delete from Redis if available
100 | if (this.redis) {
101 | try {
102 | await this.redis.del(fullKey);
103 | } catch (error) {
104 | this.logger.error(`Error deleting key ${key} from Redis:`, error);
105 | }
106 | }
107 | }
108 |
109 | public async clear(): Promise {
110 | // Clear local cache
111 | this.cache.flushAll();
112 |
113 | // Clear Redis if available
114 | if (this.redis) {
115 | try {
116 | const keys = await this.redis.keys(`${this.prefix}*`);
117 | if (keys.length > 0) {
118 | await this.redis.del(...keys);
119 | }
120 | } catch (error) {
121 | this.logger.error('Error clearing Redis:', error);
122 | }
123 | }
124 | }
125 |
126 | public async getMemory(taskId: string): Promise {
127 | const memory = await this.get(`memory:${taskId}`);
128 | if (!memory) {
129 | return {
130 | shortTerm: {},
131 | longTerm: {},
132 | episodic: []
133 | };
134 | }
135 | return memory;
136 | }
137 |
138 | public async updateMemory(taskId: string, memory: Partial): Promise {
139 | const currentMemory = await this.getMemory(taskId);
140 | const updatedMemory = {
141 | ...currentMemory,
142 | ...memory,
143 | episodic: [
144 | ...currentMemory.episodic,
145 | ...(memory.episodic || [])
146 | ]
147 | };
148 | await this.set(`memory:${taskId}`, updatedMemory);
149 | }
150 |
151 | public subscribe(event: string, callback: (data: any) => void): void {
152 | let subject = this.events.get(event);
153 | if (!subject) {
154 | subject = new Subject();
155 | this.events.set(event, subject);
156 | }
157 | subject.subscribe(callback);
158 | }
159 |
160 | public unsubscribe(event: string, callback: (data: any) => void): void {
161 | const subject = this.events.get(event);
162 | if (subject) {
163 | // Note: This is a simplified unsubscribe. In a real implementation,
164 | // you'd want to keep track of individual subscriptions.
165 | subject.unsubscribe();
166 | this.events.delete(event);
167 | }
168 | }
169 |
170 | private getFullKey(key: string): string {
171 | return `${this.prefix}${key}`;
172 | }
173 |
174 | public async dispose(): Promise {
175 | // Clear all subscriptions
176 | this.events.forEach(subject => subject.complete());
177 | this.events.clear();
178 |
179 | // Disconnect Redis if connected
180 | if (this.redis) {
181 | this.redis.disconnect();
182 | }
183 | }
184 | }
--------------------------------------------------------------------------------
/packages/context/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types';
2 | export * from './context-provider';
--------------------------------------------------------------------------------
/packages/context/src/types.ts:
--------------------------------------------------------------------------------
1 | export interface TaskMemory {
2 | shortTerm: Record;
3 | longTerm: Record;
4 | episodic: TaskMemoryEpisode[];
5 | }
6 |
7 | export interface TaskMemoryEpisode {
8 | timestamp: Date;
9 | type: 'input' | 'output' | 'error' | 'event';
10 | content: any;
11 | metadata?: Record;
12 | }
13 |
14 | export interface ContextProvider {
15 | get(key: string): Promise;
16 | set(key: string, value: any): Promise;
17 | delete(key: string): Promise;
18 | clear(): Promise;
19 |
20 | getMemory(taskId: string): Promise;
21 | updateMemory(taskId: string, memory: Partial): Promise;
22 |
23 | subscribe(event: string, callback: (data: any) => void): void;
24 | unsubscribe(event: string, callback: (data: any) => void): void;
25 |
26 | dispose(): Promise;
27 | }
--------------------------------------------------------------------------------
/packages/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@orbit/core",
3 | "version": "0.1.0",
4 | "description": "Core functionality for O.R.B.I.T Framework",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "scripts": {
8 | "build": "tsc",
9 | "test": "jest",
10 | "lint": "eslint src/**/*.ts",
11 | "docs": "typedoc"
12 | },
13 | "dependencies": {
14 | "aws-cdk-lib": "^2.175.1",
15 | "constructs": "^10.4.2",
16 | "zod": "^3.24.1",
17 | "ethers": "^6.11.0",
18 | "axios": "^1.6.7",
19 | "winston": "^3.11.0",
20 | "ioredis": "^5.3.2",
21 | "node-cache": "^5.1.2"
22 | },
23 | "peerDependencies": {
24 | "aws-cdk": "^2.0.0"
25 | },
26 | "devDependencies": {
27 | "@types/node": "^22.10.6",
28 | "@types/jest": "^29.5.14",
29 | "typescript": "^5.7.3",
30 | "jest": "^29.7.0",
31 | "ts-jest": "^29.2.5",
32 | "typedoc": "^0.25.7",
33 | "@typescript-eslint/eslint-plugin": "^6.19.1",
34 | "@typescript-eslint/parser": "^6.19.1"
35 | },
36 | "repository": {
37 | "type": "git",
38 | "url": "git+https://github.com/metros-org/orbit-framework.git",
39 | "directory": "packages/core"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/core/src/agent/base-agent.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'events';
2 | import {
3 | IAgent,
4 | AgentConfig,
5 | AgentCapabilities,
6 | AgentMetrics,
7 | AgentResponse,
8 | AgentExecuteOptions,
9 | Tool
10 | } from '../interfaces';
11 | import { Logger } from '../utils/logger';
12 |
13 | export abstract class BaseAgent extends EventEmitter implements IAgent {
14 | protected readonly logger: Logger;
15 | protected readonly tools: Map;
16 | protected status: 'idle' | 'busy' | 'error' | 'stopped';
17 |
18 | public readonly name: string;
19 | public readonly capabilities: AgentCapabilities;
20 | public readonly metrics: AgentMetrics;
21 |
22 | constructor(config: AgentConfig) {
23 | super();
24 | this.name = config.name;
25 | this.logger = new Logger(`Agent:${this.name}`);
26 | this.tools = new Map();
27 | this.status = 'idle';
28 |
29 | // Initialize metrics
30 | this.metrics = {
31 | totalTasks: 0,
32 | successfulTasks: 0,
33 | failedTasks: 0,
34 | averageResponseTime: 0,
35 | lastActive: new Date()
36 | };
37 |
38 | // Initialize capabilities
39 | this.capabilities = {
40 | canStream: false,
41 | supportedTools: [],
42 | maxConcurrentTasks: 1,
43 | supportedModels: []
44 | };
45 |
46 | // Add tools if provided
47 | if (config.tools) {
48 | config.tools.forEach(tool => this.addTool(tool));
49 | }
50 | }
51 |
52 | abstract initialize(): Promise;
53 | abstract execute(input: string, options?: AgentExecuteOptions): Promise;
54 | abstract stop(): Promise;
55 |
56 | public addTool(tool: Tool): void {
57 | this.tools.set(tool.name, tool);
58 | this.capabilities.supportedTools.push(tool.name);
59 | this.logger.info(`Tool added: ${tool.name}`);
60 | }
61 |
62 | public removeTool(toolName: string): void {
63 | if (this.tools.delete(toolName)) {
64 | this.capabilities.supportedTools = this.capabilities.supportedTools.filter(
65 | name => name !== toolName
66 | );
67 | this.logger.info(`Tool removed: ${toolName}`);
68 | }
69 | }
70 |
71 | public getStatus(): 'idle' | 'busy' | 'error' | 'stopped' {
72 | return this.status;
73 | }
74 |
75 | public getMetrics(): AgentMetrics {
76 | return { ...this.metrics };
77 | }
78 |
79 | protected async useTool(toolName: string, ...args: any[]): Promise {
80 | const tool = this.tools.get(toolName);
81 | if (!tool) {
82 | throw new Error(`Tool not found: ${toolName}`);
83 | }
84 |
85 | try {
86 | if (tool.validate) {
87 | const isValid = await tool.validate(...args);
88 | if (!isValid) {
89 | throw new Error(`Tool validation failed: ${toolName}`);
90 | }
91 | }
92 |
93 | this.logger.debug(`Using tool: ${toolName}`, { args });
94 | const result = await tool.execute(...args);
95 | this.logger.debug(`Tool ${toolName} result:`, { result });
96 | return result;
97 | } catch (error) {
98 | this.logger.error(`Tool ${toolName} error:`, error);
99 | throw error;
100 | }
101 | }
102 |
103 | protected updateMetrics(startTime: number, success: boolean): void {
104 | const duration = Date.now() - startTime;
105 |
106 | (this.metrics as any).totalTasks++;
107 | if (success) {
108 | (this.metrics as any).successfulTasks++;
109 | } else {
110 | (this.metrics as any).failedTasks++;
111 | }
112 |
113 | // Update average response time
114 | const totalTime = this.metrics.averageResponseTime * (this.metrics.totalTasks - 1) + duration;
115 | (this.metrics as any).averageResponseTime = totalTime / this.metrics.totalTasks;
116 | (this.metrics as any).lastActive = new Date();
117 | }
118 | }
--------------------------------------------------------------------------------
/packages/core/src/agent/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types';
2 | export * from './base-agent';
--------------------------------------------------------------------------------
/packages/core/src/agent/types.ts:
--------------------------------------------------------------------------------
1 | export interface AgentConfig {
2 | name: string;
3 | modelId: string;
4 | memory?: boolean;
5 | tools?: string[];
6 | maxTokens?: number;
7 | temperature?: number;
8 | }
9 |
10 | export interface AgentOptions {
11 | name: string;
12 | modelId: string;
13 | memory?: boolean;
14 | tools?: string[];
15 | }
16 |
17 | export interface AgentResponse {
18 | output: string;
19 | metadata?: Record;
20 | usage?: {
21 | promptTokens: number;
22 | completionTokens: number;
23 | totalTokens: number;
24 | };
25 | }
26 |
27 | export interface AgentContext {
28 | memory?: any[];
29 | tools?: Map;
30 | variables?: Record;
31 | }
--------------------------------------------------------------------------------
/packages/core/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './stack';
2 | export * from './agent';
3 | export * from './utils/logger';
4 | export * from './utils/config';
5 | export * from './orchestrator';
--------------------------------------------------------------------------------
/packages/core/src/interfaces/agent.interface.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'events';
2 | import { TaskContext } from './context.interface';
3 | import { Tool } from './tool.interface';
4 |
5 | export interface AgentConfig {
6 | name: string;
7 | description?: string;
8 | modelId?: string;
9 | maxTokens?: number;
10 | temperature?: number;
11 | tools?: Tool[];
12 | metadata?: Record;
13 | }
14 |
15 | export interface AgentCapabilities {
16 | canStream: boolean;
17 | supportedTools: string[];
18 | maxConcurrentTasks: number;
19 | supportedModels: string[];
20 | }
21 |
22 | export interface AgentMetrics {
23 | totalTasks: number;
24 | successfulTasks: number;
25 | failedTasks: number;
26 | averageResponseTime: number;
27 | lastActive: Date;
28 | }
29 |
30 | export interface AgentResponse {
31 | output: T;
32 | metadata?: {
33 | usage?: {
34 | promptTokens: number;
35 | completionTokens: number;
36 | totalTokens: number;
37 | };
38 | latency?: number;
39 | model?: string;
40 | finishReason?: string;
41 | };
42 | }
43 |
44 | export interface AgentExecuteOptions {
45 | context?: TaskContext;
46 | timeout?: number;
47 | priority?: number;
48 | retryStrategy?: {
49 | maxAttempts: number;
50 | backoff: 'linear' | 'exponential';
51 | initialDelay: number;
52 | };
53 | }
54 |
55 | export interface IAgent extends EventEmitter {
56 | readonly name: string;
57 | readonly capabilities: AgentCapabilities;
58 | readonly metrics: AgentMetrics;
59 |
60 | initialize(): Promise;
61 | execute(input: string, options?: AgentExecuteOptions): Promise;
62 | stop(): Promise;
63 |
64 | addTool(tool: Tool): void;
65 | removeTool(toolName: string): void;
66 |
67 | getStatus(): 'idle' | 'busy' | 'error' | 'stopped';
68 | getMetrics(): AgentMetrics;
69 | }
--------------------------------------------------------------------------------
/packages/core/src/interfaces/context.interface.ts:
--------------------------------------------------------------------------------
1 | export interface TaskContext {
2 | conversationId?: string;
3 | parentTaskId?: string;
4 | variables: Record;
5 | memory?: TaskMemory;
6 | metadata?: Record;
7 | }
8 |
9 | export interface TaskMemory {
10 | shortTerm: Record;
11 | longTerm: Record;
12 | episodic: TaskMemoryEpisode[];
13 | }
14 |
15 | export interface TaskMemoryEpisode {
16 | timestamp: Date;
17 | type: 'input' | 'output' | 'error' | 'event';
18 | content: any;
19 | metadata?: Record;
20 | }
21 |
22 | export interface ContextProvider {
23 | get(key: string): Promise;
24 | set(key: string, value: any): Promise;
25 | delete(key: string): Promise;
26 | clear(): Promise;
27 |
28 | getMemory(taskId: string): Promise;
29 | updateMemory(taskId: string, memory: Partial): Promise;
30 |
31 | subscribe(event: string, callback: (data: any) => void): void;
32 | unsubscribe(event: string, callback: (data: any) => void): void;
33 | }
--------------------------------------------------------------------------------
/packages/core/src/interfaces/index.ts:
--------------------------------------------------------------------------------
1 | export * from './agent.interface';
2 | export * from './context.interface';
3 | export * from './tool.interface';
4 | export * from './orchestrator.interface';
--------------------------------------------------------------------------------
/packages/core/src/interfaces/orchestrator.interface.ts:
--------------------------------------------------------------------------------
1 | import { IAgent } from './agent.interface';
2 | import { Tool } from './tool.interface';
3 | import { TaskContext } from './context.interface';
4 |
5 | export interface OrchestratorConfig {
6 | agents?: IAgent[];
7 | tools?: Tool[];
8 | maxConcurrentTasks?: number;
9 | defaultTimeout?: number;
10 | retryStrategy?: RetryStrategy;
11 | }
12 |
13 | export interface RetryStrategy {
14 | maxAttempts: number;
15 | backoff: 'linear' | 'exponential';
16 | initialDelay: number;
17 | }
18 |
19 | export interface TaskDefinition {
20 | id: string;
21 | type: string;
22 | input: any;
23 | context?: TaskContext;
24 | agentPreference?: string[];
25 | priority?: number;
26 | timeout?: number;
27 | retryStrategy?: RetryStrategy;
28 | }
29 |
30 | export interface TaskResult {
31 | taskId: string;
32 | status: 'success' | 'failure' | 'timeout' | 'cancelled';
33 | output?: any;
34 | error?: Error;
35 | metrics: {
36 | startTime: Date;
37 | endTime: Date;
38 | duration: number;
39 | retries: number;
40 | agentName: string;
41 | };
42 | }
43 |
44 | export interface IOrchestratorMetrics {
45 | totalTasks: number;
46 | activeTasks: number;
47 | completedTasks: number;
48 | failedTasks: number;
49 | averageTaskDuration: number;
50 | agentMetrics: Record;
55 | }
56 |
57 | export interface IOrchestrator {
58 | readonly agents: Map;
59 | readonly tools: Map;
60 | readonly metrics: IOrchestratorMetrics;
61 |
62 | initialize(): Promise;
63 | shutdown(): Promise;
64 |
65 | addAgent(agent: IAgent): void;
66 | removeAgent(agentName: string): void;
67 |
68 | addTool(tool: Tool): void;
69 | removeTool(toolName: string): void;
70 |
71 | submitTask(task: TaskDefinition): Promise;
72 | cancelTask(taskId: string): Promise;
73 |
74 | getTaskStatus(taskId: string): Promise;
75 | getMetrics(): IOrchestratorMetrics;
76 | }
--------------------------------------------------------------------------------
/packages/core/src/interfaces/tool.interface.ts:
--------------------------------------------------------------------------------
1 | export interface Tool {
2 | name: string;
3 | description: string;
4 | version: string;
5 | category?: string;
6 | metadata?: Record;
7 |
8 | execute(...args: any[]): Promise;
9 | validate?(...args: any[]): Promise;
10 |
11 | getSchema(): ToolSchema;
12 | getMetadata(): Record;
13 | }
14 |
15 | export interface ToolSchema {
16 | name: string;
17 | description: string;
18 | parameters: {
19 | type: 'object';
20 | properties: Record;
21 | required?: string[];
22 | };
23 | returns: {
24 | type: string;
25 | description: string;
26 | };
27 | }
28 |
29 | export interface ParameterSchema {
30 | type: string;
31 | description: string;
32 | enum?: string[];
33 | minimum?: number;
34 | maximum?: number;
35 | pattern?: string;
36 | format?: string;
37 | items?: ParameterSchema;
38 | properties?: Record;
39 | required?: string[];
40 | }
--------------------------------------------------------------------------------
/packages/core/src/orchestrator/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types';
2 | export * from './orchestrator';
--------------------------------------------------------------------------------
/packages/core/src/orchestrator/orchestrator.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'events';
2 | import {
3 | IOrchestrator,
4 | OrchestratorConfig,
5 | TaskDefinition,
6 | TaskResult,
7 | IOrchestratorMetrics,
8 | IAgent,
9 | Tool,
10 | AgentResponse
11 | } from '../interfaces';
12 | import { Logger } from '../utils/logger';
13 |
14 | export class Orchestrator extends EventEmitter implements IOrchestrator {
15 | private readonly logger: Logger;
16 | private readonly maxConcurrentTasks: number;
17 | private readonly defaultTimeout: number;
18 | private readonly activeTasks: Map;
19 | private readonly taskResults: Map;
20 |
21 | public readonly agents: Map;
22 | public readonly tools: Map;
23 | public readonly metrics: IOrchestratorMetrics;
24 |
25 | constructor(config: OrchestratorConfig = {}) {
26 | super();
27 | this.logger = new Logger('Orchestrator');
28 | this.agents = new Map();
29 | this.tools = new Map();
30 | this.activeTasks = new Map();
31 | this.taskResults = new Map();
32 |
33 | this.maxConcurrentTasks = config.maxConcurrentTasks || 10;
34 | this.defaultTimeout = config.defaultTimeout || 30000;
35 |
36 | // Initialize metrics
37 | this.metrics = {
38 | totalTasks: 0,
39 | activeTasks: 0,
40 | completedTasks: 0,
41 | failedTasks: 0,
42 | averageTaskDuration: 0,
43 | agentMetrics: {}
44 | };
45 |
46 | // Add agents if provided
47 | if (config.agents) {
48 | config.agents.forEach(agent => this.addAgent(agent));
49 | }
50 |
51 | // Add tools if provided
52 | if (config.tools) {
53 | config.tools.forEach(tool => this.addTool(tool));
54 | }
55 | }
56 |
57 | public async initialize(): Promise {
58 | this.logger.info('Initializing orchestrator');
59 |
60 | // Initialize all agents
61 | const initPromises = Array.from(this.agents.values()).map(agent => {
62 | return agent.initialize().catch(error => {
63 | this.logger.error(`Failed to initialize agent ${agent.name}:`, error);
64 | throw error;
65 | });
66 | });
67 |
68 | await Promise.all(initPromises);
69 | this.logger.info('Orchestrator initialized');
70 | }
71 |
72 | public async shutdown(): Promise {
73 | this.logger.info('Shutting down orchestrator');
74 |
75 | // Stop all active tasks
76 | for (const taskId of this.activeTasks.keys()) {
77 | await this.cancelTask(taskId);
78 | }
79 |
80 | // Stop all agents
81 | const stopPromises = Array.from(this.agents.values()).map(agent => {
82 | return agent.stop().catch(error => {
83 | this.logger.error(`Failed to stop agent ${agent.name}:`, error);
84 | });
85 | });
86 |
87 | await Promise.all(stopPromises);
88 | this.logger.info('Orchestrator shut down');
89 | }
90 |
91 | public addAgent(agent: IAgent): void {
92 | this.agents.set(agent.name, agent);
93 | this.metrics.agentMetrics[agent.name] = {
94 | totalTasks: 0,
95 | successRate: 0,
96 | averageResponseTime: 0
97 | };
98 | this.logger.info(`Agent added: ${agent.name}`);
99 | }
100 |
101 | public removeAgent(agentName: string): void {
102 | const agent = this.agents.get(agentName);
103 | if (agent) {
104 | agent.stop().catch(error => {
105 | this.logger.error(`Error stopping agent ${agentName}:`, error);
106 | });
107 | this.agents.delete(agentName);
108 | delete this.metrics.agentMetrics[agentName];
109 | this.logger.info(`Agent removed: ${agentName}`);
110 | }
111 | }
112 |
113 | public addTool(tool: Tool): void {
114 | this.tools.set(tool.name, tool);
115 | this.logger.info(`Tool added: ${tool.name}`);
116 | }
117 |
118 | public removeTool(toolName: string): void {
119 | if (this.tools.delete(toolName)) {
120 | this.logger.info(`Tool removed: ${toolName}`);
121 | }
122 | }
123 |
124 | public async submitTask(task: TaskDefinition): Promise {
125 | if (this.activeTasks.size >= this.maxConcurrentTasks) {
126 | throw new Error('Maximum concurrent tasks reached');
127 | }
128 |
129 | this.logger.info(`Submitting task: ${task.id}`, { task });
130 | this.activeTasks.set(task.id, task);
131 | this.metrics.activeTasks++;
132 | this.metrics.totalTasks++;
133 |
134 | try {
135 | const agent = await this.selectAgent(task);
136 | const startTime = Date.now();
137 |
138 | const result = await Promise.race([
139 | agent.execute(task.input, {
140 | context: task.context,
141 | timeout: task.timeout || this.defaultTimeout,
142 | priority: task.priority,
143 | retryStrategy: task.retryStrategy
144 | }),
145 | new Promise((_, reject) =>
146 | setTimeout(() => reject(new Error('Task timeout')),
147 | task.timeout || this.defaultTimeout)
148 | )
149 | ]);
150 |
151 | const endTime = Date.now();
152 | const duration = endTime - startTime;
153 |
154 | const taskResult: TaskResult = {
155 | taskId: task.id,
156 | status: 'success',
157 | output: result.output,
158 | metrics: {
159 | startTime: new Date(startTime),
160 | endTime: new Date(endTime),
161 | duration,
162 | retries: 0,
163 | agentName: agent.name
164 | }
165 | };
166 |
167 | this.updateMetrics(agent.name, duration, true);
168 | this.taskResults.set(task.id, taskResult);
169 | return taskResult;
170 |
171 | } catch (error: unknown) {
172 | const taskResult: TaskResult = {
173 | taskId: task.id,
174 | status: error instanceof Error && error.message === 'Task timeout' ? 'timeout' : 'failure',
175 | error: error instanceof Error ? error : new Error(String(error)),
176 | metrics: {
177 | startTime: new Date(),
178 | endTime: new Date(),
179 | duration: 0,
180 | retries: 0,
181 | agentName: ''
182 | }
183 | };
184 |
185 | this.updateMetrics('', 0, false);
186 | this.taskResults.set(task.id, taskResult);
187 | throw error;
188 |
189 | } finally {
190 | this.activeTasks.delete(task.id);
191 | this.metrics.activeTasks--;
192 | }
193 | }
194 |
195 | public async cancelTask(taskId: string): Promise {
196 | const task = this.activeTasks.get(taskId);
197 | if (!task) {
198 | throw new Error(`Task not found: ${taskId}`);
199 | }
200 |
201 | this.logger.info(`Cancelling task: ${taskId}`);
202 | this.activeTasks.delete(taskId);
203 | this.metrics.activeTasks--;
204 |
205 | const taskResult: TaskResult = {
206 | taskId,
207 | status: 'cancelled',
208 | metrics: {
209 | startTime: new Date(),
210 | endTime: new Date(),
211 | duration: 0,
212 | retries: 0,
213 | agentName: ''
214 | }
215 | };
216 |
217 | this.taskResults.set(taskId, taskResult);
218 | }
219 |
220 | public async getTaskStatus(taskId: string): Promise {
221 | return this.taskResults.get(taskId) || null;
222 | }
223 |
224 | public getMetrics(): IOrchestratorMetrics {
225 | return { ...this.metrics };
226 | }
227 |
228 | private async selectAgent(task: TaskDefinition): Promise {
229 | const availableAgents = Array.from(this.agents.values()).filter(
230 | agent => agent.getStatus() === 'idle'
231 | );
232 |
233 | if (availableAgents.length === 0) {
234 | throw new Error('No available agents');
235 | }
236 |
237 | if (task.agentPreference) {
238 | for (const preferredName of task.agentPreference) {
239 | const agent = availableAgents.find(a => a.name === preferredName);
240 | if (agent) return agent;
241 | }
242 | }
243 |
244 | // Simple round-robin selection for now
245 | // TODO: Implement more sophisticated agent selection
246 | return availableAgents[0];
247 | }
248 |
249 | private updateMetrics(agentName: string, duration: number, success: boolean): void {
250 | if (success) {
251 | this.metrics.completedTasks++;
252 | } else {
253 | this.metrics.failedTasks++;
254 | }
255 |
256 | // Update average task duration
257 | const totalDuration = this.metrics.averageTaskDuration * (this.metrics.totalTasks - 1) + duration;
258 | this.metrics.averageTaskDuration = totalDuration / this.metrics.totalTasks;
259 |
260 | // Update agent metrics
261 | if (agentName && this.metrics.agentMetrics[agentName]) {
262 | const agentMetrics = this.metrics.agentMetrics[agentName];
263 | agentMetrics.totalTasks++;
264 | agentMetrics.successRate = (agentMetrics.successRate * (agentMetrics.totalTasks - 1) + (success ? 1 : 0)) / agentMetrics.totalTasks;
265 | agentMetrics.averageResponseTime = (agentMetrics.averageResponseTime * (agentMetrics.totalTasks - 1) + duration) / agentMetrics.totalTasks;
266 | }
267 | }
268 | }
--------------------------------------------------------------------------------
/packages/core/src/orchestrator/types.ts:
--------------------------------------------------------------------------------
1 | export interface OrchestratorConfig {
2 | maxConcurrent?: number;
3 | timeout?: number;
4 | retryAttempts?: number;
5 | retryDelay?: number;
6 | }
7 |
8 | export interface TaskConfig {
9 | id: string;
10 | agents: string[];
11 | input: string;
12 | priority?: number;
13 | metadata?: Record;
14 | dependencies?: string[];
15 | }
16 |
17 | export interface TaskResult {
18 | taskId: string;
19 | status: 'success' | 'failure' | 'timeout';
20 | results: Array<{
21 | agentName: string;
22 | output: string;
23 | error?: string;
24 | duration?: number;
25 | }>;
26 | metadata?: Record;
27 | timestamp: number;
28 | }
29 |
30 | export interface TaskProgress {
31 | taskId: string;
32 | status: 'pending' | 'running' | 'completed' | 'failed';
33 | progress: number;
34 | currentAgent?: string;
35 | startTime: number;
36 | lastUpdate: number;
37 | }
--------------------------------------------------------------------------------
/packages/core/src/stack/constructs/agent.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from 'aws-cdk-lib';
2 | import * as lambda from 'aws-cdk-lib/aws-lambda';
3 | import * as iam from 'aws-cdk-lib/aws-iam';
4 | import { Construct } from 'constructs';
5 | import { AgentConfig } from '../../agent';
6 |
7 | export class AgentConstruct extends Construct {
8 | public readonly handler: lambda.Function;
9 |
10 | constructor(scope: Construct, id: string, config: AgentConfig) {
11 | super(scope, id);
12 |
13 | // Create Lambda function for agent
14 | this.handler = new lambda.Function(this, 'Handler', {
15 | runtime: lambda.Runtime.NODEJS_18_X,
16 | handler: 'index.handler',
17 | code: lambda.Code.fromAsset('lambda/agent'),
18 | timeout: cdk.Duration.minutes(15),
19 | memorySize: 1024,
20 | environment: {
21 | AGENT_NAME: config.name,
22 | MODEL_ID: config.modelId,
23 | MEMORY_ENABLED: config.memory?.toString() || 'false',
24 | },
25 | });
26 |
27 | // Add Bedrock permissions
28 | this.handler.addToRolePolicy(new iam.PolicyStatement({
29 | actions: ['bedrock:InvokeModel'],
30 | resources: ['*'], // You might want to restrict this
31 | }));
32 | }
33 | }
--------------------------------------------------------------------------------
/packages/core/src/stack/constructs/api.ts:
--------------------------------------------------------------------------------
1 | import * as apigateway from 'aws-cdk-lib/aws-apigateway';
2 | import * as lambda from 'aws-cdk-lib/aws-lambda';
3 | import { Construct } from 'constructs';
4 | import { ApiConfig } from '../types';
5 |
6 | export class Api extends Construct {
7 | public readonly api: apigateway.RestApi;
8 |
9 | constructor(scope: Construct, id: string, config: ApiConfig = {}) {
10 | super(scope, id);
11 |
12 | this.api = new apigateway.RestApi(this, 'Api', {
13 | restApiName: 'Maiga Framework API',
14 | description: 'API for Maiga Framework',
15 | defaultCorsPreflightOptions: config.cors ? {
16 | allowOrigins: apigateway.Cors.ALL_ORIGINS,
17 | allowMethods: apigateway.Cors.ALL_METHODS,
18 | } : undefined,
19 | apiKeySourceType: config.apiKey
20 | ? apigateway.ApiKeySourceType.HEADER
21 | : undefined,
22 | });
23 |
24 | // Add usage plan if API key is enabled
25 | if (config.apiKey) {
26 | const plan = this.api.addUsagePlan('UsagePlan', {
27 | name: 'Standard',
28 | throttle: {
29 | rateLimit: 10,
30 | burstLimit: 20,
31 | },
32 | });
33 |
34 | const key = this.api.addApiKey('ApiKey');
35 | plan.addApiKey(key);
36 | }
37 | }
38 |
39 | public addLambdaRoute(
40 | path: string,
41 | handler: lambda.Function,
42 | methods: string[] = ['GET']
43 | ) {
44 | const resource = this.api.root.resourceForPath(path);
45 |
46 | methods.forEach(method => {
47 | resource.addMethod(
48 | method,
49 | new apigateway.LambdaIntegration(handler)
50 | );
51 | });
52 | }
53 | }
--------------------------------------------------------------------------------
/packages/core/src/stack/constructs/database.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from 'aws-cdk-lib';
2 | import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
3 | import { Construct } from 'constructs';
4 | import { DatabaseConfig } from '../types';
5 |
6 | export class Database extends Construct {
7 | public readonly table: dynamodb.Table;
8 |
9 | constructor(scope: Construct, id: string, config: DatabaseConfig = {}) {
10 | super(scope, id);
11 |
12 | this.table = new dynamodb.Table(this, 'Table', {
13 | partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
14 | sortKey: { name: 'sk', type: dynamodb.AttributeType.STRING },
15 | billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
16 | timeToLiveAttribute: 'ttl',
17 | tableName: config.tableName,
18 | removalPolicy: config.deletionProtection
19 | ? cdk.RemovalPolicy.RETAIN
20 | : cdk.RemovalPolicy.DESTROY,
21 | });
22 |
23 | // Add GSIs
24 | this.table.addGlobalSecondaryIndex({
25 | indexName: 'GSI1',
26 | partitionKey: { name: 'GSI1PK', type: dynamodb.AttributeType.STRING },
27 | sortKey: { name: 'GSI1SK', type: dynamodb.AttributeType.STRING },
28 | });
29 | }
30 | }
--------------------------------------------------------------------------------
/packages/core/src/stack/index.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from 'aws-cdk-lib';
2 | import { Construct } from 'constructs';
3 | import { MaigaConfig } from './types';
4 | import { Database } from './constructs/database';
5 | import { AgentConstruct } from './constructs/agent';
6 | import { Api } from './constructs/api';
7 |
8 | export class MaigaStack extends cdk.Stack {
9 | public readonly database: Database;
10 | public readonly api: Api;
11 | private readonly agents: Map;
12 |
13 | constructor(scope: Construct, id: string, config: MaigaConfig) {
14 | super(scope, id, {
15 | env: {
16 | region: config.region || process.env.CDK_DEFAULT_REGION,
17 | },
18 | });
19 |
20 | // Initialize core infrastructure
21 | this.database = new Database(this, 'Database', {
22 | deletionProtection: true,
23 | });
24 |
25 | this.api = new Api(this, 'Api', {
26 | cors: true,
27 | apiKey: true,
28 | });
29 |
30 | // Initialize agents
31 | this.agents = new Map();
32 | if (config.agents) {
33 | config.agents.forEach(agentConfig => {
34 | const agent = new AgentConstruct(this, `Agent-${agentConfig.name}`, agentConfig);
35 | this.agents.set(agentConfig.name, agent);
36 |
37 | // Add API routes for this agent
38 | this.api.addLambdaRoute(
39 | `/agents/${agentConfig.name}`,
40 | agent.handler,
41 | ['GET', 'POST']
42 | );
43 | });
44 | }
45 |
46 | // Add environment variables to all agent handlers
47 | this.agents.forEach(agent => {
48 | agent.handler.addEnvironment('CHAIN_ID', config.chainId);
49 | agent.handler.addEnvironment('RPC_URL', config.rpcUrl);
50 | agent.handler.addEnvironment('TABLE_NAME', this.database.table.tableName);
51 | });
52 | }
53 |
54 | public addAgent(config: AgentConfig) {
55 | const agent = new AgentConstruct(this, `Agent-${config.name}`, config);
56 | this.agents.set(config.name, agent);
57 | return agent;
58 | }
59 | }
--------------------------------------------------------------------------------
/packages/core/src/stack/types.ts:
--------------------------------------------------------------------------------
1 | import { AgentConfig } from "../agent/types";
2 |
3 | export interface MaigaConfig {
4 | chainId: string;
5 | rpcUrl: string;
6 | stage?: string;
7 | region?: string;
8 | domainName?: string;
9 | agents?: AgentConfig[];
10 | }
11 |
12 | export interface DatabaseConfig {
13 | tableName?: string;
14 | deletionProtection?: boolean;
15 | }
16 |
17 | export interface ApiConfig {
18 | cors?: boolean;
19 | apiKey?: boolean;
20 | }
21 |
--------------------------------------------------------------------------------
/packages/core/src/tool/base-tool.ts:
--------------------------------------------------------------------------------
1 | import { Tool, ToolSchema } from '../interfaces';
2 | import { Logger } from '../utils/logger';
3 |
4 | export abstract class BaseTool implements Tool {
5 | protected readonly logger: Logger;
6 |
7 | public readonly name: string;
8 | public readonly description: string;
9 | public readonly version: string;
10 | public readonly category?: string;
11 | public readonly metadata?: Record;
12 |
13 | constructor(options: {
14 | name: string;
15 | description: string;
16 | version: string;
17 | category?: string;
18 | metadata?: Record;
19 | }) {
20 | this.name = options.name;
21 | this.description = options.description;
22 | this.version = options.version;
23 | this.category = options.category;
24 | this.metadata = options.metadata;
25 |
26 | this.logger = new Logger(`Tool:${this.name}`);
27 | }
28 |
29 | abstract execute(...args: any[]): Promise;
30 | abstract validate?(...args: any[]): Promise;
31 | abstract getSchema(): ToolSchema;
32 |
33 | public getMetadata(): Record {
34 | return {
35 | name: this.name,
36 | description: this.description,
37 | version: this.version,
38 | category: this.category,
39 | ...this.metadata
40 | };
41 | }
42 |
43 | protected validateArgs(args: any[], schema: ToolSchema): boolean {
44 | const { parameters } = schema;
45 |
46 | // Check required parameters
47 | if (parameters.required) {
48 | for (const required of parameters.required) {
49 | if (!(required in args)) {
50 | this.logger.error(`Missing required parameter: ${required}`);
51 | return false;
52 | }
53 | }
54 | }
55 |
56 | // Validate each parameter
57 | for (const [key, value] of Object.entries(args)) {
58 | const paramSchema = parameters.properties[key];
59 | if (!paramSchema) {
60 | this.logger.warn(`Unknown parameter: ${key}`);
61 | continue;
62 | }
63 |
64 | if (!this.validateValue(value, paramSchema)) {
65 | this.logger.error(`Invalid value for parameter ${key}`);
66 | return false;
67 | }
68 | }
69 |
70 | return true;
71 | }
72 |
73 | private validateValue(value: any, schema: any): boolean {
74 | switch (schema.type) {
75 | case 'string':
76 | if (typeof value !== 'string') return false;
77 | if (schema.pattern && !new RegExp(schema.pattern).test(value)) return false;
78 | if (schema.enum && !schema.enum.includes(value)) return false;
79 | break;
80 |
81 | case 'number':
82 | if (typeof value !== 'number') return false;
83 | if (schema.minimum !== undefined && value < schema.minimum) return false;
84 | if (schema.maximum !== undefined && value > schema.maximum) return false;
85 | break;
86 |
87 | case 'boolean':
88 | if (typeof value !== 'boolean') return false;
89 | break;
90 |
91 | case 'array':
92 | if (!Array.isArray(value)) return false;
93 | if (schema.items) {
94 | for (const item of value) {
95 | if (!this.validateValue(item, schema.items)) return false;
96 | }
97 | }
98 | break;
99 |
100 | case 'object':
101 | if (typeof value !== 'object' || value === null) return false;
102 | if (schema.properties) {
103 | for (const [propKey, propSchema] of Object.entries(schema.properties)) {
104 | if (schema.required?.includes(propKey) && !(propKey in value)) return false;
105 | if (propKey in value && !this.validateValue(value[propKey], propSchema)) return false;
106 | }
107 | }
108 | break;
109 |
110 | default:
111 | this.logger.warn(`Unknown schema type: ${schema.type}`);
112 | return false;
113 | }
114 |
115 | return true;
116 | }
117 | }
--------------------------------------------------------------------------------
/packages/core/src/utils/config.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod';
2 |
3 | // Configuration schema
4 | const configSchema = z.object({
5 | chainId: z.string(),
6 | rpcUrl: z.string().url(),
7 | stage: z.string().optional(),
8 | region: z.string().optional(),
9 | domainName: z.string().optional(),
10 | logLevel: z.enum(['debug', 'info', 'warn', 'error']).optional(),
11 | agents: z.array(z.object({
12 | name: z.string(),
13 | modelId: z.string(),
14 | memory: z.boolean().optional(),
15 | tools: z.array(z.string()).optional(),
16 | })).optional(),
17 | });
18 |
19 | export type Config = z.infer;
20 |
21 | export class ConfigLoader {
22 | private static instance: ConfigLoader;
23 | private config: Config;
24 |
25 | private constructor() {
26 | this.config = this.loadConfig();
27 | }
28 |
29 | public static getInstance(): ConfigLoader {
30 | if (!ConfigLoader.instance) {
31 | ConfigLoader.instance = new ConfigLoader();
32 | }
33 | return ConfigLoader.instance;
34 | }
35 |
36 | private loadConfig(): Config {
37 | // Load from environment variables
38 | const config = {
39 | chainId: process.env.CHAIN_ID,
40 | rpcUrl: process.env.RPC_URL,
41 | stage: process.env.STAGE,
42 | region: process.env.REGION,
43 | domainName: process.env.DOMAIN_NAME,
44 | logLevel: process.env.LOG_LEVEL,
45 | };
46 |
47 | // Validate config
48 | const result = configSchema.safeParse(config);
49 |
50 | if (!result.success) {
51 | throw new Error(`Invalid configuration: ${result.error.message}`);
52 | }
53 |
54 | return result.data;
55 | }
56 |
57 | public getConfig(): Config {
58 | return this.config;
59 | }
60 |
61 | public updateConfig(newConfig: Partial) {
62 | this.config = {
63 | ...this.config,
64 | ...newConfig,
65 | };
66 | }
67 | }
68 |
69 | // Helper functions
70 | export function getConfig(): Config {
71 | return ConfigLoader.getInstance().getConfig();
72 | }
73 |
74 | export function updateConfig(config: Partial) {
75 | return ConfigLoader.getInstance().updateConfig(config);
76 | }
--------------------------------------------------------------------------------
/packages/core/src/utils/logger.ts:
--------------------------------------------------------------------------------
1 | import winston from 'winston';
2 |
3 | export enum LogLevel {
4 | DEBUG = 'debug',
5 | INFO = 'info',
6 | WARN = 'warn',
7 | ERROR = 'error'
8 | }
9 |
10 | export interface LoggerOptions {
11 | level?: LogLevel;
12 | prefix?: string;
13 | metadata?: Record;
14 | }
15 |
16 | export class Logger {
17 | private logger: winston.Logger;
18 | private prefix: string;
19 | private metadata: Record;
20 |
21 | constructor(prefix?: string, options: LoggerOptions = {}) {
22 | this.prefix = prefix || '';
23 | this.metadata = options.metadata || {};
24 |
25 | this.logger = winston.createLogger({
26 | level: options.level || LogLevel.INFO,
27 | format: winston.format.combine(
28 | winston.format.timestamp(),
29 | winston.format.json()
30 | ),
31 | transports: [
32 | new winston.transports.Console({
33 | format: winston.format.combine(
34 | winston.format.colorize(),
35 | winston.format.simple()
36 | )
37 | })
38 | ]
39 | });
40 | }
41 |
42 | private formatMessage(message: string, metadata?: Record): any {
43 | return {
44 | message,
45 | prefix: this.prefix,
46 | timestamp: new Date().toISOString(),
47 | ...this.metadata,
48 | ...metadata
49 | };
50 | }
51 |
52 | public debug(message: string, metadata?: Record): void {
53 | this.logger.debug(this.formatMessage(message, metadata));
54 | }
55 |
56 | public info(message: string, metadata?: Record): void {
57 | this.logger.info(this.formatMessage(message, metadata));
58 | }
59 |
60 | public warn(message: string, metadata?: Record): void {
61 | this.logger.warn(this.formatMessage(message, metadata));
62 | }
63 |
64 | public error(message: string, error?: any): void {
65 | this.logger.error(this.formatMessage(message, {
66 | error: error?.message || error,
67 | stack: error?.stack
68 | }));
69 | }
70 |
71 | public setLevel(level: LogLevel): void {
72 | this.logger.level = level;
73 | }
74 |
75 | public addMetadata(metadata: Record): void {
76 | this.metadata = { ...this.metadata, ...metadata };
77 | }
78 |
79 | public child(options: LoggerOptions): Logger {
80 | return new Logger(
81 | options.prefix || this.prefix,
82 | {
83 | level: options.level || (this.logger.level as LogLevel),
84 | metadata: { ...this.metadata, ...options.metadata }
85 | }
86 | );
87 | }
88 | }
--------------------------------------------------------------------------------
/packages/core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "module": "commonjs",
5 | "declaration": true,
6 | "outDir": "./dist",
7 | "strict": true,
8 | "esModuleInterop": true,
9 | "skipLibCheck": true,
10 | "forceConsistentCasingInFileNames": true
11 | },
12 | "include": [
13 | "src"
14 | ],
15 | "exclude": [
16 | "node_modules",
17 | "dist"
18 | ]
19 | }
--------------------------------------------------------------------------------
/packages/security/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@orbit/security",
3 | "version": "0.1.0",
4 | "description": "Secure Communication Layer for O.R.B.I.T Framework",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "scripts": {
8 | "build": "tsc",
9 | "test": "jest",
10 | "lint": "eslint src/**/*.ts"
11 | },
12 | "dependencies": {
13 | "@orbit/core": "^0.1.0",
14 | "jose": "^5.2.0",
15 | "node-forge": "^1.3.1",
16 | "tweetnacl": "^1.0.3",
17 | "tweetnacl-util": "^0.15.1"
18 | },
19 | "devDependencies": {
20 | "@types/node": "^22.10.6",
21 | "@types/jest": "^29.5.14",
22 | "@types/node-forge": "^1.3.11",
23 | "typescript": "^5.7.3",
24 | "jest": "^29.7.0",
25 | "ts-jest": "^29.2.5"
26 | },
27 | "repository": {
28 | "type": "git",
29 | "url": "git+https://github.com/metros-org/orbit-framework.git",
30 | "directory": "packages/security"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/security/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types';
2 | export * from './providers/default-provider';
--------------------------------------------------------------------------------
/packages/security/src/providers/default-provider.ts:
--------------------------------------------------------------------------------
1 | import { Logger } from '@orbit/core';
2 | import * as jose from 'jose';
3 | import * as forge from 'node-forge';
4 | import { box, randomBytes } from 'tweetnacl';
5 | import { encodeBase64, decodeBase64 } from 'tweetnacl-util';
6 |
7 | import {
8 | SecurityProvider,
9 | SecurityConfig,
10 | EncryptionKey,
11 | SigningKey,
12 | EncryptedMessage,
13 | SignedMessage
14 | } from '../types';
15 |
16 | export class DefaultSecurityProvider implements SecurityProvider {
17 | private readonly logger: Logger;
18 | private readonly config: Required;
19 |
20 | constructor(config: SecurityConfig = {}) {
21 | this.logger = new Logger('SecurityProvider');
22 | this.config = {
23 | encryptionAlgorithm: config.encryptionAlgorithm || 'ECDH-ES+A256KW',
24 | signatureAlgorithm: config.signatureAlgorithm || 'EdDSA',
25 | keyExchangeProtocol: config.keyExchangeProtocol || 'X25519'
26 | };
27 | }
28 |
29 | public async generateEncryptionKey(): Promise {
30 | const keyPair = box.keyPair();
31 | return {
32 | publicKey: encodeBase64(keyPair.publicKey),
33 | privateKey: encodeBase64(keyPair.secretKey)
34 | };
35 | }
36 |
37 | public async generateSigningKey(): Promise {
38 | const { privateKey, publicKey } = await jose.generateKeyPair(
39 | this.config.signatureAlgorithm
40 | );
41 |
42 | return {
43 | publicKey: await jose.exportSPKI(publicKey),
44 | privateKey: await jose.exportPKCS8(privateKey)
45 | };
46 | }
47 |
48 | public async encrypt(message: string, recipientPublicKey: string): Promise {
49 | try {
50 | // Generate ephemeral key pair
51 | const ephemeralKeyPair = box.keyPair();
52 |
53 | // Decode recipient's public key
54 | const recipientPubKey = decodeBase64(recipientPublicKey);
55 |
56 | // Generate shared key
57 | const sharedKey = box.before(recipientPubKey, ephemeralKeyPair.secretKey);
58 |
59 | // Generate random nonce
60 | const nonce = randomBytes(box.nonceLength);
61 |
62 | // Encrypt message
63 | const messageUint8 = new TextEncoder().encode(message);
64 | const encrypted = box.after(messageUint8, nonce, sharedKey);
65 |
66 | return {
67 | ciphertext: encodeBase64(encrypted),
68 | iv: encodeBase64(nonce),
69 | ephemeralPublicKey: encodeBase64(ephemeralKeyPair.publicKey)
70 | };
71 | } catch (error) {
72 | this.logger.error('Encryption failed:', error);
73 | throw error;
74 | }
75 | }
76 |
77 | public async decrypt(message: EncryptedMessage, privateKey: string): Promise {
78 | try {
79 | if (!message.ephemeralPublicKey) {
80 | throw new Error('Missing ephemeral public key');
81 | }
82 |
83 | // Decode keys and message components
84 | const recipientPrivKey = decodeBase64(privateKey);
85 | const ephemeralPubKey = decodeBase64(message.ephemeralPublicKey);
86 | const ciphertext = decodeBase64(message.ciphertext);
87 | const nonce = decodeBase64(message.iv);
88 |
89 | // Generate shared key
90 | const sharedKey = box.before(ephemeralPubKey, recipientPrivKey);
91 |
92 | // Decrypt message
93 | const decrypted = box.open_after(ciphertext, nonce, sharedKey);
94 | if (!decrypted) {
95 | throw new Error('Decryption failed');
96 | }
97 |
98 | return new TextDecoder().decode(decrypted);
99 | } catch (error) {
100 | this.logger.error('Decryption failed:', error);
101 | throw error;
102 | }
103 | }
104 |
105 | public async sign(
106 | message: string | EncryptedMessage,
107 | privateKey: string
108 | ): Promise {
109 | try {
110 | const key = await jose.importPKCS8(privateKey, this.config.signatureAlgorithm);
111 | const messageStr = typeof message === 'string'
112 | ? message
113 | : JSON.stringify(message);
114 |
115 | const signature = await new jose.SignJWT({ message: messageStr })
116 | .setProtectedHeader({ alg: this.config.signatureAlgorithm })
117 | .sign(key);
118 |
119 | return {
120 | message,
121 | signature,
122 | publicKey: (await jose.exportSPKI(key)),
123 | timestamp: Date.now()
124 | };
125 | } catch (error) {
126 | this.logger.error('Signing failed:', error);
127 | throw error;
128 | }
129 | }
130 |
131 | public async verify(signedMessage: SignedMessage): Promise {
132 | try {
133 | const publicKey = await jose.importSPKI(
134 | signedMessage.publicKey,
135 | this.config.signatureAlgorithm
136 | );
137 |
138 | const { payload } = await jose.jwtVerify(
139 | signedMessage.signature,
140 | publicKey
141 | );
142 |
143 | const messageStr = typeof signedMessage.message === 'string'
144 | ? signedMessage.message
145 | : JSON.stringify(signedMessage.message);
146 |
147 | return payload.message === messageStr;
148 | } catch (error) {
149 | this.logger.error('Verification failed:', error);
150 | return false;
151 | }
152 | }
153 |
154 | public async deriveSharedSecret(privateKey: string, publicKey: string): Promise {
155 | try {
156 | const privKey = decodeBase64(privateKey);
157 | const pubKey = decodeBase64(publicKey);
158 |
159 | const sharedKey = box.before(pubKey, privKey);
160 | return encodeBase64(sharedKey);
161 | } catch (error) {
162 | this.logger.error('Key derivation failed:', error);
163 | throw error;
164 | }
165 | }
166 |
167 | private generateRandomBytes(length: number): Uint8Array {
168 | return randomBytes(length);
169 | }
170 | }
--------------------------------------------------------------------------------
/packages/security/src/types.ts:
--------------------------------------------------------------------------------
1 | export interface EncryptionKey {
2 | publicKey: string;
3 | privateKey?: string;
4 | }
5 |
6 | export interface SigningKey {
7 | publicKey: string;
8 | privateKey?: string;
9 | }
10 |
11 | export interface EncryptedMessage {
12 | ciphertext: string;
13 | iv: string;
14 | tag?: string;
15 | ephemeralPublicKey?: string;
16 | }
17 |
18 | export interface SignedMessage {
19 | message: string | EncryptedMessage;
20 | signature: string;
21 | publicKey: string;
22 | timestamp: number;
23 | }
24 |
25 | export interface SecurityConfig {
26 | encryptionAlgorithm?: string;
27 | signatureAlgorithm?: string;
28 | keyExchangeProtocol?: string;
29 | }
30 |
31 | export interface SecurityProvider {
32 | generateEncryptionKey(): Promise;
33 | generateSigningKey(): Promise;
34 |
35 | encrypt(message: string, recipientPublicKey: string): Promise;
36 | decrypt(message: EncryptedMessage, privateKey: string): Promise;
37 |
38 | sign(message: string | EncryptedMessage, privateKey: string): Promise;
39 | verify(signedMessage: SignedMessage): Promise;
40 |
41 | deriveSharedSecret(privateKey: string, publicKey: string): Promise;
42 | }
--------------------------------------------------------------------------------
/packages/tools/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@orbit/tools",
3 | "version": "0.1.0",
4 | "main": "dist/index.js",
5 | "types": "dist/index.d.ts",
6 | "scripts": {
7 | "build": "tsc",
8 | "test": "jest"
9 | },
10 | "dependencies": {
11 | "@aws-sdk/client-bedrock-runtime": "^3.726.1",
12 | "viem": "^2.22.8"
13 | },
14 | "peerDependencies": {
15 | "@orbit/core": "^0.1.0"
16 | },
17 | "repository": {
18 | "type": "git",
19 | "url": "git+https://github.com/metros-org/orbit-framework.git",
20 | "directory": "packages/tools"
21 | }
22 | }
--------------------------------------------------------------------------------
/packages/tools/src/agent/bedrock-agent.ts:
--------------------------------------------------------------------------------
1 | import { BaseAgent, AgentOptions, AgentResponse } from '@maiga/core';
2 | import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput } from '@aws-sdk/client-bedrock-runtime';
3 |
4 | interface BedrockAgentOptions extends AgentOptions {
5 | region?: string;
6 | temperature?: number;
7 | maxTokens?: number;
8 | topP?: number;
9 | frequencyPenalty?: number;
10 | presencePenalty?: number;
11 | }
12 |
13 | export class BedrockAgent extends BaseAgent {
14 | private client: BedrockRuntimeClient;
15 | private temperature: number;
16 | private maxTokens: number;
17 | private topP: number;
18 | private frequencyPenalty: number;
19 | private presencePenalty: number;
20 |
21 | constructor(options: BedrockAgentOptions) {
22 | super(options);
23 | this.client = new BedrockRuntimeClient({ region: options.region || 'us-east-1' });
24 | this.temperature = options.temperature || 0.7;
25 | this.maxTokens = options.maxTokens || 2000;
26 | this.topP = options.topP || 1.0;
27 | this.frequencyPenalty = options.frequencyPenalty || 0.0;
28 | this.presencePenalty = options.presencePenalty || 0.0;
29 | }
30 |
31 | async initialize(): Promise {
32 | this.logger.info('Initializing Bedrock agent');
33 | this.emit('ready');
34 | }
35 |
36 | private formatPrompt(input: string, context?: string[]): string {
37 | let prompt = `You are an AI assistant.`;
38 | if (context && context.length > 0) {
39 | prompt += `\nContext:\n${context.join('\n')}`;
40 | }
41 | prompt += `\n\nUser: ${input}\nAI:`;
42 | return prompt;
43 | }
44 |
45 | async execute(input: string): Promise {
46 | try {
47 | const commandInput: InvokeModelCommandInput = {
48 | modelId: this.modelId,
49 | contentType: 'application/json',
50 | accept: 'application/json',
51 | body: JSON.stringify({
52 | prompt: this.formatPrompt(input),
53 | max_tokens: this.maxTokens,
54 | temperature: this.temperature,
55 | top_p: this.topP,
56 | frequency_penalty: this.frequencyPenalty,
57 | presence_penalty: this.presencePenalty
58 | })
59 | };
60 |
61 | const command = new InvokeModelCommand(commandInput);
62 | const response = await this.client.send(command);
63 | const result = JSON.parse(new TextDecoder().decode(response.body));
64 |
65 | if (result.tool_calls) {
66 | await this.handleToolCalls(result.tool_calls);
67 | }
68 |
69 | return { output: result.completion || result.content[0].text };
70 | } catch (error) {
71 | this.logger.error('Execution error:', error);
72 | throw new Error(`Failed to execute command: ${error.message}`);
73 | }
74 | }
75 |
76 | async handleToolCalls(toolCalls: any[]): Promise {
77 | for (const call of toolCalls) {
78 | try {
79 | const tool = this.tools.get(call.name);
80 | if (tool) {
81 | await this.useTool(call.name, ...call.arguments);
82 | }
83 | } catch (error) {
84 | this.logger.error(`Error executing tool ${call.name}:`, error);
85 | }
86 | }
87 | }
88 |
89 | async stop(): Promise {
90 | this.logger.info('Stopping Bedrock agent');
91 | this.emit('stopped');
92 | }
93 | }
--------------------------------------------------------------------------------
/packages/tools/src/agent/claude-agent.ts:
--------------------------------------------------------------------------------
1 | import { BaseAgent, AgentOptions, AgentResponse } from '@maiga/core';
2 | import axios from 'axios';
3 |
4 | interface ClaudeAgentOptions extends AgentOptions {
5 | apiKey: string;
6 | apiUrl: string;
7 | temperature?: number;
8 | maxTokens?: number;
9 | topP?: number;
10 | frequencyPenalty?: number;
11 | presencePenalty?: number;
12 | }
13 |
14 | export class ClaudeAgent extends BaseAgent {
15 | private apiKey: string;
16 | private apiUrl: string;
17 | private temperature: number;
18 | private maxTokens: number;
19 | private topP: number;
20 | private frequencyPenalty: number;
21 | private presencePenalty: number;
22 |
23 | constructor(options: ClaudeAgentOptions) {
24 | super(options);
25 | this.apiKey = options.apiKey;
26 | this.apiUrl = options.apiUrl;
27 | this.temperature = options.temperature || 0.7;
28 | this.maxTokens = options.maxTokens || 2000;
29 | this.topP = options.topP || 1.0;
30 | this.frequencyPenalty = options.frequencyPenalty || 0.0;
31 | this.presencePenalty = options.presencePenalty || 0.0;
32 | }
33 |
34 | async initialize(): Promise {
35 | this.logger.info('Initializing Claude agent');
36 | this.emit('ready');
37 | }
38 |
39 | private formatPrompt(input: string, context?: string[]): string {
40 | let prompt = `You are an AI assistant.`;
41 | if (context && context.length > 0) {
42 | prompt += `\nContext:\n${context.join('\n')}`;
43 | }
44 | prompt += `\n\nUser: ${input}\nAI:`;
45 | return prompt;
46 | }
47 |
48 | async execute(input: string): Promise {
49 | try {
50 | const response = await axios.post(this.apiUrl, {
51 | prompt: this.formatPrompt(input),
52 | max_tokens: this.maxTokens,
53 | temperature: this.temperature,
54 | top_p: this.topP,
55 | frequency_penalty: this.frequencyPenalty,
56 | presence_penalty: this.presencePenalty,
57 | }, {
58 | headers: {
59 | 'Authorization': `Bearer ${this.apiKey}`,
60 | 'Content-Type': 'application/json'
61 | }
62 | });
63 |
64 | const result = response.data.completion || '';
65 |
66 | return { output: result.trim() };
67 | } catch (error) {
68 | this.logger.error('Execution error:', error);
69 | throw new Error(`Failed to execute command: ${error.message}`);
70 | }
71 | }
72 |
73 | async stop(): Promise {
74 | this.logger.info('Stopping Claude agent');
75 | this.emit('stopped');
76 | }
77 | }
--------------------------------------------------------------------------------
/packages/tools/src/agent/index.ts:
--------------------------------------------------------------------------------
1 | export * from './bedrock-agent';
2 | export * from './openai-agent';
3 | export * from './claude-agent';
4 |
--------------------------------------------------------------------------------
/packages/tools/src/agent/openai-agent.ts:
--------------------------------------------------------------------------------
1 | import { BaseAgent, AgentOptions, AgentResponse } from '@maiga/core';
2 | import { Configuration, OpenAIApi } from 'openai';
3 |
4 | interface OpenAIAgentOptions extends AgentOptions {
5 | apiKey: string;
6 | temperature?: number;
7 | maxTokens?: number;
8 | topP?: number;
9 | frequencyPenalty?: number;
10 | presencePenalty?: number;
11 | }
12 |
13 | export class OpenAIAgent extends BaseAgent {
14 | private openai: OpenAIApi;
15 | private temperature: number;
16 | private maxTokens: number;
17 | private topP: number;
18 | private frequencyPenalty: number;
19 | private presencePenalty: number;
20 |
21 | constructor(options: OpenAIAgentOptions) {
22 | super(options);
23 | const configuration = new Configuration({
24 | apiKey: options.apiKey,
25 | });
26 | this.openai = new OpenAIApi(configuration);
27 | this.temperature = options.temperature || 0.7;
28 | this.maxTokens = options.maxTokens || 2000;
29 | this.topP = options.topP || 1.0;
30 | this.frequencyPenalty = options.frequencyPenalty || 0.0;
31 | this.presencePenalty = options.presencePenalty || 0.0;
32 | }
33 |
34 | async initialize(): Promise {
35 | this.logger.info('Initializing OpenAI agent');
36 | this.emit('ready');
37 | }
38 |
39 | private formatPrompt(input: string, context?: string[]): string {
40 | let prompt = `You are an AI assistant.`;
41 | if (context && context.length > 0) {
42 | prompt += `\nContext:\n${context.join('\n')}`;
43 | }
44 | prompt += `\n\nUser: ${input}\nAI:`;
45 | return prompt;
46 | }
47 |
48 | async execute(input: string): Promise {
49 | try {
50 | const response = await this.openai.createCompletion({
51 | model: this.modelId,
52 | prompt: this.formatPrompt(input),
53 | max_tokens: this.maxTokens,
54 | temperature: this.temperature,
55 | top_p: this.topP,
56 | frequency_penalty: this.frequencyPenalty,
57 | presence_penalty: this.presencePenalty,
58 | });
59 |
60 | const result = response.data.choices[0].text || '';
61 |
62 | return { output: result.trim() };
63 | } catch (error) {
64 | this.logger.error('Execution error:', error);
65 | throw new Error(`Failed to execute command: ${error.message}`);
66 | }
67 | }
68 |
69 | async stop(): Promise {
70 | this.logger.info('Stopping OpenAI agent');
71 | this.emit('stopped');
72 | }
73 | }
--------------------------------------------------------------------------------
/packages/tools/src/base-tool.ts:
--------------------------------------------------------------------------------
1 | export interface ToolMetadata {
2 | name: string;
3 | description: string;
4 | version: string;
5 | }
6 |
7 | export abstract class BaseTool {
8 | protected metadata: ToolMetadata;
9 |
10 | constructor(metadata: ToolMetadata) {
11 | this.metadata = metadata;
12 | }
13 |
14 | abstract execute(...args: any[]): Promise;
15 |
16 | getMetadata(): ToolMetadata {
17 | return this.metadata;
18 | }
19 | }
--------------------------------------------------------------------------------
/packages/tools/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './agent';
2 | export * from './web3';
3 | export * from './social';
4 | export * from './base-tool';
--------------------------------------------------------------------------------
/packages/tools/src/social/index.ts:
--------------------------------------------------------------------------------
1 | export * from './x-tool';
--------------------------------------------------------------------------------
/packages/tools/src/social/x-tool.ts:
--------------------------------------------------------------------------------
1 | import { BaseTool } from '../base-tool';
2 |
3 | export class XTool extends BaseTool {
4 | constructor() {
5 | super({
6 | name: 'XTool',
7 | description: 'A tool for interacting with social media platform X',
8 | version: '1.0.0',
9 | });
10 | }
11 |
12 | async execute(action: string, ...args: any[]): Promise {
13 | switch (action) {
14 | case 'postMessage':
15 | return this.postMessage(args[0]);
16 | case 'getMessages':
17 | return this.getMessages();
18 | default:
19 | throw new Error(`Unknown action: ${action}`);
20 | }
21 | }
22 |
23 | private async postMessage(message: string): Promise {
24 | console.log(`Posting message to X: ${message}`);
25 | }
26 |
27 | private async getMessages(): Promise {
28 | console.log('Fetching messages from X');
29 | return ['Message 1', 'Message 2', 'Message 3'];
30 | }
31 | }
--------------------------------------------------------------------------------
/packages/tools/src/web3/index.ts:
--------------------------------------------------------------------------------
1 | export * from './web3-tool';
--------------------------------------------------------------------------------
/packages/tools/src/web3/web3-tool.ts:
--------------------------------------------------------------------------------
1 | import { BaseTool } from '../base-tool';
2 | import { createPublicClient, http } from 'viem';
3 | import { base } from 'viem/chains';
4 |
5 | export class Web3Tool extends BaseTool {
6 | private client: any;
7 |
8 | constructor() {
9 | super({
10 | name: 'web3',
11 | description: 'Interact with blockchain',
12 | version: '1.0.0',
13 | });
14 |
15 | this.client = createPublicClient({
16 | chain: base,
17 | transport: http(),
18 | });
19 | }
20 |
21 | async execute(method: string, ...args: any[]) {
22 | switch (method) {
23 | case 'getBalance':
24 | return await this.getBalance(args[0]);
25 | case 'getBlock':
26 | return await this.getBlock(args[0]);
27 | default:
28 | throw new Error(`Unknown method: ${method}`);
29 | }
30 | }
31 |
32 | private async getBalance(address: string) {
33 | return await this.client.getBalance({ address });
34 | }
35 |
36 | private async getBlock(blockNumber: number) {
37 | return await this.client.getBlock({ blockNumber });
38 | }
39 | }
--------------------------------------------------------------------------------
/packages/tools/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "module": "commonjs",
5 | "declaration": true,
6 | "outDir": "./dist",
7 | "strict": true,
8 | "esModuleInterop": true,
9 | "skipLibCheck": true,
10 | "forceConsistentCasingInFileNames": true
11 | },
12 | "include": [
13 | "src"
14 | ],
15 | "exclude": [
16 | "node_modules",
17 | "dist"
18 | ]
19 | }
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": ["**/.env.*local"],
4 | "pipeline": {
5 | "build": {
6 | "dependsOn": ["^build"],
7 | "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
8 | },
9 | "lint": {
10 | "outputs": []
11 | },
12 | "dev": {
13 | "cache": false,
14 | "persistent": true
15 | },
16 | "clean": {
17 | "cache": false
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------