app-server: expose thread permission profiles

This commit is contained in:
Michael Bolin
2026-04-21 22:52:33 -07:00
parent 0fef35dc3a
commit 1065304e68
18 changed files with 1340 additions and 13 deletions
@@ -10889,6 +10889,64 @@
}
]
},
"PermissionProfile": {
"properties": {
"fileSystem": {
"anyOf": [
{
"$ref": "#/definitions/v2/PermissionProfileFileSystemPermissions"
},
{
"type": "null"
}
]
},
"network": {
"anyOf": [
{
"$ref": "#/definitions/v2/PermissionProfileNetworkPermissions"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"PermissionProfileFileSystemPermissions": {
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/v2/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"entries"
],
"type": "object"
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"Personality": {
"enum": [
"none",
@@ -14060,6 +14118,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/v2/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -14071,7 +14141,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/v2/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/v2/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -15450,6 +15525,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/v2/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -15461,7 +15548,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/v2/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/v2/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -15749,6 +15841,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/v2/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -15760,7 +15864,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/v2/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/v2/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -7651,6 +7651,64 @@
}
]
},
"PermissionProfile": {
"properties": {
"fileSystem": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
},
{
"type": "null"
}
]
},
"network": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"PermissionProfileFileSystemPermissions": {
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"entries"
],
"type": "object"
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"Personality": {
"enum": [
"none",
@@ -11954,6 +12012,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -11965,7 +12035,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -13344,6 +13419,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -13355,7 +13442,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -13643,6 +13735,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -13654,7 +13758,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -448,6 +448,217 @@
],
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
"write",
"none"
],
"type": "string"
},
"FileSystemPath": {
"oneOf": [
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"path"
],
"title": "PathFileSystemPathType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "PathFileSystemPath",
"type": "object"
},
{
"properties": {
"pattern": {
"type": "string"
},
"type": {
"enum": [
"glob_pattern"
],
"title": "GlobPatternFileSystemPathType",
"type": "string"
}
},
"required": [
"pattern",
"type"
],
"title": "GlobPatternFileSystemPath",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"special"
],
"title": "SpecialFileSystemPathType",
"type": "string"
},
"value": {
"$ref": "#/definitions/FileSystemSpecialPath"
}
},
"required": [
"type",
"value"
],
"title": "SpecialFileSystemPath",
"type": "object"
}
]
},
"FileSystemSandboxEntry": {
"properties": {
"access": {
"$ref": "#/definitions/FileSystemAccessMode"
},
"path": {
"$ref": "#/definitions/FileSystemPath"
}
},
"required": [
"access",
"path"
],
"type": "object"
},
"FileSystemSpecialPath": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"root"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "RootFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"minimal"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "MinimalFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"current_working_directory"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "CurrentWorkingDirectoryFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"project_roots"
],
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind"
],
"title": "KindFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"tmpdir"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "TmpdirFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"slash_tmp"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "SlashTmpFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"unknown"
],
"type": "string"
},
"path": {
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"path"
],
"type": "object"
}
]
},
"FileUpdateChange": {
"properties": {
"diff": {
@@ -686,6 +897,64 @@
}
]
},
"PermissionProfile": {
"properties": {
"fileSystem": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
},
{
"type": "null"
}
]
},
"network": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"PermissionProfileFileSystemPermissions": {
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"entries"
],
"type": "object"
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"ReadOnlyAccess": {
"oneOf": [
{
@@ -2225,6 +2494,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -2236,7 +2517,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -448,6 +448,217 @@
],
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
"write",
"none"
],
"type": "string"
},
"FileSystemPath": {
"oneOf": [
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"path"
],
"title": "PathFileSystemPathType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "PathFileSystemPath",
"type": "object"
},
{
"properties": {
"pattern": {
"type": "string"
},
"type": {
"enum": [
"glob_pattern"
],
"title": "GlobPatternFileSystemPathType",
"type": "string"
}
},
"required": [
"pattern",
"type"
],
"title": "GlobPatternFileSystemPath",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"special"
],
"title": "SpecialFileSystemPathType",
"type": "string"
},
"value": {
"$ref": "#/definitions/FileSystemSpecialPath"
}
},
"required": [
"type",
"value"
],
"title": "SpecialFileSystemPath",
"type": "object"
}
]
},
"FileSystemSandboxEntry": {
"properties": {
"access": {
"$ref": "#/definitions/FileSystemAccessMode"
},
"path": {
"$ref": "#/definitions/FileSystemPath"
}
},
"required": [
"access",
"path"
],
"type": "object"
},
"FileSystemSpecialPath": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"root"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "RootFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"minimal"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "MinimalFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"current_working_directory"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "CurrentWorkingDirectoryFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"project_roots"
],
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind"
],
"title": "KindFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"tmpdir"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "TmpdirFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"slash_tmp"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "SlashTmpFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"unknown"
],
"type": "string"
},
"path": {
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"path"
],
"type": "object"
}
]
},
"FileUpdateChange": {
"properties": {
"diff": {
@@ -686,6 +897,64 @@
}
]
},
"PermissionProfile": {
"properties": {
"fileSystem": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
},
{
"type": "null"
}
]
},
"network": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"PermissionProfileFileSystemPermissions": {
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"entries"
],
"type": "object"
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"ReadOnlyAccess": {
"oneOf": [
{
@@ -2225,6 +2494,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -2236,7 +2517,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -448,6 +448,217 @@
],
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
"write",
"none"
],
"type": "string"
},
"FileSystemPath": {
"oneOf": [
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": {
"enum": [
"path"
],
"title": "PathFileSystemPathType",
"type": "string"
}
},
"required": [
"path",
"type"
],
"title": "PathFileSystemPath",
"type": "object"
},
{
"properties": {
"pattern": {
"type": "string"
},
"type": {
"enum": [
"glob_pattern"
],
"title": "GlobPatternFileSystemPathType",
"type": "string"
}
},
"required": [
"pattern",
"type"
],
"title": "GlobPatternFileSystemPath",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"special"
],
"title": "SpecialFileSystemPathType",
"type": "string"
},
"value": {
"$ref": "#/definitions/FileSystemSpecialPath"
}
},
"required": [
"type",
"value"
],
"title": "SpecialFileSystemPath",
"type": "object"
}
]
},
"FileSystemSandboxEntry": {
"properties": {
"access": {
"$ref": "#/definitions/FileSystemAccessMode"
},
"path": {
"$ref": "#/definitions/FileSystemPath"
}
},
"required": [
"access",
"path"
],
"type": "object"
},
"FileSystemSpecialPath": {
"oneOf": [
{
"properties": {
"kind": {
"enum": [
"root"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "RootFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"minimal"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "MinimalFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"current_working_directory"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "CurrentWorkingDirectoryFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"project_roots"
],
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind"
],
"title": "KindFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"tmpdir"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "TmpdirFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"slash_tmp"
],
"type": "string"
}
},
"required": [
"kind"
],
"title": "SlashTmpFileSystemSpecialPath",
"type": "object"
},
{
"properties": {
"kind": {
"enum": [
"unknown"
],
"type": "string"
},
"path": {
"type": "string"
},
"subpath": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"path"
],
"type": "object"
}
]
},
"FileUpdateChange": {
"properties": {
"diff": {
@@ -686,6 +897,64 @@
}
]
},
"PermissionProfile": {
"properties": {
"fileSystem": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
},
{
"type": "null"
}
]
},
"network": {
"anyOf": [
{
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"PermissionProfileFileSystemPermissions": {
"properties": {
"entries": {
"items": {
"$ref": "#/definitions/FileSystemSandboxEntry"
},
"type": "array"
},
"globScanMaxDepth": {
"format": "uint",
"minimum": 1.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"entries"
],
"type": "object"
},
"PermissionProfileNetworkPermissions": {
"properties": {
"enabled": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"ReadOnlyAccess": {
"oneOf": [
{
@@ -2225,6 +2494,18 @@
"modelProvider": {
"type": "string"
},
"permissionProfile": {
"allOf": [
{
"$ref": "#/definitions/PermissionProfile"
}
],
"default": {
"fileSystem": null,
"network": null
},
"description": "Canonical active permissions view for this thread."
},
"reasoningEffort": {
"anyOf": [
{
@@ -2236,7 +2517,12 @@
]
},
"sandbox": {
"$ref": "#/definitions/SandboxPolicy"
"allOf": [
{
"$ref": "#/definitions/SandboxPolicy"
}
],
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` as the canonical active permissions view."
},
"serviceTier": {
"anyOf": [
@@ -0,0 +1,7 @@
// 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 { PermissionProfileFileSystemPermissions } from "./PermissionProfileFileSystemPermissions";
import type { PermissionProfileNetworkPermissions } from "./PermissionProfileNetworkPermissions";
export type PermissionProfile = { network: PermissionProfileNetworkPermissions | null, fileSystem: PermissionProfileFileSystemPermissions | null, };
@@ -0,0 +1,6 @@
// 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 { FileSystemSandboxEntry } from "./FileSystemSandboxEntry";
export type PermissionProfileFileSystemPermissions = { entries: Array<FileSystemSandboxEntry>, globScanMaxDepth?: number, };
@@ -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 PermissionProfileNetworkPermissions = { enabled: boolean | null, };
@@ -6,6 +6,7 @@ import type { ReasoningEffort } from "../ReasoningEffort";
import type { ServiceTier } from "../ServiceTier";
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
import type { AskForApproval } from "./AskForApproval";
import type { PermissionProfile } from "./PermissionProfile";
import type { SandboxPolicy } from "./SandboxPolicy";
import type { Thread } from "./Thread";
@@ -17,4 +18,13 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval,
/**
* Reviewer currently used for approval requests on this thread.
*/
approvalsReviewer: ApprovalsReviewer, sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null, };
approvalsReviewer: ApprovalsReviewer,
/**
* Legacy sandbox policy retained for compatibility. New clients should use
* `permissionProfile` as the canonical active permissions view.
*/
sandbox: SandboxPolicy,
/**
* Canonical active permissions view for this thread.
*/
permissionProfile: PermissionProfile, reasoningEffort: ReasoningEffort | null, };
@@ -6,6 +6,7 @@ import type { ReasoningEffort } from "../ReasoningEffort";
import type { ServiceTier } from "../ServiceTier";
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
import type { AskForApproval } from "./AskForApproval";
import type { PermissionProfile } from "./PermissionProfile";
import type { SandboxPolicy } from "./SandboxPolicy";
import type { Thread } from "./Thread";
@@ -17,4 +18,13 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval,
/**
* Reviewer currently used for approval requests on this thread.
*/
approvalsReviewer: ApprovalsReviewer, sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null, };
approvalsReviewer: ApprovalsReviewer,
/**
* Legacy sandbox policy retained for compatibility. New clients should use
* `permissionProfile` as the canonical active permissions view.
*/
sandbox: SandboxPolicy,
/**
* Canonical active permissions view for this thread.
*/
permissionProfile: PermissionProfile, reasoningEffort: ReasoningEffort | null, };
@@ -6,6 +6,7 @@ import type { ReasoningEffort } from "../ReasoningEffort";
import type { ServiceTier } from "../ServiceTier";
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
import type { AskForApproval } from "./AskForApproval";
import type { PermissionProfile } from "./PermissionProfile";
import type { SandboxPolicy } from "./SandboxPolicy";
import type { Thread } from "./Thread";
@@ -17,4 +18,13 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval,
/**
* Reviewer currently used for approval requests on this thread.
*/
approvalsReviewer: ApprovalsReviewer, sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null, };
approvalsReviewer: ApprovalsReviewer,
/**
* Legacy sandbox policy retained for compatibility. New clients should use
* `permissionProfile` as the canonical active permissions view.
*/
sandbox: SandboxPolicy,
/**
* Canonical active permissions view for this thread.
*/
permissionProfile: PermissionProfile, reasoningEffort: ReasoningEffort | null, };
@@ -240,6 +240,9 @@ export type { OverriddenMetadata } from "./OverriddenMetadata";
export type { PatchApplyStatus } from "./PatchApplyStatus";
export type { PatchChangeKind } from "./PatchChangeKind";
export type { PermissionGrantScope } from "./PermissionGrantScope";
export type { PermissionProfile } from "./PermissionProfile";
export type { PermissionProfileFileSystemPermissions } from "./PermissionProfileFileSystemPermissions";
export type { PermissionProfileNetworkPermissions } from "./PermissionProfileNetworkPermissions";
export type { PermissionsRequestApprovalParams } from "./PermissionsRequestApprovalParams";
export type { PermissionsRequestApprovalResponse } from "./PermissionsRequestApprovalResponse";
export type { PlanDeltaNotification } from "./PlanDeltaNotification";
@@ -1460,6 +1460,12 @@ mod tests {
approval_policy: v2::AskForApproval::OnFailure,
approvals_reviewer: v2::ApprovalsReviewer::User,
sandbox: v2::SandboxPolicy::DangerFullAccess,
permission_profile:
codex_protocol::models::PermissionProfile::from_legacy_sandbox_policy(
&codex_protocol::protocol::SandboxPolicy::DangerFullAccess,
std::path::Path::new("/tmp"),
)
.into(),
reasoning_effort: None,
},
};
@@ -1502,6 +1508,24 @@ mod tests {
"sandbox": {
"type": "dangerFullAccess"
},
"permissionProfile": {
"network": {
"enabled": true,
},
"fileSystem": {
"entries": [
{
"path": {
"type": "special",
"value": {
"kind": "root",
},
},
"access": "write",
},
],
},
},
"reasoningEffort": null
}
}),
+147 -1
View File
@@ -1225,6 +1225,13 @@ pub struct AdditionalNetworkPermissions {
pub enabled: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct PermissionProfileNetworkPermissions {
pub enabled: Option<bool>,
}
impl From<CoreNetworkPermissions> for AdditionalNetworkPermissions {
fn from(value: CoreNetworkPermissions) -> Self {
Self {
@@ -1241,6 +1248,22 @@ impl From<AdditionalNetworkPermissions> for CoreNetworkPermissions {
}
}
impl From<CoreNetworkPermissions> for PermissionProfileNetworkPermissions {
fn from(value: CoreNetworkPermissions) -> Self {
Self {
enabled: value.enabled,
}
}
}
impl From<PermissionProfileNetworkPermissions> for CoreNetworkPermissions {
fn from(value: PermissionProfileNetworkPermissions) -> Self {
Self {
enabled: value.enabled,
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
@@ -1383,6 +1406,70 @@ impl From<FileSystemSandboxEntry> for CoreFileSystemSandboxEntry {
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct PermissionProfileFileSystemPermissions {
pub entries: Vec<FileSystemSandboxEntry>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub glob_scan_max_depth: Option<NonZeroUsize>,
}
impl From<CoreFileSystemPermissions> for PermissionProfileFileSystemPermissions {
fn from(value: CoreFileSystemPermissions) -> Self {
Self {
entries: value
.entries
.into_iter()
.map(FileSystemSandboxEntry::from)
.collect(),
glob_scan_max_depth: value.glob_scan_max_depth,
}
}
}
impl From<PermissionProfileFileSystemPermissions> for CoreFileSystemPermissions {
fn from(value: PermissionProfileFileSystemPermissions) -> Self {
Self {
entries: value
.entries
.into_iter()
.map(CoreFileSystemSandboxEntry::from)
.collect(),
glob_scan_max_depth: value.glob_scan_max_depth,
}
}
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct PermissionProfile {
pub network: Option<PermissionProfileNetworkPermissions>,
pub file_system: Option<PermissionProfileFileSystemPermissions>,
}
impl From<CorePermissionProfile> for PermissionProfile {
fn from(value: CorePermissionProfile) -> Self {
Self {
network: value.network.map(PermissionProfileNetworkPermissions::from),
file_system: value
.file_system
.map(PermissionProfileFileSystemPermissions::from),
}
}
}
impl From<PermissionProfile> for CorePermissionProfile {
fn from(value: PermissionProfile) -> Self {
Self {
network: value.network.map(CoreNetworkPermissions::from),
file_system: value.file_system.map(CoreFileSystemPermissions::from),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
@@ -3127,7 +3214,12 @@ pub struct ThreadStartResponse {
pub approval_policy: AskForApproval,
/// Reviewer currently used for approval requests on this thread.
pub approvals_reviewer: ApprovalsReviewer,
/// Legacy sandbox policy retained for compatibility. New clients should use
/// `permissionProfile` as the canonical active permissions view.
pub sandbox: SandboxPolicy,
/// Canonical active permissions view for this thread.
#[serde(default)]
pub permission_profile: PermissionProfile,
pub reasoning_effort: Option<ReasoningEffort>,
}
@@ -3216,7 +3308,12 @@ pub struct ThreadResumeResponse {
pub approval_policy: AskForApproval,
/// Reviewer currently used for approval requests on this thread.
pub approvals_reviewer: ApprovalsReviewer,
/// Legacy sandbox policy retained for compatibility. New clients should use
/// `permissionProfile` as the canonical active permissions view.
pub sandbox: SandboxPolicy,
/// Canonical active permissions view for this thread.
#[serde(default)]
pub permission_profile: PermissionProfile,
pub reasoning_effort: Option<ReasoningEffort>,
}
@@ -3296,7 +3393,12 @@ pub struct ThreadForkResponse {
pub approval_policy: AskForApproval,
/// Reviewer currently used for approval requests on this thread.
pub approvals_reviewer: ApprovalsReviewer,
/// Legacy sandbox policy retained for compatibility. New clients should use
/// `permissionProfile` as the canonical active permissions view.
pub sandbox: SandboxPolicy,
/// Canonical active permissions view for this thread.
#[serde(default)]
pub permission_profile: PermissionProfile,
pub reasoning_effort: Option<ReasoningEffort>,
}
@@ -7419,6 +7521,47 @@ mod tests {
.expect_err("zero glob scan depth should fail deserialization");
}
#[test]
fn permission_profile_file_system_permissions_preserves_glob_scan_depth() {
let core_permissions = CoreFileSystemPermissions {
entries: vec![CoreFileSystemSandboxEntry {
path: CoreFileSystemPath::GlobPattern {
pattern: "**/*.env".to_string(),
},
access: CoreFileSystemAccessMode::None,
}],
glob_scan_max_depth: NonZeroUsize::new(2),
};
let permissions = PermissionProfileFileSystemPermissions::from(core_permissions.clone());
assert_eq!(
permissions,
PermissionProfileFileSystemPermissions {
entries: vec![FileSystemSandboxEntry {
path: FileSystemPath::GlobPattern {
pattern: "**/*.env".to_string(),
},
access: FileSystemAccessMode::None,
}],
glob_scan_max_depth: NonZeroUsize::new(2),
}
);
assert_eq!(
CoreFileSystemPermissions::from(permissions),
core_permissions
);
}
#[test]
fn permission_profile_file_system_permissions_rejects_zero_glob_scan_depth() {
serde_json::from_value::<PermissionProfileFileSystemPermissions>(json!({
"entries": [],
"globScanMaxDepth": 0,
}))
.expect_err("zero glob scan depth should fail deserialization");
}
#[test]
fn permissions_request_approval_response_uses_granted_permission_profile_without_macos() {
let read_only_path = if cfg!(windows) {
@@ -9708,7 +9851,7 @@ mod tests {
}
#[test]
fn thread_lifecycle_responses_default_missing_instruction_sources() {
fn thread_lifecycle_responses_default_missing_compat_fields() {
let response = json!({
"thread": {
"id": "thread-id",
@@ -9749,6 +9892,9 @@ mod tests {
assert_eq!(start.instruction_sources, Vec::<AbsolutePathBuf>::new());
assert_eq!(resume.instruction_sources, Vec::<AbsolutePathBuf>::new());
assert_eq!(fork.instruction_sources, Vec::<AbsolutePathBuf>::new());
assert_eq!(start.permission_profile, PermissionProfile::default());
assert_eq!(resume.permission_profile, PermissionProfile::default());
assert_eq!(fork.permission_profile, PermissionProfile::default());
}
#[test]