├── .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 | O.R.B.I.T. Logo 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 | O.R.B.I.T. Architecture 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 | } --------------------------------------------------------------------------------