@ellipsis-dev/sdk 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,24 +1,14 @@
1
1
  {
2
2
  "$defs": {
3
- "AttributionType": {
4
- "enum": [
5
- "github_user",
6
- "linear_user",
7
- "slack_user",
8
- "api_key"
9
- ],
10
- "title": "AttributionType",
11
- "type": "string"
12
- },
13
- "Automation": {
14
- "description": "An automation: a saved agent definition that runs on its trigger or\nwhen invoked, plus where it syncs from and the state of that sync.",
3
+ "Agent": {
4
+ "description": "An agent: a saved agent definition that runs on its trigger or\nwhen invoked, plus where it syncs from and the state of that sync.",
15
5
  "properties": {
16
6
  "config": {
17
- "$ref": "#/$defs/AutomationConfig",
18
- "description": "The automation definition itself, in the same schema as its YAML file: identity, trigger, input contract, and the session block."
7
+ "$ref": "#/$defs/AgentConfig",
8
+ "description": "The agent definition itself, in the same schema as its YAML file: identity, trigger, input contract, and the session block."
19
9
  },
20
10
  "created_at": {
21
- "description": "When the automation was created.",
11
+ "description": "When the agent was created.",
22
12
  "format": "date-time",
23
13
  "title": "Created At",
24
14
  "type": "string"
@@ -46,10 +36,10 @@
46
36
  }
47
37
  ],
48
38
  "default": null,
49
- "description": "The GitHub account that last edited the automation, when the edit came from a known user."
39
+ "description": "The GitHub account that last edited the agent, when the edit came from a known user."
50
40
  },
51
41
  "id": {
52
- "description": "Unique identifier of the automation.",
42
+ "description": "Unique identifier of the agent.",
53
43
  "title": "Id",
54
44
  "type": "string"
55
45
  },
@@ -77,7 +67,7 @@
77
67
  }
78
68
  ],
79
69
  "default": null,
80
- "description": "The most recent session this automation started, or null if it has never run.",
70
+ "description": "The most recent session this agent started, or null if it has never run.",
81
71
  "title": "Last Session Id"
82
72
  },
83
73
  "last_sync_error": {
@@ -90,7 +80,7 @@
90
80
  }
91
81
  ],
92
82
  "default": null,
93
- "description": "The parse or validation error from the most recent sync attempt, or null when it succeeded. A non-null value means the automation is not running the YAML currently on the branch.",
83
+ "description": "The parse or validation error from the most recent sync attempt, or null when it succeeded. A non-null value means the agent is not running the YAML currently on the branch.",
94
84
  "title": "Last Sync Error"
95
85
  },
96
86
  "last_synced_commit_sha": {
@@ -103,12 +93,12 @@
103
93
  }
104
94
  ],
105
95
  "default": null,
106
- "description": "The last commit the automation was synced from.",
96
+ "description": "The last commit the agent was synced from.",
107
97
  "title": "Last Synced Commit Sha"
108
98
  },
109
99
  "managed_by": {
110
100
  "$ref": "#/$defs/ConfigManagedBy",
111
- "description": "Which writer owns this automation. \"github\" automations are defined by a file in a repository and are changed by editing that file; \"api\" automations have no file and are changed through this API."
101
+ "description": "Which writer owns this agent. \"github\" agents are defined by a file in a repository and are changed by editing that file; \"api\" agents have no file and are changed through this API."
112
102
  },
113
103
  "name": {
114
104
  "anyOf": [
@@ -120,7 +110,7 @@
120
110
  }
121
111
  ],
122
112
  "default": null,
123
- "description": "The automation's account-unique addressable name (a slug of its display name); usable anywhere an automation is referenced, interchangeably with the id.",
113
+ "description": "The agent's account-unique addressable name (a slug of its display name); usable anywhere an agent is referenced, interchangeably with the id.",
124
114
  "title": "Name"
125
115
  },
126
116
  "pending_pull_request_url": {
@@ -133,7 +123,7 @@
133
123
  }
134
124
  ],
135
125
  "default": null,
136
- "description": "The open pull request that adds this automation's file. Non-null means the automation is not live yet: it starts running once the pull request merges and syncs.",
126
+ "description": "The open pull request that adds this agent's file. Non-null means the agent is not live yet: it starts running once the pull request merges and syncs.",
137
127
  "title": "Pending Pull Request Url"
138
128
  },
139
129
  "sha": {
@@ -151,10 +141,10 @@
151
141
  }
152
142
  ],
153
143
  "default": null,
154
- "description": "The repository, path, and branch the automation syncs from. Null only transiently, before the creating pull request's file lands on the branch."
144
+ "description": "The repository, path, and branch the agent syncs from. Null only transiently, before the creating pull request's file lands on the branch."
155
145
  },
156
146
  "updated_at": {
157
- "description": "When the automation was last updated.",
147
+ "description": "When the agent was last updated.",
158
148
  "format": "date-time",
159
149
  "title": "Updated At",
160
150
  "type": "string"
@@ -177,25 +167,15 @@
177
167
  "source_details",
178
168
  "updated_at"
179
169
  ],
180
- "title": "Automation",
170
+ "title": "Agent",
181
171
  "type": "object"
182
172
  },
