Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
dff215e
feat(reborn): add OpenAI-compatible API contracts
hanakannzashi Jun 4, 2026
035a265
fix(reborn): tighten OpenAI-compatible response contracts
hanakannzashi Jun 5, 2026
9a5d9a6
fix(reborn): address OpenAI compat contract review
hanakannzashi Jun 6, 2026
a2c2ee0
Merge origin/main into OpenAI compat contracts
think-in-universe Jun 7, 2026
4222ac5
Merge remote-tracking branch 'origin/main' into issue-4442-reborn-ope…
hanakannzashi Jun 8, 2026
5264f35
fix(reborn): satisfy merged main clippy
hanakannzashi Jun 8, 2026
9af95ed
Merge remote-tracking branch 'origin/main' into issue-4442-reborn-ope…
hanakannzashi Jun 8, 2026
f9611c7
feat(reborn): add OpenAI-compatible product refs
hanakannzashi Jun 5, 2026
3d5249b
fix(reborn): validate OpenAI-compatible ref mappings
hanakannzashi Jun 5, 2026
f02dab6
fix(reborn): address OpenAI product refs review
hanakannzashi Jun 6, 2026
6abf732
feat(reborn): route chat completions through ProductWorkflow
hanakannzashi Jun 5, 2026
b054561
fix(reborn): simplify chat completion timestamps
hanakannzashi Jun 5, 2026
d7d07ac
fix(reborn): use explicit ProductWorkflow submit door
hanakannzashi Jun 8, 2026
b96fda5
test(reborn): stabilize subagent cancellation propagation
hanakannzashi Jun 8, 2026
89f68e7
Validate durable OpenAI compat ref records
think-in-universe Jun 8, 2026
1e12d6c
Fix chat completions idempotency validation
think-in-universe Jun 8, 2026
63cfd9b
Format OpenAI compat storage review fixes
think-in-universe Jun 8, 2026
4a66e1a
Merge branch 'issue-4443-reborn-openai-product-refs' into issue-4444-…
think-in-universe Jun 8, 2026
68730db
feat(reborn): add OpenAI-compatible product refs (#4489)
hanakannzashi Jun 8, 2026
a4ea2e9
Address chat completions review comments
think-in-universe Jun 8, 2026
2d0aeb9
Persist chat completion idempotency replay metadata
think-in-universe Jun 8, 2026
4ccbe4a
Export OpenAI compat ack recording request
think-in-universe Jun 8, 2026
caf632c
Persist OpenAI compat accepted workflow acks
think-in-universe Jun 8, 2026
1a2789c
Merge main into OpenAI compatibility contracts
think-in-universe Jun 8, 2026
801d1e8
Merge OpenAI API contracts base into chat completions workflow
think-in-universe Jun 8, 2026
270ccc1
feat(reborn): route responses through ProductWorkflow
think-in-universe Jun 8, 2026
5ea0be2
fix(reborn): declare compat storage chrono dependency
think-in-universe Jun 8, 2026
fa6f010
fix(reborn): resolve chat completions review feedback
think-in-universe Jun 8, 2026
84e4882
fix(reborn): resolve chat completions review feedback
think-in-universe Jun 8, 2026
5aed75d
fix(reborn): update chat completions workflow stack
think-in-universe Jun 8, 2026
09f22e8
merge remote chat completions review fix
think-in-universe Jun 8, 2026
2cdcc89
fix(reborn): resolve responses workflow review feedback
think-in-universe Jun 8, 2026
423bb31
fix(reborn): keep responses cancel within adapter boundary
think-in-universe Jun 8, 2026
80146b5
feat(reborn): translate projection streams to OpenAI SSE
think-in-universe Jun 8, 2026
daba0c0
fix(reborn): format chat streaming workflow
think-in-universe Jun 8, 2026
23c0cdc
fix(reborn): format responses streaming workflow
think-in-universe Jun 8, 2026
e5c843d
fix(reborn): handle terminal projection stream status
think-in-universe Jun 8, 2026
4952bf2
fix(reborn): make OpenAI stream replay terminal-safe
think-in-universe Jun 8, 2026
7711c81
fix: add user-scoped WebUI tool approvals
think-in-universe Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions FEATURE_PARITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ Trace Commons issuer/TenantCtx note: the server-side `zmanian/tracedao-server` s
| GSuite WASM tools | ✅ | 🚧 | Reborn bundles operation-level Google Drive/Docs/Sheets/Slides WASM packages with host-mediated HTTP egress, product-auth scoped bearer injection, and manifest-declared Google OAuth setup metadata; full live-recorded parity remains follow-up |
| Hosted MCP extensions | ✅ | 🚧 | Reborn composes host-mediated MCP runtime, bundles the current Notion MCP supported tool set, wires Notion ProductAuth OAuth exchange/refresh, can use Reborn ProductAuth DCR OAuth setup through the host callback origin, and can activate hosted MCP packages with live `tools/list` schema discovery through host-staged product-auth credentials |
| NEAR AI MCP extension | ✅ | 🚧 | Host-bundled Reborn MCP extension exposes `nearai.search` via host-mediated HTTP and `llm_nearai_api_key`; manifest-declared product-auth credentials can now be staged through the hosted MCP runtime/discovery bridge, while NEAR remains a static supported-tool adapter |
| Tool policies (allow/deny) | ✅ | ✅ | |
| Tool policies (allow/deny) | ✅ | ✅ | User-scoped WebUI settings can list tools, toggle global always-allow for eligible tools, and set per-tool always/ask/disabled overrides without operator privileges |
| Exec approvals (`/approve`) | ✅ | ✅ | TUI approval overlay |
| Tool inventory cache | ✅ | ❌ | Coalesced effective-tool inventory cache with channel-registry invalidation |
| Pending exec approval `errorMessage` cleanup | ✅ | ❌ | Failed restart-interrupted approval-pending sessions instead of replaying stale ids |
Expand Down Expand Up @@ -741,7 +741,7 @@ Trace Commons issuer/TenantCtx note: the server-side `zmanian/tracedao-server` s
| Sandbox env sanitization | ✅ | 🚧 | Shell tool scrubs env vars (secret detection); Reborn process sandbox rejects sensitive raw env values in plans and uses placeholders for brokered credentials, but production secure-capture and MITM transport wiring remain partial |
| `OPENCLAW_*` env block | ✅ | ❌ | Untrusted workspace `.env` cannot inject OpenClaw runtime-control vars |
| Workspace `.env` injection blocks | ✅ | ❌ | Block `CLOUDSDK_PYTHON`, ambient Homebrew, Windows system PATH vars, `MINIMAX_API_HOST`, `npm_execpath` |
| Tool policies | ✅ | ✅ | |
| Tool policies | ✅ | ✅ | User-scoped WebUI settings can list tools, toggle global always-allow for eligible tools, and set per-tool always/ask/disabled overrides without operator privileges |
| Elevated mode | ✅ | ❌ | |
| Safe bins allowlist | ✅ | ❌ | Hardened path trust; non-user-writable absolute helpers for CLI/ffmpeg/OpenSSL |
| LD*/DYLD* validation | ✅ | ❌ | Block Mercurial/Rust/Make env redirects in host exec sanitization |
Expand Down
3 changes: 3 additions & 0 deletions crates/ironclaw_approvals/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ ironclaw_authorization = { path = "../ironclaw_authorization" }
ironclaw_events = { path = "../ironclaw_events" }
ironclaw_host_api = { path = "../ironclaw_host_api" }
ironclaw_run_state = { path = "../ironclaw_run_state" }
async-trait = "0.1"
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1", features = ["derive"] }
thiserror = "2"

[dev-dependencies]
Expand Down
107 changes: 107 additions & 0 deletions crates/ironclaw_approvals/src/auto_approve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use std::{collections::HashMap, sync::RwLock};

use async_trait::async_trait;
use chrono::Utc;
use ironclaw_host_api::{Principal, ResourceScope, TenantId, Timestamp, UserId};
use serde::{Deserialize, Serialize};

use crate::ToolPermissionStoreError;

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct AutoApproveSettingKey {
pub tenant_id: TenantId,
pub user_id: UserId,
}

impl AutoApproveSettingKey {
pub fn from_resource_scope(scope: &ResourceScope) -> Self {
Self {
tenant_id: scope.tenant_id.clone(),
user_id: scope.user_id.clone(),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AutoApproveSettingRecord {
pub key: AutoApproveSettingKey,
pub enabled: bool,
pub updated_by: Principal,
pub created_at: Timestamp,
pub updated_at: Timestamp,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AutoApproveSettingInput {
pub scope: ResourceScope,
pub enabled: bool,
pub updated_by: Principal,
}

#[async_trait]
pub trait AutoApproveSettingStore: Send + Sync {
async fn set(
&self,
input: AutoApproveSettingInput,
) -> Result<AutoApproveSettingRecord, ToolPermissionStoreError>;

async fn get(
&self,
key: &AutoApproveSettingKey,
) -> Result<Option<AutoApproveSettingRecord>, ToolPermissionStoreError>;

async fn is_enabled(&self, scope: &ResourceScope) -> Result<bool, ToolPermissionStoreError> {
let key = AutoApproveSettingKey::from_resource_scope(scope);
Ok(self.get(&key).await?.is_some_and(|record| record.enabled))
}
}

#[derive(Debug, Default)]
pub struct InMemoryAutoApproveSettingStore {
settings: RwLock<HashMap<AutoApproveSettingKey, AutoApproveSettingRecord>>,
}

impl InMemoryAutoApproveSettingStore {
pub fn new() -> Self {
Self::default()
}
}

#[async_trait]
impl AutoApproveSettingStore for InMemoryAutoApproveSettingStore {
async fn set(
&self,
input: AutoApproveSettingInput,
) -> Result<AutoApproveSettingRecord, ToolPermissionStoreError> {
let key = AutoApproveSettingKey::from_resource_scope(&input.scope);
let mut settings = self
.settings
.write()
.unwrap_or_else(|poisoned| poisoned.into_inner());
let now = Utc::now();
let created_at = settings
.get(&key)
.map_or(now, |existing| existing.created_at);
let record = AutoApproveSettingRecord {
key: key.clone(),
enabled: input.enabled,
updated_by: input.updated_by,
created_at,
updated_at: now,
};
settings.insert(key, record.clone());
Ok(record)
}

async fn get(
&self,
key: &AutoApproveSettingKey,
) -> Result<Option<AutoApproveSettingRecord>, ToolPermissionStoreError> {
Ok(self
.settings
.read()
.unwrap_or_else(|poisoned| poisoned.into_inner())
.get(key)
.cloned())
}
}
20 changes: 20 additions & 0 deletions crates/ironclaw_approvals/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ use ironclaw_host_api::{
use ironclaw_run_state::{ApprovalRecord, ApprovalRequestStore, ApprovalStatus, RunStateError};
use thiserror::Error;

mod auto_approve;
mod persistent_policy;
mod tool_permission;

pub use auto_approve::{
AutoApproveSettingInput, AutoApproveSettingKey, AutoApproveSettingRecord,
AutoApproveSettingStore, InMemoryAutoApproveSettingStore,
};
pub use persistent_policy::{
InMemoryPersistentApprovalPolicyStore, PersistentApprovalAction, PersistentApprovalPolicy,
PersistentApprovalPolicyError, PersistentApprovalPolicyInput, PersistentApprovalPolicyKey,
PersistentApprovalPolicyStore, PersistentApprovalScope,
permission_mode_allows_persistent_approval, persistent_approval_grant_issuer,
};
pub use tool_permission::{
InMemoryToolPermissionOverrideStore, ToolPermissionOverride, ToolPermissionOverrideInput,
ToolPermissionOverrideKey, ToolPermissionOverrideRecord, ToolPermissionOverrideStore,
ToolPermissionState, ToolPermissionStoreError,
};

pub struct ApprovalResolver<'a, A, L>
where
A: ApprovalRequestStore + ?Sized,
Expand Down
Loading
Loading