[RFC] Multi-AI Era Refactoring — Implementation Ready, Need Reviewers and Testers #1577
professional-slacker
started this conversation in
Ideas
Replies: 1 comment 2 replies
-
|
This is neat but your assumption about single-key providers is VERY flawed. It's only that the openai env is multi-used. its possible to directly assign a key without using that based on the provider in question. I don't understand the request to use cd.. your in a prompt not your shell anymore.. session rename issue is a concern.. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
[RFC] Multi-AI Era Refactoring — Implementation Ready, Need Reviewers and Testers
TL;DR
Looking for: code reviewers, cross-platform testers (Linux/macOS/Windows), and design input. If you've been bitten by any of these issues, your experience helps.
Community Impact
Past incidents and root causes:
P1 (API_KEY issue) is a limitation of the current design scope.
/providerworks correctly within the current scope. The goal of this proposal is to build the foundation for handling multiple credentials simultaneously in the multi-agent era.Reproduce
Proposal 1: Provider Credential Isolation
This would make OpenClaude the only application currently capable of true multi-agent orchestration.
In the current design, a Provider is treated as an active state that can be switched within a session. The architecture does not support holding and using multiple Provider credentials independently and in parallel within a single session.
This creates constraints in use cases such as:
Using Opengateway Mimo for chat, Agent A (DeepSeek) for source code search, and Agent B (Gemini) for image recognition concurrently in the same session.
Switching via /provider overwrites the active Provider reference, causing state conflicts in workflows that assume multiple Providers can be handled simultaneously.
Additionally, differences in priority between environment variables and CLI settings can cause mismatches between startup configuration and runtime state, leading to "API_KEY invalid" errors due to misconfiguration — a recurring issue for a significant number of users.
The goal is to treat provider / model / API_KEY as a per-agent separable identifier, structurally preventing authentication and configuration conflicts during multi-agent execution.
Currently, WebSearch already maintains its own independent credentials (TAVILY_API_KEY, etc.) separate from the LLM API key. This proposal applies the same pattern to LLM providers — transparent credential resolution per agent.
Proposal 2: Virtual cd and Spawn CWD Mismatch
When
cwdis not specified in spawn calls, the startup directory is used by default. This causes issues not only when usingcd, but also in scenarios such as installers using spawn commands and remote connections via gRPC — even without any directory change. These inconsistencies should be resolved.Proposal 3: Path-Dependent Session Resume
If a directory is renamed or accessed via a symlink, the session key (cwd hash) changes, making it impossible to resume previous sessions. This stems from how cwd is fundamentally handled — P2 and P3 are complementary fixes.
1. Provider/Credential Layer (Class Diagram)
classDiagram note "【Current Architecture】\nTight coupling with Single Provider & Single API Key" class ProviderConfig { +string activeProfile +string apiKey +getActiveConfig() } note for ProviderConfig "- Strictly expects OPENAI_API_KEY as final fallback\n- Incapable of maintaining multiple concurrent provider sessions" %% ========================================== note "【Proposed Target Architecture】\nSeparation of Registry & Credentials (Loose Coupling)" class CredentialStore { <<interface>> +get(providerId: string) Credential +set(providerId: string, cred: Credential) void } class ProviderRegistry { <<interface>> +Map~string, ProviderConfig~ providers +resolve(model: string) ProviderConfig } class Credential { +string apiKey +string baseUrl +string authType } class TargetProviderConfig { +string providerId +string defaultModel +validate() bool } ProviderRegistry "1" *-- "many" TargetProviderConfig : Manages ProviderRegistry ..> CredentialStore : Resolves credentials TargetProviderConfig ..> Credential : Applies2. Shell Execution & Context Management (Sequence Diagram)
sequenceDiagram autonumber box RGBA(255, 0, 0, 0.1) Current Broken Flow (Defective process.cwd Dependency) actor User as User Agent participant Shell as Shell.ts (AsyncLocal) participant Hook as toolHooks.ts participant Spawn as bashProvider.ts (spawn) end User->>Shell: cd subdir Note over Shell: Only mutates AsyncLocalStorage state override.<br/>The actual OS-level process.cwd() remains unmutated. Shell-->>User: Command execution ack User->>Spawn: spawn("ls") Spawn->>Hook: Fetch execution context (CWD fallback) Hook-->>Spawn: Returns unmutated process.cwd() (Root directory) Note over Spawn: Executes command inside original root directory,<br/>violating user's mental model and context. Spawn-->>User: Returns file list of root instead of subdir (Critical Bug) %% ========================================== box RGBA(0, 255, 0, 0.1) Proposed Flow (Stateful VirtualCWD Synchronization) actor User2 as User Agent participant Session as SessionManager participant Spawn2 as bashProvider.ts (spawn) participant Node as OS Process Base end User2->>Session: cd subdir Note over Session: Directly mutates stateful session.virtualCwd Session->>Node: Synchronizes environment via process.chdir(subdir) Node-->>Session: Execution ack Session-->>User2: Command execution ack User2->>Spawn2: spawn("ls") Note over Spawn2: Explicitly injects session.virtualCwd<br/>into target options.cwd allocation Spawn2->>Node: Spawns sub-process inside resolved target subdir Node-->>Spawn2: Expected execution stdout/stderr Spawn2-->>User2: Returns correct subdir file list (Expected Behavior)3. Session Lifecycle & Persistence (State Transition Diagram)
stateDiagram-v2 state "【Current Design】\nAbsolute Path String Hash Dependency (Brittle)" as CurrentSession { [*] --> Init : process.cwd() = /home/user/project Init --> Transform : Execution of sanitizePath() Transform --> KeyGeneration : Yields rigid key "home-user-project-v1-hash" KeyGeneration --> HardcodedBinding : Persisted directly under ~/.openclaude/projects/ HardcodedBinding --> EnvironmentShift : External mv / symlink / bind mount action EnvironmentShift --> HistorialDataLoss : Path string deviation causes complete failure to resolve legacy session } %% ========================================== state "【Proposed Target Design】\n3-Tier Identification Topology (Highly Portable)" as ProposedSession { [*] --> Resolution : Triggered via specific sessionId or Recursive Git Root Search Resolution --> StructuralIdentity : Detects immutable "projectId" bound to Git Repository Root StructuralIdentity --> ContextSync : Fully restores agent execution context using sessionId metadata index ContextSync --> WorkspaceNavigation : Local path modifications strictly update "virtualCwd" state metadata only WorkspaceNavigation --> ContinuousPersistence : Seamlessly persists session states across path/machine migrations via stable IDs }4. Blast Radius Matrix (Flowchart)
flowchart LR subgraph BlastRadius [Blast Radius Matrix / Systemic Dependencies] direction TB P1["Proposal1: Legacy Provider Management<br/>(Single API Key Constraint)"] P2["Proposal 2: Flawed CWD Virtualization<br/>(Pseudo 'cd' Layer)"] P3["Proposal 3: Brittle Absolute Path Dependency<br/>(Fragile Resume Index)"] config["config/profile<br/>(Profile Management)"] API["API Client Layer"] shell["shell/spawn<br/>(Process Orchestration)"] fileOps["File System Operations"] session["Session Persistence<br/>(Storage Engine)"] resume["Session Resume Trigger"] vscode["VSCode Extension Context"] P1 --> config P1 --> API P2 --> shell P2 --> fileOps P3 --> session P3 --> resume P3 --> vscode end style P1 fill:#ff9999,stroke:#333,stroke-width:2px,color:#000 style P2 fill:#ff9999,stroke:#333,stroke-width:2px,color:#000 style P3 fill:#ff9999,stroke:#333,stroke-width:2px,color:#000Summary
Beta Was this translation helpful? Give feedback.
All reactions