Add AI/Web3 integration bundle with multi-language SDK adapters and deployment workflow#29
Add AI/Web3 integration bundle with multi-language SDK adapters and deployment workflow#29
Conversation
Co-authored-by: lippytm <65956507+lippytm@users.noreply.github.com>
Co-authored-by: lippytm <65956507+lippytm@users.noreply.github.com>
Co-authored-by: lippytm <65956507+lippytm@users.noreply.github.com>
Co-authored-by: lippytm <65956507+lippytm@users.noreply.github.com>
Co-authored-by: lippytm <65956507+lippytm@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive AI/Web3 integration infrastructure with SDK adapters for Node.js, Python, Go, and Rust. It includes optional dependencies for AI providers (OpenAI, HuggingFace, LangChain, LlamaIndex), vector stores (Pinecone, Weaviate, Chroma), Web3 chains (Ethereum/Solana), messaging services (Slack/Discord), and data storage options (Postgres/Redis/S3/IPFS). A GitHub Actions workflow enables container deployment to ghcr.io with dev/stage/prod environments.
Changes:
- Added multi-language SDK adapters with factory/config pattern for provider management across Node.js, Python, Go, and Rust
- Added optional dependencies to package manifests (package.json, pyproject.toml, go.mod, Cargo.toml) for AI/Web3/messaging/data integrations
- Added GitHub Actions deployment workflow for automated container builds and pushes to ghcr.io with environment matrix support
- Updated documentation with integration adapter guides, environment variable references, and deployment instructions
Reviewed changes
Copilot reviewed 19 out of 21 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/sdk-config.test.js | Unit tests for SDK configuration loaders covering all config classes and validation logic |
| sdk/node/index.js | Node.js SDK implementation with config classes for AI, vector stores, Web3, messaging, and data storage |
| sdk/node/package.json | Package manifest for Node.js SDK with optional peer dependencies |
| sdk/python/init.py | Python SDK implementation with equivalent config classes following Python conventions |
| sdk/python/setup.py | Python package setup with extras_require for optional dependency bundles |
| sdk/go/sdk.go | Go SDK implementation with idiomatic Go patterns and error handling |
| sdk/rust/lib.rs | Rust SDK implementation with Result types and Option handling |
| sdk/README.md | Cross-language SDK documentation with usage examples and security notes |
| go-service/main.go | Placeholder Go service stub for future implementation |
| src-rust/main.rs | Placeholder Rust service stub for future implementation |
| package.json | Root package manifest with optional AI/Web3 dependencies and concurrently dev dependency |
| backend/package.json | Backend package manifest with optional AI/Web3 dependencies |
| python-service/requirements.txt | Python service requirements with commented optional dependencies |
| python-service/pyproject.toml | Python service project configuration with optional dependency extras |
| go.mod | Go module file with commented optional dependencies |
| Cargo.toml | Rust package manifest with feature flags for optional components |
| .github/workflows/deploy.yml | Container deployment workflow with multi-service builds and environment matrix |
| README.md | Updated with AI/Web3 integration section, provider documentation, and deployment instructions |
| .env.example | Added environment variable examples for AI/Web3 integrations |
| .gitignore | Added Go and Rust build artifacts to ignore list |
| package-lock.json | Updated lock file with concurrently and related dependencies |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| description='AI/Web3 Integration SDK for AI Time Machines', | ||
| author='', | ||
| license='GPL-3.0', | ||
| packages=find_packages(), |
There was a problem hiding this comment.
The Python SDK uses from lippytm_ai_sdk import AITimesMachinesSDK but the package name in setup.py is lippytm-ai-sdk with a hyphen. Python package names with hyphens are converted to underscores for imports, so the import statement in README.md should be from lippytm_ai_sdk import AITimesMachinesSDK which is correct. However, for consistency with the actual module structure in sdk/python/__init__.py, the package directory should either be named lippytm_ai_sdk or the import path needs adjustment. The current implementation has the code in sdk/python/__init__.py without an explicit package directory structure.
| packages=find_packages(), | |
| packages=['lippytm_ai_sdk'], | |
| package_dir={'lippytm_ai_sdk': '.'}, |
|
|
||
| if errors: | ||
| # Only log in non-production environments | ||
| import os |
There was a problem hiding this comment.
The os module is imported within the validate_all method at line 152, but it's already imported at the module level on line 8. This redundant import should be removed to avoid confusion and follow Python best practices.
| import os |
| self.rpc_url = config.get('rpc_url', os.getenv('WEB3_RPC_URL')) | ||
| self.private_key = config.get('private_key', os.getenv('WEB3_PRIVATE_KEY')) |
There was a problem hiding this comment.
Storing Web3 private keys in environment variables (WEB3_PRIVATE_KEY) is a security risk, even in development. The TODO comments mention using a secure secret manager, but the current implementation allows direct reading from environment variables. Consider adding a warning when private keys are loaded from environment variables, or better yet, require the use of a key management service or encrypted storage for private keys. The private_key field is accessible as a plain string property which could be accidentally logged or exposed.
| if privateKey == "" { | ||
| privateKey = os.Getenv("WEB3_PRIVATE_KEY") |
There was a problem hiding this comment.
Storing Web3 private keys in environment variables (WEB3_PRIVATE_KEY) is a security risk, even in development. The TODO comments mention using a secure secret manager, but the current implementation allows direct reading from environment variables. Consider adding a warning when private keys are loaded from environment variables, or better yet, require the use of a key management service or encrypted storage for private keys. The PrivateKey field is accessible as a plain string property which could be accidentally logged or exposed.
| rpc_url: rpc_url.unwrap_or_else(|| env::var("WEB3_RPC_URL").unwrap_or_default()), | ||
| private_key: private_key.unwrap_or_else(|| env::var("WEB3_PRIVATE_KEY").unwrap_or_default()), |
There was a problem hiding this comment.
Storing Web3 private keys in environment variables (WEB3_PRIVATE_KEY) is a security risk, even in development. The TODO comments mention using a secure secret manager, but the current implementation allows direct reading from environment variables. Consider adding a warning when private keys are loaded from environment variables, or better yet, require the use of a key management service or encrypted storage for private keys. The private_key field is accessible as a plain string property which could be accidentally logged or exposed.
|
|
||
| See `.github/workflows/deploy.yml` for deployment configuration and environment matrix (dev/stage/prod). | ||
|
|
||
| ## 📚 Resources |
There was a problem hiding this comment.
The "## 📚 Resources" section header appears twice in the README - once at line 328 (before the AI/Web3 Integration section) and again at line 480 (after the Container Deployment section). The first occurrence at line 328 seems out of place and creates a duplicate heading. This appears to be missing the "## 🎯 Roadmap" header that was referenced in the diff context. The section starting at line 483 with roadmap items should have the "## 🎯 Roadmap" header instead of the duplicate "## 📚 Resources" at line 480.
| ## 📚 Resources | |
| ## 🎯 Roadmap |
| constructor(config = {}) { | ||
| this.chain = config.chain || 'ethereum'; // 'ethereum' | 'solana' | 'polygon' | etc | ||
| this.rpcUrl = config.rpcUrl || process.env.WEB3_RPC_URL; | ||
| this.privateKey = config.privateKey || process.env.WEB3_PRIVATE_KEY; |
There was a problem hiding this comment.
Storing Web3 private keys in environment variables (WEB3_PRIVATE_KEY) is a security risk, even in development. The TODO comments mention using a secure secret manager, but the current implementation allows direct reading from environment variables. Consider adding a warning log when private keys are loaded from environment variables, or better yet, require the use of a key management service or encrypted storage for private keys. The privateKey field is accessible as a plain string property which could be accidentally logged or exposed.
| this.privateKey = config.privateKey || process.env.WEB3_PRIVATE_KEY; | |
| const resolvedPrivateKey = config.privateKey || process.env.WEB3_PRIVATE_KEY; | |
| if (!config.privateKey && process.env.WEB3_PRIVATE_KEY) { | |
| // Warning: using environment variables for private keys is discouraged. | |
| // Prefer a dedicated secret manager or key management service. | |
| // This warning is logged once per Web3Config instantiation using the env var. | |
| // eslint-disable-next-line no-console | |
| console.warn( | |
| '[Web3Config] WARNING: Loaded WEB3_PRIVATE_KEY from environment variables. ' + | |
| 'This is insecure and intended only for development. ' + | |
| 'Use a secret manager or key management service for production.' | |
| ); | |
| } | |
| Object.defineProperty(this, 'privateKey', { | |
| configurable: false, | |
| enumerable: false, // reduce risk of accidental logging/serialization | |
| get() { | |
| return resolvedPrivateKey; | |
| }, | |
| }); |
| self.api_key = config.get('api_key', os.getenv('AI_API_KEY')) | ||
| self.model = config.get('model', 'gpt-4') | ||
| # TODO: Load from secure secret manager | ||
|
|
||
| def validate(self) -> bool: | ||
| if not self.api_key: | ||
| raise ValueError('AI_API_KEY not configured. Set via environment or constructor.') |
There was a problem hiding this comment.
There's an inconsistency in environment variable naming for the AI provider API key. The SDK code loads from AI_API_KEY environment variable, but the README examples and documentation all reference OPENAI_API_KEY. The .env.example file also only includes OPENAI_API_KEY. This will cause the SDK to fail to load the API key from environment variables when users follow the documentation. Either update the SDK to use OPENAI_API_KEY for OpenAI provider, or update all documentation to use AI_API_KEY and add it to .env.example.
| self.api_key = config.get('api_key', os.getenv('AI_API_KEY')) | |
| self.model = config.get('model', 'gpt-4') | |
| # TODO: Load from secure secret manager | |
| def validate(self) -> bool: | |
| if not self.api_key: | |
| raise ValueError('AI_API_KEY not configured. Set via environment or constructor.') | |
| env_api_key = os.getenv('OPENAI_API_KEY') or os.getenv('AI_API_KEY') | |
| self.api_key = config.get('api_key', env_api_key) | |
| self.model = config.get('model', 'gpt-4') | |
| # TODO: Load from secure secret manager | |
| def validate(self) -> bool: | |
| if not self.api_key: | |
| raise ValueError('OPENAI_API_KEY (or AI_API_KEY) not configured. Set via environment or constructor.') |
| provider = "openai" | ||
| } | ||
| if apiKey == "" { | ||
| apiKey = os.Getenv("AI_API_KEY") |
There was a problem hiding this comment.
There's an inconsistency in environment variable naming for the AI provider API key. The SDK code loads from AI_API_KEY environment variable, but the README examples and documentation all reference OPENAI_API_KEY. The .env.example file also only includes OPENAI_API_KEY. This will cause the SDK to fail to load the API key from environment variables when users follow the documentation. Either update the SDK to use OPENAI_API_KEY for OpenAI provider, or update all documentation to use AI_API_KEY and add it to .env.example.
| "peerDependencies": { | ||
| "openai": "^4.20.0", | ||
| "@huggingface/inference": "^2.7.0", | ||
| "langchain": "^0.1.0", | ||
| "llamaindex": "^0.1.0", | ||
| "@pinecone-database/pinecone": "^2.0.0", | ||
| "weaviate-ts-client": "^2.0.0", | ||
| "chromadb": "^1.7.0", | ||
| "ethers": "^6.10.0", | ||
| "@solana/web3.js": "^1.87.0", | ||
| "@coral-xyz/anchor": "^0.29.0", | ||
| "@slack/web-api": "^6.11.0", | ||
| "discord.js": "^14.14.0", | ||
| "redis": "^4.6.0", | ||
| "@aws-sdk/client-s3": "^3.490.0", | ||
| "ipfs-http-client": "^60.0.1" | ||
| }, |
There was a problem hiding this comment.
The SDK supports PostgreSQL as documented in the DataStorageConfig class and README, but the pg package is not listed in the peerDependencies. While the backend package.json includes pg as a dependency, the SDK package should list it as an optional peerDependency for completeness and to avoid confusion. Users installing the SDK standalone would not have PostgreSQL client support without explicitly knowing to install pg separately.
Description
Adds comprehensive AI/Web3 integration infrastructure with SDK adapters across Node.js, Python, Go, and Rust. Includes optional dependencies for AI providers (OpenAI, HuggingFace, LangChain, LlamaIndex), vector stores (Pinecone, Weaviate, Chroma), Web3 chains (Ethereum/Solana), messaging (Slack/Discord), and data storage (Postgres/Redis/S3/IPFS). Container deployment workflow targets ghcr.io with dev/stage/prod environments.
Type of Change
Changes Made
Dependency Manifests (Additive Only)
[ai],[vector],[web3],[messaging],[data])SDK Adapters (
sdk/)Factory/config pattern for provider management across languages:
Equivalent implementations in Python, Go, and Rust with idiomatic patterns. All include validation, environment-based configuration, and TODO markers for secret manager integration.
GitHub Actions Deploy Workflow
Documentation
Placeholder Services
go-service/main.gosrc-rust/main.rsTesting
Checklist
Additional Context
All dependencies are optional/peer dependencies to prevent bloat. Install selectively:
Extension points documented for additional Web3 chains beyond Ethereum/Solana.
Original prompt
This pull request was created from Copilot chat.
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.