app-server: use permission ids and runtime workspace roots

This commit is contained in:
Michael Bolin
2026-05-14 18:06:33 -07:00
parent 033e494dd4
commit d46638770b
56 changed files with 799 additions and 602 deletions
@@ -1850,31 +1850,6 @@
}
]
},
"PermissionProfileModificationParams": {
"oneOf": [
{
"description": "Additional concrete directory that should be writable.",
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"additionalWritableRoot"
],
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "AdditionalWritableRootPermissionProfileModificationParams",
"type": "object"
}
]
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
@@ -1886,40 +1861,6 @@
],
"type": "object"
},
"PermissionProfileSelectionParams": {
"oneOf": [
{
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
"properties": {
"id": {
"type": "string"
},
"modifications": {
"items": {
"$ref": "#/definitions/PermissionProfileModificationParams"
},
"type": [
"array",
"null"
]
},
"type": {
"enum": [
"profile"
],
"title": "ProfilePermissionProfileSelectionParamsType",
"type": "string"
}
},
"required": [
"id",
"type"
],
"title": "ProfilePermissionProfileSelectionParams",
"type": "object"
}
]
},
"Personality": {
"enum": [
"none",
@@ -11732,31 +11732,6 @@
}
]
},
"PermissionProfileModificationParams": {
"oneOf": [
{
"description": "Additional concrete directory that should be writable.",
"properties": {
"path": {
"$ref": "#/definitions/v2/AbsolutePathBuf"
},
"type": {
"enum": [
"additionalWritableRoot"
],
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "AdditionalWritableRootPermissionProfileModificationParams",
"type": "object"
}
]
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
@@ -11768,40 +11743,6 @@
],
"type": "object"
},
"PermissionProfileSelectionParams": {
"oneOf": [
{
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
"properties": {
"id": {
"type": "string"
},
"modifications": {
"items": {
"$ref": "#/definitions/v2/PermissionProfileModificationParams"
},
"type": [
"array",
"null"
]
},
"type": {
"enum": [
"profile"
],
"title": "ProfilePermissionProfileSelectionParamsType",
"type": "string"
}
},
"required": [
"id",
"type"
],
"title": "ProfilePermissionProfileSelectionParams",
"type": "object"
}
]
},
"Personality": {
"enum": [
"none",
@@ -8281,31 +8281,6 @@
}
]
},
"PermissionProfileModificationParams": {
"oneOf": [
{
"description": "Additional concrete directory that should be writable.",
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"additionalWritableRoot"
],
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "AdditionalWritableRootPermissionProfileModificationParams",
"type": "object"
}
]
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
@@ -8317,40 +8292,6 @@
],
"type": "object"
},
"PermissionProfileSelectionParams": {
"oneOf": [
{
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
"properties": {
"id": {
"type": "string"
},
"modifications": {
"items": {
"$ref": "#/definitions/PermissionProfileModificationParams"
},
"type": [
"array",
"null"
]
},
"type": {
"enum": [
"profile"
],
"title": "ProfilePermissionProfileSelectionParamsType",
"type": "string"
}
},
"required": [
"id",
"type"
],
"title": "ProfilePermissionProfileSelectionParams",
"type": "object"
}
]
},
"Personality": {
"enum": [
"none",
@@ -1,10 +1,6 @@
{
"$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": [
@@ -64,65 +60,6 @@
}
]
},
"PermissionProfileModificationParams": {
"oneOf": [
{
"description": "Additional concrete directory that should be writable.",
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"additionalWritableRoot"
],
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "AdditionalWritableRootPermissionProfileModificationParams",
"type": "object"
}
]
},
"PermissionProfileSelectionParams": {
"oneOf": [
{
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
"properties": {
"id": {
"type": "string"
},
"modifications": {
"items": {
"$ref": "#/definitions/PermissionProfileModificationParams"
},
"type": [
"array",
"null"
]
},
"type": {
"enum": [
"profile"
],
"title": "ProfilePermissionProfileSelectionParamsType",
"type": "string"
}
},
"required": [
"id",
"type"
],
"title": "ProfilePermissionProfileSelectionParams",
"type": "object"
}
]
},
"SandboxMode": {
"enum": [
"read-only",
@@ -1,10 +1,6 @@
{
"$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": [
@@ -298,65 +294,6 @@
}
]
},
"PermissionProfileModificationParams": {
"oneOf": [
{
"description": "Additional concrete directory that should be writable.",
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"additionalWritableRoot"
],
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "AdditionalWritableRootPermissionProfileModificationParams",
"type": "object"
}
]
},
"PermissionProfileSelectionParams": {
"oneOf": [
{
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
"properties": {
"id": {
"type": "string"
},
"modifications": {
"items": {
"$ref": "#/definitions/PermissionProfileModificationParams"
},
"type": [
"array",
"null"
]
},
"type": {
"enum": [
"profile"
],
"title": "ProfilePermissionProfileSelectionParamsType",
"type": "string"
}
},
"required": [
"id",
"type"
],
"title": "ProfilePermissionProfileSelectionParams",
"type": "object"
}
]
},
"Personality": {
"enum": [
"none",
@@ -90,65 +90,6 @@
],
"type": "object"
},
"PermissionProfileModificationParams": {
"oneOf": [
{
"description": "Additional concrete directory that should be writable.",
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"additionalWritableRoot"
],
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "AdditionalWritableRootPermissionProfileModificationParams",
"type": "object"
}
]
},
"PermissionProfileSelectionParams": {
"oneOf": [
{
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
"properties": {
"id": {
"type": "string"
},
"modifications": {
"items": {
"$ref": "#/definitions/PermissionProfileModificationParams"
},
"type": [
"array",
"null"
]
},
"type": {
"enum": [
"profile"
],
"title": "ProfilePermissionProfileSelectionParamsType",
"type": "string"
}
},
"required": [
"id",
"type"
],
"title": "ProfilePermissionProfileSelectionParams",
"type": "object"
}
]
},
"Personality": {
"enum": [
"none",
@@ -114,65 +114,6 @@
],
"type": "string"
},
"PermissionProfileModificationParams": {
"oneOf": [
{
"description": "Additional concrete directory that should be writable.",
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"additionalWritableRoot"
],
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "AdditionalWritableRootPermissionProfileModificationParams",
"type": "object"
}
]
},
"PermissionProfileSelectionParams": {
"oneOf": [
{
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
"properties": {
"id": {
"type": "string"
},
"modifications": {
"items": {
"$ref": "#/definitions/PermissionProfileModificationParams"
},
"type": [
"array",
"null"
]
},
"type": {
"enum": [
"profile"
],
"title": "ProfilePermissionProfileSelectionParamsType",
"type": "string"
}
},
"required": [
"id",
"type"
],
"title": "ProfilePermissionProfileSelectionParams",
"type": "object"
}
]
},
"Personality": {
"enum": [
"none",
@@ -1,6 +0,0 @@
// 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";
export type PermissionProfileModificationParams = { "type": "additionalWritableRoot", path: AbsolutePathBuf, };
@@ -1,6 +0,0 @@
// 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 { PermissionProfileModificationParams } from "./PermissionProfileModificationParams";
export type PermissionProfileSelectionParams = { "type": "profile", id: string, modifications?: Array<PermissionProfileModificationParams> | null, };
@@ -257,9 +257,7 @@ export type { PatchChangeKind } from "./PatchChangeKind";
export type { PermissionGrantScope } from "./PermissionGrantScope";
export type { PermissionProfile } from "./PermissionProfile";
export type { PermissionProfileFileSystemPermissions } from "./PermissionProfileFileSystemPermissions";
export type { PermissionProfileModificationParams } from "./PermissionProfileModificationParams";
export type { PermissionProfileNetworkPermissions } from "./PermissionProfileNetworkPermissions";
export type { PermissionProfileSelectionParams } from "./PermissionProfileSelectionParams";
export type { PermissionsRequestApprovalParams } from "./PermissionsRequestApprovalParams";
export type { PermissionsRequestApprovalResponse } from "./PermissionsRequestApprovalResponse";
export type { PlanDeltaNotification } from "./PlanDeltaNotification";
@@ -2296,6 +2296,7 @@ mod tests {
model_provider: "openai".to_string(),
service_tier: None,
cwd,
runtime_workspace_roots: Vec::new(),
instruction_sources: vec![absolute_path("/tmp/AGENTS.md")],
approval_policy: v2::AskForApproval::OnFailure,
approvals_reviewer: v2::ApprovalsReviewer::User,
@@ -2340,6 +2341,7 @@ mod tests {
"modelProvider": "openai",
"serviceTier": null,
"cwd": absolute_path_string("tmp"),
"runtimeWorkspaceRoots": [],
"instructionSources": [absolute_path_string("tmp/AGENTS.md")],
"approvalPolicy": "on-failure",
"approvalsReviewer": "user",
@@ -21,7 +21,9 @@ use codex_protocol::request_permissions::RequestPermissionProfile as CoreRequest
use codex_utils_absolute_path::AbsolutePathBuf;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::Serializer;
use std::num::NonZeroUsize;
use std::path::PathBuf;
use ts_rs::TS;
@@ -456,31 +458,100 @@ impl From<ActivePermissionProfile> for CoreActivePermissionProfile {
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "camelCase")]
#[ts(tag = "type")]
#[ts(export_to = "v2/")]
pub enum PermissionProfileSelectionParams {
/// Select a named built-in or user-defined profile and optionally apply
/// bounded modifications that Codex knows how to validate.
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
Profile {
id: String,
#[ts(optional = nullable)]
modifications: Option<Vec<PermissionProfileModificationParams>>,
},
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PermissionProfileSelectionParams {
id: String,
legacy_additional_writable_roots: Vec<AbsolutePathBuf>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "camelCase")]
#[ts(tag = "type")]
#[ts(export_to = "v2/")]
pub enum PermissionProfileModificationParams {
/// Additional concrete directory that should be writable.
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
AdditionalWritableRoot { path: AbsolutePathBuf },
impl PermissionProfileSelectionParams {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
legacy_additional_writable_roots: Vec::new(),
}
}
pub fn id(&self) -> &str {
&self.id
}
pub fn into_id(self) -> String {
self.id
}
pub fn legacy_additional_writable_roots(&self) -> &[AbsolutePathBuf] {
&self.legacy_additional_writable_roots
}
}
impl From<String> for PermissionProfileSelectionParams {
fn from(id: String) -> Self {
Self::new(id)
}
}
impl Serialize for PermissionProfileSelectionParams {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.id)
}
}
impl<'de> Deserialize<'de> for PermissionProfileSelectionParams {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum Wire {
Id(String),
LegacyProfile {
#[serde(rename = "type")]
_type: LegacyPermissionProfileSelectionType,
id: String,
#[serde(default)]
modifications: Option<Vec<LegacyPermissionProfileModificationParams>>,
},
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
enum LegacyPermissionProfileSelectionType {
Profile,
}
#[derive(Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
enum LegacyPermissionProfileModificationParams {
#[serde(rename_all = "camelCase")]
AdditionalWritableRoot { path: AbsolutePathBuf },
}
match Wire::deserialize(deserializer)? {
Wire::Id(id) => Ok(Self::new(id)),
Wire::LegacyProfile {
id, modifications, ..
} => {
let legacy_additional_writable_roots = modifications
.unwrap_or_default()
.into_iter()
.map(|modification| match modification {
LegacyPermissionProfileModificationParams::AdditionalWritableRoot {
path,
} => path,
})
.collect();
Ok(Self {
id,
legacy_additional_writable_roots,
})
}
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
@@ -655,6 +655,61 @@ fn permissions_request_approval_response_accepts_strict_auto_review() {
assert_eq!(response.strict_auto_review, Some(true));
}
#[test]
fn permission_profile_selection_accepts_legacy_object_shape() {
let additional_root = absolute_path("additional-root");
let params = json!({
"permissions": {
"type": "profile",
"id": ":workspace",
"modifications": [
{
"type": "additionalWritableRoot",
"path": additional_root.clone(),
}
],
},
});
let start: ThreadStartParams =
serde_json::from_value(params.clone()).expect("thread/start params deserialize");
assert_legacy_permission_profile_selection(start.permissions, &additional_root);
let resume: ThreadResumeParams = serde_json::from_value(json!({
"threadId": "thread-1",
"permissions": params["permissions"].clone(),
}))
.expect("thread/resume params deserialize");
assert_legacy_permission_profile_selection(resume.permissions, &additional_root);
let fork: ThreadForkParams = serde_json::from_value(json!({
"threadId": "thread-1",
"permissions": params["permissions"].clone(),
}))
.expect("thread/fork params deserialize");
assert_legacy_permission_profile_selection(fork.permissions, &additional_root);
let turn: TurnStartParams = serde_json::from_value(json!({
"threadId": "thread-1",
"input": [],
"permissions": params["permissions"].clone(),
}))
.expect("turn/start params deserialize");
assert_legacy_permission_profile_selection(turn.permissions, &additional_root);
}
fn assert_legacy_permission_profile_selection(
selection: Option<PermissionProfileSelectionParams>,
additional_root: &AbsolutePathBuf,
) {
let selection = selection.expect("permissions should be present");
assert_eq!(selection.id(), ":workspace");
assert_eq!(
selection.legacy_additional_writable_roots(),
&[additional_root.clone()]
);
}
#[test]
fn fs_get_metadata_response_round_trips_minimal_fields() {
let response = FsGetMetadataResponse {
@@ -3469,6 +3524,7 @@ fn turn_start_params_preserve_explicit_null_service_tier() {
responsesapi_client_metadata: None,
environments: None,
cwd: None,
runtime_workspace_roots: None,
approval_policy: None,
approvals_reviewer: None,
sandbox_policy: None,
@@ -107,6 +107,11 @@ pub struct ThreadStartParams {
pub service_tier: Option<Option<String>>,
#[ts(optional = nullable)]
pub cwd: Option<String>,
/// Replace the thread's runtime workspace roots. Relative paths are
/// resolved against the effective cwd for the thread.
#[experimental("thread/start.runtimeWorkspaceRoots")]
#[ts(optional = nullable)]
pub runtime_workspace_roots: Option<Vec<PathBuf>>,
#[experimental(nested)]
#[ts(optional = nullable)]
pub approval_policy: Option<AskForApproval>,
@@ -116,10 +121,10 @@ pub struct ThreadStartParams {
pub approvals_reviewer: Option<ApprovalsReviewer>,
#[ts(optional = nullable)]
pub sandbox: Option<SandboxMode>,
/// Named profile selection for this thread. Cannot be combined with
/// `sandbox`. Use bounded `modifications` for supported turn/thread
/// adjustments instead of replacing the full permissions profile.
/// Named profile id for this thread. Cannot be combined with `sandbox`.
#[experimental("thread/start.permissions")]
#[schemars(with = "Option<String>")]
#[ts(type = "string | null")]
#[ts(optional = nullable)]
pub permissions: Option<PermissionProfileSelectionParams>,
#[ts(optional = nullable)]
@@ -195,6 +200,11 @@ pub struct ThreadStartResponse {
pub model_provider: String,
pub service_tier: Option<String>,
pub cwd: AbsolutePathBuf,
/// Thread-scoped runtime workspace roots used to materialize
/// `:workspace_roots`.
#[experimental("thread/start.runtimeWorkspaceRoots")]
#[serde(default)]
pub runtime_workspace_roots: Vec<AbsolutePathBuf>,
/// Instruction source files currently loaded for this thread.
#[serde(default)]
pub instruction_sources: Vec<AbsolutePathBuf>,
@@ -264,6 +274,11 @@ pub struct ThreadResumeParams {
pub service_tier: Option<Option<String>>,
#[ts(optional = nullable)]
pub cwd: Option<String>,
/// Replace the thread's runtime workspace roots. Relative paths are
/// resolved against the effective cwd for the thread.
#[experimental("thread/resume.runtimeWorkspaceRoots")]
#[ts(optional = nullable)]
pub runtime_workspace_roots: Option<Vec<PathBuf>>,
#[experimental(nested)]
#[ts(optional = nullable)]
pub approval_policy: Option<AskForApproval>,
@@ -273,10 +288,11 @@ pub struct ThreadResumeParams {
pub approvals_reviewer: Option<ApprovalsReviewer>,
#[ts(optional = nullable)]
pub sandbox: Option<SandboxMode>,
/// Named profile selection for the resumed thread. Cannot be combined
/// with `sandbox`. Use bounded `modifications` for supported thread
/// adjustments instead of replacing the full permissions profile.
/// Named profile id for the resumed thread. Cannot be combined with
/// `sandbox`.
#[experimental("thread/resume.permissions")]
#[schemars(with = "Option<String>")]
#[ts(type = "string | null")]
#[ts(optional = nullable)]
pub permissions: Option<PermissionProfileSelectionParams>,
#[ts(optional = nullable)]
@@ -310,6 +326,11 @@ pub struct ThreadResumeResponse {
pub model_provider: String,
pub service_tier: Option<String>,
pub cwd: AbsolutePathBuf,
/// Thread-scoped runtime workspace roots used to materialize
/// `:workspace_roots`.
#[experimental("thread/resume.runtimeWorkspaceRoots")]
#[serde(default)]
pub runtime_workspace_roots: Vec<AbsolutePathBuf>,
/// Instruction source files currently loaded for this thread.
#[serde(default)]
pub instruction_sources: Vec<AbsolutePathBuf>,
@@ -370,6 +391,11 @@ pub struct ThreadForkParams {
pub service_tier: Option<Option<String>>,
#[ts(optional = nullable)]
pub cwd: Option<String>,
/// Replace the thread's runtime workspace roots. Relative paths are
/// resolved against the effective cwd for the thread.
#[experimental("thread/fork.runtimeWorkspaceRoots")]
#[ts(optional = nullable)]
pub runtime_workspace_roots: Option<Vec<PathBuf>>,
#[experimental(nested)]
#[ts(optional = nullable)]
pub approval_policy: Option<AskForApproval>,
@@ -379,10 +405,11 @@ pub struct ThreadForkParams {
pub approvals_reviewer: Option<ApprovalsReviewer>,
#[ts(optional = nullable)]
pub sandbox: Option<SandboxMode>,
/// Named profile selection for the forked thread. Cannot be combined with
/// `sandbox`. Use bounded `modifications` for supported thread
/// adjustments instead of replacing the full permissions profile.
/// Named profile id for the forked thread. Cannot be combined with
/// `sandbox`.
#[experimental("thread/fork.permissions")]
#[schemars(with = "Option<String>")]
#[ts(type = "string | null")]
#[ts(optional = nullable)]
pub permissions: Option<PermissionProfileSelectionParams>,
#[ts(optional = nullable)]
@@ -419,6 +446,11 @@ pub struct ThreadForkResponse {
pub model_provider: String,
pub service_tier: Option<String>,
pub cwd: AbsolutePathBuf,
/// Thread-scoped runtime workspace roots used to materialize
/// `:workspace_roots`.
#[experimental("thread/fork.runtimeWorkspaceRoots")]
#[serde(default)]
pub runtime_workspace_roots: Vec<AbsolutePathBuf>,
/// Instruction source files currently loaded for this thread.
#[serde(default)]
pub instruction_sources: Vec<AbsolutePathBuf>,
@@ -64,6 +64,12 @@ pub struct TurnStartParams {
/// Override the working directory for this turn and subsequent turns.
#[ts(optional = nullable)]
pub cwd: Option<PathBuf>,
/// Replace the thread's runtime workspace roots for this turn and
/// subsequent turns. Relative paths are resolved against the effective
/// cwd for the turn.
#[experimental("turn/start.runtimeWorkspaceRoots")]
#[ts(optional = nullable)]
pub runtime_workspace_roots: Option<Vec<PathBuf>>,
/// Override the approval policy for this turn and subsequent turns.
#[experimental(nested)]
#[ts(optional = nullable)]
@@ -75,11 +81,11 @@ pub struct TurnStartParams {
/// Override the sandbox policy for this turn and subsequent turns.
#[ts(optional = nullable)]
pub sandbox_policy: Option<SandboxPolicy>,
/// Select a named permissions profile for this turn and subsequent turns.
/// Cannot be combined with `sandboxPolicy`. Use bounded `modifications`
/// for supported turn adjustments instead of replacing the full
/// permissions profile.
/// Select a named permissions profile id for this turn and subsequent
/// turns. Cannot be combined with `sandboxPolicy`.
#[experimental("turn/start.permissions")]
#[schemars(with = "Option<String>")]
#[ts(type = "string | null")]
#[ts(optional = nullable)]
pub permissions: Option<PermissionProfileSelectionParams>,
/// Override the model for this turn and subsequent turns.