2025-10-30 16:56:55 -07:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
|
|
use codex_protocol::ConversationId;
|
|
|
|
|
use codex_protocol::config_types::ForcedLoginMethod;
|
|
|
|
|
use codex_protocol::config_types::ReasoningSummary;
|
|
|
|
|
use codex_protocol::config_types::SandboxMode;
|
|
|
|
|
use codex_protocol::config_types::Verbosity;
|
|
|
|
|
use codex_protocol::models::ResponseItem;
|
2025-12-03 12:30:43 -08:00
|
|
|
use codex_protocol::openai_models::ReasoningEffort;
|
[app-server] feat: add v2 command execution approval flow (#6758)
This PR adds the API V2 version of the command‑execution approval flow
for the shell tool.
This PR wires the new RPC (`item/commandExecution/requestApproval`, V2
only) and related events (`item/started`, `item/completed`, and
`item/commandExecution/delta`, which are emitted in both V1 and V2)
through the app-server
protocol. The new approval RPC is only sent when the user initiates a
turn with the new `turn/start` API so we don't break backwards
compatibility with VSCE.
The approach I took was to make as few changes to the Codex core as
possible, leveraging existing `EventMsg` core events, and translating
those in app-server. I did have to add additional fields to
`EventMsg::ExecCommandEndEvent` to capture the command's input so that
app-server can statelessly transform these events to a
`ThreadItem::CommandExecution` item for the `item/completed` event.
Once we stabilize the API and it's complete enough for our partners, we
can work on migrating the core to be aware of command execution items as
a first-class concept.
**Note**: We'll need followup work to make sure these APIs work for the
unified exec tool, but will wait til that's stable and landed before
doing a pass on app-server.
Example payloads below:
```
{
"method": "item/started",
"params": {
"item": {
"aggregatedOutput": null,
"command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
"cwd": "/Users/owen/repos/codex/codex-rs",
"durationMs": null,
"exitCode": null,
"id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"status": "inProgress",
"type": "commandExecution"
}
}
}
```
```
{
"id": 0,
"method": "item/commandExecution/requestApproval",
"params": {
"itemId": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"reason": "Need to create file in /tmp which is outside workspace sandbox",
"risk": null,
"threadId": "019a93e8-0a52-7fe3-9808-b6bc40c0989a",
"turnId": "1"
}
}
```
```
{
"id": 0,
"result": {
"acceptSettings": {
"forSession": false
},
"decision": "accept"
}
}
```
```
{
"params": {
"item": {
"aggregatedOutput": null,
"command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
"cwd": "/Users/owen/repos/codex/codex-rs",
"durationMs": 224,
"exitCode": 0,
"id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"status": "completed",
"type": "commandExecution"
}
}
}
```
2025-11-17 16:23:54 -08:00
|
|
|
use codex_protocol::parse_command::ParsedCommand;
|
2025-10-30 16:56:55 -07:00
|
|
|
use codex_protocol::protocol::AskForApproval;
|
|
|
|
|
use codex_protocol::protocol::EventMsg;
|
[app-server] feat: add v2 command execution approval flow (#6758)
This PR adds the API V2 version of the command‑execution approval flow
for the shell tool.
This PR wires the new RPC (`item/commandExecution/requestApproval`, V2
only) and related events (`item/started`, `item/completed`, and
`item/commandExecution/delta`, which are emitted in both V1 and V2)
through the app-server
protocol. The new approval RPC is only sent when the user initiates a
turn with the new `turn/start` API so we don't break backwards
compatibility with VSCE.
The approach I took was to make as few changes to the Codex core as
possible, leveraging existing `EventMsg` core events, and translating
those in app-server. I did have to add additional fields to
`EventMsg::ExecCommandEndEvent` to capture the command's input so that
app-server can statelessly transform these events to a
`ThreadItem::CommandExecution` item for the `item/completed` event.
Once we stabilize the API and it's complete enough for our partners, we
can work on migrating the core to be aware of command execution items as
a first-class concept.
**Note**: We'll need followup work to make sure these APIs work for the
unified exec tool, but will wait til that's stable and landed before
doing a pass on app-server.
Example payloads below:
```
{
"method": "item/started",
"params": {
"item": {
"aggregatedOutput": null,
"command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
"cwd": "/Users/owen/repos/codex/codex-rs",
"durationMs": null,
"exitCode": null,
"id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"status": "inProgress",
"type": "commandExecution"
}
}
}
```
```
{
"id": 0,
"method": "item/commandExecution/requestApproval",
"params": {
"itemId": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"reason": "Need to create file in /tmp which is outside workspace sandbox",
"risk": null,
"threadId": "019a93e8-0a52-7fe3-9808-b6bc40c0989a",
"turnId": "1"
}
}
```
```
{
"id": 0,
"result": {
"acceptSettings": {
"forSession": false
},
"decision": "accept"
}
}
```
```
{
"params": {
"item": {
"aggregatedOutput": null,
"command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
"cwd": "/Users/owen/repos/codex/codex-rs",
"durationMs": 224,
"exitCode": 0,
"id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"status": "completed",
"type": "commandExecution"
}
}
}
```
2025-11-17 16:23:54 -08:00
|
|
|
use codex_protocol::protocol::FileChange;
|
|
|
|
|
use codex_protocol::protocol::ReviewDecision;
|
2025-10-30 16:56:55 -07:00
|
|
|
use codex_protocol::protocol::SandboxPolicy;
|
2025-11-06 14:13:24 -08:00
|
|
|
use codex_protocol::protocol::SessionSource;
|
2025-10-30 16:56:55 -07:00
|
|
|
use codex_protocol::protocol::TurnAbortReason;
|
2025-12-12 15:25:22 -08:00
|
|
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
2025-10-30 16:56:55 -07:00
|
|
|
use schemars::JsonSchema;
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use serde::Serialize;
|
|
|
|
|
use ts_rs::TS;
|
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
|
|
// Reuse shared types defined in `common.rs`.
|
|
|
|
|
use crate::protocol::common::AuthMode;
|
|
|
|
|
use crate::protocol::common::GitSha;
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct InitializeParams {
|
|
|
|
|
pub client_info: ClientInfo,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ClientInfo {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub title: Option<String>,
|
|
|
|
|
pub version: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct InitializeResponse {
|
|
|
|
|
pub user_agent: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct NewConversationParams {
|
|
|
|
|
pub model: Option<String>,
|
|
|
|
|
pub model_provider: Option<String>,
|
|
|
|
|
pub profile: Option<String>,
|
|
|
|
|
pub cwd: Option<String>,
|
|
|
|
|
pub approval_policy: Option<AskForApproval>,
|
|
|
|
|
pub sandbox: Option<SandboxMode>,
|
|
|
|
|
pub config: Option<HashMap<String, serde_json::Value>>,
|
|
|
|
|
pub base_instructions: Option<String>,
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
pub developer_instructions: Option<String>,
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
pub compact_prompt: Option<String>,
|
|
|
|
|
pub include_apply_patch_tool: Option<bool>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct NewConversationResponse {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
pub model: String,
|
|
|
|
|
pub reasoning_effort: Option<ReasoningEffort>,
|
|
|
|
|
pub rollout_path: PathBuf,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ResumeConversationResponse {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
pub model: String,
|
|
|
|
|
pub initial_messages: Option<Vec<EventMsg>>,
|
|
|
|
|
pub rollout_path: PathBuf,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(untagged)]
|
|
|
|
|
pub enum GetConversationSummaryParams {
|
|
|
|
|
RolloutPath {
|
|
|
|
|
#[serde(rename = "rolloutPath")]
|
|
|
|
|
rollout_path: PathBuf,
|
|
|
|
|
},
|
|
|
|
|
ConversationId {
|
|
|
|
|
#[serde(rename = "conversationId")]
|
|
|
|
|
conversation_id: ConversationId,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct GetConversationSummaryResponse {
|
|
|
|
|
pub summary: ConversationSummary,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ListConversationsParams {
|
|
|
|
|
pub page_size: Option<usize>,
|
|
|
|
|
pub cursor: Option<String>,
|
|
|
|
|
pub model_providers: Option<Vec<String>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ConversationSummary {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
pub path: PathBuf,
|
|
|
|
|
pub preview: String,
|
|
|
|
|
pub timestamp: Option<String>,
|
|
|
|
|
pub model_provider: String,
|
2025-11-06 14:13:24 -08:00
|
|
|
pub cwd: PathBuf,
|
|
|
|
|
pub cli_version: String,
|
|
|
|
|
pub source: SessionSource,
|
|
|
|
|
pub git_info: Option<ConversationGitInfo>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
|
pub struct ConversationGitInfo {
|
|
|
|
|
pub sha: Option<String>,
|
|
|
|
|
pub branch: Option<String>,
|
|
|
|
|
pub origin_url: Option<String>,
|
2025-10-30 16:56:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ListConversationsResponse {
|
|
|
|
|
pub items: Vec<ConversationSummary>,
|
|
|
|
|
pub next_cursor: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ResumeConversationParams {
|
|
|
|
|
pub path: Option<PathBuf>,
|
|
|
|
|
pub conversation_id: Option<ConversationId>,
|
|
|
|
|
pub history: Option<Vec<ResponseItem>>,
|
|
|
|
|
pub overrides: Option<NewConversationParams>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct AddConversationSubscriptionResponse {
|
|
|
|
|
#[schemars(with = "String")]
|
|
|
|
|
pub subscription_id: Uuid,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ArchiveConversationParams {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
pub rollout_path: PathBuf,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ArchiveConversationResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct RemoveConversationSubscriptionResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct LoginApiKeyParams {
|
|
|
|
|
pub api_key: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct LoginApiKeyResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct LoginChatGptResponse {
|
|
|
|
|
#[schemars(with = "String")]
|
|
|
|
|
pub login_id: Uuid,
|
|
|
|
|
pub auth_url: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct GitDiffToRemoteResponse {
|
|
|
|
|
pub sha: GitSha,
|
|
|
|
|
pub diff: String,
|
|
|
|
|
}
|
|
|
|
|
|
[app-server] feat: add v2 command execution approval flow (#6758)
This PR adds the API V2 version of the command‑execution approval flow
for the shell tool.
This PR wires the new RPC (`item/commandExecution/requestApproval`, V2
only) and related events (`item/started`, `item/completed`, and
`item/commandExecution/delta`, which are emitted in both V1 and V2)
through the app-server
protocol. The new approval RPC is only sent when the user initiates a
turn with the new `turn/start` API so we don't break backwards
compatibility with VSCE.
The approach I took was to make as few changes to the Codex core as
possible, leveraging existing `EventMsg` core events, and translating
those in app-server. I did have to add additional fields to
`EventMsg::ExecCommandEndEvent` to capture the command's input so that
app-server can statelessly transform these events to a
`ThreadItem::CommandExecution` item for the `item/completed` event.
Once we stabilize the API and it's complete enough for our partners, we
can work on migrating the core to be aware of command execution items as
a first-class concept.
**Note**: We'll need followup work to make sure these APIs work for the
unified exec tool, but will wait til that's stable and landed before
doing a pass on app-server.
Example payloads below:
```
{
"method": "item/started",
"params": {
"item": {
"aggregatedOutput": null,
"command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
"cwd": "/Users/owen/repos/codex/codex-rs",
"durationMs": null,
"exitCode": null,
"id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"status": "inProgress",
"type": "commandExecution"
}
}
}
```
```
{
"id": 0,
"method": "item/commandExecution/requestApproval",
"params": {
"itemId": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"reason": "Need to create file in /tmp which is outside workspace sandbox",
"risk": null,
"threadId": "019a93e8-0a52-7fe3-9808-b6bc40c0989a",
"turnId": "1"
}
}
```
```
{
"id": 0,
"result": {
"acceptSettings": {
"forSession": false
},
"decision": "accept"
}
}
```
```
{
"params": {
"item": {
"aggregatedOutput": null,
"command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
"cwd": "/Users/owen/repos/codex/codex-rs",
"durationMs": 224,
"exitCode": 0,
"id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
"parsedCmd": [
{
"cmd": "touch /tmp/should-trigger-approval",
"type": "unknown"
}
],
"status": "completed",
"type": "commandExecution"
}
}
}
```
2025-11-17 16:23:54 -08:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ApplyPatchApprovalParams {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
/// Use to correlate this with [codex_core::protocol::PatchApplyBeginEvent]
|
|
|
|
|
/// and [codex_core::protocol::PatchApplyEndEvent].
|
|
|
|
|
pub call_id: String,
|
|
|
|
|
pub file_changes: HashMap<PathBuf, FileChange>,
|
|
|
|
|
/// Optional explanatory reason (e.g. request for extra write access).
|
|
|
|
|
pub reason: Option<String>,
|
|
|
|
|
/// When set, the agent is asking the user to allow writes under this root
|
|
|
|
|
/// for the remainder of the session (unclear if this is honored today).
|
|
|
|
|
pub grant_root: Option<PathBuf>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ApplyPatchApprovalResponse {
|
|
|
|
|
pub decision: ReviewDecision,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ExecCommandApprovalParams {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
/// Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent]
|
|
|
|
|
/// and [codex_core::protocol::ExecCommandEndEvent].
|
|
|
|
|
pub call_id: String,
|
|
|
|
|
pub command: Vec<String>,
|
|
|
|
|
pub cwd: PathBuf,
|
|
|
|
|
pub reason: Option<String>,
|
|
|
|
|
pub parsed_cmd: Vec<ParsedCommand>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
pub struct ExecCommandApprovalResponse {
|
|
|
|
|
pub decision: ReviewDecision,
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-30 16:56:55 -07:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct CancelLoginChatGptParams {
|
|
|
|
|
#[schemars(with = "String")]
|
|
|
|
|
pub login_id: Uuid,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct GitDiffToRemoteParams {
|
|
|
|
|
pub cwd: PathBuf,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct CancelLoginChatGptResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct LogoutChatGptParams {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct LogoutChatGptResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct GetAuthStatusParams {
|
|
|
|
|
pub include_token: Option<bool>,
|
|
|
|
|
pub refresh_token: Option<bool>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ExecOneOffCommandParams {
|
|
|
|
|
pub command: Vec<String>,
|
|
|
|
|
pub timeout_ms: Option<u64>,
|
|
|
|
|
pub cwd: Option<PathBuf>,
|
|
|
|
|
pub sandbox_policy: Option<SandboxPolicy>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct ExecOneOffCommandResponse {
|
|
|
|
|
pub exit_code: i32,
|
|
|
|
|
pub stdout: String,
|
|
|
|
|
pub stderr: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct GetAuthStatusResponse {
|
|
|
|
|
pub auth_method: Option<AuthMode>,
|
|
|
|
|
pub auth_token: Option<String>,
|
|
|
|
|
pub requires_openai_auth: Option<bool>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct GetUserAgentResponse {
|
|
|
|
|
pub user_agent: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct UserInfoResponse {
|
|
|
|
|
pub alleged_user_email: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct GetUserSavedConfigResponse {
|
|
|
|
|
pub config: UserSavedConfig,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SetDefaultModelParams {
|
|
|
|
|
pub model: Option<String>,
|
|
|
|
|
pub reasoning_effort: Option<ReasoningEffort>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SetDefaultModelResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct UserSavedConfig {
|
|
|
|
|
pub approval_policy: Option<AskForApproval>,
|
|
|
|
|
pub sandbox_mode: Option<SandboxMode>,
|
|
|
|
|
pub sandbox_settings: Option<SandboxSettings>,
|
|
|
|
|
pub forced_chatgpt_workspace_id: Option<String>,
|
|
|
|
|
pub forced_login_method: Option<ForcedLoginMethod>,
|
|
|
|
|
pub model: Option<String>,
|
|
|
|
|
pub model_reasoning_effort: Option<ReasoningEffort>,
|
|
|
|
|
pub model_reasoning_summary: Option<ReasoningSummary>,
|
|
|
|
|
pub model_verbosity: Option<Verbosity>,
|
|
|
|
|
pub tools: Option<Tools>,
|
|
|
|
|
pub profile: Option<String>,
|
|
|
|
|
pub profiles: HashMap<String, Profile>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct Profile {
|
|
|
|
|
pub model: Option<String>,
|
|
|
|
|
pub model_provider: Option<String>,
|
|
|
|
|
pub approval_policy: Option<AskForApproval>,
|
|
|
|
|
pub model_reasoning_effort: Option<ReasoningEffort>,
|
|
|
|
|
pub model_reasoning_summary: Option<ReasoningSummary>,
|
|
|
|
|
pub model_verbosity: Option<Verbosity>,
|
|
|
|
|
pub chatgpt_base_url: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct Tools {
|
|
|
|
|
pub web_search: Option<bool>,
|
|
|
|
|
pub view_image: Option<bool>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Debug, Clone, PartialEq, Serialize, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SandboxSettings {
|
|
|
|
|
#[serde(default)]
|
2025-12-12 15:25:22 -08:00
|
|
|
pub writable_roots: Vec<AbsolutePathBuf>,
|
2025-10-30 16:56:55 -07:00
|
|
|
pub network_access: Option<bool>,
|
|
|
|
|
pub exclude_tmpdir_env_var: Option<bool>,
|
|
|
|
|
pub exclude_slash_tmp: Option<bool>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SendUserMessageParams {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
pub items: Vec<InputItem>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SendUserTurnParams {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
pub items: Vec<InputItem>,
|
|
|
|
|
pub cwd: PathBuf,
|
|
|
|
|
pub approval_policy: AskForApproval,
|
|
|
|
|
pub sandbox_policy: SandboxPolicy,
|
|
|
|
|
pub model: String,
|
|
|
|
|
pub effort: Option<ReasoningEffort>,
|
|
|
|
|
pub summary: ReasoningSummary,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SendUserTurnResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct InterruptConversationParams {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct InterruptConversationResponse {
|
|
|
|
|
pub abort_reason: TurnAbortReason,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SendUserMessageResponse {}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct AddConversationListenerParams {
|
|
|
|
|
pub conversation_id: ConversationId,
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub experimental_raw_events: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct RemoveConversationListenerParams {
|
|
|
|
|
#[schemars(with = "String")]
|
|
|
|
|
pub subscription_id: Uuid,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
#[serde(tag = "type", content = "data")]
|
|
|
|
|
pub enum InputItem {
|
|
|
|
|
Text { text: String },
|
|
|
|
|
Image { image_url: String },
|
|
|
|
|
LocalImage { path: PathBuf },
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-05 17:13:55 -08:00
|
|
|
/// Deprecated in favor of AccountLoginCompletedNotification.
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct LoginChatGptCompleteNotification {
|
|
|
|
|
#[schemars(with = "String")]
|
|
|
|
|
pub login_id: Uuid,
|
|
|
|
|
pub success: bool,
|
|
|
|
|
pub error: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
pub struct SessionConfiguredNotification {
|
|
|
|
|
pub session_id: ConversationId,
|
|
|
|
|
pub model: String,
|
|
|
|
|
pub reasoning_effort: Option<ReasoningEffort>,
|
|
|
|
|
pub history_log_id: u64,
|
|
|
|
|
#[ts(type = "number")]
|
|
|
|
|
pub history_entry_count: usize,
|
|
|
|
|
pub initial_messages: Option<Vec<EventMsg>>,
|
|
|
|
|
pub rollout_path: PathBuf,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2025-11-03 22:01:33 -08:00
|
|
|
/// Deprecated notification. Use AccountUpdatedNotification instead.
|
2025-10-30 16:56:55 -07:00
|
|
|
pub struct AuthStatusChangeNotification {
|
|
|
|
|
pub auth_method: Option<AuthMode>,
|
|
|
|
|
}
|