mirror of
https://github.com/openai/codex.git
synced 2026-11-09 00:39:32 +00:00
Add per-account approval settings for apps (#42047)
## What changed - Add `apps.<app_id>.links.<link_id>` configuration for overriding `approvals_reviewer` and `default_tools_approval_mode` per connected account. - Expose link settings through the app-server protocol and generated JSON and TypeScript schemas. ## Testing - Extend `config/read` coverage for populated, empty, and absent `links` sections. GitOrigin-RevId: 43004d2722439060fdadc5e5cd9ed3108774ecaf
This commit is contained in:
1 parent
90ae0c4ef9
commit
0ec375eb70
15 files changed
+316
-14
No files matched your search
+41
@@ -6999,6 +6999,17 @@
|
|||||||
"default": true,
|
"default": true,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"links": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/v2/AppLinksConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Per-account approval settings keyed by link ID."
|
||||||
|
},
|
||||||
"open_world_enabled": {
|
"open_world_enabled": {
|
||||||
"type": [
|
"type": [
|
||||||
"boolean",
|
"boolean",
|
||||||
@@ -7127,6 +7138,36 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"AppLinkConfig": {
|
||||||
|
"description": "Approval settings for a connected account within an app.",
|
||||||
|
"properties": {
|
||||||
|
"approvals_reviewer": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/v2/ApprovalsReviewer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_tools_approval_mode": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/v2/AppToolApproval"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"AppLinksConfig": {
|
||||||
|
"description": "Account settings for a single app.",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"AppListUpdatedNotification": {
|
"AppListUpdatedNotification": {
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"description": "EXPERIMENTAL - notification emitted when the app list changes.",
|
"description": "EXPERIMENTAL - notification emitted when the app list changes.",
|
||||||
|
|||||||
+41
@@ -490,6 +490,17 @@
|
|||||||
"default": true,
|
"default": true,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"links": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/AppLinksConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Per-account approval settings keyed by link ID."
|
||||||
|
},
|
||||||
"open_world_enabled": {
|
"open_world_enabled": {
|
||||||
"type": [
|
"type": [
|
||||||
"boolean",
|
"boolean",
|
||||||
@@ -618,6 +629,36 @@
|
|||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"AppLinkConfig": {
|
||||||
|
"description": "Approval settings for a connected account within an app.",
|
||||||
|
"properties": {
|
||||||
|
"approvals_reviewer": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/ApprovalsReviewer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_tools_approval_mode": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/AppToolApproval"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"AppLinksConfig": {
|
||||||
|
"description": "Account settings for a single app.",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"AppListUpdatedNotification": {
|
"AppListUpdatedNotification": {
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"description": "EXPERIMENTAL - notification emitted when the app list changes.",
|
"description": "EXPERIMENTAL - notification emitted when the app list changes.",
|
||||||
|
|||||||
@@ -62,6 +62,17 @@
|
|||||||
"default": true,
|
"default": true,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"links": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/AppLinksConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Per-account approval settings keyed by link ID."
|
||||||
|
},
|
||||||
"open_world_enabled": {
|
"open_world_enabled": {
|
||||||
"type": [
|
"type": [
|
||||||
"boolean",
|
"boolean",
|
||||||
@@ -81,6 +92,36 @@
|
|||||||
},
|
},
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"AppLinkConfig": {
|
||||||
|
"description": "Approval settings for a connected account within an app.",
|
||||||
|
"properties": {
|
||||||
|
"approvals_reviewer": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/ApprovalsReviewer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default_tools_approval_mode": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/AppToolApproval"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"AppLinksConfig": {
|
||||||
|
"description": "Account settings for a single app.",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"AppToolApproval": {
|
"AppToolApproval": {
|
||||||
"enum": [
|
"enum": [
|
||||||
"auto",
|
"auto",
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,10 @@
|
|||||||
|
// 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 { AppToolApproval } from "./AppToolApproval";
|
||||||
|
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Account settings for a single app.
|
||||||
|
*/
|
||||||
|
export type AppLinksConfig = { [key in string]?: { approvals_reviewer: ApprovalsReviewer | null, default_tools_approval_mode: AppToolApproval | null, } };
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
// 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.
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
import type { AppLinksConfig } from "./AppLinksConfig";
|
||||||
import type { AppToolApproval } from "./AppToolApproval";
|
import type { AppToolApproval } from "./AppToolApproval";
|
||||||
import type { AppToolsConfig } from "./AppToolsConfig";
|
import type { AppToolsConfig } from "./AppToolsConfig";
|
||||||
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
|
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
|
||||||
import type { AppsDefaultConfig } from "./AppsDefaultConfig";
|
import type { AppsDefaultConfig } from "./AppsDefaultConfig";
|
||||||
|
|
||||||
export type AppsConfig = { _default: AppsDefaultConfig | null, } & ({ [key in string]?: { enabled: boolean, approvals_reviewer: ApprovalsReviewer | null, destructive_enabled: boolean | null, open_world_enabled: boolean | null, default_tools_approval_mode: AppToolApproval | null, default_tools_enabled: boolean | null, tools: AppToolsConfig | null, } });
|
export type AppsConfig = { _default: AppsDefaultConfig | null, } & ({ [key in string]?: { enabled: boolean, approvals_reviewer: ApprovalsReviewer | null, destructive_enabled: boolean | null, open_world_enabled: boolean | null, default_tools_approval_mode: AppToolApproval | null, default_tools_enabled: boolean | null, tools: AppToolsConfig | null,
|
||||||
|
/**
|
||||||
|
* Per-account approval settings keyed by link ID.
|
||||||
|
*/
|
||||||
|
links: AppLinksConfig | null, } });
|
||||||
@@ -20,6 +20,7 @@ export type { AllowDenyRequirement } from "./AllowDenyRequirement";
|
|||||||
export type { AnalyticsConfig } from "./AnalyticsConfig";
|
export type { AnalyticsConfig } from "./AnalyticsConfig";
|
||||||
export type { AppBranding } from "./AppBranding";
|
export type { AppBranding } from "./AppBranding";
|
||||||
export type { AppInfo } from "./AppInfo";
|
export type { AppInfo } from "./AppInfo";
|
||||||
|
export type { AppLinksConfig } from "./AppLinksConfig";
|
||||||
export type { AppListUpdatedNotification } from "./AppListUpdatedNotification";
|
export type { AppListUpdatedNotification } from "./AppListUpdatedNotification";
|
||||||
export type { AppMetadata } from "./AppMetadata";
|
export type { AppMetadata } from "./AppMetadata";
|
||||||
export type { AppReview } from "./AppReview";
|
export type { AppReview } from "./AppReview";
|
||||||
|
|||||||
@@ -209,6 +209,24 @@ pub struct AppToolsConfig {
|
|||||||
pub tools: HashMap<String, AppToolConfig>,
|
pub tools: HashMap<String, AppToolConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Approval settings for a connected account within an app.
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[ts(export_to = "v2/")]
|
||||||
|
pub struct AppLinkConfig {
|
||||||
|
pub approvals_reviewer: Option<ApprovalsReviewer>,
|
||||||
|
pub default_tools_approval_mode: Option<AppToolApproval>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Account settings for a single app.
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[ts(export_to = "v2/")]
|
||||||
|
pub struct AppLinksConfig {
|
||||||
|
#[serde(default, flatten)]
|
||||||
|
pub links: HashMap<String, AppLinkConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
#[ts(export_to = "v2/")]
|
#[ts(export_to = "v2/")]
|
||||||
@@ -221,6 +239,8 @@ pub struct AppConfig {
|
|||||||
pub default_tools_approval_mode: Option<AppToolApproval>,
|
pub default_tools_approval_mode: Option<AppToolApproval>,
|
||||||
pub default_tools_enabled: Option<bool>,
|
pub default_tools_enabled: Option<bool>,
|
||||||
pub tools: Option<AppToolsConfig>,
|
pub tools: Option<AppToolsConfig>,
|
||||||
|
/// Per-account approval settings keyed by link ID.
|
||||||
|
pub links: Option<AppLinksConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||||
|
|||||||
@@ -2416,6 +2416,11 @@ Setting the app value to `"user"` routes its approval prompts to the user
|
|||||||
instead of Guardian; setting it to `"auto_review"` opts that app into Guardian
|
instead of Guardian; setting it to `"auto_review"` opts that app into Guardian
|
||||||
review when allowed by configuration requirements.
|
review when allowed by configuration requirements.
|
||||||
|
|
||||||
|
Per-account approval configuration uses `apps.<app_id>.links.<link_id>` with
|
||||||
|
`approvals_reviewer` and `default_tools_approval_mode`. Like `tools`, `links` is
|
||||||
|
an optional section: `config/read` returns `null` when it is absent, `{}` when
|
||||||
|
it is explicitly empty, and a map keyed by link ID when accounts are configured.
|
||||||
|
|
||||||
Use `apps._default.default_tools_approval_mode` to set the approval mode for
|
Use `apps._default.default_tools_approval_mode` to set the approval mode for
|
||||||
tools without a per-app or per-tool override. Supported values are `"auto"`,
|
tools without a per-app or per-tool override. Supported values are `"auto"`,
|
||||||
`"prompt"`, `"writes"`, and `"approve"`. The `"writes"` mode prompts for tools
|
`"prompt"`, `"writes"`, and `"approve"`. The `"writes"` mode prompts for tools
|
||||||
|
|||||||
@@ -357,6 +357,7 @@ async fn write_value_supports_nested_app_paths() -> Result<()> {
|
|||||||
default_tools_approval_mode: Some(AppToolApproval::Prompt),
|
default_tools_approval_mode: Some(AppToolApproval::Prompt),
|
||||||
default_tools_enabled: None,
|
default_tools_enabled: None,
|
||||||
tools: None,
|
tools: None,
|
||||||
|
links: None,
|
||||||
},
|
},
|
||||||
)]),
|
)]),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ use app_test_support::test_path_buf_with_windows;
|
|||||||
use app_test_support::test_tmp_path_buf;
|
use app_test_support::test_tmp_path_buf;
|
||||||
use codex_app_server_protocol::AllowDenyRequirement;
|
use codex_app_server_protocol::AllowDenyRequirement;
|
||||||
use codex_app_server_protocol::AppConfig;
|
use codex_app_server_protocol::AppConfig;
|
||||||
|
use codex_app_server_protocol::AppLinkConfig;
|
||||||
|
use codex_app_server_protocol::AppLinksConfig;
|
||||||
use codex_app_server_protocol::AppToolApproval;
|
use codex_app_server_protocol::AppToolApproval;
|
||||||
use codex_app_server_protocol::ApprovalsReviewer;
|
use codex_app_server_protocol::ApprovalsReviewer;
|
||||||
use codex_app_server_protocol::AppsConfig;
|
use codex_app_server_protocol::AppsConfig;
|
||||||
@@ -1020,6 +1022,18 @@ enabled = false
|
|||||||
approvals_reviewer = "user"
|
approvals_reviewer = "user"
|
||||||
destructive_enabled = false
|
destructive_enabled = false
|
||||||
default_tools_approval_mode = "prompt"
|
default_tools_approval_mode = "prompt"
|
||||||
|
|
||||||
|
[apps.app1.links.link_work]
|
||||||
|
approvals_reviewer = "auto_review"
|
||||||
|
default_tools_approval_mode = "approve"
|
||||||
|
|
||||||
|
[apps.app1.links.link_personal]
|
||||||
|
default_tools_approval_mode = "writes"
|
||||||
|
|
||||||
|
[apps.app_without_links]
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[apps.app_with_empty_links.links]
|
||||||
"#,
|
"#,
|
||||||
)?;
|
)?;
|
||||||
let codex_home_path = codex_home.path().canonicalize()?;
|
let codex_home_path = codex_home.path().canonicalize()?;
|
||||||
@@ -1037,11 +1051,21 @@ default_tools_approval_mode = "prompt"
|
|||||||
cwd: None,
|
cwd: None,
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
let response: serde_json::Value =
|
||||||
|
timeout(DEFAULT_READ_TIMEOUT, mcp.read_response(request_id)).await??;
|
||||||
|
assert_eq!(
|
||||||
|
response["config"]["apps"]["app_without_links"].get("links"),
|
||||||
|
Some(&json!(null)),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
response["config"]["apps"]["app_with_empty_links"].get("links"),
|
||||||
|
Some(&json!({})),
|
||||||
|
);
|
||||||
let ConfigReadResponse {
|
let ConfigReadResponse {
|
||||||
config,
|
config,
|
||||||
origins,
|
origins,
|
||||||
layers,
|
layers,
|
||||||
} = timeout(DEFAULT_READ_TIMEOUT, mcp.read_response(request_id)).await??;
|
} = serde_json::from_value(response)?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.apps,
|
config.apps,
|
||||||
@@ -1053,18 +1077,66 @@ default_tools_approval_mode = "prompt"
|
|||||||
open_world_enabled: true,
|
open_world_enabled: true,
|
||||||
default_tools_approval_mode: Some(AppToolApproval::Writes),
|
default_tools_approval_mode: Some(AppToolApproval::Writes),
|
||||||
}),
|
}),
|
||||||
apps: std::collections::HashMap::from([(
|
apps: std::collections::HashMap::from([
|
||||||
"app1".to_string(),
|
(
|
||||||
AppConfig {
|
"app1".to_string(),
|
||||||
enabled: false,
|
AppConfig {
|
||||||
approvals_reviewer: Some(ApprovalsReviewer::User),
|
enabled: false,
|
||||||
destructive_enabled: Some(false),
|
approvals_reviewer: Some(ApprovalsReviewer::User),
|
||||||
open_world_enabled: None,
|
destructive_enabled: Some(false),
|
||||||
default_tools_approval_mode: Some(AppToolApproval::Prompt),
|
open_world_enabled: None,
|
||||||
default_tools_enabled: None,
|
default_tools_approval_mode: Some(AppToolApproval::Prompt),
|
||||||
tools: None,
|
default_tools_enabled: None,
|
||||||
},
|
tools: None,
|
||||||
)]),
|
links: Some(AppLinksConfig {
|
||||||
|
links: std::collections::HashMap::from([
|
||||||
|
(
|
||||||
|
"link_work".to_string(),
|
||||||
|
AppLinkConfig {
|
||||||
|
approvals_reviewer: Some(ApprovalsReviewer::AutoReview),
|
||||||
|
default_tools_approval_mode: Some(AppToolApproval::Approve),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"link_personal".to_string(),
|
||||||
|
AppLinkConfig {
|
||||||
|
approvals_reviewer: None,
|
||||||
|
default_tools_approval_mode: Some(AppToolApproval::Writes),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"app_without_links".to_string(),
|
||||||
|
AppConfig {
|
||||||
|
enabled: true,
|
||||||
|
approvals_reviewer: None,
|
||||||
|
destructive_enabled: None,
|
||||||
|
open_world_enabled: None,
|
||||||
|
default_tools_approval_mode: None,
|
||||||
|
default_tools_enabled: None,
|
||||||
|
tools: None,
|
||||||
|
links: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"app_with_empty_links".to_string(),
|
||||||
|
AppConfig {
|
||||||
|
enabled: true,
|
||||||
|
approvals_reviewer: None,
|
||||||
|
destructive_enabled: None,
|
||||||
|
open_world_enabled: None,
|
||||||
|
default_tools_approval_mode: None,
|
||||||
|
default_tools_enabled: None,
|
||||||
|
tools: None,
|
||||||
|
links: Some(AppLinksConfig {
|
||||||
|
links: std::collections::HashMap::new(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -455,6 +455,28 @@ pub struct AppToolsConfig {
|
|||||||
pub tools: HashMap<String, AppToolConfig>,
|
pub tools: HashMap<String, AppToolConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Approval settings for a connected account within an app.
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
|
||||||
|
#[schemars(deny_unknown_fields)]
|
||||||
|
pub struct AppLinkConfig {
|
||||||
|
/// Reviewer for approval prompts from this account, overriding the app default.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub approvals_reviewer: Option<ApprovalsReviewer>,
|
||||||
|
|
||||||
|
/// Approval mode for this account unless a tool override exists.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub default_tools_approval_mode: Option<AppToolApproval>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Account settings for a single app.
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
|
||||||
|
#[schemars(deny_unknown_fields)]
|
||||||
|
pub struct AppLinksConfig {
|
||||||
|
/// Per-account approval settings keyed by link ID.
|
||||||
|
#[serde(default, flatten)]
|
||||||
|
pub links: HashMap<String, AppLinkConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Config values for a single app/connector.
|
/// Config values for a single app/connector.
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema)]
|
||||||
#[schemars(deny_unknown_fields)]
|
#[schemars(deny_unknown_fields)]
|
||||||
@@ -486,6 +508,10 @@ pub struct AppConfig {
|
|||||||
/// Per-tool settings for this app.
|
/// Per-tool settings for this app.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub tools: Option<AppToolsConfig>,
|
pub tools: Option<AppToolsConfig>,
|
||||||
|
|
||||||
|
/// Per-account approval settings keyed by link ID.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub links: Option<AppLinksConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// App/connector settings loaded from `config.toml`.
|
/// App/connector settings loaded from `config.toml`.
|
||||||
|
|||||||
@@ -147,6 +147,14 @@
|
|||||||
"description": "When `false`, Codex does not surface this app.",
|
"description": "When `false`, Codex does not surface this app.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"links": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/AppLinksConfig"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Per-account approval settings keyed by link ID."
|
||||||
|
},
|
||||||
"open_world_enabled": {
|
"open_world_enabled": {
|
||||||
"description": "Whether tools with `open_world_hint = true` are allowed for this app.",
|
"description": "Whether tools with `open_world_hint = true` are allowed for this app.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
@@ -162,6 +170,36 @@
|
|||||||
},
|
},
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"AppLinkConfig": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Approval settings for a connected account within an app.",
|
||||||
|
"properties": {
|
||||||
|
"approvals_reviewer": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/ApprovalsReviewer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Reviewer for approval prompts from this account, overriding the app default."
|
||||||
|
},
|
||||||
|
"default_tools_approval_mode": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/AppToolApproval"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Approval mode for this account unless a tool override exists."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"AppLinksConfig": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/definitions/AppLinkConfig"
|
||||||
|
},
|
||||||
|
"description": "Account settings for a single app.",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"AppToolApproval": {
|
"AppToolApproval": {
|
||||||
"enum": [
|
"enum": [
|
||||||
"auto",
|
"auto",
|
||||||
|
|||||||
@@ -2065,6 +2065,7 @@ async fn persist_codex_app_tool_approval_writes_tool_override() {
|
|||||||
},
|
},
|
||||||
)]),
|
)]),
|
||||||
}),
|
}),
|
||||||
|
links: None,
|
||||||
},
|
},
|
||||||
)]),
|
)]),
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in new issue
Block a user