183
- "AutomationConfig": {
173
+ "AgentConfig": {
184
174
  "additionalProperties": false,
185
- "description": "A saved automation, as written in its YAML file: identity\n(`ellipsis`), when it runs (`trigger`), what goes in (`input`), and the\n`session:` block every session it starts is frozen from. Field order is\nthe canonical key order for files and `to_yaml` exports.",
175
+ "description": "A saved agent, as written in its YAML file: identity\n(`ellipsis`), when it runs (`trigger`), what goes in (`input`), and the\n`session:` block every session it starts is frozen from. Field order is\nthe canonical key order for files and `to_yaml` exports.",
186
176
  "properties": {
187
177
  "ellipsis": {
188
- "$ref": "#/$defs/AutomationIdentity",
189
- "default": {
190
- "description": null,
191
- "enabled": true,
192
- "metadata": {
193
- "annotations": {},
194
- "labels": []
195
- },
196
- "name": null,
197
- "version": "v1"
198
- }
178
+ "$ref": "#/$defs/AgentIdentity"
199
179
  },
200
180
  "input": {
201
181
  "anyOf": [
@@ -244,12 +224,12 @@
244
224
  "session",
245
225
  "trigger"
246
226
  ],
247
- "title": "AutomationConfig",
227
+ "title": "AgentConfig",
248
228
  "type": "object"
249
229
  },
250
- "AutomationIdentity": {
230
+ "AgentIdentity": {
251
231
  "additionalProperties": false,
252
- "description": "The Ellipsis product namespace for a config file: which schema this is\n(`version`), the human-facing identity (`name`/`description`), freeform\norganizational `metadata`, and whether the agent is `enabled`. The\npresence of a top-level `ellipsis:` mapping is what marks a YAML file as\nan Ellipsis automation (vs arbitrary YAML that merely lives under a\nconfig directory) \u2014 see `yaml_is_ellipsis_config`.\n\n`enabled` is agent behavior, not freeform metadata, so it stays inside\nthe config `sha` (only `metadata` is sha-excluded). Whether a session\naccepts messages is a per-run choice (POST /v1/sessions `interactive`),\nnot a config one.",
232
+ "description": "The Ellipsis product namespace for a config file: which schema this is\n(`version`), the human-facing identity (`name`/`description`), freeform\norganizational `metadata`, and whether the agent is `enabled`. The\npresence of a top-level `ellipsis:` mapping is what marks a YAML file as\nan Ellipsis agent (vs arbitrary YAML that merely lives under a\nconfig directory) \u2014 see `yaml_is_ellipsis_config`.\n\n`enabled` is agent behavior, not freeform metadata, so it stays inside\nthe config `sha` (only `metadata` is sha-excluded). Whether a session\naccepts messages is a per-run choice (POST /v1/sessions `interactive`),\nnot a config one.",
253
233
  "properties": {
254
234
  "description": {
255
235
  "anyOf": [
@@ -268,6 +248,11 @@
268
248
  "title": "Enabled",
269
249
  "type": "boolean"
270
250
  },
251
+ "kind": {
252
+ "const": "agent",
253
+ "title": "Kind",
254
+ "type": "string"
255
+ },
271
256
  "metadata": {
272
257
  "$ref": "#/$defs/ConfigMetadata",
273
258
  "default": {
@@ -296,36 +281,47 @@
296
281
  "required": [
297
282
  "description",
298
283
  "enabled",
284
+ "kind",
299
285
  "metadata",
300
286
  "name",
301
287
  "version"
302
288
  ],
303
- "title": "AutomationIdentity",
289
+ "title": "AgentIdentity",
304
290
  "type": "object"
305
291
  },
306
- "AutomationListStreamMessage": {
292
+ "AgentListStreamMessage": {
307
293
  "properties": {
308
- "automations": {
294
+ "agents": {
309
295
  "items": {
310
- "$ref": "#/$defs/Automation"
296
+ "$ref": "#/$defs/Agent"
311
297
  },
312
- "title": "Automations",
298
+ "title": "Agents",
313
299
  "type": "array"
314
300
  },
315
301
  "type": {
316
- "const": "automations",
317
- "default": "automations",
302
+ "const": "agents",
303
+ "default": "agents",
318
304
  "title": "Type",
319
305
  "type": "string"
320
306
  }
321
307
  },
322
308
  "required": [
323
- "automations",
309
+ "agents",
324
310
  "type"
325
311
  ],
326
- "title": "AutomationListStreamMessage",
312
+ "title": "AgentListStreamMessage",
327
313
  "type": "object"
328
314
  },
315
+ "AttributionType": {
316
+ "enum": [
317
+ "github_user",
318
+ "linear_user",
319
+ "slack_user",
320
+ "api_key"
321
+ ],
322
+ "title": "AttributionType",
323
+ "type": "string"
324
+ },
329
325
  "BudgetConfig": {
330
326
  "additionalProperties": false,
331
327
  "properties": {
@@ -356,6 +352,7 @@
356
352
  "session": {
357
353
  "anyOf": [
358
354
  {
355
+ "exclusiveMinimum": 0,
359
356
  "type": "number"
360
357
  },
361
358
  {
@@ -387,17 +384,6 @@
387
384
  "title": "BudgetConfig",
388
385
  "type": "object"
389
386
  },
390
- "BudgetSource": {
391
- "description": "Which layer actually determined the enforced budget.\n\nNot derivable from the run row alone (the run does not store the config\ncents or the account default), so we persist it for the UI / audit.",
392
- "enum": [
393
- "system",
394
- "account",
395
- "config",
396
- "run"
397
- ],
398
- "title": "BudgetSource",
399
- "type": "string"
400
- },
401
387
  "ClaudeConfig": {
402
388
  "additionalProperties": false,
403
389
  "description": "Native Claude Code options for an explicitly selected harness.",
@@ -450,6 +436,19 @@
450
436
  "default": null,
451
437
  "title": "Model"
452
438
  },
439
+ "prompt": {
440
+ "anyOf": [
441
+ {
442
+ "type": "string"
443
+ },
444
+ {
445
+ "type": "null"
446
+ }
447
+ ],
448
+ "default": null,
449
+ "description": "The initial user message, passed verbatim. Omit to start an interactive session idle.",
450
+ "title": "Prompt"
451
+ },
453
452
  "settings": {
454
453
  "anyOf": [
455
454
  {
@@ -460,11 +459,6 @@
460
459
  }
461
460
  ],
462
461
  "default": null
463
- },
464
- "type": {
465
- "const": "claude_code",
466
- "title": "Type",
467
- "type": "string"
468
462
  }
469
463
  },
470
464
  "required": [
@@ -472,8 +466,8 @@
472
466
  "fallback_model",
473
467
  "max_turns",
474
468
  "model",
475
- "settings",
476
- "type"
469
+ "prompt",
470
+ "settings"
477
471
  ],
478
472
  "title": "ClaudeConfig",
479
473
  "type": "object"
@@ -499,16 +493,24 @@
499
493
  "title": "Model",
500
494
  "type": "string"
501
495
  },
502
- "type": {
503
- "const": "codex",
504
- "title": "Type",
505
- "type": "string"
496
+ "prompt": {
497
+ "anyOf": [
498
+ {
499
+ "type": "string"
500
+ },
501
+ {
502
+ "type": "null"
503
+ }
504
+ ],
505
+ "default": null,
506
+ "description": "The initial user message, passed verbatim. Omit to start an interactive session idle.",
507
+ "title": "Prompt"
506
508
  }
507
509
  },
508
510
  "required": [
509
511
  "effort",
510
512
  "model",
511
- "type"
513
+ "prompt"
512
514
  ],
513
515
  "title": "CodexConfig",
514
516
  "type": "object"
@@ -542,7 +544,7 @@
542
544
  },
543
545
  "ComputeConfig": {
544
546
  "additionalProperties": false,
545
- "description": "Sandbox compute sizing. Every field is optional; None inherits the\nplatform default (2 vCPU / 4096 MiB / 3600s \u2014 see DEFAULT_SANDBOX_* in\nmodels/ellipsis/sandboxes/sandbox.py). A resolved value outside the platform\nbounds fails validation loudly (a sync error on the config) rather than\nbeing clamped silently.\n\n`memory` and `timeout` each accept a shorthand string (\"8GB\", \"30m\") or an\nexplicit units object ({gb: 8}, {minutes: 30}); the `memory_mib` /\n`timeout_seconds` properties resolve either form to the canonical integer\nthe sandbox driver consumes.\n\n`timeout` is the max wall-clock the agent may run before its execution is\nstopped, capped at 1h (MAX_SANDBOX_TIMEOUT_SECONDS \u2014 equal to the default, so\ntoday the knob only shortens a session; the cap matches the 1-hour validity\nof the sandbox's GitHub token). The worker's lease/visibility heartbeat\nceiling is derived from that cap, so a run at the max stays owned by its\nworker for its whole life.\n\nCompute currently uses a temporary flat one-cent amount per allocated\nexecution, subject to the account's existing free-compute exemptions.",
547
+ "description": "Sandbox compute sizing. Every field is optional; None inherits the\nplatform default (2 vCPU / 4096 MiB / 3600s \u2014 see DEFAULT_SANDBOX_* in\nmodels/ellipsis/vms/vm_execution.py). A resolved value outside the platform\nbounds fails validation loudly (a sync error on the config) rather than\nbeing clamped silently.\n\n`memory` and `timeout` each accept a shorthand string (\"8GB\", \"30m\") or an\nexplicit units object ({gb: 8}, {minutes: 30}); the `memory_mib` /\n`timeout_seconds` properties resolve either form to the canonical integer\nthe sandbox driver consumes.\n\n`timeout` is the max wall-clock the agent may run before its execution is\nstopped, capped at 1h (MAX_SANDBOX_TIMEOUT_SECONDS \u2014 equal to the default, so\ntoday the knob only shortens a session; the cap matches the 1-hour validity\nof the sandbox's GitHub token). The worker's lease/visibility heartbeat\nceiling is derived from that cap, so a run at the max stays owned by its\nworker for its whole life.\n\nCompute currently uses a temporary flat one-cent amount per allocated\nexecution, subject to the account's existing free-compute exemptions.",
546
548
  "properties": {
547
549
  "cpu": {
548
550
  "anyOf": [
@@ -633,6 +635,14 @@
633
635
  "title": "ConfigMetadata",
634
636
  "type": "object"
635
637
  },
638
+ "ConversationState": {
639
+ "enum": [
640
+ "open",
641
+ "closed"
642
+ ],
643
+ "title": "ConversationState",
644
+ "type": "string"
645
+ },
636
646
  "CronTrigger": {
637
647
  "additionalProperties": false,
638
648
  "properties": {
@@ -778,9 +788,43 @@
778
788
  "title": "EllipsisPermissions",
779
789
  "type": "object"
780
790
  },
791
+ "EnvironmentBaseBuild": {
792
+ "additionalProperties": false,
793
+ "description": "Create a reusable base, optionally using only selected repository files.",
794
+ "properties": {
795
+ "inputs": {
796
+ "anyOf": [
797
+ {
798
+ "items": {
799
+ "type": "string"
800
+ },
801
+ "type": "array"
802
+ },
803
+ {
804
+ "type": "null"
805
+ }
806
+ ],
807
+ "default": null,
808
+ "description": "Exact files relative to /sandbox, including the repository name. Only these files are available during build_base and their contents and modes determine reuse. Omit to use all repositories and invalidate on any source change; [] means no repository files.",
809
+ "title": "Inputs"
810
+ },
811
+ "run": {
812
+ "description": "Shell script to run in /sandbox.",
813
+ "minLength": 1,
814
+ "title": "Run",
815
+ "type": "string"
816
+ }
817
+ },
818
+ "required": [
819
+ "inputs",
820
+ "run"
821
+ ],
822
+ "title": "EnvironmentBaseBuild",
823
+ "type": "object"
824
+ },
781
825
  "EnvironmentConfig": {
782
826
  "additionalProperties": false,
783
- "description": "Everything about the environment (the sandbox) the agent runs in: which\n`repositories` are cloned into it, which environment `variables` it gets,\nits `compute` sizing, how its `image` is customized, and lifecycle `hooks`.\nWhat the agent may *do* from that environment is the top-level\n`permissions:` block, not this one.\n\nEach `variables` entry names a variable to inject; with an inline `value` it\nis hardcoded, without one it is resolved from the account's sandbox-secrets\nstore. Only the named variables reach this agent; the rest of the account's\nstored variables never do. This is how a config brings in the config and\ncredentials a custom CLI needs.",
827
+ "description": "Everything about the environment (the sandbox) the agent runs in: which\n`repositories` are cloned into it, which environment `variables` it gets,\nits `compute` sizing, and lifecycle `hooks`.\nWhat the agent may *do* from that environment is the top-level\n`permissions:` block, not this one.\n\nEach `variables` entry names a variable to inject; with an inline `value` it\nis hardcoded, without one it is resolved from the account's sandbox-secrets\nstore. Only the named variables reach this agent; the rest of the account's\nstored variables never do. This is how a config brings in the config and\ncredentials a custom CLI needs.",
784
828
  "properties": {
785
829
  "compute": {
786
830
  "$ref": "#/$defs/ComputeConfig",
@@ -793,17 +837,13 @@
793
837
  "hooks": {
794
838
  "$ref": "#/$defs/EnvironmentHooks",
795
839
  "default": {
840
+ "after_checkout": null,
841
+ "before_start": null,
842
+ "build_base": null,
796
843
  "post_clone": null,
797
844
  "post_start": null
798
845
  }
799
846
  },
800
- "image": {
801
- "$ref": "#/$defs/EnvironmentImage",
802
- "default": {
803
- "dockerfile_append": null,
804
- "setup": null
805
- }
806
- },
807
847
  "mcp_servers": {
808
848
  "default": [],
809
849
  "items": {
@@ -845,7 +885,6 @@
845
885
  "required": [
846
886
  "compute",
847
887
  "hooks",
848
- "image",
849
888
  "mcp_servers",
850
889
  "repositories",
851
890
  "variables"
@@ -855,10 +894,13 @@
855
894
  },
856
895
  "EnvironmentHooks": {
857
896
  "additionalProperties": false,
858
- "description": "Shell scripts run at points in the sandbox lifecycle, each as the sandbox\nuser with the sandbox's environment variables available. A non-zero exit\nfails the run (exit_status = LIFECYCLE_HOOK_FAILED) and is not retried.\n\n`post_start` runs after the container starts, before any repo is cloned \u2014\nrepo-independent setup (authenticate a CLI, e.g. `doppler setup`). On Freestyle\nthe repo is baked into the image so it is incidentally present, but\n`post_start` must not depend on repo contents (that's `post_clone`).\n\n`post_clone` runs after all repos are cloned/checked out, before the agent \u2014\nrepo-dependent setup (`pip install -r requirements.txt`, codegen).\n\nHooks run on every run and their output is never cached. A dependency\ninstall whose result should be reused across runs belongs in `image.setup`\n(baked into the cached image) instead; keep hooks for per-run work \u2014 e.g.\nanything that touches run-scoped credentials.",
897
+ "description": "Environment lifecycle scripts, in order: build_base, after_checkout,\nbefore_start. The first two produce reusable snapshots; before_start runs\nbefore an agent starts or resumes its session. Scripts run as the sandbox\nuser in /sandbox. A nonzero exit fails the session.\n\nLegacy post_start/post_clone scripts remain supported for existing configs;\nboth run after workspace preparation, before the agent starts or resumes.\nThey cannot be combined with the new lifecycle fields.",
859
898
  "properties": {
860
- "post_clone": {
899
+ "after_checkout": {
861
900
  "anyOf": [
901
+ {
902
+ "$ref": "#/$defs/EnvironmentScript"
903
+ },
862
904
  {
863
905
  "type": "string"
864
906
  },
@@ -867,10 +909,14 @@
867
909
  }
868
910
  ],
869
911
  "default": null,
870
- "title": "Post Clone"
912
+ "description": "Prepare the requested source revision after Ellipsis checks out all repositories, before saving the prepared sandbox. Skipped when that prepared sandbox is reused.",
913
+ "title": "After Checkout"
871
914
  },
872
- "post_start": {
915
+ "before_start": {
873
916
  "anyOf": [
917
+ {
918
+ "$ref": "#/$defs/EnvironmentScript"
919
+ },
874
920
  {
875
921
  "type": "string"
876
922
  },
@@ -879,21 +925,26 @@
879
925
  }
880
926
  ],
881
927
  "default": null,
882
- "title": "Post Start"
883
- }
884
- },
885
- "required": [
886
- "post_clone",
887
- "post_start"
888
- ],
889
- "title": "EnvironmentHooks",
890
- "type": "object"
891
- },
892
- "EnvironmentImage": {
893
- "additionalProperties": false,
894
- "description": "How to customize the container image the agent runs in. You\ncontribute appended layers (`dockerfile_append`) and a build-time script\n(`setup`) only \u2014 Ellipsis owns FROM / base tooling / entrypoint / user.\nToday only inline bodies are supported; a file reference (resolved at the\nrun's SHA) will come later.\n\nThe split: `dockerfile_append` runs when the image is assembled, before any\nrepo exists \u2014 toolchain installs (a package manager binary, apt packages).\n`setup` runs at image-build time *after* the configured repositories are\nchecked out, and its output is captured by the filesystem snapshot that\nbecomes the cached image \u2014 dependency installs (`poetry install`,\n`npm install`), so later runs start with deps already on disk. Neither runs\nper run; that's `hooks.post_start` / `hooks.post_clone`.",
895
- "properties": {
896
- "dockerfile_append": {
928
+ "description": "Run before the agent starts or resumes a session, after the sandbox is ready. This hook is not cached and adds to session startup time.",
929
+ "title": "Before Start"
930
+ },
931
+ "build_base": {
932
+ "anyOf": [
933
+ {
934
+ "$ref": "#/$defs/EnvironmentBaseBuild"
935
+ },
936
+ {
937
+ "type": "string"
938
+ },
939
+ {
940
+ "type": "null"
941
+ }
942
+ ],
943
+ "default": null,
944
+ "description": "Build a reusable environment before full checkout. Cached by declared inputs, script, toolchain, resources, and build configuration. A string is shorthand for run with all repositories as inputs.",
945
+ "title": "Build Base"
946
+ },
947
+ "post_clone": {
897
948
  "anyOf": [
898
949
  {
899
950
  "type": "string"
@@ -903,9 +954,10 @@
903
954
  }
904
955
  ],
905
956
  "default": null,
906
- "title": "Dockerfile Append"
957
+ "description": "Legacy session startup script. Use before_start for session setup or after_checkout for cached source preparation.",
958
+ "title": "Post Clone"
907
959
  },
908
- "setup": {
960
+ "post_start": {
909
961
  "anyOf": [
910
962
  {
911
963
  "type": "string"
@@ -915,21 +967,42 @@
915
967
  }
916
968
  ],
917
969
  "default": null,
918
- "title": "Setup"
970
+ "description": "Legacy session startup script. Use before_start in new configurations.",
971
+ "title": "Post Start"
972
+ }
973
+ },
974
+ "required": [
975
+ "after_checkout",
976
+ "before_start",
977
+ "build_base",
978
+ "post_clone",
979
+ "post_start"
980
+ ],
981
+ "title": "EnvironmentHooks",
982
+ "type": "object"
983
+ },
984
+ "EnvironmentScript": {
985
+ "additionalProperties": false,
986
+ "description": "An inline shell script run as the sandbox user, with /sandbox as cwd.",
987
+ "properties": {
988
+ "run": {
989
+ "description": "Shell script to run in /sandbox.",
990
+ "minLength": 1,
991
+ "title": "Run",
992
+ "type": "string"
919
993
  }
920
994
  },
921
995
  "required": [
922
- "dockerfile_append",
923
- "setup"
996
+ "run"
924
997
  ],
925
- "title": "EnvironmentImage",
998
+ "title": "EnvironmentScript",
926
999
  "type": "object"
927
1000
  },
928
1001
  "EnvironmentSource": {
929
1002
  "description": "How a session's environment was chosen. None (the field is nullable)\nwhen the config carried an inline environment block and no resolution ran \u2014\nan inline environment is not a reference, so there is nothing to record.\n\nNot derivable from the row: `environment_id` says WHICH environment, not\nhow it was chosen, and is null for the built-in basic sandbox.",
930
1003
  "enum": [
931
1004
  "request",
932
- "automation",
1005
+ "agent",
933
1006
  "repo_default",
934
1007
  "account_default",
935
1008
  "platform_default"
@@ -995,6 +1068,10 @@
995
1068
  "title": "Include"
996
1069
  }
997
1070
  },
1071
+ "required": [
1072
+ "exclude",
1073
+ "include"
1074
+ ],
998
1075
  "title": "GithubAccountFilter",
999
1076
  "type": "object"
1000
1077
  },
@@ -1065,6 +1142,57 @@
1065
1142
  "title": "GithubAccountType",
1066
1143
  "type": "string"
1067
1144
  },
1145
+ "GithubIssueEvent": {
1146
+ "properties": {
1147
+ "action": {
1148
+ "$ref": "#/$defs/IssueAction"
1149
+ },
1150
+ "actor": {
1151
+ "anyOf": [
1152
+ {
1153
+ "$ref": "#/$defs/SessionEventActor"
1154
+ },
1155
+ {
1156
+ "type": "null"
1157
+ }
1158
+ ],
1159
+ "default": null
1160
+ },
1161
+ "number": {
1162
+ "title": "Number",
1163
+ "type": "integer"
1164
+ },
1165
+ "repository": {
1166
+ "title": "Repository",
1167
+ "type": "string"
1168
+ },
1169
+ "title": {
1170
+ "title": "Title",
1171
+ "type": "string"
1172
+ },
1173
+ "type": {
1174
+ "const": "github.issue",
1175
+ "default": "github.issue",
1176
+ "title": "Type",
1177
+ "type": "string"
1178
+ },
1179
+ "url": {
1180
+ "title": "Url",
1181
+ "type": "string"
1182
+ }
1183
+ },
1184
+ "required": [
1185
+ "action",
1186
+ "actor",
1187
+ "number",
1188
+ "repository",
1189
+ "title",
1190
+ "type",
1191
+ "url"
1192
+ ],
1193
+ "title": "GithubIssueEvent",
1194
+ "type": "object"
1195
+ },
1068
1196
  "GithubPermissions": {
1069
1197
  "additionalProperties": false,
1070
1198
  "description": "The agent's GitHub access: the scope of the installation token minted for\nits sandbox \u2014 the credential `git`, `gh`, and the GitHub MCP server\nauthenticate with.\n\nBy default the token carries the installation's full permissions on all of\nthe installation's repositories. `permissions` narrows what it may do:\nthe string `read_only` grants read access to contents, issues, metadata and\npull requests; a map requests explicit levels per GitHub App permission\nscope (e.g. `{contents: read, pull_requests: write}`) and may never exceed\nwhat the installation granted. `repositories` scopes the token to exactly\nthe listed repos, by name (they must belong to the installation).\n\nRestriction is enforced by GitHub, not by Ellipsis: the token itself is\nminted with the reduced scope, so nothing running in the sandbox can\nexceed it.",
@@ -1111,114 +1239,194 @@
1111
1239
  "title": "GithubPermissions",
1112
1240
  "type": "object"
1113
1241
  },
1114
- "GithubSourceDetails": {
1115
- "description": "Identifies the file a GitHub-sourced automation is synced from.\n\nKeyed on the repository ID (not owner/name) so repository and org renames\ndon't orphan the config; resolve display names from gh_repositories at\nread time.",
1116
- "properties": {
1117
- "branch": {
1118
- "title": "Branch",
1119
- "type": "string"
1120
- },
1121
- "path": {
1122
- "title": "Path",
1123
- "type": "string"
1124
- },
1125
- "repo_id": {
1126
- "title": "Repo Id",
1127
- "type": "integer"
1128
- }
1129
- },
1130
- "required": [
1131
- "branch",
1132
- "path",
1133
- "repo_id"
1134
- ],
1135
- "title": "GithubSourceDetails",
1136
- "type": "object"
1137
- },
1138
- "Harness": {
1139
- "enum": [
1140
- "claude_code",
1141
- "codex"
1142
- ],
1143
- "title": "Harness",
1144
- "type": "string"
1145
- },
1146
- "HarnessOptions": {
1147
- "discriminator": {
1148
- "mapping": {
1149
- "claude_code": "#/$defs/ClaudeConfig",
1150
- "codex": "#/$defs/CodexConfig"
1151
- },
1152
- "propertyName": "type"
1153
- },
1154
- "oneOf": [
1155
- {
1156
- "$ref": "#/$defs/ClaudeConfig"
1157
- },
1158
- {
1159
- "$ref": "#/$defs/CodexConfig"
1160
- }
1161
- ]
1162
- },
1163
- "InputContract": {
1164
- "additionalProperties": false,
1165
- "description": "The typed input contract: what goes INTO a session (the trigger is\nwhen it happens; this is what goes in).\n\n`json_schema` types the payload a caller-started session takes\n(`POST /v1/sessions` `input`, validated at the door; required when\ndeclared). It is illegal on a react-triggered agent \u2014 react payloads are\nplatform-shaped (the published surface field sets), not caller-shaped.\n\n`message` is the initial-message template: exact `{{path}}` substitution\nover the caller payload (or, on a react agent, over the surface's\npublished fields), no conditionals/loops/filters. Refs are validated at\ndeploy time against the governing field set (see AutomationConfig's\n`_check_input`).",
1242
+ "GithubPullRequestEvent": {
1166
1243
  "properties": {
1167
- "json_schema": {
1244
+ "action": {
1168
1245
  "anyOf": [
1169
1246
  {
1170
- "additionalProperties": true,
1171
- "type": "object"
1247
+ "$ref": "#/$defs/PullRequestAction"
1172
1248
  },
1173
1249
  {
1174
- "type": "null"
1250
+ "const": "review_commented",
1251
+ "type": "string"
1175
1252
  }
1176
1253
  ],
1177
- "default": null,
1178
- "title": "Json Schema"
1254
+ "title": "Action"
1179
1255
  },
1180
- "message": {
1256
+ "actor": {
1181
1257
  "anyOf": [
1182
1258
  {
1183
- "type": "string"
1259
+ "$ref": "#/$defs/SessionEventActor"
1184
1260
  },
1185
1261
  {
1186
1262
  "type": "null"
1187
1263
  }
1188
1264
  ],
1189
- "default": null,
1190
- "title": "Message"
1191
- }
1192
- },
1193
- "required": [
1194
- "json_schema",
1195
- "message"
1196
- ],
1197
- "title": "InputContract",
1198
- "type": "object"
1199
- },
1200
- "Instructions": {
1201
- "anyOf": [
1202
- {
1265
+ "default": null
1266
+ },
1267
+ "branch": {
1268
+ "title": "Branch",
1203
1269
  "type": "string"
1204
1270
  },
1205
- {
1206
- "$ref": "#/$defs/SystemFileRef"
1271
+ "number": {
1272
+ "title": "Number",
1273
+ "type": "integer"
1207
1274
  },
1208
- {
1209
- "items": {
1210
- "anyOf": [
1211
- {
1212
- "type": "string"
1213
- },
1214
- {
1215
- "$ref": "#/$defs/SystemFileRef"
1216
- }
1217
- ]
1218
- },
1219
- "type": "array"
1275
+ "repository": {
1276
+ "title": "Repository",
1277
+ "type": "string"
1278
+ },
1279
+ "title": {
1280
+ "title": "Title",
1281
+ "type": "string"
1282
+ },
1283
+ "type": {
1284
+ "const": "github.pull_request",
1285
+ "default": "github.pull_request",
1286
+ "title": "Type",
1287
+ "type": "string"
1288
+ },
1289
+ "url": {
1290
+ "title": "Url",
1291
+ "type": "string"
1220
1292
  }
1221
- ]
1293
+ },
1294
+ "required": [
1295
+ "action",
1296
+ "actor",
1297
+ "branch",
1298
+ "number",
1299
+ "repository",
1300
+ "title",
1301
+ "type",
1302
+ "url"
1303
+ ],
1304
+ "title": "GithubPullRequestEvent",
1305
+ "type": "object"
1306
+ },
1307
+ "GithubPushEvent": {
1308
+ "properties": {
1309
+ "actor": {
1310
+ "anyOf": [
1311
+ {
1312
+ "$ref": "#/$defs/SessionEventActor"
1313
+ },
1314
+ {
1315
+ "type": "null"
1316
+ }
1317
+ ],
1318
+ "default": null
1319
+ },
1320
+ "after": {
1321
+ "title": "After",
1322
+ "type": "string"
1323
+ },
1324
+ "before": {
1325
+ "title": "Before",
1326
+ "type": "string"
1327
+ },
1328
+ "branch": {
1329
+ "title": "Branch",
1330
+ "type": "string"
1331
+ },
1332
+ "repository": {
1333
+ "title": "Repository",
1334
+ "type": "string"
1335
+ },
1336
+ "type": {
1337
+ "const": "github.push",
1338
+ "default": "github.push",
1339
+ "title": "Type",
1340
+ "type": "string"
1341
+ },
1342
+ "url": {
1343
+ "title": "Url",
1344
+ "type": "string"
1345
+ }
1346
+ },
1347
+ "required": [
1348
+ "actor",
1349
+ "after",
1350
+ "before",
1351
+ "branch",
1352
+ "repository",
1353
+ "type",
1354
+ "url"
1355
+ ],
1356
+ "title": "GithubPushEvent",
1357
+ "type": "object"
1358
+ },
1359
+ "GithubSourceDetails": {
1360
+ "description": "Identifies the file a GitHub-sourced agent is synced from.\n\nKeyed on the repository ID (not owner/name) so repository and org renames\ndon't orphan the config; resolve display names from gh_repositories at\nread time.",
1361
+ "properties": {
1362
+ "branch": {
1363
+ "title": "Branch",
1364
+ "type": "string"
1365
+ },
1366
+ "path": {
1367
+ "title": "Path",
1368
+ "type": "string"
1369
+ },
1370
+ "repo_id": {
1371
+ "title": "Repo Id",
1372
+ "type": "integer"
1373
+ }
1374
+ },
1375
+ "required": [
1376
+ "branch",
1377
+ "path",
1378
+ "repo_id"
1379
+ ],
1380
+ "title": "GithubSourceDetails",
1381
+ "type": "object"
1382
+ },
1383
+ "HandlerService": {
1384
+ "description": "The service whose events a handler responds to.",
1385
+ "enum": [
1386
+ "slack",
1387
+ "github",
1388
+ "linear",
1389
+ "sentry"
1390
+ ],
1391
+ "title": "HandlerService",
1392
+ "type": "string"
1393
+ },
1394
+ "InputContract": {
1395
+ "additionalProperties": false,
1396
+ "description": "The typed input contract: what goes INTO a session (the trigger is\nwhen it happens; this is what goes in).\n\n`json_schema` validates customer data sent as `input` to\n`POST /v1/agents/{id}/sessions` and stored as `session.input`.\nInvocations require input when a schema is declared. React agents\ncannot declare schemas: the platform defines their event payloads.\n\n`message` is the initial-message template: exact `{{path}}` substitution\nover the caller payload (or, on a react agent, over the surface's\npublished fields), no conditionals/loops/filters. Refs are validated at\ndeploy time against the governing field set (see AgentConfig's\n`_check_input`).",
1397
+ "properties": {
1398
+ "json_schema": {
1399
+ "anyOf": [
1400
+ {
1401
+ "additionalProperties": true,
1402
+ "type": "object"
1403
+ },
1404
+ {
1405
+ "type": "null"
1406
+ }
1407
+ ],
1408
+ "default": null,
1409
+ "title": "Json Schema"
1410
+ },
1411
+ "message": {
1412
+ "anyOf": [
1413
+ {
1414
+ "type": "string"
1415
+ },
1416
+ {
1417
+ "type": "null"
1418
+ }
1419
+ ],
1420
+ "default": null,
1421
+ "title": "Message"
1422
+ }
1423
+ },
1424
+ "required": [
1425
+ "json_schema",
1426
+ "message"
1427
+ ],
1428
+ "title": "InputContract",
1429
+ "type": "object"
1222
1430
  },
1223
1431
  "IssueAction": {
1224
1432
  "enum": [
@@ -1246,6 +1454,74 @@
1246
1454
  "title": "LinearIssueAction",
1247
1455
  "type": "string"
1248
1456
  },
1457
+ "LinearIssueEvent": {
1458
+ "properties": {
1459
+ "action": {
1460
+ "anyOf": [
1461
+ {
1462
+ "$ref": "#/$defs/LinearIssueAction"
1463
+ },
1464
+ {
1465
+ "const": "commented",
1466
+ "type": "string"
1467
+ }
1468
+ ],
1469
+ "title": "Action"
1470
+ },
1471
+ "actor": {
1472
+ "anyOf": [
1473
+ {
1474
+ "$ref": "#/$defs/SessionEventActor"
1475
+ },
1476
+ {
1477
+ "type": "null"
1478
+ }
1479
+ ],
1480
+ "default": null
1481
+ },
1482
+ "identifier": {
1483
+ "anyOf": [
1484
+ {
1485
+ "type": "string"
1486
+ },
1487
+ {
1488
+ "type": "null"
1489
+ }
1490
+ ],
1491
+ "default": null,
1492
+ "title": "Identifier"
1493
+ },
1494
+ "number": {
1495
+ "title": "Number",
1496
+ "type": "integer"
1497
+ },
1498
+ "title": {
1499
+ "title": "Title",
1500
+ "type": "string"
1501
+ },
1502
+ "type": {
1503
+ "const": "linear.issue",
1504
+ "default": "linear.issue",
1505
+ "title": "Type",
1506
+ "type": "string"
1507
+ },
1508
+ "url": {
1509
+ "title": "Url",
1510
+ "type": "string"
1511
+ }
1512
+ },
1513
+ "required": [
1514
+ "action",
1515
+ "actor",
1516
+ "identifier",
1517
+ "number",
1518
+ "title",
1519
+ "type",
1520
+ "url"
1521
+ ],
1522
+ "title": "LinearIssueEvent",
1523
+ "type": "object"
1524
+ },
1249
1525
  "McpRemoteServer": {
1250
1526
  "additionalProperties": false,
1251
1527
  "description": "A bring-your-own remote MCP server: the harness talks HTTP to `url`.\nNothing runs in the sandbox image. `headers` carry static auth (e.g.\n`Authorization: Bearer ${TOKEN}`); values may embed `${NAME}` secret\nreferences, resolved at run time from the account's secrets store.",
@@ -1292,7 +1568,7 @@
1292
1568
  },
1293
1569
  "McpStdioServer": {
1294
1570
  "additionalProperties": false,
1295
- "description": "A bring-your-own stdio MCP server: the harness spawns `command` inside\nthe sandbox and speaks JSON-RPC over its stdin/stdout. The command must be\nrunnable in the sandbox image \u2014 install its runtime via `image.setup` /\n`image.dockerfile_append` if the base image lacks it.\n\n`env` values may embed `${NAME}` references, resolved at run time from the\naccount's secrets store (see `mcp_secret_refs`); everything else is passed\nliterally.",
1571
+ "description": "A bring-your-own stdio MCP server: the harness spawns `command` inside\nthe sandbox and speaks JSON-RPC over its stdin/stdout. The command must be\nrunnable in the sandbox image \u2014 install its runtime via `hooks.build_base` /\n`hooks.after_checkout` if the managed environment lacks it.\n\n`env` values may embed `${NAME}` references, resolved at run time from the\naccount's secrets store (see `mcp_secret_refs`); everything else is passed\nliterally.",
1296
1572
  "properties": {
1297
1573
  "args": {
1298
1574
  "default": [],
@@ -1382,15 +1658,6 @@
1382
1658
  "title": "OutputConfig",
1383
1659
  "type": "object"
1384
1660
  },
1385
- "ParentKind": {
1386
- "description": "How a session relates to its predecessor (parent_agent_session_id) \u2014\nthe ONE \"preceded-by\" chain for every predecessor relationship. Routing\nreads this when the distinction matters.\n\nCONTINUATION \u2014 a follow-up in the same conversation surface (e.g. a Slack\nthread reply spawning a fresh session on the same thread).\nRESUME \u2014 a conversation re-hosted on a new box after its sandbox was torn\ndown (interactive platform; later phase).",
1387
- "enum": [
1388
- "continuation",
1389
- "resume"
1390
- ],
1391
- "title": "ParentKind",
1392
- "type": "string"
1393
- },
1394
1661
  "PermissionsConfig": {
1395
1662
  "additionalProperties": false,
1396
1663
  "description": "What the agent is allowed to touch, per credential the platform mints\ninto its sandbox. Distinct from `environment:`, which is where the agent\nruns; this is what it may do from there.\n\n`ellipsis` scopes the sandbox's Ellipsis API token\n(`ELLIPSIS_API_TOKEN`, what the in-sandbox `agent` CLI authenticates\nwith). `true` / the string `all` (the default) grant the full sandbox\nceiling \u2014 everything a sandbox token can ever do. A map narrows it per\nresource (see `EllipsisPermissions`); the minted token carries\nthe intersection, so a config can only ever reduce access. `false` fails\nvalidation \u2014 an agent with no API token cannot report its own progress.\n\n`github` scopes the sandbox's GitHub installation token (`GH_TOKEN`) \u2014\nsee `GithubPermissions`. GitHub enforces it at mint time.",
@@ -1759,6 +2026,10 @@
1759
2026
  "type": "array"
1760
2027
  }
1761
2028
  },
2029
+ "required": [
2030
+ "exclude",
2031
+ "include"
2032
+ ],
1762
2033
  "title": "RepositoryFilter",
1763
2034
  "type": "object"
1764
2035
  },
@@ -1832,22 +2103,6 @@
1832
2103
  "title": "Resource",
1833
2104
  "type": "string"
1834
2105
  },
1835
- "RunStatus": {
1836
- "description": "What the current (or most recent) execution is doing (backs `run`).",
1837
- "enum": [
1838
- "scheduled",
1839
- "starting",
1840
- "working",
1841
- "waiting",
1842
- "done",
1843
- "failed",
1844
- "stopped",
1845
- "cancelled",
1846
- "retrying"
1847
- ],
1848
- "title": "RunStatus",
1849
- "type": "string"
1850
- },
1851
2106
  "SandboxCacheTier": {
1852
2107
  "description": "Which image-cache tier a sandbox creation took \u2014 the customer-facing\nnames for `create_sandbox_from_default`'s exact / latest / default tiers.\nRides on `Sandbox.cache_tier` and the sandbox_ready lifecycle record.",
1853
2108
  "enum": [
@@ -1971,237 +2226,10 @@
1971
2226
  "title": "SandboxRepository",
1972
2227
  "type": "object"
1973
2228
  },
1974
- "SandboxResponse": {
2229
+ "SandboxSnapshotFrame": {
1975
2230
  "properties": {
1976
- "cache_tier": {
1977
- "anyOf": [
1978
- {
1979
- "$ref": "#/$defs/SandboxCacheTier"
1980
- },
1981
- {
1982
- "type": "null"
1983
- }
1984
- ]
1985
- },
1986
- "cost_sandbox_cpu": {
1987
- "title": "Cost Sandbox Cpu",
1988
- "type": "integer"
1989
- },
1990
- "cost_sandbox_memory": {
1991
- "title": "Cost Sandbox Memory",
1992
- "type": "integer"
1993
- },
1994
- "cpu": {
1995
- "title": "Cpu",
1996
- "type": "number"
1997
- },
1998
- "dockerfile": {
1999
- "anyOf": [
2000
- {
2001
- "type": "string"
2002
- },
2003
- {
2004
- "type": "null"
2005
- }
2006
- ],
2007
- "title": "Dockerfile"
2008
- },
2009
- "encrypted_ports": {
2010
- "items": {
2011
- "type": "integer"
2012
- },
2013
- "title": "Encrypted Ports",
2014
- "type": "array"
2015
- },
2016
- "environment_variable_keys": {
2017
- "items": {
2018
- "type": "string"
2019
- },
2020
- "title": "Environment Variable Keys",
2021
- "type": "array"
2022
- },
2023
- "failed_at": {
2024
- "anyOf": [
2025
- {
2026
- "format": "date-time",
2027
- "type": "string"
2028
- },
2029
- {
2030
- "type": "null"
2031
- }
2032
- ],
2033
- "title": "Failed At"
2034
- },
2035
- "id": {
2036
- "title": "Id",
2037
- "type": "string"
2038
- },
2039
- "image_setup": {
2040
- "anyOf": [
2041
- {
2042
- "type": "string"
2043
- },
2044
- {
2045
- "type": "null"
2046
- }
2047
- ],
2048
- "title": "Image Setup"
2049
- },
2050
- "memory_mib": {
2051
- "title": "Memory Mib",
2052
- "type": "integer"
2053
- },
2054
- "phase_timings": {
2055
- "additionalProperties": {
2056
- "type": "number"
2057
- },
2058
- "title": "Phase Timings",
2059
- "type": "object"
2060
- },
2061
- "post_clone": {
2062
- "anyOf": [
2063
- {
2064
- "type": "string"
2065
- },
2066
- {
2067
- "type": "null"
2068
- }
2069
- ],
2070
- "title": "Post Clone"
2071
- },
2072
- "post_start": {
2073
- "anyOf": [
2074
- {
2075
- "type": "string"
2076
- },
2077
- {
2078
- "type": "null"
2079
- }
2080
- ],
2081
- "title": "Post Start"
2082
- },
2083
- "repositories": {
2084
- "items": {
2085
- "$ref": "#/$defs/SandboxRepository"
2086
- },
2087
- "title": "Repositories",
2088
- "type": "array"
2089
- },
2090
- "running_at": {
2091
- "anyOf": [
2092
- {
2093
- "format": "date-time",
2094
- "type": "string"
2095
- },
2096
- {
2097
- "type": "null"
2098
- }
2099
- ],
2100
- "title": "Running At"
2101
- },
2102
- "scheduled_at": {
2103
- "format": "date-time",
2104
- "title": "Scheduled At",
2105
- "type": "string"
2106
- },
2107
- "source": {
2108
- "$ref": "#/$defs/SandboxSource"
2109
- },
2110
- "source_session_id": {
2111
- "anyOf": [
2112
- {
2113
- "type": "string"
2114
- },
2115
- {
2116
- "type": "null"
2117
- }
2118
- ],
2119
- "title": "Source Session Id"
2120
- },
2121
- "status": {
2122
- "$ref": "#/$defs/SandboxStatus"
2123
- },
2124
- "terminated_at": {
2125
- "anyOf": [
2126
- {
2127
- "format": "date-time",
2128
- "type": "string"
2129
- },
2130
- {
2131
- "type": "null"
2132
- }
2133
- ],
2134
- "title": "Terminated At"
2135
- },
2136
- "terminating_at": {
2137
- "anyOf": [
2138
- {
2139
- "format": "date-time",
2140
- "type": "string"
2141
- },
2142
- {
2143
- "type": "null"
2144
- }
2145
- ],
2146
- "title": "Terminating At"
2147
- },
2148
- "timeout_seconds": {
2149
- "title": "Timeout Seconds",
2150
- "type": "integer"
2151
- },
2152
- "tunnels": {
2153
- "items": {
2154
- "$ref": "#/$defs/SandboxPort"
2155
- },
2156
- "title": "Tunnels",
2157
- "type": "array"
2158
- },
2159
- "type": {
2160
- "$ref": "#/$defs/SandboxType"
2161
- },
2162
- "unencrypted_ports": {
2163
- "items": {
2164
- "type": "integer"
2165
- },
2166
- "title": "Unencrypted Ports",
2167
- "type": "array"
2168
- }
2169
- },
2170
- "required": [
2171
- "cache_tier",
2172
- "cost_sandbox_cpu",
2173
- "cost_sandbox_memory",
2174
- "cpu",
2175
- "dockerfile",
2176
- "encrypted_ports",
2177
- "environment_variable_keys",
2178
- "failed_at",
2179
- "id",
2180
- "image_setup",
2181
- "memory_mib",
2182
- "phase_timings",
2183
- "post_clone",
2184
- "post_start",
2185
- "repositories",
2186
- "running_at",
2187
- "scheduled_at",
2188
- "source",
2189
- "source_session_id",
2190
- "status",
2191
- "terminated_at",
2192
- "terminating_at",
2193
- "timeout_seconds",
2194
- "tunnels",
2195
- "type",
2196
- "unencrypted_ports"
2197
- ],
2198
- "title": "SandboxResponse",
2199
- "type": "object"
2200
- },
2201
- "SandboxSnapshotFrame": {
2202
- "properties": {
2203
- "sandbox": {
2204
- "$ref": "#/$defs/SandboxResponse"
2231
+ "sandbox": {
2232
+ "$ref": "#/$defs/VMExecutionResponse"
2205
2233
  },
2206
2234
  "type": {
2207
2235
  "const": "snapshot",
@@ -2222,7 +2250,7 @@
2222
2250
  "cli",
2223
2251
  "web_ui",
2224
2252
  "ingest_pull_request_job_run",
2225
- "agent_session",
2253
+ "session",
2226
2254
  "image_refresh",
2227
2255
  "test",
2228
2256
  "script"
@@ -2253,7 +2281,7 @@
2253
2281
  "SandboxUpdateFrame": {
2254
2282
  "properties": {
2255
2283
  "sandbox": {
2256
- "$ref": "#/$defs/SandboxResponse"
2284
+ "$ref": "#/$defs/VMExecutionResponse"
2257
2285
  },
2258
2286
  "type": {
2259
2287
  "const": "sandbox",
@@ -2277,111 +2305,59 @@
2277
2305
  "title": "SentryAction",
2278
2306
  "type": "string"
2279
2307
  },
2280
- "Session": {
2281
- "description": "An agent session: one conversation with an agent, from trigger to\nterminal state. Returned by `GET /v1/sessions/{id}` and carried by the\nsession stream's `session`/`snapshot` frames \u2014 REST and stream never\ndisagree about what a session looks like.",
2308
+ "SentryAlertEvent": {
2282
2309
  "properties": {
2283
- "attribution": {
2284
- "$ref": "#/$defs/SessionAttribution",
2285
- "description": "The principal this session is attributed to."
2286
- },
2287
- "automation": {
2288
- "anyOf": [
2289
- {
2290
- "$ref": "#/$defs/SessionAutomation"
2291
- },
2292
- {
2293
- "type": "null"
2294
- }
2295
- ],
2296
- "default": null,
2297
- "description": "The automation the session was started from, or null for a raw session started with POST /v1/sessions."
2298
- },
2299
- "budget": {
2300
- "$ref": "#/$defs/SessionBudget",
2301
- "description": "The spend budget enforced for this session."
2302
- },
2303
- "config": {
2304
- "$ref": "#/$defs/SessionConfig",
2305
- "description": "What the session ran on, frozen when it was created: the harness block, the resolved environment, permissions, skills, output contract, and budget."
2310
+ "action": {
2311
+ "$ref": "#/$defs/SentryAction"
2306
2312
  },
2307
- "context_repository": {
2313
+ "actor": {
2308
2314
  "anyOf": [
2309
2315
  {
2310
- "type": "string"
2316
+ "$ref": "#/$defs/SessionEventActor"
2311
2317
  },
2312
2318
  {
2313
2319
  "type": "null"
2314
2320
  }
2315
2321
  ],
2316
- "default": null,
2317
- "description": "The \"owner/name\" repository context the session was started in, if any.",
2318
- "title": "Context Repository"
2319
- },
2320
- "cost": {
2321
- "$ref": "#/$defs/SessionCost",
2322
- "description": "What the session cost, in millicents, broken down by leg and carrying its own total."
2322
+ "default": null
2323
2323
  },
2324
- "created_at": {
2325
- "description": "When the session was created.",
2326
- "format": "date-time",
2327
- "title": "Created At",
2324
+ "organization_slug": {
2325
+ "title": "Organization Slug",
2328
2326
  "type": "string"
2329
2327
  },
2330
- "environment": {
2331
- "$ref": "#/$defs/SessionEnvironment",
2332
- "description": "The environment the session resolved: the saved environment's id and how it was chosen. The environment's frozen body is `config.environment`."
2333
- },
2334
- "exit_status": {
2328
+ "project_slug": {
2335
2329
  "anyOf": [
2336
2330
  {
2337
- "$ref": "#/$defs/SessionExitStatus"
2331
+ "type": "string"
2338
2332
  },
2339
2333
  {
2340
2334
  "type": "null"
2341
2335
  }
2342
2336
  ],
2343
2337
  "default": null,
2344
- "description": "How the session ended; null until it is terminal."
2338
+ "title": "Project Slug"
2345
2339
  },
2346
- "git": {
2340
+ "title": {
2347
2341
  "anyOf": [
2348
2342
  {
2349
- "$ref": "#/$defs/SessionGit"
2343
+ "type": "string"
2350
2344
  },
2351
2345
  {
2352
2346
  "type": "null"
2353
2347
  }
2354
2348
  ],
2355
2349
  "default": null,
2356
- "description": "What the session did to git, one entry per repository in its workspace: the commit and branch it sits on, per-file line counts for its uncommitted changes, and the pull requests it opened. Null if nothing was ever captured."
2357
- },
2358
- "harness": {
2359
- "$ref": "#/$defs/Harness",
2360
- "description": "The coding-agent harness the session runs on."
2350
+ "title": "Title"
2361
2351
  },
2362
- "id": {
2363
- "description": "Unique identifier of the session.",
2364
- "title": "Id",
2352
+ "type": {
2353
+ "const": "sentry.alert",
2354
+ "default": "sentry.alert",
2355
+ "title": "Type",
2365
2356
  "type": "string"
2366
2357
  },
2367
- "last_activity_at": {
2368
- "anyOf": [
2369
- {
2370
- "format": "date-time",
2371
- "type": "string"
2372
- },
2373
- {
2374
- "type": "null"
2375
- }
2376
- ],
2377
- "default": null,
2378
- "description": "When the session last showed activity.",
2379
- "title": "Last Activity At"
2380
- },
2381
- "last_message_at": {
2358
+ "url": {
2382
2359
  "anyOf": [
2383
2360
  {
2384
- "format": "date-time",
2385
2361
  "type": "string"
2386
2362
  },
2387
2363
  {
@@ -2389,148 +2365,343 @@
2389
2365
  }
2390
2366
  ],
2391
2367
  "default": null,
2392
- "description": "When the session last received a message.",
2393
- "title": "Last Message At"
2394
- },
2395
- "metadata": {
2396
- "additionalProperties": {
2397
- "type": "string"
2398
- },
2399
- "default": {},
2400
- "description": "Caller-supplied metadata key-value pairs.",
2401
- "title": "Metadata",
2402
- "type": "object"
2368
+ "title": "Url"
2369
+ }
2370
+ },
2371
+ "required": [
2372
+ "action",
2373
+ "actor",
2374
+ "organization_slug",
2375
+ "project_slug",
2376
+ "title",
2377
+ "type",
2378
+ "url"
2379
+ ],
2380
+ "title": "SentryAlertEvent",
2381
+ "type": "object"
2382
+ },
2383
+ "Session": {
2384
+ "additionalProperties": false,
2385
+ "allOf": [
2386
+ {
2387
+ "oneOf": [
2388
+ {
2389
+ "properties": {
2390
+ "claude_code": {
2391
+ "additionalProperties": true,
2392
+ "type": "object"
2393
+ },
2394
+ "codex": {
2395
+ "type": "null"
2396
+ }
2397
+ },
2398
+ "required": [
2399
+ "claude_code",
2400
+ "codex"
2401
+ ]
2402
+ },
2403
+ {
2404
+ "properties": {
2405
+ "claude_code": {
2406
+ "type": "null"
2407
+ },
2408
+ "codex": {
2409
+ "additionalProperties": true,
2410
+ "type": "object"
2411
+ }
2412
+ },
2413
+ "required": [
2414
+ "claude_code",
2415
+ "codex"
2416
+ ]
2417
+ }
2418
+ ]
2419
+ }
2420
+ ],
2421
+ "description": "An agent session: one conversation with an agent, from trigger to\nterminal state. Returned by `GET /v1/sessions/{id}` and carried by the\nsession stream's `session`/`snapshot` frames \u2014 REST and stream never\ndisagree about what a session looks like.",
2422
+ "properties": {
2423
+ "agent": {
2424
+ "anyOf": [
2425
+ {
2426
+ "$ref": "#/$defs/SessionAgent"
2427
+ },
2428
+ {
2429
+ "type": "null"
2430
+ }
2431
+ ],
2432
+ "default": null,
2433
+ "description": "The agent the session was started from, or null for a raw session started with POST /v1/sessions."
2403
2434
  },
2404
- "parent": {
2405
- "$ref": "#/$defs/SessionParent",
2406
- "description": "What preceded this session, if anything."
2435
+ "attribution": {
2436
+ "$ref": "#/$defs/SessionAttribution",
2437
+ "description": "The principal this session is attributed to."
2407
2438
  },
2408
- "prompt": {
2439
+ "budget": {
2440
+ "default": 0,
2441
+ "description": "The spend budget enforced for this session, in US dollars, after resolving defaults and ceilings.",
2442
+ "title": "Budget",
2443
+ "type": "number"
2444
+ },
2445
+ "claude_code": {
2409
2446
  "anyOf": [
2410
2447
  {
2411
- "type": "string"
2448
+ "$ref": "#/$defs/ClaudeConfig"
2412
2449
  },
2413
2450
  {
2414
2451
  "type": "null"
2415
2452
  }
2416
2453
  ],
2417
2454
  "default": null,
2418
- "description": "The per-session prompt the session was started with.",
2419
- "title": "Prompt"
2420
- },
2421
- "prompting": {
2422
- "$ref": "#/$defs/SessionPrompting",
2423
- "description": "Whether a client may send this session a message and, when it may not, the reason to show instead of a composer."
2455
+ "description": "Claude Code input and native options. Set exactly one of claude_code or codex."
2424
2456
  },
2425
- "session_state": {
2457
+ "codex": {
2426
2458
  "anyOf": [
2427
2459
  {
2428
- "$ref": "#/$defs/SessionState"
2460
+ "$ref": "#/$defs/CodexConfig"
2429
2461
  },
2430
2462
  {
2431
2463
  "type": "null"
2432
2464
  }
2433
2465
  ],
2434
2466
  "default": null,
2435
- "description": "Lifecycle state of the durable conversation, or null for sessions without one."
2467
+ "description": "Codex input and native options. Set exactly one of claude_code or codex."
2436
2468
  },
2437
- "source": {
2438
- "$ref": "#/$defs/SessionSource",
2439
- "description": "Where the session came from (e.g. react, web, api, cli, mention, cron)."
2469
+ "cost": {
2470
+ "$ref": "#/$defs/SessionCost",
2471
+ "description": "What the session cost, in millicents, broken down by leg and carrying its own total."
2440
2472
  },
2441
- "status": {
2442
- "$ref": "#/$defs/SessionStatus",
2443
- "description": "Execution status of the session."
2473
+ "environment": {
2474
+ "$ref": "#/$defs/SessionEnvironment",
2475
+ "description": "The full environment configuration frozen when the session was created, with the saved environment's id and how it was chosen."
2444
2476
  },
2445
- "status_reason": {
2477
+ "event": {
2446
2478
  "anyOf": [
2447
2479
  {
2448
- "type": "string"
2480
+ "discriminator": {
2481
+ "mapping": {
2482
+ "github.issue": "#/$defs/GithubIssueEvent",
2483
+ "github.pull_request": "#/$defs/GithubPullRequestEvent",
2484
+ "github.push": "#/$defs/GithubPushEvent",
2485
+ "linear.issue": "#/$defs/LinearIssueEvent",
2486
+ "sentry.alert": "#/$defs/SentryAlertEvent",
2487
+ "slack.channel_created": "#/$defs/SlackChannelCreatedEvent",
2488
+ "slack.message": "#/$defs/SlackMessageEvent"
2489
+ },
2490
+ "propertyName": "type"
2491
+ },
2492
+ "oneOf": [
2493
+ {
2494
+ "$ref": "#/$defs/GithubPullRequestEvent"
2495
+ },
2496
+ {
2497
+ "$ref": "#/$defs/GithubIssueEvent"
2498
+ },
2499
+ {
2500
+ "$ref": "#/$defs/GithubPushEvent"
2501
+ },
2502
+ {
2503
+ "$ref": "#/$defs/LinearIssueEvent"
2504
+ },
2505
+ {
2506
+ "$ref": "#/$defs/SlackMessageEvent"
2507
+ },
2508
+ {
2509
+ "$ref": "#/$defs/SlackChannelCreatedEvent"
2510
+ },
2511
+ {
2512
+ "$ref": "#/$defs/SentryAlertEvent"
2513
+ }
2514
+ ]
2449
2515
  },
2450
2516
  {
2451
2517
  "type": "null"
2452
2518
  }
2453
2519
  ],
2454
2520
  "default": null,
2455
- "description": "Human-readable reason for the current status, when there is one.",
2456
- "title": "Status Reason"
2521
+ "description": "The typed external event that started the session; null for direct and scheduled starts.",
2522
+ "title": "Event"
2457
2523
  },
2458
- "stopped": {
2459
- "$ref": "#/$defs/SessionStopped",
2460
- "description": "The stop request, if the session was stopped."
2524
+ "git": {
2525
+ "anyOf": [
2526
+ {
2527
+ "$ref": "#/$defs/SessionGit"
2528
+ },
2529
+ {
2530
+ "type": "null"
2531
+ }
2532
+ ],
2533
+ "default": null,
2534
+ "description": "What the session did to git, one entry per repository in its workspace: the commit and branch it sits on, per-file line counts for its uncommitted changes, and the pull requests it opened. Null if nothing was ever captured."
2461
2535
  },
2462
- "summary": {
2536
+ "handler": {
2463
2537
  "anyOf": [
2464
2538
  {
2465
- "$ref": "#/$defs/SessionSummary"
2539
+ "$ref": "#/$defs/SessionHandler"
2466
2540
  },
2467
2541
  {
2468
2542
  "type": "null"
2469
2543
  }
2470
2544
  ],
2471
2545
  "default": null,
2472
- "description": "The latest live summary of the session's progress while it runs, and when it was generated."
2546
+ "description": "The saved handler and its effective display name when this session started, frozen at creation. Null for built-in responders, legacy sessions, and sessions started without a handler."
2547
+ },
2548
+ "id": {
2549
+ "description": "Unique identifier of the session.",
2550
+ "title": "Id",
2551
+ "type": "string"
2473
2552
  },
2474
- "surface": {
2475
- "$ref": "#/$defs/SessionSurface",
2476
- "description": "The public status projection: the durable conversation (`session`), the current execution (`run`), and the one derived `status` word."
2553
+ "lifecycle": {
2554
+ "$ref": "#/$defs/SessionLifecycle",
2555
+ "description": "The session's activity, conversation state, messaging policy, outcomes, and timestamps."
2477
2556
  },
2478
- "tokens": {
2479
- "$ref": "#/$defs/SessionTokens",
2480
- "description": "The tokens the session spent and the model they went to. `total` includes the prompt-cache lanes."
2557
+ "metadata": {
2558
+ "additionalProperties": {
2559
+ "type": "string"
2560
+ },
2561
+ "default": {},
2562
+ "description": "Caller-supplied metadata key-value pairs.",
2563
+ "title": "Metadata",
2564
+ "type": "object"
2481
2565
  },
2482
- "trigger": {
2566
+ "output": {
2483
2567
  "anyOf": [
2484
2568
  {
2485
- "$ref": "#/$defs/SessionTrigger"
2569
+ "$ref": "#/$defs/OutputConfig"
2486
2570
  },
2487
2571
  {
2488
2572
  "type": "null"
2489
2573
  }
2490
2574
  ],
2491
2575
  "default": null,
2492
- "description": "The external event that started the session."
2576
+ "description": "The structured-output exit contract for this session."
2493
2577
  },
2494
- "updated_at": {
2495
- "description": "When the session was last updated.",
2496
- "format": "date-time",
2497
- "title": "Updated At",
2498
- "type": "string"
2578
+ "parent": {
2579
+ "anyOf": [
2580
+ {
2581
+ "$ref": "#/$defs/SessionParent"
2582
+ },
2583
+ {
2584
+ "type": "null"
2585
+ }
2586
+ ],
2587
+ "default": null,
2588
+ "description": "The predecessor session this session continues; null when there is none."
2589
+ },
2590
+ "permissions": {
2591
+ "$ref": "#/$defs/PermissionsConfig",
2592
+ "description": "What the session may touch, per minted credential."
2593
+ },
2594
+ "skills": {
2595
+ "description": "Skills installed for this session.",
2596
+ "items": {
2597
+ "$ref": "#/$defs/SkillRef"
2598
+ },
2599
+ "title": "Skills",
2600
+ "type": "array"
2601
+ },
2602
+ "source": {
2603
+ "$ref": "#/$defs/SessionSource",
2604
+ "description": "Where the session came from (e.g. react, web, api, cli, mention, cron)."
2605
+ },
2606
+ "summary": {
2607
+ "anyOf": [
2608
+ {
2609
+ "$ref": "#/$defs/SessionSummary"
2610
+ },
2611
+ {
2612
+ "type": "null"
2613
+ }
2614
+ ],
2615
+ "default": null,
2616
+ "description": "The latest live summary of the session's progress while it runs, and when it was generated."
2617
+ },
2618
+ "tokens": {
2619
+ "$ref": "#/$defs/SessionTokens",
2620
+ "description": "The tokens the session spent and the model they went to. `total` includes the prompt-cache lanes."
2499
2621
  }
2500
2622
  },
2501
2623
  "required": [
2624
+ "agent",
2502
2625
  "attribution",
2503
- "automation",
2504
2626
  "budget",
2505
- "config",
2506
- "context_repository",
2627
+ "claude_code",
2628
+ "codex",
2507
2629
  "cost",
2508
- "created_at",
2509
2630
  "environment",
2510
- "exit_status",
2631
+ "event",
2511
2632
  "git",
2512
- "harness",
2633
+ "handler",
2513
2634
  "id",
2514
- "last_activity_at",
2515
- "last_message_at",
2635
+ "lifecycle",
2516
2636
  "metadata",
2637
+ "output",
2517
2638
  "parent",
2518
- "prompt",
2519
- "prompting",
2520
- "session_state",
2639
+ "permissions",
2640
+ "skills",
2521
2641
  "source",
2522
- "status",
2523
- "status_reason",
2524
- "stopped",
2525
2642
  "summary",
2526
- "surface",
2527
- "tokens",
2528
- "trigger",
2529
- "updated_at"
2643
+ "tokens"
2530
2644
  ],
2531
2645
  "title": "Session",
2532
2646
  "type": "object"
2533
2647
  },
2648
+ "SessionAgent": {
2649
+ "description": "The agent this session was started from: the definition frozen\nwhen the session was created, and the saved agent it came from as it\nexists NOW. They diverge legitimately \u2014 a YAML edit after the session\nstarted leaves the pointer describing something the session never ran.",
2650
+ "properties": {
2651
+ "config": {
2652
+ "$ref": "#/$defs/AgentConfig",
2653
+ "description": "The agent definition the session was started from, frozen when the session was created."
2654
+ },
2655
+ "id": {
2656
+ "anyOf": [
2657
+ {
2658
+ "type": "string"
2659
+ },
2660
+ {
2661
+ "type": "null"
2662
+ }
2663
+ ],
2664
+ "default": null,
2665
+ "description": "Identifier of the saved agent this session's snapshot was taken from. Null for a routing-file agent, a code-review stage agent, or the built-in mention agent, which have no saved agent behind them. Points at the agent as it exists now, which may have changed since.",
2666
+ "title": "Id"
2667
+ }
2668
+ },
2669
+ "required": [
2670
+ "config",
2671
+ "id"
2672
+ ],
2673
+ "title": "SessionAgent",
2674
+ "type": "object"
2675
+ },
2676
+ "SessionArchived": {
2677
+ "description": "When the session was archived and the GitHub user who archived it.",
2678
+ "properties": {
2679
+ "at": {
2680
+ "description": "When the session was archived.",
2681
+ "format": "date-time",
2682
+ "title": "At",
2683
+ "type": "string"
2684
+ },
2685
+ "by": {
2686
+ "anyOf": [
2687
+ {
2688
+ "$ref": "#/$defs/GithubAccountSnippet"
2689
+ },
2690
+ {
2691
+ "type": "null"
2692
+ }
2693
+ ],
2694
+ "default": null,
2695
+ "description": "The GitHub user who archived the session; null if unknown or unavailable."
2696
+ }
2697
+ },
2698
+ "required": [
2699
+ "at",
2700
+ "by"
2701
+ ],
2702
+ "title": "SessionArchived",
2703
+ "type": "object"
2704
+ },
2534
2705
  "SessionAttribution": {
2535
2706
  "description": "The principal a session is attributed to: what kind, its id, and \u2014 when\nthe kind is a GitHub user \u2014 the resolved display snippet.",
2536
2707
  "properties": {
@@ -2580,59 +2751,45 @@
2580
2751
  "title": "SessionAttribution",
2581
2752
  "type": "object"
2582
2753
  },
2583
- "SessionAutomation": {
2584
- "description": "The automation this session was started from: the definition frozen\nwhen the session was created, and the saved automation it came from as it\nexists NOW. They diverge legitimately \u2014 a YAML edit after the session\nstarted leaves the pointer describing something the session never ran.",
2585
- "properties": {
2586
- "config": {
2587
- "$ref": "#/$defs/AutomationConfig",
2588
- "description": "The automation definition the session was started from, frozen when the session was created."
2589
- },
2590
- "id": {
2591
- "anyOf": [
2754
+ "SessionConfig": {
2755
+ "additionalProperties": false,
2756
+ "allOf": [
2757
+ {
2758
+ "oneOf": [
2592
2759
  {
2593
- "type": "string"
2760
+ "properties": {
2761
+ "claude_code": {
2762
+ "additionalProperties": true,
2763
+ "type": "object"
2764
+ },
2765
+ "codex": {
2766
+ "type": "null"
2767
+ }
2768
+ },
2769
+ "required": [
2770
+ "claude_code",
2771
+ "codex"
2772
+ ]
2594
2773
  },
2595
2774
  {
2596
- "type": "null"
2775
+ "properties": {
2776
+ "claude_code": {
2777
+ "type": "null"
2778
+ },
2779
+ "codex": {
2780
+ "additionalProperties": true,
2781
+ "type": "object"
2782
+ }
2783
+ },
2784
+ "required": [
2785
+ "claude_code",
2786
+ "codex"
2787
+ ]
2597
2788
  }
2598
- ],
2599
- "default": null,
2600
- "description": "Identifier of the saved automation this session's snapshot was taken from. Null for a routing-file agent, a code-review stage agent, or the built-in mention agent, which have no saved automation behind them. Points at the automation as it exists now, which may have changed since.",
2601
- "title": "Id"
2789
+ ]
2602
2790
  }
2603
- },
2604
- "required": [
2605
- "config",
2606
- "id"
2607
2791
  ],
2608
- "title": "SessionAutomation",
2609
- "type": "object"
2610
- },
2611
- "SessionBudget": {
2612
- "description": "The spend budget actually enforced for this session, and which layer of\nthe cascade set it.",
2613
- "properties": {
2614
- "cents": {
2615
- "default": 0,
2616
- "description": "The spend budget resolved for this session, in cents.",
2617
- "title": "Cents",
2618
- "type": "integer"
2619
- },
2620
- "source": {
2621
- "$ref": "#/$defs/BudgetSource",
2622
- "default": "account",
2623
- "description": "Where the resolved budget came from."
2624
- }
2625
- },
2626
- "required": [
2627
- "cents",
2628
- "source"
2629
- ],
2630
- "title": "SessionBudget",
2631
- "type": "object"
2632
- },
2633
- "SessionConfig": {
2634
- "additionalProperties": false,
2635
- "description": "What one session runs on: its selected harness, where it runs, what it\nmay touch, its skills, its exit contract, and its spend cap. Every session\nfreezes one of these (`agent_sessions.session_config`); an automation\ncarries one under `session:` (`AutomationConfig.session`); and\n`POST /v1/sessions` is this shape flattened onto the request body, plus the\nrun settings. Nothing in here is an automation's identity or trigger \u2014\nthose belong to `AutomationConfig`.\n\nField order is the canonical key order for `session:` blocks and YAML\nexports: what runs (`harness`, `instructions`), where (`environment`), what it may\ntouch (`permissions`), then the rest.",
2792
+ "description": "What one session runs on: its selected harness, where it runs, what it\nmay touch, its skills, its exit contract, and its spend cap. Every session\nfreezes one of these (`sessions.session_config`); an agent\ncarries one under `session:` (`AgentConfig.session`); and\n`POST /v1/sessions` is this shape flattened onto the request body, plus the\nrun settings. Nothing in here is an agent's identity or trigger \u2014\nthose belong to `AgentConfig`.\n\nField order is the canonical key order for `session:` blocks and YAML\nexports: what runs (`claude_code` or `codex`), where (`environment`), what it may\ntouch (`permissions`), then the rest.",
2636
2793
  "properties": {
2637
2794
  "budget": {
2638
2795
  "$ref": "#/$defs/BudgetConfig",
@@ -2643,6 +2800,30 @@
2643
2800
  "week": null
2644
2801
  }
2645
2802
  },
2803
+ "claude_code": {
2804
+ "anyOf": [
2805
+ {
2806
+ "$ref": "#/$defs/ClaudeConfig"
2807
+ },
2808
+ {
2809
+ "type": "null"
2810
+ }
2811
+ ],
2812
+ "default": null,
2813
+ "description": "Claude Code input and native options. Set exactly one of claude_code or codex."
2814
+ },
2815
+ "codex": {
2816
+ "anyOf": [
2817
+ {
2818
+ "$ref": "#/$defs/CodexConfig"
2819
+ },
2820
+ {
2821
+ "type": "null"
2822
+ }
2823
+ ],
2824
+ "default": null,
2825
+ "description": "Codex input and native options. Set exactly one of claude_code or codex."
2826
+ },
2646
2827
  "environment": {
2647
2828
  "anyOf": [
2648
2829
  {
@@ -2659,28 +2840,18 @@
2659
2840
  "timeout": null
2660
2841
  },
2661
2842
  "hooks": {
2843
+ "after_checkout": null,
2844
+ "before_start": null,
2845
+ "build_base": null,
2662
2846
  "post_clone": null,
2663
2847
  "post_start": null
2664
2848
  },
2665
- "image": {
2666
- "dockerfile_append": null,
2667
- "setup": null
2668
- },
2669
2849
  "mcp_servers": [],
2670
2850
  "repositories": [],
2671
2851
  "variables": []
2672
2852
  },
2673
2853
  "title": "Environment"
2674
2854
  },
2675
- "harness": {
2676
- "$ref": "#/$defs/HarnessOptions",
2677
- "description": "The explicitly selected harness and its native options."
2678
- },
2679
- "instructions": {
2680
- "$ref": "#/$defs/Instructions",
2681
- "default": "",
2682
- "description": "Instructions appended to the harness's own prompt. Text and repository file references are resolved in order."
2683
- },
2684
2855
  "output": {
2685
2856
  "anyOf": [
2686
2857
  {
@@ -2713,9 +2884,9 @@
2713
2884
  },
2714
2885
  "required": [
2715
2886
  "budget",
2887
+ "claude_code",
2888
+ "codex",
2716
2889
  "environment",
2717
- "harness",
2718
- "instructions",
2719
2890
  "output",
2720
2891
  "permissions",
2721
2892
  "skills"
@@ -2726,6 +2897,12 @@
2726
2897
  "SessionCost": {
2727
2898
  "description": "What a session (or one turn of it) cost, in millicents.\n\n`llm` is deliberately NOT called `tokens`: it would sit beside the `tokens`\nobject and read as \"the token count's cost\" rather than \"the cost of the\nLLM leg\".",
2728
2899
  "properties": {
2900
+ "cpu": {
2901
+ "default": 0,
2902
+ "description": "Sandbox CPU spend in millicents.",
2903
+ "title": "Cpu",
2904
+ "type": "integer"
2905
+ },
2729
2906
  "fee": {
2730
2907
  "default": 0,
2731
2908
  "description": "Platform fee in millicents.",
@@ -2738,39 +2915,52 @@
2738
2915
  "title": "Llm",
2739
2916
  "type": "integer"
2740
2917
  },
2741
- "sandbox_cpu": {
2742
- "default": 0,
2743
- "description": "Sandbox CPU spend in millicents.",
2744
- "title": "Sandbox Cpu",
2745
- "type": "integer"
2746
- },
2747
- "sandbox_memory": {
2918
+ "memory": {
2748
2919
  "default": 0,
2749
2920
  "description": "Sandbox memory spend in millicents.",
2750
- "title": "Sandbox Memory",
2921
+ "title": "Memory",
2751
2922
  "type": "integer"
2752
2923
  },
2753
2924
  "total": {
2754
2925
  "default": 0,
2755
- "description": "The grand total in millicents: llm + sandbox_cpu + sandbox_memory + fee.",
2926
+ "description": "The grand total in millicents: llm + cpu + memory + fee.",
2756
2927
  "title": "Total",
2757
2928
  "type": "integer"
2758
2929
  }
2759
2930
  },
2760
2931
  "required": [
2932
+ "cpu",
2761
2933
  "fee",
2762
2934
  "llm",
2763
- "sandbox_cpu",
2764
- "sandbox_memory",
2935
+ "memory",
2765
2936
  "total"
2766
2937
  ],
2767
2938
  "title": "SessionCost",
2768
2939
  "type": "object"
2769
2940
  },
2770
2941
  "SessionEnvironment": {
2771
- "description": "The environment this session resolved: which saved environment (as it\nexists now) and how it was chosen. The environment's frozen BODY rides\ninside `config.environment` \u2014 substitution happens before the config\nsnapshot freezes \u2014 so this object is provenance, not payload.",
2942
+ "additionalProperties": false,
2943
+ "description": "The environment configuration frozen at session creation, enriched with\nthe saved environment's identity and how it was chosen.",
2772
2944
  "properties": {
2773
- "environment_id": {
2945
+ "compute": {
2946
+ "$ref": "#/$defs/ComputeConfig",
2947
+ "default": {
2948
+ "cpu": null,
2949
+ "memory": null,
2950
+ "timeout": null
2951
+ }
2952
+ },
2953
+ "hooks": {
2954
+ "$ref": "#/$defs/EnvironmentHooks",
2955
+ "default": {
2956
+ "after_checkout": null,
2957
+ "before_start": null,
2958
+ "build_base": null,
2959
+ "post_clone": null,
2960
+ "post_start": null
2961
+ }
2962
+ },
2963
+ "id": {
2774
2964
  "anyOf": [
2775
2965
  {
2776
2966
  "type": "string"
@@ -2781,7 +2971,36 @@
2781
2971
  ],
2782
2972
  "default": null,
2783
2973
  "description": "Identifier of the saved environment the session's config resolved. Null for an inline environment block or the built-in basic sandbox.",
2784
- "title": "Environment Id"
2974
+ "title": "Id"
2975
+ },
2976
+ "mcp_servers": {
2977
+ "default": [],
2978
+ "items": {
2979
+ "anyOf": [
2980
+ {
2981
+ "type": "string"
2982
+ },
2983
+ {
2984
+ "$ref": "#/$defs/McpServerRef"
2985
+ },
2986
+ {
2987
+ "$ref": "#/$defs/McpStdioServer"
2988
+ },
2989
+ {
2990
+ "$ref": "#/$defs/McpRemoteServer"
2991
+ }
2992
+ ]
2993
+ },
2994
+ "title": "Mcp Servers",
2995
+ "type": "array"
2996
+ },
2997
+ "repositories": {
2998
+ "default": [],
2999
+ "items": {
3000
+ "$ref": "#/$defs/RepositoryRef"
3001
+ },
3002
+ "title": "Repositories",
3003
+ "type": "array"
2785
3004
  },
2786
3005
  "source": {
2787
3006
  "anyOf": [
@@ -2793,16 +3012,97 @@
2793
3012
  }
2794
3013
  ],
2795
3014
  "default": null,
2796
- "description": "How the environment was chosen (request, automation, platform_default; repo_default and account_default on sessions from before those ladders were removed). Null when the config carried its own inline environment."
3015
+ "description": "How the environment was chosen (request, agent, platform_default; repo_default and account_default on sessions from before those ladders were removed). An inline request uses request; an inline environment declared in session configuration has no source."
3016
+ },
3017
+ "variables": {
3018
+ "default": [],
3019
+ "items": {
3020
+ "$ref": "#/$defs/EnvironmentVariable"
3021
+ },
3022
+ "title": "Variables",
3023
+ "type": "array"
2797
3024
  }
2798
3025
  },
2799
3026
  "required": [
2800
- "environment_id",
2801
- "source"
3027
+ "compute",
3028
+ "hooks",
3029
+ "id",
3030
+ "mcp_servers",
3031
+ "repositories",
3032
+ "source",
3033
+ "variables"
2802
3034
  ],
2803
3035
  "title": "SessionEnvironment",
2804
3036
  "type": "object"
2805
3037
  },
3038
+ "SessionEventActor": {
3039
+ "description": "The event's initiator, when known; never inferred from resource ownership.",
3040
+ "properties": {
3041
+ "avatar_url": {
3042
+ "anyOf": [
3043
+ {
3044
+ "type": "string"
3045
+ },
3046
+ {
3047
+ "type": "null"
3048
+ }
3049
+ ],
3050
+ "default": null,
3051
+ "title": "Avatar Url"
3052
+ },
3053
+ "is_bot": {
3054
+ "anyOf": [
3055
+ {
3056
+ "type": "boolean"
3057
+ },
3058
+ {
3059
+ "type": "null"
3060
+ }
3061
+ ],
3062
+ "default": null,
3063
+ "title": "Is Bot"
3064
+ },
3065
+ "name": {
3066
+ "title": "Name",
3067
+ "type": "string"
3068
+ }
3069
+ },
3070
+ "required": [
3071
+ "avatar_url",
3072
+ "is_bot",
3073
+ "name"
3074
+ ],
3075
+ "title": "SessionEventActor",
3076
+ "type": "object"
3077
+ },
3078
+ "SessionExecutionResult": {
3079
+ "description": "Outcome of the last finished execution, retained across subsequent resumes.\n\nAn execution spans a start or resume through parking or termination, and may\ncontain several turns. Admission failures also produce a result, even when\nprovisioning never starts.",
3080
+ "properties": {
3081
+ "completion_reason": {
3082
+ "$ref": "#/$defs/SessionExitStatus",
3083
+ "description": "Why the last execution ended; completed also includes parking an open conversation."
3084
+ },
3085
+ "detail": {
3086
+ "anyOf": [
3087
+ {
3088
+ "type": "string"
3089
+ },
3090
+ {
3091
+ "type": "null"
3092
+ }
3093
+ ],
3094
+ "default": null,
3095
+ "description": "Human-readable explanation of that outcome.",
3096
+ "title": "Detail"
3097
+ }
3098
+ },
3099
+ "required": [
3100
+ "completion_reason",
3101
+ "detail"
3102
+ ],
3103
+ "title": "SessionExecutionResult",
3104
+ "type": "object"
3105
+ },
2806
3106
  "SessionExitStatus": {
2807
3107
  "description": "Why a terminal agent session ended \u2014 a finer-grained reason than `status`.\n\n`status` (SessionStatus) is the lifecycle state: COMPLETED / ERROR /\nCANCELLED. `exit_status` explains *why* a run reached that terminal state, so\nthe UI and metrics can tell a budget cutoff apart from a crashed tool call or\na deliberate cancellation. It is None until the run reaches a terminal state.",
2808
3108
  "enum": [
@@ -2825,7 +3125,7 @@
2825
3125
  "type": "string"
2826
3126
  },
2827
3127
  "SessionGit": {
2828
- "description": "Every repo the session touched. Small enough to ride on `agent_sessions`\nand be returned by every session read.",
3128
+ "description": "Every repo the session touched. Small enough to ride on `sessions`\nand be returned by every session read.",
2829
3129
  "properties": {
2830
3130
  "repos": {
2831
3131
  "default": [],
@@ -3032,64 +3332,61 @@
3032
3332
  "title": "SessionGitRepo",
3033
3333
  "type": "object"
3034
3334
  },
3035
- "SessionListStreamMessage": {
3335
+ "SessionHandler": {
3336
+ "description": "The saved handler and its display name when the session started.",
3036
3337
  "properties": {
3037
- "session": {
3038
- "$ref": "#/$defs/Session"
3338
+ "agent_name": {
3339
+ "description": "The handler's effective display name when the session started: ellipsis.name, or the service default (Slack, GitHub, Linear, or sentry).",
3340
+ "minLength": 1,
3341
+ "title": "Agent Name",
3342
+ "type": "string"
3039
3343
  },
3040
- "type": {
3041
- "const": "session",
3042
- "default": "session",
3043
- "title": "Type",
3344
+ "id": {
3345
+ "description": "Identifier of the saved handler.",
3346
+ "minLength": 1,
3347
+ "title": "Id",
3348
+ "type": "string"
3349
+ },
3350
+ "service": {
3351
+ "$ref": "#/$defs/HandlerService",
3352
+ "description": "The service the handler responds to."
3353
+ },
3354
+ "sha": {
3355
+ "description": "Content fingerprint of the validated handler configuration used when the session started. This is not the Git commit SHA.",
3356
+ "minLength": 1,
3357
+ "title": "Sha",
3044
3358
  "type": "string"
3045
3359
  }
3046
3360
  },
3047
3361
  "required": [
3048
- "session",
3049
- "type"
3362
+ "agent_name",
3363
+ "id",
3364
+ "service",
3365
+ "sha"
3050
3366
  ],
3051
- "title": "SessionListStreamMessage",
3367
+ "title": "SessionHandler",
3052
3368
  "type": "object"
3053
3369
  },
3054
- "SessionLiveness": {
3055
- "description": "The durable conversation axis (backs the surfaced `session` field).",
3056
- "enum": [
3057
- "alive",
3058
- "idle",
3059
- "closed"
3060
- ],
3061
- "title": "SessionLiveness",
3062
- "type": "string"
3063
- },
3064
- "SessionParent": {
3065
- "description": "The ONE \"preceded-by\" chain: the predecessor session and how this one\nrelates to it. Not a parent that orchestrates children \u2014 a session never\nspawns sub-sessions.",
3370
+ "SessionLifecycle": {
3371
+ "description": "Current activity, conversation state, messaging policy, and lifecycle history.",
3066
3372
  "properties": {
3067
- "kind": {
3373
+ "archived": {
3068
3374
  "anyOf": [
3069
3375
  {
3070
- "$ref": "#/$defs/ParentKind"
3376
+ "$ref": "#/$defs/SessionArchived"
3071
3377
  },
3072
3378
  {
3073
3379
  "type": "null"
3074
3380
  }
3075
3381
  ],
3076
3382
  "default": null,
3077
- "description": "How this session relates to its parent session, if any."
3383
+ "description": "When and by whom the session was archived; null when unarchived. Archiving does not stop or close a session."
3078
3384
  },
3079
- "replayed_from_session_id": {
3080
- "anyOf": [
3081
- {
3082
- "type": "string"
3083
- },
3084
- {
3085
- "type": "null"
3086
- }
3087
- ],
3088
- "default": null,
3089
- "description": "Identifier of the original session this one was replayed from, if it was started via replay.",
3090
- "title": "Replayed From Session Id"
3385
+ "conversation": {
3386
+ "$ref": "#/$defs/ConversationState",
3387
+ "description": "Whether the conversation is open or permanently closed. Open does not imply direct messages are permitted."
3091
3388
  },
3092
- "session_id": {
3389
+ "detail": {
3093
3390
  "anyOf": [
3094
3391
  {
3095
3392
  "type": "string"
@@ -3099,114 +3396,139 @@
3099
3396
  }
3100
3397
  ],
3101
3398
  "default": null,
3102
- "description": "Identifier of the parent session that spawned this one, if any.",
3103
- "title": "Session Id"
3104
- }
3105
- },
3106
- "required": [
3107
- "kind",
3108
- "replayed_from_session_id",
3109
- "session_id"
3110
- ],
3111
- "title": "SessionParent",
3112
- "type": "object"
3113
- },
3114
- "SessionPrompting": {
3115
- "description": "The prompt-affordance projection. `enabled` answers \"would a send work\",\nand when it wouldn't, `blocked_reason` + `detail` say why.\n\n`surface_name` is set only for MENTION_SURFACE, naming where to reply.",
3116
- "properties": {
3117
- "blocked_reason": {
3118
- "anyOf": [
3119
- {
3120
- "$ref": "#/$defs/PromptBlockedReason"
3121
- },
3122
- {
3123
- "type": "null"
3124
- }
3125
- ],
3126
- "default": null
3399
+ "description": "Explanation of the current status, when applicable.",
3400
+ "title": "Detail"
3127
3401
  },
3128
- "detail": {
3402
+ "interactive": {
3403
+ "description": "Whether the session stays open after its first turn.",
3404
+ "title": "Interactive",
3405
+ "type": "boolean"
3406
+ },
3407
+ "last_execution_result": {
3129
3408
  "anyOf": [
3130
3409
  {
3131
- "type": "string"
3410
+ "$ref": "#/$defs/SessionExecutionResult"
3132
3411
  },
3133
3412
  {
3134
3413
  "type": "null"
3135
3414
  }
3136
3415
  ],
3137
3416
  "default": null,
3138
- "title": "Detail"
3417
+ "description": "The last finished execution's outcome, retained across resumes; null until an outcome has been recorded."
3139
3418
  },
3140
- "enabled": {
3141
- "title": "Enabled",
3142
- "type": "boolean"
3419
+ "prompting": {
3420
+ "$ref": "#/$defs/SessionPrompting",
3421
+ "description": "The session's policy for direct messages. Caller authorization and message validation are checked separately."
3143
3422
  },
3144
- "surface_name": {
3423
+ "status": {
3424
+ "$ref": "#/$defs/SessionLifecycleStatus",
3425
+ "description": "Canonical current activity. working means a turn is in progress; waiting means the worker is warm and awaiting input; idle means parked. A failed, stopped, or cancelled execution may leave an open conversation."
3426
+ },
3427
+ "stopped": {
3145
3428
  "anyOf": [
3146
3429
  {
3147
- "type": "string"
3430
+ "$ref": "#/$defs/SessionStopped"
3148
3431
  },
3149
3432
  {
3150
3433
  "type": "null"
3151
3434
  }
3152
3435
  ],
3153
3436
  "default": null,
3154
- "title": "Surface Name"
3437
+ "description": "When and by whom a stop was requested; null when no stop is pending for this execution."
3438
+ },
3439
+ "timestamps": {
3440
+ "$ref": "#/$defs/SessionTimestamps"
3155
3441
  }
3156
3442
  },
3157
3443
  "required": [
3158
- "blocked_reason",
3444
+ "archived",
3445
+ "conversation",
3159
3446
  "detail",
3160
- "enabled",
3161
- "surface_name"
3447
+ "interactive",
3448
+ "last_execution_result",
3449
+ "prompting",
3450
+ "status",
3451
+ "stopped",
3452
+ "timestamps"
3162
3453
  ],
3163
- "title": "SessionPrompting",
3454
+ "title": "SessionLifecycle",
3164
3455
  "type": "object"
3165
3456
  },
3166
- "SessionSource": {
3167
- "description": "Where a session came from: the credential that started it (web app,\nAPI key, CLI) or the trigger that fired (react, mention, cron). Never\ntaken from a request body.",
3457
+ "SessionLifecycleStatus": {
3168
3458
  "enum": [
3169
- "react",
3170
- "web",
3171
- "api",
3172
- "cli",
3173
- "mention",
3174
- "cron"
3459
+ "scheduled",
3460
+ "starting",
3461
+ "working",
3462
+ "waiting",
3463
+ "retrying",
3464
+ "idle",
3465
+ "closed",
3466
+ "failed",
3467
+ "stopped",
3468
+ "cancelled"
3175
3469
  ],
3176
- "title": "SessionSource",
3470
+ "title": "SessionLifecycleStatus",
3177
3471
  "type": "string"
3178
3472
  },
3179
- "SessionState": {
3180
- "description": "Lifecycle of a keyed (multi-turn) session \u2014 the durable conversation.\nDistinct from SessionStatus, which is per-execution (one turn's run) and\nmoves to agent_turns in a later slice. IDLE: alive, waiting for the next\nmessage. RUNNING: a turn is executing. CLOSED: the conversation is done and\nits sandbox/snapshots are torn down.",
3181
- "enum": [
3182
- "idle",
3183
- "running",
3184
- "closed"
3473
+ "SessionListStreamMessage": {
3474
+ "properties": {
3475
+ "session": {
3476
+ "$ref": "#/$defs/Session"
3477
+ },
3478
+ "type": {
3479
+ "const": "session",
3480
+ "default": "session",
3481
+ "title": "Type",
3482
+ "type": "string"
3483
+ }
3484
+ },
3485
+ "required": [
3486
+ "session",
3487
+ "type"
3185
3488
  ],
3186
- "title": "SessionState",
3187
- "type": "string"
3489
+ "title": "SessionListStreamMessage",
3490
+ "type": "object"
3188
3491
  },
3189
- "SessionStatus": {
3190
- "enum": [
3191
- "scheduled",
3192
- "creating_sandbox",
3193
- "running",
3194
- "retrying",
3195
- "completed",
3196
- "error",
3197
- "cancelled",
3198
- "stopped"
3492
+ "SessionParent": {
3493
+ "description": "The predecessor session this session continues.",
3494
+ "properties": {
3495
+ "session_id": {
3496
+ "anyOf": [
3497
+ {
3498
+ "type": "string"
3499
+ },
3500
+ {
3501
+ "type": "null"
3502
+ }
3503
+ ],
3504
+ "default": null,
3505
+ "description": "Identifier of the predecessor session this session continues, if any.",
3506
+ "title": "Session Id"
3507
+ }
3508
+ },
3509
+ "required": [
3510
+ "session_id"
3199
3511
  ],
3200
- "title": "SessionStatus",
3201
- "type": "string"
3512
+ "title": "SessionParent",
3513
+ "type": "object"
3202
3514
  },
3203
- "SessionStopped": {
3204
- "description": "The stop request, if there was one: when, by which GitHub account id,\nand that account resolved to a display snippet.",
3515
+ "SessionPrompting": {
3516
+ "description": "The prompt-affordance projection. `enabled` answers \"would a send work\",\nand when it wouldn't, `blocked_reason` + `detail` say why.\n\n`surface_name` is set only for MENTION_SURFACE, naming where to reply.",
3205
3517
  "properties": {
3206
- "at": {
3518
+ "blocked_reason": {
3519
+ "anyOf": [
3520
+ {
3521
+ "$ref": "#/$defs/PromptBlockedReason"
3522
+ },
3523
+ {
3524
+ "type": "null"
3525
+ }
3526
+ ],
3527
+ "default": null
3528
+ },
3529
+ "detail": {
3207
3530
  "anyOf": [
3208
3531
  {
3209
- "format": "date-time",
3210
3532
  "type": "string"
3211
3533
  },
3212
3534
  {
@@ -3214,23 +3536,57 @@
3214
3536
  }
3215
3537
  ],
3216
3538
  "default": null,
3217
- "description": "When a stop was requested, if one was.",
3218
- "title": "At"
3539
+ "title": "Detail"
3219
3540
  },
3220
- "by": {
3541
+ "enabled": {
3542
+ "title": "Enabled",
3543
+ "type": "boolean"
3544
+ },
3545
+ "surface_name": {
3221
3546
  "anyOf": [
3222
3547
  {
3223
- "type": "integer"
3548
+ "type": "string"
3224
3549
  },
3225
3550
  {
3226
3551
  "type": "null"
3227
3552
  }
3228
3553
  ],
3229
3554
  "default": null,
3230
- "description": "GitHub account id of the user who stopped the session, if known.",
3231
- "title": "By"
3555
+ "title": "Surface Name"
3556
+ }
3557
+ },
3558
+ "required": [
3559
+ "blocked_reason",
3560
+ "detail",
3561
+ "enabled",
3562
+ "surface_name"
3563
+ ],
3564
+ "title": "SessionPrompting",
3565
+ "type": "object"
3566
+ },
3567
+ "SessionSource": {
3568
+ "description": "Where a session came from: the credential that started it (web app,\nAPI key, CLI) or the trigger that fired (react, mention, cron). Never\ntaken from a request body.",
3569
+ "enum": [
3570
+ "react",
3571
+ "web",
3572
+ "api",
3573
+ "cli",
3574
+ "mention",
3575
+ "cron"
3576
+ ],
3577
+ "title": "SessionSource",
3578
+ "type": "string"
3579
+ },
3580
+ "SessionStopped": {
3581
+ "description": "When a stop was requested and the GitHub user who requested it.",
3582
+ "properties": {
3583
+ "at": {
3584
+ "description": "When a stop was requested.",
3585
+ "format": "date-time",
3586
+ "title": "At",
3587
+ "type": "string"
3232
3588
  },
3233
- "by_user": {
3589
+ "by": {
3234
3590
  "anyOf": [
3235
3591
  {
3236
3592
  "$ref": "#/$defs/GithubAccountSnippet"
@@ -3240,13 +3596,12 @@
3240
3596
  }
3241
3597
  ],
3242
3598
  "default": null,
3243
- "description": "The GitHub user who stopped the session, resolved at read time."
3599
+ "description": "The GitHub user who stopped the session, resolved at read time. Null if the user is unknown or unavailable."
3244
3600
  }
3245
3601
  },
3246
3602
  "required": [
3247
3603
  "at",
3248
- "by",
3249
- "by_user"
3604
+ "by"
3250
3605
  ],
3251
3606
  "title": "SessionStopped",
3252
3607
  "type": "object"
@@ -3281,47 +3636,56 @@
3281
3636
  "title": "SessionSummary",
3282
3637
  "type": "object"
3283
3638
  },
3284
- "SessionSurface": {
3285
- "description": "The three fields we expose.\n\n`use_enum_values=True` (from CustomBaseModel) stores the members as their\nstring values, so this serializes to `{\"session\": \"alive\", \"run\": \"waiting\",\n\"status\": \"waiting\"}` \u2014 a plain object, not enum names.",
3639
+ "SessionTimestamps": {
3286
3640
  "properties": {
3287
- "run": {
3288
- "anyOf": [
3289
- {
3290
- "$ref": "#/$defs/RunStatus"
3291
- },
3292
- {
3293
- "type": "null"
3294
- }
3295
- ]
3641
+ "created_at": {
3642
+ "description": "When the session was created.",
3643
+ "format": "date-time",
3644
+ "title": "Created At",
3645
+ "type": "string"
3296
3646
  },
3297
- "session": {
3647
+ "last_activity_at": {
3298
3648
  "anyOf": [
3299
3649
  {
3300
- "$ref": "#/$defs/SessionLiveness"
3650
+ "format": "date-time",
3651
+ "type": "string"
3301
3652
  },
3302
3653
  {
3303
3654
  "type": "null"
3304
3655
  }
3305
- ]
3656
+ ],
3657
+ "default": null,
3658
+ "description": "When the session last showed agent activity.",
3659
+ "title": "Last Activity At"
3306
3660
  },
3307
- "status": {
3661
+ "last_message_at": {
3308
3662
  "anyOf": [
3309
3663
  {
3664
+ "format": "date-time",
3310
3665
  "type": "string"
3311
3666
  },
3312
3667
  {
3313
3668
  "type": "null"
3314
3669
  }
3315
3670
  ],
3316
- "title": "Status"
3671
+ "default": null,
3672
+ "description": "When the session last received a message.",
3673
+ "title": "Last Message At"
3674
+ },
3675
+ "updated_at": {
3676
+ "description": "When the session was last updated.",
3677
+ "format": "date-time",
3678
+ "title": "Updated At",
3679
+ "type": "string"
3317
3680
  }
3318
3681
  },
3319
3682
  "required": [
3320
- "run",
3321
- "session",
3322
- "status"
3683
+ "created_at",
3684
+ "last_activity_at",
3685
+ "last_message_at",
3686
+ "updated_at"
3323
3687
  ],
3324
- "title": "SessionSurface",
3688
+ "title": "SessionTimestamps",
3325
3689
  "type": "object"
3326
3690
  },
3327
3691
  "SessionTokens": {
@@ -3375,57 +3739,78 @@
3375
3739
  "title": "SessionTokens",
3376
3740
  "type": "object"
3377
3741
  },
3378
- "SessionTrigger": {
3379
- "description": "The external event that started a session, without raw webhook payloads.",
3742
+ "SettingsRef": {
3743
+ "additionalProperties": false,
3744
+ "description": "A config-declared Claude Code settings.json, resolved at run start and\npassed to `claude --settings <path>`. That is the CLI settings tier \u2014 BELOW\nEllipsis's managed-settings.json floor \u2014 so it customizes behavior (model\npermissions, includeCoAuthoredBy, statusLine, ...) but can never weaken a\nsecurity setting. Lets a team point the cloud agent at the same settings file\nthey already use with Claude Code locally instead of re-encoding it as YAML.",
3380
3745
  "properties": {
3381
- "action": {
3382
- "anyOf": [
3383
- {
3384
- "type": "string"
3385
- },
3386
- {
3387
- "type": "null"
3388
- }
3389
- ],
3390
- "default": null,
3391
- "title": "Action"
3746
+ "path": {
3747
+ "title": "Path",
3748
+ "type": "string"
3392
3749
  },
3393
- "actor": {
3750
+ "repository": {
3394
3751
  "anyOf": [
3395
3752
  {
3396
- "$ref": "#/$defs/SessionTriggerActor"
3753
+ "$ref": "#/$defs/RepositoryRef"
3397
3754
  },
3398
3755
  {
3399
3756
  "type": "null"
3400
3757
  }
3401
3758
  ],
3402
3759
  "default": null
3760
+ }
3761
+ },
3762
+ "required": [
3763
+ "path",
3764
+ "repository"
3765
+ ],
3766
+ "title": "SettingsRef",
3767
+ "type": "object"
3768
+ },
3769
+ "SkillRef": {
3770
+ "additionalProperties": false,
3771
+ "description": "A repository directory containing SKILL.md and supporting UTF-8 files.\nResolved at run start and installed in the selected harness's skill directory.\nExplicit skill references require a model with the skills capability.",
3772
+ "properties": {
3773
+ "path": {
3774
+ "title": "Path",
3775
+ "type": "string"
3403
3776
  },
3404
- "branch": {
3777
+ "repository": {
3405
3778
  "anyOf": [
3406
3779
  {
3407
- "type": "string"
3780
+ "$ref": "#/$defs/RepositoryRef"
3408
3781
  },
3409
3782
  {
3410
3783
  "type": "null"
3411
3784
  }
3412
3785
  ],
3413
- "default": null,
3414
- "title": "Branch"
3415
- },
3416
- "number": {
3786
+ "default": null
3787
+ }
3788
+ },
3789
+ "required": [
3790
+ "path",
3791
+ "repository"
3792
+ ],
3793
+ "title": "SkillRef",
3794
+ "type": "object"
3795
+ },
3796
+ "SlackChannelCreatedEvent": {
3797
+ "properties": {
3798
+ "actor": {
3417
3799
  "anyOf": [
3418
3800
  {
3419
- "type": "integer"
3801
+ "$ref": "#/$defs/SessionEventActor"
3420
3802
  },
3421
3803
  {
3422
3804
  "type": "null"
3423
3805
  }
3424
3806
  ],
3425
- "default": null,
3426
- "title": "Number"
3807
+ "default": null
3427
3808
  },
3428
- "repository": {
3809
+ "channel_id": {
3810
+ "title": "Channel Id",
3811
+ "type": "string"
3812
+ },
3813
+ "channel_name": {
3429
3814
  "anyOf": [
3430
3815
  {
3431
3816
  "type": "string"
@@ -3435,21 +3820,55 @@
3435
3820
  }
3436
3821
  ],
3437
3822
  "default": null,
3438
- "title": "Repository"
3823
+ "title": "Channel Name"
3824
+ },
3825
+ "type": {
3826
+ "const": "slack.channel_created",
3827
+ "default": "slack.channel_created",
3828
+ "title": "Type",
3829
+ "type": "string"
3830
+ },
3831
+ "url": {
3832
+ "title": "Url",
3833
+ "type": "string"
3834
+ }
3835
+ },
3836
+ "required": [
3837
+ "actor",
3838
+ "channel_id",
3839
+ "channel_name",
3840
+ "type",
3841
+ "url"
3842
+ ],
3843
+ "title": "SlackChannelCreatedEvent",
3844
+ "type": "object"
3845
+ },
3846
+ "SlackMessageEvent": {
3847
+ "properties": {
3848
+ "action": {
3849
+ "enum": [
3850
+ "message",
3851
+ "app_mention"
3852
+ ],
3853
+ "title": "Action",
3854
+ "type": "string"
3439
3855
  },
3440
- "surface": {
3856
+ "actor": {
3441
3857
  "anyOf": [
3442
3858
  {
3443
- "type": "string"
3859
+ "$ref": "#/$defs/SessionEventActor"
3444
3860
  },
3445
3861
  {
3446
3862
  "type": "null"
3447
3863
  }
3448
3864
  ],
3449
- "default": null,
3450
- "title": "Surface"
3865
+ "default": null
3451
3866
  },
3452
- "title": {
3867
+ "channel_id": {
3868
+ "title": "Channel Id",
3869
+ "type": "string"
3870
+ },
3871
+ "channel_name": {
3453
3872
  "anyOf": [
3454
3873
  {
3455
3874
  "type": "string"
@@ -3459,9 +3878,13 @@
3459
3878
  }
3460
3879
  ],
3461
3880
  "default": null,
3462
- "title": "Title"
3881
+ "title": "Channel Name"
3463
3882
  },
3464
- "url": {
3883
+ "message_ts": {
3884
+ "title": "Message Ts",
3885
+ "type": "string"
3886
+ },
3887
+ "thread_ts": {
3465
3888
  "anyOf": [
3466
3889
  {
3467
3890
  "type": "string"
@@ -3471,143 +3894,255 @@
3471
3894
  }
3472
3895
  ],
3473
3896
  "default": null,
3474
- "title": "Url"
3897
+ "title": "Thread Ts"
3898
+ },
3899
+ "type": {
3900
+ "const": "slack.message",
3901
+ "default": "slack.message",
3902
+ "title": "Type",
3903
+ "type": "string"
3904
+ },
3905
+ "url": {
3906
+ "title": "Url",
3907
+ "type": "string"
3475
3908
  }
3476
3909
  },
3477
3910
  "required": [
3478
3911
  "action",
3479
3912
  "actor",
3480
- "branch",
3481
- "number",
3482
- "repository",
3483
- "surface",
3484
- "title",
3913
+ "channel_id",
3914
+ "channel_name",
3915
+ "message_ts",
3916
+ "thread_ts",
3917
+ "type",
3485
3918
  "url"
3486
3919
  ],
3487
- "title": "SessionTrigger",
3920
+ "title": "SlackMessageEvent",
3488
3921
  "type": "object"
3489
3922
  },
3490
- "SessionTriggerActor": {
3923
+ "VMExecutionResponse": {
3491
3924
  "properties": {
3492
- "avatar_url": {
3925
+ "cache_tier": {
3926
+ "anyOf": [
3927
+ {
3928
+ "$ref": "#/$defs/SandboxCacheTier"
3929
+ },
3930
+ {
3931
+ "type": "null"
3932
+ }
3933
+ ]
3934
+ },
3935
+ "cost_sandbox_cpu": {
3936
+ "title": "Cost Sandbox Cpu",
3937
+ "type": "integer"
3938
+ },
3939
+ "cost_sandbox_memory": {
3940
+ "title": "Cost Sandbox Memory",
3941
+ "type": "integer"
3942
+ },
3943
+ "cpu": {
3944
+ "title": "Cpu",
3945
+ "type": "number"
3946
+ },
3947
+ "encrypted_ports": {
3948
+ "items": {
3949
+ "type": "integer"
3950
+ },
3951
+ "title": "Encrypted Ports",
3952
+ "type": "array"
3953
+ },
3954
+ "environment_variable_keys": {
3955
+ "items": {
3956
+ "type": "string"
3957
+ },
3958
+ "title": "Environment Variable Keys",
3959
+ "type": "array"
3960
+ },
3961
+ "failed_at": {
3493
3962
  "anyOf": [
3494
3963
  {
3964
+ "format": "date-time",
3495
3965
  "type": "string"
3496
3966
  },
3497
3967
  {
3498
3968
  "type": "null"
3499
3969
  }
3500
3970
  ],
3501
- "default": null,
3502
- "title": "Avatar Url"
3971
+ "title": "Failed At"
3503
3972
  },
3504
- "is_bot": {
3505
- "default": false,
3506
- "title": "Is Bot",
3507
- "type": "boolean"
3973
+ "hooks": {
3974
+ "$ref": "#/$defs/EnvironmentHooks",
3975
+ "default": {
3976
+ "after_checkout": null,
3977
+ "before_start": null,
3978
+ "build_base": null,
3979
+ "post_clone": null,
3980
+ "post_start": null
3981
+ }
3508
3982
  },
3509
- "name": {
3510
- "title": "Name",
3511
- "type": "string"
3512
- }
3513
- },
3514
- "required": [
3515
- "avatar_url",
3516
- "is_bot",
3517
- "name"
3518
- ],
3519
- "title": "SessionTriggerActor",
3520
- "type": "object"
3521
- },
3522
- "SettingsRef": {
3523
- "additionalProperties": false,
3524
- "description": "A config-declared Claude Code settings.json, resolved at run start and\npassed to `claude --settings <path>`. That is the CLI settings tier \u2014 BELOW\nEllipsis's managed-settings.json floor \u2014 so it customizes behavior (model\npermissions, includeCoAuthoredBy, statusLine, ...) but can never weaken a\nsecurity setting. Lets a team point the cloud agent at the same settings file\nthey already use with Claude Code locally instead of re-encoding it as YAML.",
3525
- "properties": {
3526
- "path": {
3527
- "title": "Path",
3983
+ "id": {
3984
+ "title": "Id",
3528
3985
  "type": "string"
3529
3986
  },
3530
- "repository": {
3987
+ "memory_mib": {
3988
+ "title": "Memory Mib",
3989
+ "type": "integer"
3990
+ },
3991
+ "phase_timings": {
3992
+ "additionalProperties": {
3993
+ "type": "number"
3994
+ },
3995
+ "title": "Phase Timings",
3996
+ "type": "object"
3997
+ },
3998
+ "post_clone": {
3531
3999
  "anyOf": [
3532
4000
  {
3533
- "$ref": "#/$defs/RepositoryRef"
4001
+ "type": "string"
3534
4002
  },
3535
4003
  {
3536
4004
  "type": "null"
3537
4005
  }
3538
4006
  ],
3539
- "default": null
3540
- }
3541
- },
3542
- "required": [
3543
- "path",
3544
- "repository"
3545
- ],
3546
- "title": "SettingsRef",
3547
- "type": "object"
3548
- },
3549
- "SkillRef": {
3550
- "additionalProperties": false,
3551
- "description": "A repository directory containing SKILL.md and supporting UTF-8 files.\nResolved at run start and installed in the selected harness's skill directory.\nExplicit skill references require a model with the skills capability.",
3552
- "properties": {
3553
- "path": {
3554
- "title": "Path",
3555
- "type": "string"
4007
+ "title": "Post Clone"
3556
4008
  },
3557
- "repository": {
4009
+ "post_start": {
3558
4010
  "anyOf": [
3559
4011
  {
3560
- "$ref": "#/$defs/RepositoryRef"
4012
+ "type": "string"
3561
4013
  },
3562
4014
  {
3563
4015
  "type": "null"
3564
4016
  }
3565
4017
  ],
3566
- "default": null
3567
- }
3568
- },
3569
- "required": [
3570
- "path",
3571
- "repository"
3572
- ],
3573
- "title": "SkillRef",
3574
- "type": "object"
3575
- },
3576
- "SystemFileRef": {
3577
- "additionalProperties": false,
3578
- "properties": {
3579
- "file": {
3580
- "title": "File",
4018
+ "title": "Post Start"
4019
+ },
4020
+ "repositories": {
4021
+ "items": {
4022
+ "$ref": "#/$defs/SandboxRepository"
4023
+ },
4024
+ "title": "Repositories",
4025
+ "type": "array"
4026
+ },
4027
+ "running_at": {
4028
+ "anyOf": [
4029
+ {
4030
+ "format": "date-time",
4031
+ "type": "string"
4032
+ },
4033
+ {
4034
+ "type": "null"
4035
+ }
4036
+ ],
4037
+ "title": "Running At"
4038
+ },
4039
+ "scheduled_at": {
4040
+ "format": "date-time",
4041
+ "title": "Scheduled At",
3581
4042
  "type": "string"
3582
4043
  },
3583
- "repository": {
4044
+ "source": {
4045
+ "$ref": "#/$defs/SandboxSource"
4046
+ },
4047
+ "source_session_id": {
3584
4048
  "anyOf": [
3585
4049
  {
3586
- "$ref": "#/$defs/RepositoryRef"
4050
+ "type": "string"
3587
4051
  },
3588
4052
  {
3589
4053
  "type": "null"
3590
4054
  }
3591
4055
  ],
3592
- "default": null
4056
+ "title": "Source Session Id"
4057
+ },
4058
+ "status": {
4059
+ "$ref": "#/$defs/SandboxStatus"
4060
+ },
4061
+ "terminated_at": {
4062
+ "anyOf": [
4063
+ {
4064
+ "format": "date-time",
4065
+ "type": "string"
4066
+ },
4067
+ {
4068
+ "type": "null"
4069
+ }
4070
+ ],
4071
+ "title": "Terminated At"
4072
+ },
4073
+ "terminating_at": {
4074
+ "anyOf": [
4075
+ {
4076
+ "format": "date-time",
4077
+ "type": "string"
4078
+ },
4079
+ {
4080
+ "type": "null"
4081
+ }
4082
+ ],
4083
+ "title": "Terminating At"
4084
+ },
4085
+ "timeout_seconds": {
4086
+ "title": "Timeout Seconds",
4087
+ "type": "integer"
4088
+ },
4089
+ "tunnels": {
4090
+ "items": {
4091
+ "$ref": "#/$defs/SandboxPort"
4092
+ },
4093
+ "title": "Tunnels",
4094
+ "type": "array"
4095
+ },
4096
+ "type": {
4097
+ "$ref": "#/$defs/SandboxType"
4098
+ },
4099
+ "unencrypted_ports": {
4100
+ "items": {
4101
+ "type": "integer"
4102
+ },
4103
+ "title": "Unencrypted Ports",
4104
+ "type": "array"
3593
4105
  }
3594
4106
  },
3595
4107
  "required": [
3596
- "file",
3597
- "repository"
4108
+ "cache_tier",
4109
+ "cost_sandbox_cpu",
4110
+ "cost_sandbox_memory",
4111
+ "cpu",
4112
+ "encrypted_ports",
4113
+ "environment_variable_keys",
4114
+ "failed_at",
4115
+ "hooks",
4116
+ "id",
4117
+ "memory_mib",
4118
+ "phase_timings",
4119
+ "post_clone",
4120
+ "post_start",
4121
+ "repositories",
4122
+ "running_at",
4123
+ "scheduled_at",
4124
+ "source",
4125
+ "source_session_id",
4126
+ "status",
4127
+ "terminated_at",
4128
+ "terminating_at",
4129
+ "timeout_seconds",
4130
+ "tunnels",
4131
+ "type",
4132
+ "unencrypted_ports"
3598
4133
  ],
3599
- "title": "SystemFileRef",
4134
+ "title": "VMExecutionResponse",
3600
4135
  "type": "object"
3601
4136
  }
3602
4137
  },
3603
4138
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3604
- "description": "Frames on /v1/sessions/stream, /v1/automations/stream and /v1/sandboxes/{id}/stream. Ignore unknown frame types.",
4139
+ "description": "Frames on /v1/sessions/stream, /v1/agents/stream and /v1/vm-executions/{id}/stream. Ignore unknown frame types.",
3605
4140
  "oneOf": [
3606
4141
  {
3607
4142
  "$ref": "#/$defs/SessionListStreamMessage"
3608
4143
  },
3609
4144
  {
3610
- "$ref": "#/$defs/AutomationListStreamMessage"
4145
+ "$ref": "#/$defs/AgentListStreamMessage"
3611
4146
  },
3612
4147
  {
3613
4148
  "$ref": "#/$defs/CollectionStreamHeartbeat"