Expose exact requirements through app server

This commit is contained in:
Abhinav Vedmala
2026-06-17 02:36:52 +00:00
parent 79dd7b63ee
commit e7efba1fc3
9 changed files with 295 additions and 2 deletions
@@ -8160,6 +8160,12 @@
"null"
]
},
"allowLoginShell": {
"type": [
"boolean",
"null"
]
},
"allowManagedHooksOnly": {
"type": [
"boolean",
@@ -8217,6 +8223,12 @@
"null"
]
},
"checkForUpdateOnStartup": {
"type": [
"boolean",
"null"
]
},
"computerUse": {
"anyOf": [
{
@@ -8251,6 +8263,52 @@
"object",
"null"
]
},
"feedback": {
"anyOf": [
{
"$ref": "#/definitions/v2/FeedbackRequirements"
},
{
"type": "null"
}
]
},
"logDir": {
"anyOf": [
{
"$ref": "#/definitions/v2/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"modelCatalogJson": {
"anyOf": [
{
"$ref": "#/definitions/v2/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"sqliteHome": {
"anyOf": [
{
"$ref": "#/definitions/v2/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"windowsSandboxPrivateDesktop": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -9249,6 +9307,17 @@
],
"type": "string"
},
"FeedbackRequirements": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"FeedbackUploadParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
@@ -4473,6 +4473,12 @@
"null"
]
},
"allowLoginShell": {
"type": [
"boolean",
"null"
]
},
"allowManagedHooksOnly": {
"type": [
"boolean",
@@ -4530,6 +4536,12 @@
"null"
]
},
"checkForUpdateOnStartup": {
"type": [
"boolean",
"null"
]
},
"computerUse": {
"anyOf": [
{
@@ -4564,6 +4576,52 @@
"object",
"null"
]
},
"feedback": {
"anyOf": [
{
"$ref": "#/definitions/FeedbackRequirements"
},
{
"type": "null"
}
]
},
"logDir": {
"anyOf": [
{
"$ref": "#/definitions/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"modelCatalogJson": {
"anyOf": [
{
"$ref": "#/definitions/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"sqliteHome": {
"anyOf": [
{
"$ref": "#/definitions/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"windowsSandboxPrivateDesktop": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -5562,6 +5620,17 @@
],
"type": "string"
},
"FeedbackRequirements": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"FeedbackUploadParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
@@ -1,6 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AbsolutePathBuf": {
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
"type": "string"
},
"ApprovalsReviewer": {
"description": "Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `auto_review` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request. The legacy value `guardian_subagent` is accepted for compatibility.",
"enum": [
@@ -79,6 +83,12 @@
"null"
]
},
"allowLoginShell": {
"type": [
"boolean",
"null"
]
},
"allowManagedHooksOnly": {
"type": [
"boolean",
@@ -136,6 +146,12 @@
"null"
]
},
"checkForUpdateOnStartup": {
"type": [
"boolean",
"null"
]
},
"computerUse": {
"anyOf": [
{
@@ -170,6 +186,52 @@
"object",
"null"
]
},
"feedback": {
"anyOf": [
{
"$ref": "#/definitions/FeedbackRequirements"
},
{
"type": "null"
}
]
},
"logDir": {
"anyOf": [
{
"$ref": "#/definitions/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"modelCatalogJson": {
"anyOf": [
{
"$ref": "#/definitions/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"sqliteHome": {
"anyOf": [
{
"$ref": "#/definitions/AbsolutePathBuf"
},
{
"type": "null"
}
]
},
"windowsSandboxPrivateDesktop": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
@@ -274,6 +336,17 @@
],
"type": "object"
},
"FeedbackRequirements": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"ManagedHooksRequirements": {
"properties": {
"PermissionRequest": {
@@ -1,11 +1,13 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
import type { WebSearchMode } from "../WebSearchMode";
import type { AskForApproval } from "./AskForApproval";
import type { ComputerUseRequirements } from "./ComputerUseRequirements";
import type { FeedbackRequirements } from "./FeedbackRequirements";
import type { ResidencyRequirement } from "./ResidencyRequirement";
import type { SandboxMode } from "./SandboxMode";
import type { WindowsSandboxSetupMode } from "./WindowsSandboxSetupMode";
export type ConfigRequirements = {allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedWindowsSandboxImplementations: Array<WindowsSandboxSetupMode> | null, allowedPermissionProfiles: { [key in string]?: boolean } | null, defaultPermissions: string | null, allowedWebSearchModes: Array<WebSearchMode> | null, allowManagedHooksOnly: boolean | null, allowAppshots: boolean | null, allowRemoteControl: boolean | null, computerUse: ComputerUseRequirements | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null};
export type ConfigRequirements = {allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedWindowsSandboxImplementations: Array<WindowsSandboxSetupMode> | null, allowedPermissionProfiles: { [key in string]?: boolean } | null, defaultPermissions: string | null, allowedWebSearchModes: Array<WebSearchMode> | null, allowManagedHooksOnly: boolean | null, allowAppshots: boolean | null, allowRemoteControl: boolean | null, computerUse: ComputerUseRequirements | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null, sqliteHome: AbsolutePathBuf | null, logDir: AbsolutePathBuf | null, modelCatalogJson: AbsolutePathBuf | null, checkForUpdateOnStartup: boolean | null, allowLoginShell: boolean | null, feedback: FeedbackRequirements | null, windowsSandboxPrivateDesktop: boolean | null};
@@ -0,0 +1,5 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type FeedbackRequirements = { enabled: boolean | null, };
@@ -117,6 +117,7 @@ export type { ExternalAgentConfigImportResponse } from "./ExternalAgentConfigImp
export type { ExternalAgentConfigImportTypeResult } from "./ExternalAgentConfigImportTypeResult";
export type { ExternalAgentConfigMigrationItem } from "./ExternalAgentConfigMigrationItem";
export type { ExternalAgentConfigMigrationItemType } from "./ExternalAgentConfigMigrationItemType";
export type { FeedbackRequirements } from "./FeedbackRequirements";
export type { FeedbackUploadParams } from "./FeedbackUploadParams";
export type { FeedbackUploadResponse } from "./FeedbackUploadResponse";
export type { FileChangeApprovalDecision } from "./FileChangeApprovalDecision";
@@ -389,6 +389,20 @@ pub struct ConfigRequirements {
pub enforce_residency: Option<ResidencyRequirement>,
#[experimental("configRequirements/read.network")]
pub network: Option<NetworkRequirements>,
pub sqlite_home: Option<AbsolutePathBuf>,
pub log_dir: Option<AbsolutePathBuf>,
pub model_catalog_json: Option<AbsolutePathBuf>,
pub check_for_update_on_startup: Option<bool>,
pub allow_login_shell: Option<bool>,
pub feedback: Option<FeedbackRequirements>,
pub windows_sandbox_private_desktop: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct FeedbackRequirements {
pub enabled: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
@@ -1719,6 +1719,13 @@ fn config_requirements_granular_allowed_approval_policy_is_marked_experimental()
hooks: None,
enforce_residency: None,
network: None,
sqlite_home: None,
log_dir: None,
model_catalog_json: None,
check_for_update_on_startup: None,
allow_login_shell: None,
feedback: None,
windows_sandbox_private_desktop: None,
});
assert_eq!(reason, Some("askForApproval.granular"));
@@ -21,6 +21,7 @@ use codex_app_server_protocol::ConfiguredHookHandler;
use codex_app_server_protocol::ConfiguredHookMatcherGroup;
use codex_app_server_protocol::ExperimentalFeatureEnablementSetParams;
use codex_app_server_protocol::ExperimentalFeatureEnablementSetResponse;
use codex_app_server_protocol::FeedbackRequirements;
use codex_app_server_protocol::JSONRPCErrorError;
use codex_app_server_protocol::ManagedHooksRequirements;
use codex_app_server_protocol::ModelProviderCapabilitiesReadResponse;
@@ -314,6 +315,11 @@ impl ConfigRequestProcessor {
}
fn map_requirements_toml_to_api(requirements: ConfigRequirementsToml) -> ConfigRequirements {
let windows_sandbox_private_desktop = requirements
.windows
.as_ref()
.and_then(|windows| windows.sandbox_private_desktop);
ConfigRequirements {
allowed_approval_policies: requirements.allowed_approval_policies.map(|policies| {
policies
@@ -376,6 +382,15 @@ fn map_requirements_toml_to_api(requirements: ConfigRequirementsToml) -> ConfigR
.enforce_residency
.map(map_residency_requirement_to_api),
network: requirements.network.map(map_network_requirements_to_api),
sqlite_home: requirements.sqlite_home,
log_dir: requirements.log_dir,
model_catalog_json: requirements.model_catalog_json,
check_for_update_on_startup: requirements.check_for_update_on_startup,
allow_login_shell: requirements.allow_login_shell,
feedback: requirements.feedback.map(|feedback| FeedbackRequirements {
enabled: feedback.enabled,
}),
windows_sandbox_private_desktop,
}
}
@@ -566,10 +581,13 @@ fn config_write_error(code: ConfigWriteErrorCode, message: impl Into<String>) ->
#[cfg(test)]
mod tests {
use super::map_requirements_toml_to_api;
use codex_app_server_protocol::FeedbackRequirements;
use codex_app_server_protocol::WindowsSandboxSetupMode;
use codex_config::ComputerUseRequirementsToml;
use codex_config::ConfigRequirementsToml;
use codex_config::WindowsRequirementsToml;
use codex_config::types::FeedbackConfigToml;
use codex_utils_absolute_path::AbsolutePathBuf;
use pretty_assertions::assert_eq;
use std::collections::BTreeMap;
@@ -654,7 +672,7 @@ mod tests {
codex_config::types::WindowsSandboxModeToml::Elevated,
codex_config::types::WindowsSandboxModeToml::Unelevated,
]),
sandbox_private_desktop: None,
sandbox_private_desktop: Some(false),
}),
..ConfigRequirementsToml::default()
});
@@ -666,5 +684,40 @@ mod tests {
WindowsSandboxSetupMode::Unelevated,
])
);
assert_eq!(mapped.windows_sandbox_private_desktop, Some(false));
}
#[test]
fn requirements_api_includes_exact_managed_values() {
let sqlite_home = AbsolutePathBuf::try_from(std::env::temp_dir().join("managed-state"))
.expect("managed sqlite home should be absolute");
let log_dir = AbsolutePathBuf::try_from(std::env::temp_dir().join("managed-logs"))
.expect("managed log dir should be absolute");
let model_catalog_json =
AbsolutePathBuf::try_from(std::env::temp_dir().join("managed-models.json"))
.expect("managed model catalog path should be absolute");
let mapped = map_requirements_toml_to_api(ConfigRequirementsToml {
sqlite_home: Some(sqlite_home.clone()),
log_dir: Some(log_dir.clone()),
model_catalog_json: Some(model_catalog_json.clone()),
check_for_update_on_startup: Some(false),
allow_login_shell: Some(false),
feedback: Some(FeedbackConfigToml {
enabled: Some(false),
}),
..ConfigRequirementsToml::default()
});
assert_eq!(mapped.sqlite_home, Some(sqlite_home));
assert_eq!(mapped.log_dir, Some(log_dir));
assert_eq!(mapped.model_catalog_json, Some(model_catalog_json));
assert_eq!(mapped.check_for_update_on_startup, Some(false));
assert_eq!(mapped.allow_login_shell, Some(false));
assert_eq!(
mapped.feedback,
Some(FeedbackRequirements {
enabled: Some(false),
})
);
}
}