From e886fbb632fa27ef68b7327a6a10567cf1c21ee1 Mon Sep 17 00:00:00 2001 From: CrazyBoyM Date: Tue, 17 Mar 2026 12:14:57 +0800 Subject: [PATCH 1/2] feat: add Kode-Agent as a new provider Add support for Kode (https://github.com/shareAI-lab/Kode-Agent), an open-source AI-powered terminal assistant for intelligent code development. Kode is a multi-model coding agent that supports both Anthropic and OpenAI APIs. Changes: - New provider plugin (kode.rs) with ANTHROPIC_API_KEY and OPENAI_API_KEY credential discovery - CLI enum variant for --type kode - Provider type normalization with aliases: kode, kwa, kd - Network policy for kode_agent allowing api.anthropic.com and api.openai.com access - Unit tests for credential discovery and alias normalization --- crates/openshell-cli/src/main.rs | 2 + crates/openshell-providers/src/lib.rs | 5 ++ .../openshell-providers/src/providers/kode.rs | 58 +++++++++++++++++++ .../openshell-providers/src/providers/mod.rs | 1 + .../testdata/sandbox-policy.yaml | 11 ++++ 5 files changed, 77 insertions(+) create mode 100644 crates/openshell-providers/src/providers/kode.rs diff --git a/crates/openshell-cli/src/main.rs b/crates/openshell-cli/src/main.rs index 84a323b5..ce27e4d9 100644 --- a/crates/openshell-cli/src/main.rs +++ b/crates/openshell-cli/src/main.rs @@ -583,6 +583,7 @@ enum CliProviderType { Nvidia, Gitlab, Github, + Kode, Outlook, } @@ -613,6 +614,7 @@ impl CliProviderType { Self::Nvidia => "nvidia", Self::Gitlab => "gitlab", Self::Github => "github", + Self::Kode => "kode", Self::Outlook => "outlook", } } diff --git a/crates/openshell-providers/src/lib.rs b/crates/openshell-providers/src/lib.rs index 143466d2..6c1420d3 100644 --- a/crates/openshell-providers/src/lib.rs +++ b/crates/openshell-providers/src/lib.rs @@ -84,6 +84,7 @@ impl ProviderRegistry { registry.register(providers::nvidia::NvidiaProvider); registry.register(providers::gitlab::GitlabProvider); registry.register(providers::github::GithubProvider); + registry.register(providers::kode::KodeProvider); registry.register(providers::outlook::OutlookProvider); registry } @@ -135,6 +136,7 @@ pub fn normalize_provider_type(input: &str) -> Option<&'static str> { "nvidia" => Some("nvidia"), "gitlab" | "glab" => Some("gitlab"), "github" | "gh" => Some("github"), + "kode" | "kwa" | "kd" => Some("kode"), "outlook" => Some("outlook"), _ => None, } @@ -164,6 +166,9 @@ mod tests { assert_eq!(normalize_provider_type("openai"), Some("openai")); assert_eq!(normalize_provider_type("anthropic"), Some("anthropic")); assert_eq!(normalize_provider_type("nvidia"), Some("nvidia")); + assert_eq!(normalize_provider_type("kode"), Some("kode")); + assert_eq!(normalize_provider_type("kwa"), Some("kode")); + assert_eq!(normalize_provider_type("kd"), Some("kode")); assert_eq!(normalize_provider_type("unknown"), None); } diff --git a/crates/openshell-providers/src/providers/kode.rs b/crates/openshell-providers/src/providers/kode.rs new file mode 100644 index 00000000..a4094c0b --- /dev/null +++ b/crates/openshell-providers/src/providers/kode.rs @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ + ProviderDiscoverySpec, ProviderError, ProviderPlugin, RealDiscoveryContext, discover_with_spec, +}; + +pub struct KodeProvider; + +pub const SPEC: ProviderDiscoverySpec = ProviderDiscoverySpec { + id: "kode", + credential_env_vars: &["ANTHROPIC_API_KEY", "OPENAI_API_KEY"], +}; + +impl ProviderPlugin for KodeProvider { + fn id(&self) -> &'static str { + SPEC.id + } + + fn discover_existing(&self) -> Result, ProviderError> { + discover_with_spec(&SPEC, &RealDiscoveryContext) + } + + fn credential_env_vars(&self) -> &'static [&'static str] { + SPEC.credential_env_vars + } +} + +#[cfg(test)] +mod tests { + use super::SPEC; + use crate::discover_with_spec; + use crate::test_helpers::MockDiscoveryContext; + + #[test] + fn discovers_kode_anthropic_credentials() { + let ctx = MockDiscoveryContext::new().with_env("ANTHROPIC_API_KEY", "test-key"); + let discovered = discover_with_spec(&SPEC, &ctx) + .expect("discovery") + .expect("provider"); + assert_eq!( + discovered.credentials.get("ANTHROPIC_API_KEY"), + Some(&"test-key".to_string()) + ); + } + + #[test] + fn discovers_kode_openai_credentials() { + let ctx = MockDiscoveryContext::new().with_env("OPENAI_API_KEY", "test-key"); + let discovered = discover_with_spec(&SPEC, &ctx) + .expect("discovery") + .expect("provider"); + assert_eq!( + discovered.credentials.get("OPENAI_API_KEY"), + Some(&"test-key".to_string()) + ); + } +} diff --git a/crates/openshell-providers/src/providers/mod.rs b/crates/openshell-providers/src/providers/mod.rs index 8ab52ed9..aa90b769 100644 --- a/crates/openshell-providers/src/providers/mod.rs +++ b/crates/openshell-providers/src/providers/mod.rs @@ -6,6 +6,7 @@ pub mod claude; pub mod codex; pub mod generic; pub mod github; +pub mod kode; pub mod gitlab; pub mod nvidia; pub mod openai; diff --git a/crates/openshell-sandbox/testdata/sandbox-policy.yaml b/crates/openshell-sandbox/testdata/sandbox-policy.yaml index 6f0011ce..719cd2ca 100644 --- a/crates/openshell-sandbox/testdata/sandbox-policy.yaml +++ b/crates/openshell-sandbox/testdata/sandbox-policy.yaml @@ -39,6 +39,17 @@ network_policies: - { path: /usr/local/bin/claude } - { path: /usr/bin/node } + kode_agent: + name: kode_agent + endpoints: + - { host: api.anthropic.com, port: 443 } + - { host: api.openai.com, port: 443 } + binaries: + - { path: /usr/local/bin/kode } + - { path: /usr/local/bin/kwa } + - { path: /usr/local/bin/kd } + - { path: /usr/bin/node } + github_ssh_over_https: name: github-ssh-over-https endpoints: From a380dea35ae9d221858aeebe4e9c3685e31ff22c Mon Sep 17 00:00:00 2001 From: CrazyBoyM Date: Tue, 17 Mar 2026 12:20:53 +0800 Subject: [PATCH 2/2] refine: keep only kode command, add documentation - Remove kwa/kd aliases, register only the kode command - Simplify network policy binaries to kode and node only - Add Kode to supported-agents and default-policy docs --- crates/openshell-providers/src/lib.rs | 4 +--- crates/openshell-sandbox/testdata/sandbox-policy.yaml | 2 -- docs/about/supported-agents.md | 1 + docs/reference/default-policy.md | 1 + 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/openshell-providers/src/lib.rs b/crates/openshell-providers/src/lib.rs index 6c1420d3..9e1c3444 100644 --- a/crates/openshell-providers/src/lib.rs +++ b/crates/openshell-providers/src/lib.rs @@ -136,7 +136,7 @@ pub fn normalize_provider_type(input: &str) -> Option<&'static str> { "nvidia" => Some("nvidia"), "gitlab" | "glab" => Some("gitlab"), "github" | "gh" => Some("github"), - "kode" | "kwa" | "kd" => Some("kode"), + "kode" => Some("kode"), "outlook" => Some("outlook"), _ => None, } @@ -167,8 +167,6 @@ mod tests { assert_eq!(normalize_provider_type("anthropic"), Some("anthropic")); assert_eq!(normalize_provider_type("nvidia"), Some("nvidia")); assert_eq!(normalize_provider_type("kode"), Some("kode")); - assert_eq!(normalize_provider_type("kwa"), Some("kode")); - assert_eq!(normalize_provider_type("kd"), Some("kode")); assert_eq!(normalize_provider_type("unknown"), None); } diff --git a/crates/openshell-sandbox/testdata/sandbox-policy.yaml b/crates/openshell-sandbox/testdata/sandbox-policy.yaml index 719cd2ca..b95b1f9e 100644 --- a/crates/openshell-sandbox/testdata/sandbox-policy.yaml +++ b/crates/openshell-sandbox/testdata/sandbox-policy.yaml @@ -46,8 +46,6 @@ network_policies: - { host: api.openai.com, port: 443 } binaries: - { path: /usr/local/bin/kode } - - { path: /usr/local/bin/kwa } - - { path: /usr/local/bin/kd } - { path: /usr/bin/node } github_ssh_over_https: diff --git a/docs/about/supported-agents.md b/docs/about/supported-agents.md index c21335a8..ebcc965f 100644 --- a/docs/about/supported-agents.md +++ b/docs/about/supported-agents.md @@ -5,6 +5,7 @@ The following table summarizes the agents that run in OpenShell sandboxes. All a | Agent | Source | Default Policy | Notes | |---|---|---|---| | [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | [`base`](https://github.com/NVIDIA/OpenShell-Community/tree/main/sandboxes/base) | Full coverage | Works out of the box. Requires `ANTHROPIC_API_KEY`. | +| [Kode](https://github.com/shareAI-lab/Kode-Agent) | [`base`](https://github.com/NVIDIA/OpenShell-Community/tree/main/sandboxes/base) | Full coverage | Multi-model AI coding agent. Requires `ANTHROPIC_API_KEY` and/or `OPENAI_API_KEY`. | | [OpenCode](https://opencode.ai/) | [`base`](https://github.com/NVIDIA/OpenShell-Community/tree/main/sandboxes/base) | Partial coverage | Pre-installed. Add `opencode.ai` endpoint and OpenCode binary paths to the policy for full functionality. | | [Codex](https://developers.openai.com/codex) | [`base`](https://github.com/NVIDIA/OpenShell-Community/tree/main/sandboxes/base) | No coverage | Pre-installed. Requires a custom policy with OpenAI endpoints and Codex binary paths. Requires `OPENAI_API_KEY`. | | [OpenClaw](https://openclaw.ai/) | [`openclaw`](https://github.com/NVIDIA/OpenShell-Community/tree/main/sandboxes/openclaw) | Bundled | Agent orchestration layer. Launch with `openshell sandbox create --from openclaw`. | diff --git a/docs/reference/default-policy.md b/docs/reference/default-policy.md index 27115aa8..7f6f2a55 100644 --- a/docs/reference/default-policy.md +++ b/docs/reference/default-policy.md @@ -23,6 +23,7 @@ The following table shows the coverage of the default policy for common agents. | Agent | Coverage | Action Required | |---|---|---| | Claude Code | Full | None. Works out of the box. | +| Kode | Full | None. Works out of the box. | | OpenCode | Partial | Add `opencode.ai` endpoint and OpenCode binary paths. | | Codex | None | Provide a complete custom policy with OpenAI endpoints and Codex binary paths. |