@opengeni/contracts 1.0.1 → 2.2.0-canary.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.
- package/dist/agent-authored-durable-text.d.ts +64 -0
- package/dist/atlassian.d.ts +1 -0
- package/dist/atlassian.js +14 -13
- package/dist/{chunk-Y3MLSLB4.js → chunk-3SIZGL3O.js} +42 -30
- package/dist/chunk-3SIZGL3O.js.map +1 -0
- package/dist/{chunk-JBCIY7QD.js → chunk-7RMTKFJW.js} +45 -22
- package/dist/chunk-7RMTKFJW.js.map +1 -0
- package/dist/{chunk-NX5JNF4L.js → chunk-7ZZ3R27P.js} +9322 -5798
- package/dist/chunk-7ZZ3R27P.js.map +1 -0
- package/dist/{chunk-5UDNP7AO.js → chunk-MRWYRAS5.js} +56 -8
- package/dist/chunk-MRWYRAS5.js.map +1 -0
- package/dist/{chunk-LW7OH6CS.js → chunk-N6GRVXAJ.js} +6 -5
- package/dist/chunk-N6GRVXAJ.js.map +1 -0
- package/dist/{chunk-TZ6YEYN4.js → chunk-NVJMJWLL.js} +3 -1
- package/dist/chunk-NVJMJWLL.js.map +1 -0
- package/dist/chunk-PX3VCKAU.js +29 -0
- package/dist/chunk-PX3VCKAU.js.map +1 -0
- package/dist/{chunk-LSB7GRLG.js → chunk-TXTQIYCV.js} +15 -11
- package/dist/chunk-TXTQIYCV.js.map +1 -0
- package/dist/{chunk-CADSX6UN.js → chunk-Y3KNXVTD.js} +2 -2
- package/dist/chunk-YBW5JSA3.js +251 -0
- package/dist/chunk-YBW5JSA3.js.map +1 -0
- package/dist/company-brain-governed-writes.d.ts +475 -0
- package/dist/company-brain.d.ts +398 -0
- package/dist/company-profile.d.ts +268 -0
- package/dist/connection-authority.d.ts +501 -0
- package/dist/connection-authority.js +364 -0
- package/dist/connection-authority.js.map +1 -0
- package/dist/connector-attachments.d.ts +95 -0
- package/dist/connector-attachments.js +51 -0
- package/dist/connector-attachments.js.map +1 -0
- package/dist/editable-artifact-codec-registry.d.ts +16 -7
- package/dist/editable-artifact-codec-registry.js +18 -8
- package/dist/editable-artifact-committed-transaction.d.ts +2 -2
- package/dist/editable-artifact-committed-transaction.js +2 -2
- package/dist/editable-artifact-live.d.ts +11 -12
- package/dist/editable-artifact-live.js +111 -46
- package/dist/editable-artifact-live.js.map +1 -1
- package/dist/editable-artifact-serialized-commit.d.ts +2 -1
- package/dist/editable-artifact-serialized-commit.js +9 -8
- package/dist/editable-artifact-versions.d.ts +20 -5
- package/dist/editable-artifact-versions.js +23 -5
- package/dist/editable-artifacts.d.ts +2 -0
- package/dist/editable-artifacts.js +51 -39
- package/dist/google-drive.d.ts +1 -0
- package/dist/google-drive.js +14 -13
- package/dist/google-drive.js.map +1 -1
- package/dist/governed-learning-activation.d.ts +154 -0
- package/dist/governed-learning-evaluator.d.ts +152 -0
- package/dist/index.d.ts +12224 -1328
- package/dist/index.js +831 -115
- package/dist/interaction.d.ts +68 -0
- package/dist/knowledge.d.ts +119 -0
- package/dist/organization-membership-lifecycle.d.ts +516 -0
- package/dist/permissions.d.ts +52 -0
- package/dist/personal-github.d.ts +319 -0
- package/dist/personal-github.js +209 -0
- package/dist/personal-github.js.map +1 -0
- package/dist/preference-registry.d.ts +17 -0
- package/dist/remember.d.ts +331 -0
- package/dist/sandbox-file-artifacts.d.ts +56 -0
- package/dist/sandbox-snapshots.d.ts +21 -0
- package/dist/slack-bot-scopes.d.ts +34 -14
- package/dist/slack-bot-scopes.js +5 -1
- package/dist/spreadsheet-artifact-commands.d.ts +2 -3
- package/dist/spreadsheet-artifact-commands.js +4 -2
- package/dist/spreadsheet-artifact-query.js +3 -2
- package/dist/task-notes.d.ts +42 -1
- package/dist/tool-result-spill.d.ts +16 -0
- package/dist/workspace-instruction-policies.d.ts +81 -0
- package/dist/workspace-learning-administration.d.ts +289 -0
- package/package.json +13 -1
- package/src/agent-authored-durable-text.ts +105 -0
- package/src/company-brain-governed-writes.ts +356 -0
- package/src/company-brain.ts +201 -0
- package/src/company-profile.ts +122 -1
- package/src/connection-authority.ts +413 -0
- package/src/connector-attachments.ts +327 -0
- package/src/editable-artifact-codec-registry.ts +55 -17
- package/src/editable-artifact-committed-transaction.ts +44 -31
- package/src/editable-artifact-live.ts +123 -57
- package/src/editable-artifact-serialized-commit.ts +2 -1
- package/src/editable-artifact-versions.ts +26 -5
- package/src/editable-artifacts.ts +2 -0
- package/src/governed-learning-activation.ts +191 -0
- package/src/governed-learning-evaluator.ts +176 -0
- package/src/index.ts +3033 -392
- package/src/interaction.ts +55 -1
- package/src/knowledge.ts +118 -6
- package/src/organization-membership-lifecycle.ts +330 -0
- package/src/permissions.ts +55 -0
- package/src/personal-github.ts +267 -0
- package/src/preference-registry.ts +17 -0
- package/src/remember.ts +242 -0
- package/src/sandbox-file-artifacts.ts +65 -0
- package/src/sandbox-snapshots.ts +78 -0
- package/src/slack-bot-scopes.ts +81 -9
- package/src/spreadsheet-artifact-commands.ts +12 -13
- package/src/task-notes.ts +14 -1
- package/src/tool-result-spill.ts +35 -0
- package/src/workspace-instruction-policies.ts +30 -0
- package/src/workspace-learning-administration.ts +88 -0
- package/dist/chunk-5UDNP7AO.js.map +0 -1
- package/dist/chunk-BVGIYW7D.js +0 -11
- package/dist/chunk-BVGIYW7D.js.map +0 -1
- package/dist/chunk-JBCIY7QD.js.map +0 -1
- package/dist/chunk-LSB7GRLG.js.map +0 -1
- package/dist/chunk-LW7OH6CS.js.map +0 -1
- package/dist/chunk-NX5JNF4L.js.map +0 -1
- package/dist/chunk-TZ6YEYN4.js.map +0 -1
- package/dist/chunk-Y3MLSLB4.js.map +0 -1
- /package/dist/{chunk-CADSX6UN.js.map → chunk-Y3KNXVTD.js.map} +0 -0
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { Permission } from "./permissions";
|
|
2
3
|
import { ScopedKnowledgeScope } from "./scoped-knowledge";
|
|
3
4
|
import {
|
|
4
5
|
boundSessionEventPayload,
|
|
@@ -11,11 +12,13 @@ import { WorkspaceInstructionPolicyRoleKeyInput } from "./workspace-instruction-
|
|
|
11
12
|
import { ClientResumableVoiceInputConfig } from "./transcription-recordings";
|
|
12
13
|
import { MediaGenerationResult } from "./video-generation";
|
|
13
14
|
import { KnowledgeProviderCitation } from "./knowledge";
|
|
15
|
+
import { XaiProviderAccountAuthoritySnapshotV1 } from "./xai-provider-account-authority";
|
|
14
16
|
|
|
15
17
|
export * from "./slack-bot-scopes";
|
|
16
18
|
export * from "./slack-task-policy";
|
|
17
19
|
export * from "./atlassian";
|
|
18
20
|
export * from "./connector-destinations";
|
|
21
|
+
export * from "./connector-attachments";
|
|
19
22
|
export * from "./memory-slack-delivery";
|
|
20
23
|
export * from "./image-generation";
|
|
21
24
|
export * from "./video-generation";
|
|
@@ -23,7 +26,10 @@ export * from "./editable-artifacts";
|
|
|
23
26
|
export * from "./editable-artifact-committed-transaction";
|
|
24
27
|
export * from "./editable-artifact-serialized-commit";
|
|
25
28
|
export * from "./tool-catalog";
|
|
29
|
+
export * from "./tool-result-spill";
|
|
26
30
|
export * from "./interaction";
|
|
31
|
+
export * from "./sandbox-file-artifacts";
|
|
32
|
+
export * from "./permissions";
|
|
27
33
|
|
|
28
34
|
export {
|
|
29
35
|
CreateWorkspaceArtifactRequest,
|
|
@@ -119,15 +125,21 @@ export {
|
|
|
119
125
|
export {
|
|
120
126
|
NATIVE_SNAPSHOT_PREFIXES,
|
|
121
127
|
WORKSPACE_ARCHIVE_DESCRIPTOR_VERSION,
|
|
128
|
+
WORKSPACE_ARCHIVE_OBJECT_REF_SCHEMA,
|
|
122
129
|
backendForNativeSnapshotProvider,
|
|
123
130
|
decodeNativeSnapshotRef,
|
|
124
131
|
encodeNativeSnapshotRef,
|
|
132
|
+
omitInlineWorkspaceArchiveWhenObjectRefPresent,
|
|
125
133
|
parseWorkspaceArchiveDescriptor,
|
|
134
|
+
parseWorkspaceArchiveObjectRef,
|
|
135
|
+
workspaceArchiveObjectKey,
|
|
136
|
+
workspaceArchivePayloadPresent,
|
|
126
137
|
type NativeSnapshotDescriptor,
|
|
127
138
|
type NativeSnapshotProvider,
|
|
128
139
|
type NativeSnapshotRef,
|
|
129
140
|
type TarWorkspaceArchiveDescriptor,
|
|
130
141
|
type WorkspaceArchiveDescriptor,
|
|
142
|
+
type WorkspaceArchiveObjectRef,
|
|
131
143
|
type WorkspaceTreeFingerprint,
|
|
132
144
|
} from "./sandbox-snapshots";
|
|
133
145
|
|
|
@@ -148,11 +160,12 @@ export const SessionStatus = z.enum([
|
|
|
148
160
|
]);
|
|
149
161
|
export type SessionStatus = z.infer<typeof SessionStatus>;
|
|
150
162
|
|
|
151
|
-
//
|
|
163
|
+
// 12 backends; 3-way enum parity (contracts / sdk / deployment) is pinned by
|
|
152
164
|
// `packages/sdk/test/contract-parity.test.ts`. Every member is ADDITIVE AT THE
|
|
153
165
|
// END (the parity test pins positions): the original four, then the six cloud
|
|
154
166
|
// backends, then `selfhosted` (bring-your-own-compute — a user's own machine
|
|
155
|
-
// enrolled as a first-class sandbox)
|
|
167
|
+
// enrolled as a first-class sandbox), then `opensandbox` (an optional
|
|
168
|
+
// Kubernetes-native provisioned sandbox provider).
|
|
156
169
|
export const SandboxBackend = z.enum([
|
|
157
170
|
"docker",
|
|
158
171
|
"modal",
|
|
@@ -165,6 +178,7 @@ export const SandboxBackend = z.enum([
|
|
|
165
178
|
"cloudflare",
|
|
166
179
|
"vercel",
|
|
167
180
|
"selfhosted",
|
|
181
|
+
"opensandbox",
|
|
168
182
|
]);
|
|
169
183
|
export type SandboxBackend = z.infer<typeof SandboxBackend>;
|
|
170
184
|
|
|
@@ -190,6 +204,7 @@ export const SANDBOX_PROVIDER_INSTANCE_ID_FIELDS_BY_BACKEND = {
|
|
|
190
204
|
cloudflare: ["sandboxId"],
|
|
191
205
|
vercel: ["sandboxId"],
|
|
192
206
|
selfhosted: ["agentId"],
|
|
207
|
+
opensandbox: ["sandboxId"],
|
|
193
208
|
} as const satisfies Record<SandboxBackend, readonly string[]>;
|
|
194
209
|
export const LEGACY_SANDBOX_PROVIDER_INSTANCE_ID_FIELDS = [
|
|
195
210
|
"sandboxId",
|
|
@@ -594,6 +609,36 @@ export const CAPABILITY_DESCRIPTORS: Record<SandboxBackend, CapabilityDescriptor
|
|
|
594
609
|
persistable: false,
|
|
595
610
|
supportsRunAs: false,
|
|
596
611
|
},
|
|
612
|
+
// Optional Kubernetes-native provisioned sandbox through OpenSandbox.
|
|
613
|
+
// Desktop-class when the box image includes ttyd/browserd/Xvfb: PTY over ttyd,
|
|
614
|
+
// noVNC and browserd over signed URI-mode ingress. OpenGeni owns persistence
|
|
615
|
+
// through its portable tar checkpoint path in object storage; native
|
|
616
|
+
// OpenSandbox pause/resume and snapshots are deliberately not used.
|
|
617
|
+
opensandbox: {
|
|
618
|
+
backend: "opensandbox",
|
|
619
|
+
backendId: "opensandbox",
|
|
620
|
+
tier: "desktop",
|
|
621
|
+
os: { supported: ["linux"], default: "linux" },
|
|
622
|
+
capabilities: {
|
|
623
|
+
FileSystem: { available: true, readOnly: false },
|
|
624
|
+
Terminal: { available: true, transport: "sse-events", pty: true },
|
|
625
|
+
Git: { available: true },
|
|
626
|
+
DesktopStream: { available: true, transport: "vnc-ws" },
|
|
627
|
+
Recording: { available: true },
|
|
628
|
+
},
|
|
629
|
+
lifetime: {
|
|
630
|
+
requiresSnapshotRollover: false,
|
|
631
|
+
hasIdleKiller: false,
|
|
632
|
+
supportsSuspendResume: false,
|
|
633
|
+
resumeIsLockFree: true,
|
|
634
|
+
},
|
|
635
|
+
snapshot: { kind: "tar-only", hasTarFallback: true },
|
|
636
|
+
portExposure: { kind: "provider-tunnel", supportsOnDemandPorts: true },
|
|
637
|
+
workspaceRoot: "/workspace",
|
|
638
|
+
nativeBucketMount: false,
|
|
639
|
+
persistable: true,
|
|
640
|
+
supportsRunAs: false,
|
|
641
|
+
},
|
|
597
642
|
};
|
|
598
643
|
|
|
599
644
|
export const ReasoningEffort = z.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
@@ -673,91 +718,6 @@ export const SessionSpawnDenial = z.object({
|
|
|
673
718
|
});
|
|
674
719
|
export type SessionSpawnDenial = z.infer<typeof SessionSpawnDenial>;
|
|
675
720
|
|
|
676
|
-
export const Permission = z.enum([
|
|
677
|
-
"account:read",
|
|
678
|
-
"account:admin",
|
|
679
|
-
"members:manage",
|
|
680
|
-
"workspace:create",
|
|
681
|
-
"billing:read",
|
|
682
|
-
"billing:manage",
|
|
683
|
-
"workspace:read",
|
|
684
|
-
"workspace:admin",
|
|
685
|
-
"sessions:create",
|
|
686
|
-
"sessions:read",
|
|
687
|
-
"sessions:control",
|
|
688
|
-
// sandbox workspace (sandbox contract §C.3 / crosscut PART 1.2). stream:view is a
|
|
689
|
-
// REAL, distinct permission — strictly BROADER than sessions:read — because the
|
|
690
|
-
// pixel plane (Channel B) exposes raw pixels: a viewer can see content the
|
|
691
|
-
// structured Channel-A event log never captured. sessions:read is NOT
|
|
692
|
-
// permission to watch raw pixels.
|
|
693
|
-
"stream:view",
|
|
694
|
-
// SEPARATE from stream:view: raw input to the desktop (bypasses approvalQueue /
|
|
695
|
-
// interrupt). NEVER granted by default in v1 (the input plane is OFF —
|
|
696
|
-
// streamControlEnabled=false); the permission exists so later hardening is a
|
|
697
|
-
// flag flip, not a redesign.
|
|
698
|
-
"stream:control",
|
|
699
|
-
// Accept the pixel-plane secret-leak acknowledgment (consent gate before the
|
|
700
|
-
// un-redacted desktop URL is handed out).
|
|
701
|
-
"stream:acknowledge",
|
|
702
|
-
"files:upload",
|
|
703
|
-
"files:read",
|
|
704
|
-
// Channel-A structured write surface (FS writes / apply-patch); distinct from
|
|
705
|
-
// files:read so a read-only viewer can't mutate the box filesystem.
|
|
706
|
-
"files:write",
|
|
707
|
-
// Attach to an interactive PTY (terminal-as-pty, Channel A); distinct from
|
|
708
|
-
// sessions:read which only reads the command-output firehose.
|
|
709
|
-
"terminal:attach",
|
|
710
|
-
"documents:manage",
|
|
711
|
-
"documents:search",
|
|
712
|
-
"scheduled_tasks:manage",
|
|
713
|
-
"scheduled_tasks:run",
|
|
714
|
-
"github:manage",
|
|
715
|
-
"github:use",
|
|
716
|
-
"api_keys:manage",
|
|
717
|
-
"connections:read",
|
|
718
|
-
"connections:write",
|
|
719
|
-
/** @deprecated alias of variable-sets:manage */
|
|
720
|
-
"environments:manage",
|
|
721
|
-
/** @deprecated alias of variable-sets:use */
|
|
722
|
-
"environments:use",
|
|
723
|
-
"variable-sets:list",
|
|
724
|
-
"variable-sets:read",
|
|
725
|
-
"variable-sets:write",
|
|
726
|
-
"variable-sets:manage",
|
|
727
|
-
"variable-sets:use",
|
|
728
|
-
"secrets:list",
|
|
729
|
-
"secrets:read",
|
|
730
|
-
"secrets:write",
|
|
731
|
-
// Attach or rotate per-session third-party MCP server credentials. Deliberately
|
|
732
|
-
// not part of the worker's default first-party MCP permission set: a sandboxed
|
|
733
|
-
// agent must not be able to hand itself new bearer credentials.
|
|
734
|
-
"mcp_servers:attach",
|
|
735
|
-
// Programmatic sandbox -> tool access through the first-party MCP gate. This is
|
|
736
|
-
// intentionally narrow and is never part of first-party MCP defaults; callers
|
|
737
|
-
// must receive it through an explicit delegated `ogd_` mint carrying sessionId.
|
|
738
|
-
"codemode:call",
|
|
739
|
-
"goals:manage",
|
|
740
|
-
// Bring-your-own-compute (M5). enrollments:read lists a workspace's machines;
|
|
741
|
-
// enrollments:manage approves a device-flow enrollment (the LOUD whole-machine
|
|
742
|
-
// consent) + revokes a machine. Distinct from sessions/stream perms because an
|
|
743
|
-
// enrollment grants WHOLE-MACHINE access to a user's own hardware — a high-trust,
|
|
744
|
-
// admin-shaped action. workspace:admin is the super-wildcard over both.
|
|
745
|
-
"enrollments:read",
|
|
746
|
-
"enrollments:manage",
|
|
747
|
-
// Rigs (workspace-scoped, versioned sandbox machine definitions). rigs:use is
|
|
748
|
-
// read + propose-change (the agent-native, additive path a sandboxed session
|
|
749
|
-
// is trusted with); rigs:manage is create/edit/activate/promote/delete (the
|
|
750
|
-
// admin-shaped path that mints or rolls versions). workspace:admin is the
|
|
751
|
-
// super-wildcard over both.
|
|
752
|
-
"rigs:use",
|
|
753
|
-
"rigs:manage",
|
|
754
|
-
// Workspace-published HTML artifacts. Read permits listing/source retrieval;
|
|
755
|
-
// publish permits create, version publication, and rollback.
|
|
756
|
-
"artifacts:read",
|
|
757
|
-
"artifacts:publish",
|
|
758
|
-
]);
|
|
759
|
-
export type Permission = z.infer<typeof Permission>;
|
|
760
|
-
|
|
761
721
|
/**
|
|
762
722
|
* Capability-first permissions signed into a session's first-party OpenGeni
|
|
763
723
|
* MCP token when a top-level creator does not explicitly narrow them.
|
|
@@ -781,8 +741,12 @@ export const DEFAULT_FIRST_PARTY_MCP_PERMISSIONS = [
|
|
|
781
741
|
// tools resolve an already-installed workspace principal. Credentials stay
|
|
782
742
|
// inside the broker and remain subject to each tool's own authorization.
|
|
783
743
|
"connections:read",
|
|
744
|
+
"variable-sets:list",
|
|
745
|
+
"variable-sets:write",
|
|
746
|
+
"variable-sets:attach",
|
|
784
747
|
"variable-sets:use",
|
|
785
|
-
"
|
|
748
|
+
"secrets:list",
|
|
749
|
+
"secrets:write",
|
|
786
750
|
"rigs:use",
|
|
787
751
|
"github:use",
|
|
788
752
|
"artifacts:read",
|
|
@@ -802,6 +766,7 @@ export const FIRST_PARTY_MCP_TOOL_NAMES = [
|
|
|
802
766
|
"goal_set",
|
|
803
767
|
"goal_update",
|
|
804
768
|
"goal_progress",
|
|
769
|
+
"goal_wait",
|
|
805
770
|
"goal_complete",
|
|
806
771
|
"goal_pause",
|
|
807
772
|
"memory_search",
|
|
@@ -812,6 +777,18 @@ export const FIRST_PARTY_MCP_TOOL_NAMES = [
|
|
|
812
777
|
"task_notes_list",
|
|
813
778
|
"task_note_save",
|
|
814
779
|
"task_note_archive",
|
|
780
|
+
"task_note_replace",
|
|
781
|
+
"knowledge_propose",
|
|
782
|
+
"knowledge_correct",
|
|
783
|
+
"task_note_promote_knowledge",
|
|
784
|
+
"task_note_promote_instruction_policy",
|
|
785
|
+
"task_note_promote_preference",
|
|
786
|
+
"instruction_policy_propose",
|
|
787
|
+
"preference_propose",
|
|
788
|
+
"remember",
|
|
789
|
+
"remember_confirm",
|
|
790
|
+
"company_profile_propose",
|
|
791
|
+
"company_profile_confirm",
|
|
815
792
|
"sandboxes_list",
|
|
816
793
|
"sandbox_attach",
|
|
817
794
|
"sandbox_swap",
|
|
@@ -826,11 +803,13 @@ export const FIRST_PARTY_MCP_TOOL_NAMES = [
|
|
|
826
803
|
"sessions_list",
|
|
827
804
|
"session_get",
|
|
828
805
|
"session_events",
|
|
806
|
+
"session_wait",
|
|
829
807
|
"session_create",
|
|
830
808
|
"session_send_message",
|
|
831
809
|
"session_pause",
|
|
832
810
|
"session_resume",
|
|
833
811
|
"session_steer",
|
|
812
|
+
"session_human_input_respond",
|
|
834
813
|
"set_other_session_title",
|
|
835
814
|
"interaction_discover",
|
|
836
815
|
"browser_open",
|
|
@@ -889,6 +868,7 @@ export const FIRST_PARTY_MCP_TOOL_NAMES = [
|
|
|
889
868
|
"scheduled_tasks_delete",
|
|
890
869
|
"scheduled_task_runs_list",
|
|
891
870
|
"slack_bot_list_channels",
|
|
871
|
+
"slack_bot_search",
|
|
892
872
|
"slack_bot_channel_history",
|
|
893
873
|
"slack_bot_thread_replies",
|
|
894
874
|
"slack_bot_list_users",
|
|
@@ -915,6 +895,7 @@ export const FIRST_PARTY_MCP_TOOL_NAMES = [
|
|
|
915
895
|
"artifacts_create",
|
|
916
896
|
"artifacts_publish",
|
|
917
897
|
"artifacts_rollback",
|
|
898
|
+
"sandbox_file_publish",
|
|
918
899
|
"editable_artifact_list",
|
|
919
900
|
"editable_artifact_create",
|
|
920
901
|
"editable_artifact_import",
|
|
@@ -965,8 +946,15 @@ const FIRST_PARTY_IN_PROCESS_TOOL_NAME_SET = new Set<FirstPartyMcpToolName>(
|
|
|
965
946
|
* trustworthy logical-delivery identity. Server-owned Slack delivery paths
|
|
966
947
|
* call the internal client directly with their own durable operation IDs.
|
|
967
948
|
*/
|
|
949
|
+
// Names kept so previously written data still parses - immutable scheduled-task
|
|
950
|
+
// execution snapshots recorded the tool set that was default at the time, and
|
|
951
|
+
// they are strictly re-parsed on replay. Retiring a tool must not strand an
|
|
952
|
+
// accepted occurrence. These are never registered, never default, and never
|
|
953
|
+
// authorized; they exist so history stays readable.
|
|
968
954
|
const FIRST_PARTY_COMPATIBILITY_ONLY_TOOL_NAMES = [
|
|
969
955
|
"slack_bot_post_message",
|
|
956
|
+
"memory_save",
|
|
957
|
+
"memory_correct",
|
|
970
958
|
] as const satisfies readonly FirstPartyMcpToolName[];
|
|
971
959
|
|
|
972
960
|
const FIRST_PARTY_COMPATIBILITY_ONLY_TOOL_NAME_SET = new Set<FirstPartyMcpToolName>(
|
|
@@ -999,6 +987,10 @@ export const EDITABLE_ARTIFACT_MCP_CODEMODE_PATHS = {
|
|
|
999
987
|
*/
|
|
1000
988
|
export const DEFAULT_FIRST_PARTY_MCP_TOOLS = FIRST_PARTY_MCP_TOOL_NAMES.filter(
|
|
1001
989
|
(name) =>
|
|
990
|
+
// Memory V1 writes are retired entirely; `remember` and task-note
|
|
991
|
+
// promotion own durable agent writes.
|
|
992
|
+
name !== "memory_save" &&
|
|
993
|
+
name !== "memory_correct" &&
|
|
1002
994
|
!name.startsWith("social_") &&
|
|
1003
995
|
!name.startsWith("x_") &&
|
|
1004
996
|
!name.startsWith("reddit_") &&
|
|
@@ -1054,6 +1046,178 @@ export const PersonalResourceRetentionMode = z.enum(["retain", "delete_after"]);
|
|
|
1054
1046
|
export type PersonalResourceRetentionMode = z.infer<typeof PersonalResourceRetentionMode>;
|
|
1055
1047
|
|
|
1056
1048
|
export const SessionTenancyVisibility = z.enum(["user_private", "workspace_shared"]);
|
|
1049
|
+
|
|
1050
|
+
export const UserResourceAuthorityScope = z.literal("user");
|
|
1051
|
+
export const UserResourceKind = z.enum([
|
|
1052
|
+
"connection",
|
|
1053
|
+
"document",
|
|
1054
|
+
"variable_set",
|
|
1055
|
+
"rig",
|
|
1056
|
+
"connected_machine",
|
|
1057
|
+
]);
|
|
1058
|
+
export type UserResourceKind = z.infer<typeof UserResourceKind>;
|
|
1059
|
+
|
|
1060
|
+
export const USER_RESOURCE_ACTION_BY_KIND = {
|
|
1061
|
+
connection: "connection.use",
|
|
1062
|
+
document: "document.read",
|
|
1063
|
+
variable_set: "variable_set.use",
|
|
1064
|
+
rig: "rig.use",
|
|
1065
|
+
connected_machine: "connected_machine.use",
|
|
1066
|
+
} as const satisfies Record<UserResourceKind, string>;
|
|
1067
|
+
|
|
1068
|
+
export const UserResourceLifecycleGrantMode = z.enum(["once", "session", "always"]);
|
|
1069
|
+
export const PERSONAL_RESOURCE_SHARED_OUTPUT_WARNING_VERSION = 1 as const;
|
|
1070
|
+
export const PERSONAL_RESOURCE_SHARED_OUTPUT_WARNING =
|
|
1071
|
+
"Personal resources used in a workspace-shared session may influence outputs visible to other workspace members. The underlying credentials and secret values are not shared by the attachment itself.";
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* Owner-authored issuance intent for the fixed personal Variable Set/Rig/
|
|
1075
|
+
* Connected Machine closure selected by one session. The server derives every resource,
|
|
1076
|
+
* authority and action from the locked session; callers never nominate grants.
|
|
1077
|
+
*/
|
|
1078
|
+
export const PersonalResourceAttachmentIntent = z
|
|
1079
|
+
.object({
|
|
1080
|
+
mode: UserResourceLifecycleGrantMode,
|
|
1081
|
+
expectedAuthorityEpoch: z.number().int().positive().optional(),
|
|
1082
|
+
workspaceSharedAcknowledged: z.boolean().default(false),
|
|
1083
|
+
sharedOutputWarningVersion: z.literal(PERSONAL_RESOURCE_SHARED_OUTPUT_WARNING_VERSION),
|
|
1084
|
+
})
|
|
1085
|
+
.strict();
|
|
1086
|
+
export type PersonalResourceAttachmentIntent = z.infer<typeof PersonalResourceAttachmentIntent>;
|
|
1087
|
+
|
|
1088
|
+
function requireEstablishedPersonalResourceEpoch(
|
|
1089
|
+
value: {
|
|
1090
|
+
personalResourceAttachment?: PersonalResourceAttachmentIntent | undefined;
|
|
1091
|
+
},
|
|
1092
|
+
context: z.RefinementCtx,
|
|
1093
|
+
): void {
|
|
1094
|
+
if (
|
|
1095
|
+
value.personalResourceAttachment !== undefined &&
|
|
1096
|
+
value.personalResourceAttachment.expectedAuthorityEpoch === undefined
|
|
1097
|
+
) {
|
|
1098
|
+
context.addIssue({
|
|
1099
|
+
code: z.ZodIssueCode.custom,
|
|
1100
|
+
path: ["personalResourceAttachment", "expectedAuthorityEpoch"],
|
|
1101
|
+
message: "established-session attachment requires expectedAuthorityEpoch",
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/** Credential-free accepted-work projection. Resource ids remain private. */
|
|
1107
|
+
export const PersonalResourceAttachmentSummary = z
|
|
1108
|
+
.object({
|
|
1109
|
+
mode: UserResourceLifecycleGrantMode,
|
|
1110
|
+
context: SessionTenancyVisibility,
|
|
1111
|
+
resourceCount: z.number().int().positive(),
|
|
1112
|
+
resourceKinds: z
|
|
1113
|
+
.array(z.enum(["variable_set", "rig", "connected_machine"]))
|
|
1114
|
+
.min(1)
|
|
1115
|
+
.max(3),
|
|
1116
|
+
sharedOutputWarningVersion: z.literal(PERSONAL_RESOURCE_SHARED_OUTPUT_WARNING_VERSION),
|
|
1117
|
+
})
|
|
1118
|
+
.strict();
|
|
1119
|
+
export type PersonalResourceAttachmentSummary = z.infer<typeof PersonalResourceAttachmentSummary>;
|
|
1120
|
+
/** Public owner-management deliberately excludes race-prone standalone `once`. */
|
|
1121
|
+
export const ManagedUserResourceGrantMode = z.enum(["session", "always"]);
|
|
1122
|
+
export const UserResourceAuthorityGrant = z.object({
|
|
1123
|
+
grantId: z.string().uuid(),
|
|
1124
|
+
targetWorkspaceId: z.string().uuid(),
|
|
1125
|
+
targetSessionId: z.string().uuid().nullable(),
|
|
1126
|
+
action: z.enum([
|
|
1127
|
+
"connection.use",
|
|
1128
|
+
"document.read",
|
|
1129
|
+
"variable_set.use",
|
|
1130
|
+
"rig.use",
|
|
1131
|
+
"connected_machine.use",
|
|
1132
|
+
]),
|
|
1133
|
+
mode: UserResourceLifecycleGrantMode,
|
|
1134
|
+
context: SessionTenancyVisibility,
|
|
1135
|
+
authorityEpoch: z.number().int().positive().nullable(),
|
|
1136
|
+
generation: z.number().int().positive(),
|
|
1137
|
+
status: z.enum(["active", "consumed", "revoked", "expired"]),
|
|
1138
|
+
expiresAt: z.string().datetime().nullable(),
|
|
1139
|
+
delegation: z.lazy(() => UserResourceDelegation),
|
|
1140
|
+
});
|
|
1141
|
+
export const UserResourceAuthoritySummary = z.object({
|
|
1142
|
+
authorityId: z.string().uuid(),
|
|
1143
|
+
resourceKind: UserResourceKind,
|
|
1144
|
+
resourceId: z.string().uuid(),
|
|
1145
|
+
originWorkspaceId: z.string().uuid().nullable(),
|
|
1146
|
+
generation: z.number().int().positive(),
|
|
1147
|
+
status: z.enum(["active", "retained", "revoked"]),
|
|
1148
|
+
grants: z.array(UserResourceAuthorityGrant),
|
|
1149
|
+
});
|
|
1150
|
+
export const ListUserResourceAuthoritiesQuery = z.object({
|
|
1151
|
+
scope: UserResourceAuthorityScope,
|
|
1152
|
+
resourceKind: UserResourceKind,
|
|
1153
|
+
cursor: z.string().uuid().optional(),
|
|
1154
|
+
limit: z.coerce.number().int().min(1).max(100).default(50),
|
|
1155
|
+
});
|
|
1156
|
+
export const ListUserResourceAuthoritiesResponse = z.object({
|
|
1157
|
+
scope: UserResourceAuthorityScope,
|
|
1158
|
+
authorities: z.array(UserResourceAuthoritySummary),
|
|
1159
|
+
nextCursor: z.string().uuid().nullable(),
|
|
1160
|
+
});
|
|
1161
|
+
export const IssueUserResourceGrantRequest = z
|
|
1162
|
+
.object({
|
|
1163
|
+
scope: UserResourceAuthorityScope,
|
|
1164
|
+
resourceKind: UserResourceKind,
|
|
1165
|
+
mode: ManagedUserResourceGrantMode,
|
|
1166
|
+
context: SessionTenancyVisibility,
|
|
1167
|
+
sessionId: z.string().uuid().nullable().optional(),
|
|
1168
|
+
expectedAuthorityEpoch: z.number().int().positive().nullable().optional(),
|
|
1169
|
+
workspaceSharedAcknowledged: z.boolean().default(false),
|
|
1170
|
+
})
|
|
1171
|
+
.superRefine((value, context) => {
|
|
1172
|
+
if (value.context === "workspace_shared" && !value.workspaceSharedAcknowledged) {
|
|
1173
|
+
context.addIssue({
|
|
1174
|
+
code: "custom",
|
|
1175
|
+
path: ["workspaceSharedAcknowledged"],
|
|
1176
|
+
message: "workspace_shared requires durable shared-output acknowledgement",
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
if (value.mode === "always" && (value.sessionId || value.expectedAuthorityEpoch)) {
|
|
1180
|
+
context.addIssue({
|
|
1181
|
+
code: "custom",
|
|
1182
|
+
path: ["sessionId"],
|
|
1183
|
+
message: "always is unbound from session authority",
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
if (value.mode === "session" && (!value.sessionId || !value.expectedAuthorityEpoch)) {
|
|
1187
|
+
context.addIssue({
|
|
1188
|
+
code: "custom",
|
|
1189
|
+
path: ["sessionId"],
|
|
1190
|
+
message: "session grants require a target session and expectedAuthorityEpoch",
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
});
|
|
1194
|
+
export const UserResourceGrantMutationResponse = z.object({
|
|
1195
|
+
scope: UserResourceAuthorityScope,
|
|
1196
|
+
grant: UserResourceAuthorityGrant,
|
|
1197
|
+
});
|
|
1198
|
+
export const UserResourceGrantRevocationResponse = z.object({
|
|
1199
|
+
scope: UserResourceAuthorityScope,
|
|
1200
|
+
grant: z.object({
|
|
1201
|
+
grantId: z.string().uuid(),
|
|
1202
|
+
generation: z.number().int().positive(),
|
|
1203
|
+
status: z.literal("revoked"),
|
|
1204
|
+
revokedAt: z.string().datetime(),
|
|
1205
|
+
}),
|
|
1206
|
+
});
|
|
1207
|
+
export const RevokeUserResourceGrantQuery = z.object({
|
|
1208
|
+
scope: UserResourceAuthorityScope,
|
|
1209
|
+
});
|
|
1210
|
+
export type UserResourceAuthorityGrant = z.infer<typeof UserResourceAuthorityGrant>;
|
|
1211
|
+
export type UserResourceAuthoritySummary = z.infer<typeof UserResourceAuthoritySummary>;
|
|
1212
|
+
export type ListUserResourceAuthoritiesQuery = z.infer<typeof ListUserResourceAuthoritiesQuery>;
|
|
1213
|
+
export type ListUserResourceAuthoritiesResponse = z.infer<
|
|
1214
|
+
typeof ListUserResourceAuthoritiesResponse
|
|
1215
|
+
>;
|
|
1216
|
+
export type IssueUserResourceGrantRequest = z.infer<typeof IssueUserResourceGrantRequest>;
|
|
1217
|
+
export type UserResourceGrantMutationResponse = z.infer<typeof UserResourceGrantMutationResponse>;
|
|
1218
|
+
export type UserResourceGrantRevocationResponse = z.infer<
|
|
1219
|
+
typeof UserResourceGrantRevocationResponse
|
|
1220
|
+
>;
|
|
1057
1221
|
export type SessionTenancyVisibility = z.infer<typeof SessionTenancyVisibility>;
|
|
1058
1222
|
|
|
1059
1223
|
/** Public/session API vocabulary. Persistence keeps the explicit tenancy names. */
|
|
@@ -1275,6 +1439,100 @@ export const SessionTenancyPublicProjection = z.object({
|
|
|
1275
1439
|
});
|
|
1276
1440
|
export type SessionTenancyPublicProjection = z.infer<typeof SessionTenancyPublicProjection>;
|
|
1277
1441
|
|
|
1442
|
+
export const SessionTenancyBlocker = z.enum([
|
|
1443
|
+
"nonterminal_turn",
|
|
1444
|
+
"nonterminal_attempt",
|
|
1445
|
+
"unsettled_interruption",
|
|
1446
|
+
"pending_system_update",
|
|
1447
|
+
"pending_human_input",
|
|
1448
|
+
"pending_tool_receipt",
|
|
1449
|
+
"run_state",
|
|
1450
|
+
"active_goal",
|
|
1451
|
+
"capacity_waiter",
|
|
1452
|
+
"active_realtime",
|
|
1453
|
+
"active_scheduled_task",
|
|
1454
|
+
"workspace_mutation_admission",
|
|
1455
|
+
"retained_process",
|
|
1456
|
+
"active_sandbox_access",
|
|
1457
|
+
"shared_sandbox_group",
|
|
1458
|
+
]);
|
|
1459
|
+
export type SessionTenancyBlocker = z.infer<typeof SessionTenancyBlocker>;
|
|
1460
|
+
|
|
1461
|
+
export const SESSION_OPERATION_KEY_MAX_CHARS = 256;
|
|
1462
|
+
const SessionTenancyIdempotencyKey = z.string().trim().min(1).max(SESSION_OPERATION_KEY_MAX_CHARS);
|
|
1463
|
+
|
|
1464
|
+
export const UpdateSessionVisibilityRequest = z
|
|
1465
|
+
.object({
|
|
1466
|
+
visibility: SessionVisibility,
|
|
1467
|
+
expectedAuthorityEpoch: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
1468
|
+
idempotencyKey: SessionTenancyIdempotencyKey,
|
|
1469
|
+
})
|
|
1470
|
+
.strict();
|
|
1471
|
+
export type UpdateSessionVisibilityRequest = z.infer<typeof UpdateSessionVisibilityRequest>;
|
|
1472
|
+
|
|
1473
|
+
export const UpdateSessionVisibilityResponse = z
|
|
1474
|
+
.object({
|
|
1475
|
+
operationId: z.string().uuid(),
|
|
1476
|
+
eventId: z.string().uuid().nullable(),
|
|
1477
|
+
eventSequence: z.number().int().positive().nullable(),
|
|
1478
|
+
visibility: SessionVisibility,
|
|
1479
|
+
authorityEpoch: z.number().int().positive(),
|
|
1480
|
+
changed: z.boolean(),
|
|
1481
|
+
replay: z.boolean(),
|
|
1482
|
+
revokedGrantCount: z.number().int().nonnegative(),
|
|
1483
|
+
})
|
|
1484
|
+
.strict()
|
|
1485
|
+
.superRefine((value, context) => {
|
|
1486
|
+
if (value.changed !== (value.eventId !== null && value.eventSequence !== null)) {
|
|
1487
|
+
context.addIssue({
|
|
1488
|
+
code: "custom",
|
|
1489
|
+
path: ["changed"],
|
|
1490
|
+
message: "changed must match the presence of the durable event receipt",
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
if ((value.eventId === null) !== (value.eventSequence === null)) {
|
|
1494
|
+
context.addIssue({
|
|
1495
|
+
code: "custom",
|
|
1496
|
+
path: ["eventId"],
|
|
1497
|
+
message: "eventId and eventSequence must be present or absent together",
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
export type UpdateSessionVisibilityResponse = z.infer<typeof UpdateSessionVisibilityResponse>;
|
|
1502
|
+
|
|
1503
|
+
export const ForkSessionRequest = z
|
|
1504
|
+
.object({
|
|
1505
|
+
idempotencyKey: SessionTenancyIdempotencyKey,
|
|
1506
|
+
visibility: SessionVisibility,
|
|
1507
|
+
workspaceSharedAcknowledged: z.boolean(),
|
|
1508
|
+
})
|
|
1509
|
+
.strict()
|
|
1510
|
+
.superRefine((value, context) => {
|
|
1511
|
+
if (value.visibility === "private" && value.workspaceSharedAcknowledged) {
|
|
1512
|
+
context.addIssue({
|
|
1513
|
+
code: "custom",
|
|
1514
|
+
path: ["workspaceSharedAcknowledged"],
|
|
1515
|
+
message: "workspaceSharedAcknowledged must be false for a private destination",
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
});
|
|
1519
|
+
export type ForkSessionRequest = z.infer<typeof ForkSessionRequest>;
|
|
1520
|
+
|
|
1521
|
+
export const ForkSessionResponse = z
|
|
1522
|
+
.object({
|
|
1523
|
+
operationId: z.string().uuid(),
|
|
1524
|
+
eventId: z.string().uuid(),
|
|
1525
|
+
eventSequence: z.number().int().positive(),
|
|
1526
|
+
sessionId: z.string().uuid(),
|
|
1527
|
+
workspaceId: z.string().uuid(),
|
|
1528
|
+
visibility: SessionVisibility,
|
|
1529
|
+
authorityEpoch: z.literal(1),
|
|
1530
|
+
copiedHistoryItemCount: z.number().int().nonnegative(),
|
|
1531
|
+
replay: z.boolean(),
|
|
1532
|
+
})
|
|
1533
|
+
.strict();
|
|
1534
|
+
export type ForkSessionResponse = z.infer<typeof ForkSessionResponse>;
|
|
1535
|
+
|
|
1278
1536
|
export const ManagedAccount = z.object({
|
|
1279
1537
|
id: z.string().uuid(),
|
|
1280
1538
|
name: z.string(),
|
|
@@ -1622,6 +1880,37 @@ export const WorkspaceVoiceInputSettings = z
|
|
|
1622
1880
|
.strict();
|
|
1623
1881
|
export type WorkspaceVoiceInputSettings = z.infer<typeof WorkspaceVoiceInputSettings>;
|
|
1624
1882
|
|
|
1883
|
+
/** Model policy inherited by newly created chats and scheduled tasks. */
|
|
1884
|
+
export const WorkspaceSessionDefaults = z
|
|
1885
|
+
.object({
|
|
1886
|
+
model: z.string().trim().min(1).max(256),
|
|
1887
|
+
reasoningEffort: ReasoningEffort,
|
|
1888
|
+
})
|
|
1889
|
+
.strict();
|
|
1890
|
+
export type WorkspaceSessionDefaults = z.infer<typeof WorkspaceSessionDefaults>;
|
|
1891
|
+
|
|
1892
|
+
/**
|
|
1893
|
+
* Exact capability selection inherited by new top-level sessions.
|
|
1894
|
+
*
|
|
1895
|
+
* The product UI presents understandable capability groups, but persistence
|
|
1896
|
+
* stays source-of-truth exact: MCP server ids and first-party tool names. This
|
|
1897
|
+
* keeps the runtime independent from presentation labels and lets a session
|
|
1898
|
+
* narrow the resulting policy without changing the workspace default.
|
|
1899
|
+
*/
|
|
1900
|
+
export const WorkspaceSessionToolDefaults = z
|
|
1901
|
+
.object({
|
|
1902
|
+
mcpServerIds: z
|
|
1903
|
+
.array(z.string().trim().min(1).max(128))
|
|
1904
|
+
.max(128)
|
|
1905
|
+
.transform((ids) => [...new Set(ids)]),
|
|
1906
|
+
firstPartyMcpTools: z
|
|
1907
|
+
.array(FirstPartyMcpToolName)
|
|
1908
|
+
.max(512)
|
|
1909
|
+
.transform((tools) => [...new Set(tools)]),
|
|
1910
|
+
})
|
|
1911
|
+
.strict();
|
|
1912
|
+
export type WorkspaceSessionToolDefaults = z.infer<typeof WorkspaceSessionToolDefaults>;
|
|
1913
|
+
|
|
1625
1914
|
/** Client-safe voice-input capability projection. Never includes provider secrets. */
|
|
1626
1915
|
export const ClientVoiceInputConfig = z
|
|
1627
1916
|
.object({
|
|
@@ -1715,17 +2004,79 @@ export const DEFAULT_WORKSPACE_SLACK_REACTION_SUMMON_SETTINGS = {
|
|
|
1715
2004
|
channelPolicy: { mode: "bot_member" },
|
|
1716
2005
|
} as const satisfies WorkspaceSlackReactionSummonSettings;
|
|
1717
2006
|
|
|
2007
|
+
/**
|
|
2008
|
+
* Per-workspace switches for the two Slack orchestration notices: a pointer
|
|
2009
|
+
* card when a child worker of a Slack-originated session blocks on human input
|
|
2010
|
+
* or a tool approval, and a one-line notice when that session's goal pauses for
|
|
2011
|
+
* budget or the continuation cap.
|
|
2012
|
+
*
|
|
2013
|
+
* Both are OFF unless this workspace explicitly turned them on. An unsolicited
|
|
2014
|
+
* Slack post is worse than a missed one, and the in-app rail and priority feed
|
|
2015
|
+
* already surface a blocked child, so an absent, malformed, or partially
|
|
2016
|
+
* invalid setting resolves to both disabled - see
|
|
2017
|
+
* `resolveWorkspaceSlackOrchestrationNoticeSettings`.
|
|
2018
|
+
*
|
|
2019
|
+
* Deliberately not `.strict()`: this is a KNOWN key of the stored settings bag,
|
|
2020
|
+
* so rejecting it rejects the whole bag and silently reverts memoryEnabled,
|
|
2021
|
+
* agentHumanInputEnabled, codexCompactionDefault, voiceInput, and the Slack
|
|
2022
|
+
* reaction shortcut to their defaults too. An unknown key here is a notice a
|
|
2023
|
+
* newer release added, and a rollback must not cost five unrelated settings.
|
|
2024
|
+
* An invalid VALUE still fails the bag, and therefore fails closed to silence.
|
|
2025
|
+
*/
|
|
2026
|
+
export const WorkspaceSlackOrchestrationNoticeSettings = z.object({
|
|
2027
|
+
childRequiresAction: z.boolean().optional(),
|
|
2028
|
+
goalPaused: z.boolean().optional(),
|
|
2029
|
+
});
|
|
2030
|
+
export type WorkspaceSlackOrchestrationNoticeSettings = z.infer<
|
|
2031
|
+
typeof WorkspaceSlackOrchestrationNoticeSettings
|
|
2032
|
+
>;
|
|
2033
|
+
|
|
2034
|
+
/**
|
|
2035
|
+
* The resolved answer: every notice is an explicit boolean, never absent.
|
|
2036
|
+
* Spelled out rather than derived with `Required<>`, which would keep the
|
|
2037
|
+
* `| undefined` that the optional zod fields carry into their inferred type.
|
|
2038
|
+
*/
|
|
2039
|
+
export type ResolvedWorkspaceSlackOrchestrationNoticeSettings = {
|
|
2040
|
+
childRequiresAction: boolean;
|
|
2041
|
+
goalPaused: boolean;
|
|
2042
|
+
};
|
|
2043
|
+
|
|
2044
|
+
export const DEFAULT_WORKSPACE_SLACK_ORCHESTRATION_NOTICE_SETTINGS = {
|
|
2045
|
+
childRequiresAction: false,
|
|
2046
|
+
goalPaused: false,
|
|
2047
|
+
} as const satisfies ResolvedWorkspaceSlackOrchestrationNoticeSettings;
|
|
2048
|
+
|
|
2049
|
+
// Memory V1's standing prompt block is retired, but the enum deliberately still
|
|
2050
|
+
// ACCEPTS `legacy_standing`. `.passthrough()` only preserves unknown keys - it
|
|
2051
|
+
// does not rescue a known key holding a value the enum rejects - so collapsing
|
|
2052
|
+
// this to one value would fail the whole settings parse for any workspace that
|
|
2053
|
+
// opted in. Every resolver here is "parse the bag, fall back on failure", so
|
|
2054
|
+
// that single rejection would silently revert memoryEnabled,
|
|
2055
|
+
// agentHumanInputEnabled, codexCompactionDefault, voiceInput and Slack summon
|
|
2056
|
+
// to their defaults. The value is accepted and then ignored: see
|
|
2057
|
+
// resolveWorkspaceMemoryPromptMode.
|
|
1718
2058
|
export const WorkspaceMemoryPromptMode = z.enum(["legacy_standing", "retrieval_only"]);
|
|
1719
2059
|
export type WorkspaceMemoryPromptMode = z.infer<typeof WorkspaceMemoryPromptMode>;
|
|
1720
2060
|
|
|
2061
|
+
/**
|
|
2062
|
+
* What an already-accepted turn recorded. Snapshots and receipts are immutable,
|
|
2063
|
+
* so turns accepted before the standing block was retired still read back
|
|
2064
|
+
* `legacy_standing`. That is a fact about history, not a mode anyone can pick -
|
|
2065
|
+
* keep the two apart so retiring the setting never rewrites the record.
|
|
2066
|
+
*/
|
|
2067
|
+
export const HistoricalMemoryPromptMode = z.enum(["legacy_standing", "retrieval_only"]);
|
|
2068
|
+
export type HistoricalMemoryPromptMode = z.infer<typeof HistoricalMemoryPromptMode>;
|
|
2069
|
+
|
|
1721
2070
|
// Validates the KNOWN keys of workspaces.settings; passthrough keeps unknown
|
|
1722
2071
|
// (future) keys rather than stripping them. memoryEnabled defaults off and the
|
|
1723
|
-
//
|
|
2072
|
+
// Memory V1 prompt mode is always retrieval-only composition;
|
|
1724
2073
|
// voiceInput defaults to enabled when the deployment has a provider.
|
|
1725
2074
|
export const WorkspaceSettingsSchema = z
|
|
1726
2075
|
.object({
|
|
1727
2076
|
memoryEnabled: z.boolean().optional(),
|
|
1728
2077
|
memoryPromptMode: WorkspaceMemoryPromptMode.optional(),
|
|
2078
|
+
sessionDefaults: WorkspaceSessionDefaults.optional(),
|
|
2079
|
+
sessionToolDefaults: WorkspaceSessionToolDefaults.optional(),
|
|
1729
2080
|
/** Preferred workspace voice-input toggle. */
|
|
1730
2081
|
voiceInput: WorkspaceVoiceInputSettings.optional(),
|
|
1731
2082
|
/**
|
|
@@ -1745,6 +2096,11 @@ export const WorkspaceSettingsSchema = z
|
|
|
1745
2096
|
// Optional Slack reaction invocation. Absent/invalid fails closed to the
|
|
1746
2097
|
// disabled default via resolveWorkspaceSlackReactionSummonSettings.
|
|
1747
2098
|
slackReactionSummon: WorkspaceSlackReactionSummonSettings.optional(),
|
|
2099
|
+
// Optional Slack orchestration notices (blocked child worker, paused goal).
|
|
2100
|
+
// BOTH DEFAULT OFF: absent, malformed, or partially invalid settings fail
|
|
2101
|
+
// closed to disabled via resolveWorkspaceSlackOrchestrationNoticeSettings,
|
|
2102
|
+
// because an unsolicited Slack post is worse than a missed one.
|
|
2103
|
+
slackOrchestrationNotices: WorkspaceSlackOrchestrationNoticeSettings.optional(),
|
|
1748
2104
|
})
|
|
1749
2105
|
.passthrough();
|
|
1750
2106
|
export type WorkspaceSettings = z.infer<typeof WorkspaceSettingsSchema>;
|
|
@@ -1755,10 +2111,31 @@ export function resolveWorkspaceMemoryEnabled(settings: unknown): boolean {
|
|
|
1755
2111
|
return parsed.success ? parsed.data.memoryEnabled === true : false;
|
|
1756
2112
|
}
|
|
1757
2113
|
|
|
1758
|
-
/**
|
|
1759
|
-
export function
|
|
2114
|
+
/** Explicit defaults for new chats/schedules, or null for deployment defaults. */
|
|
2115
|
+
export function resolveWorkspaceSessionDefaults(
|
|
2116
|
+
settings: unknown,
|
|
2117
|
+
): WorkspaceSessionDefaults | null {
|
|
2118
|
+
const parsed = WorkspaceSettingsSchema.safeParse(settings ?? {});
|
|
2119
|
+
return parsed.success ? (parsed.data.sessionDefaults ?? null) : null;
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
/** Exact capability defaults for new sessions, or null for deployment defaults. */
|
|
2123
|
+
export function resolveWorkspaceSessionToolDefaults(
|
|
2124
|
+
settings: unknown,
|
|
2125
|
+
): WorkspaceSessionToolDefaults | null {
|
|
1760
2126
|
const parsed = WorkspaceSettingsSchema.safeParse(settings ?? {});
|
|
1761
|
-
return parsed.success ? (parsed.data.
|
|
2127
|
+
return parsed.success ? (parsed.data.sessionToolDefaults ?? null) : null;
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
/**
|
|
2131
|
+
* Memory V1 prompt mode. Always `retrieval_only`: the standing pinned/recency
|
|
2132
|
+
* block is retired, so an absent, unrecognized, or stored-`legacy_standing`
|
|
2133
|
+
* setting all resolve the same way. Kept as a function so the call sites and
|
|
2134
|
+
* the frozen SQL snapshot keep agreeing without each one having to learn that
|
|
2135
|
+
* the choice is gone.
|
|
2136
|
+
*/
|
|
2137
|
+
export function resolveWorkspaceMemoryPromptMode(): "retrieval_only" {
|
|
2138
|
+
return "retrieval_only";
|
|
1762
2139
|
}
|
|
1763
2140
|
|
|
1764
2141
|
/** Default Codex compaction mode for new Codex sessions (remote_v2 when unset). */
|
|
@@ -1815,6 +2192,30 @@ export function resolveWorkspaceSlackReactionSummonSettings(
|
|
|
1815
2192
|
: { ...configured, channelPolicy: { mode: "bot_member" } };
|
|
1816
2193
|
}
|
|
1817
2194
|
|
|
2195
|
+
/**
|
|
2196
|
+
* Resolve the two Slack orchestration notice switches, failing closed.
|
|
2197
|
+
*
|
|
2198
|
+
* Off is the product decision, not a placeholder: the in-app rail and priority
|
|
2199
|
+
* feed already surface a blocked child worker and a paused goal, so a missed
|
|
2200
|
+
* Slack post costs a delay while an unsolicited one costs the thread's
|
|
2201
|
+
* credibility. Absent settings, a settings bag this schema rejects, and a
|
|
2202
|
+
* partially invalid notice object therefore all resolve to both disabled -
|
|
2203
|
+
* only an explicit `true` on a valid bag turns a notice on.
|
|
2204
|
+
*/
|
|
2205
|
+
export function resolveWorkspaceSlackOrchestrationNoticeSettings(
|
|
2206
|
+
settings: unknown,
|
|
2207
|
+
): ResolvedWorkspaceSlackOrchestrationNoticeSettings {
|
|
2208
|
+
const parsed = WorkspaceSettingsSchema.safeParse(settings ?? {});
|
|
2209
|
+
const configured = parsed.success ? parsed.data.slackOrchestrationNotices : undefined;
|
|
2210
|
+
return {
|
|
2211
|
+
childRequiresAction:
|
|
2212
|
+
configured?.childRequiresAction ??
|
|
2213
|
+
DEFAULT_WORKSPACE_SLACK_ORCHESTRATION_NOTICE_SETTINGS.childRequiresAction,
|
|
2214
|
+
goalPaused:
|
|
2215
|
+
configured?.goalPaused ?? DEFAULT_WORKSPACE_SLACK_ORCHESTRATION_NOTICE_SETTINGS.goalPaused,
|
|
2216
|
+
};
|
|
2217
|
+
}
|
|
2218
|
+
|
|
1818
2219
|
export function workspaceSlackReactionChannelAllowed(
|
|
1819
2220
|
settings: WorkspaceSlackReactionSummonSettings,
|
|
1820
2221
|
channelId: string,
|
|
@@ -1832,6 +2233,8 @@ export const UpdateWorkspaceSettingsRequest = z
|
|
|
1832
2233
|
.object({
|
|
1833
2234
|
memoryEnabled: z.boolean().optional(),
|
|
1834
2235
|
memoryPromptMode: WorkspaceMemoryPromptMode.optional(),
|
|
2236
|
+
sessionDefaults: WorkspaceSessionDefaults.optional(),
|
|
2237
|
+
sessionToolDefaults: WorkspaceSessionToolDefaults.optional(),
|
|
1835
2238
|
voiceInput: WorkspaceVoiceInputSettings.optional(),
|
|
1836
2239
|
/** @deprecated Prefer `voiceInput`. Kept for one compatibility release. */
|
|
1837
2240
|
transcription: WorkspaceTranscriptionPolicy.optional(),
|
|
@@ -1839,6 +2242,7 @@ export const UpdateWorkspaceSettingsRequest = z
|
|
|
1839
2242
|
codexCompactionDefault: CodexCompactionMode.optional(),
|
|
1840
2243
|
agentHumanInputEnabled: z.boolean().optional(),
|
|
1841
2244
|
slackReactionSummon: WorkspaceSlackReactionSummonSettings.optional(),
|
|
2245
|
+
slackOrchestrationNotices: WorkspaceSlackOrchestrationNoticeSettings.optional(),
|
|
1842
2246
|
})
|
|
1843
2247
|
.passthrough();
|
|
1844
2248
|
export type UpdateWorkspaceSettingsRequest = z.infer<typeof UpdateWorkspaceSettingsRequest>;
|
|
@@ -2349,6 +2753,17 @@ export const StreamTokenPayload = z.object({
|
|
|
2349
2753
|
// Short TTL (120s default); rotation is event-driven under the epoch fence,
|
|
2350
2754
|
// not on a keepalive clock.
|
|
2351
2755
|
exp: z.number().int().positive(),
|
|
2756
|
+
// The authenticated subject the token was minted for (0281). Optional for
|
|
2757
|
+
// rolling compatibility: old verifiers strip it, old mints omit it.
|
|
2758
|
+
subjectId: z.string().min(1).max(512).optional(),
|
|
2759
|
+
// The session authority epoch observed at mint (0281). The relay tracks the
|
|
2760
|
+
// highest value presented per LIVE channel and rejects tokens below that
|
|
2761
|
+
// floor. The floor is defense-in-depth, not the revocation authority: it
|
|
2762
|
+
// lives only as long as the channel does (both sides detached, the
|
|
2763
|
+
// half-open reaper, or a relay restart reset it), so a stale in-TTL token
|
|
2764
|
+
// can still attach to a fresh channel. Real revocation is the mint refusing
|
|
2765
|
+
// to issue new tokens plus the 120 s TTL bounding the old ones.
|
|
2766
|
+
authorityEpoch: z.number().int().positive().optional(),
|
|
2352
2767
|
});
|
|
2353
2768
|
export type StreamTokenPayload = z.infer<typeof StreamTokenPayload>;
|
|
2354
2769
|
|
|
@@ -2510,6 +2925,7 @@ export const ApiKey = z.object({
|
|
|
2510
2925
|
accountId: z.string().uuid(),
|
|
2511
2926
|
workspaceId: z.string().uuid().nullable(),
|
|
2512
2927
|
name: z.string(),
|
|
2928
|
+
description: z.string().nullable(),
|
|
2513
2929
|
prefix: z.string(),
|
|
2514
2930
|
permissions: z.array(Permission),
|
|
2515
2931
|
expiresAt: z.string().nullable(),
|
|
@@ -2522,6 +2938,7 @@ export type ApiKey = z.infer<typeof ApiKey>;
|
|
|
2522
2938
|
|
|
2523
2939
|
export const CreateApiKeyRequest = z.object({
|
|
2524
2940
|
name: z.string().min(1),
|
|
2941
|
+
description: z.string().trim().min(1).max(500).optional(),
|
|
2525
2942
|
workspaceId: z.string().uuid().optional(),
|
|
2526
2943
|
permissions: z.array(Permission).min(1),
|
|
2527
2944
|
expiresAt: z.string().datetime({ offset: true }).optional(),
|
|
@@ -2675,6 +3092,59 @@ export type InsightsBillingPath = z.infer<typeof InsightsBillingPath>;
|
|
|
2675
3092
|
export const InsightsPricingSource = z.enum(["configured_list_price", "gateway_reported"]);
|
|
2676
3093
|
export type InsightsPricingSource = z.infer<typeof InsightsPricingSource>;
|
|
2677
3094
|
|
|
3095
|
+
export const ModelContextContributionSource = z.enum([
|
|
3096
|
+
"workspace_instruction_policy",
|
|
3097
|
+
"legacy_workspace_instructions",
|
|
3098
|
+
"preference_registry_descriptor",
|
|
3099
|
+
"company_profile",
|
|
3100
|
+
"legacy_memory_v1",
|
|
3101
|
+
"runtime_skill_catalog",
|
|
3102
|
+
]);
|
|
3103
|
+
export type ModelContextContributionSource = z.infer<typeof ModelContextContributionSource>;
|
|
3104
|
+
|
|
3105
|
+
/** Content-free per-call summary of model-visible Company Brain material. */
|
|
3106
|
+
export const ModelContextContributionSummary = z
|
|
3107
|
+
.object({
|
|
3108
|
+
source: ModelContextContributionSource,
|
|
3109
|
+
items: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
3110
|
+
utf8Bytes: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
3111
|
+
estimatedTokens: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
3112
|
+
})
|
|
3113
|
+
.strict();
|
|
3114
|
+
export type ModelContextContributionSummary = z.infer<typeof ModelContextContributionSummary>;
|
|
3115
|
+
|
|
3116
|
+
export const ModelContextContributionSummaries = z
|
|
3117
|
+
.array(ModelContextContributionSummary)
|
|
3118
|
+
.max(6)
|
|
3119
|
+
.superRefine((summaries, context) => {
|
|
3120
|
+
const seen = new Set<ModelContextContributionSource>();
|
|
3121
|
+
for (const [index, summary] of summaries.entries()) {
|
|
3122
|
+
if (seen.has(summary.source)) {
|
|
3123
|
+
context.addIssue({
|
|
3124
|
+
code: "custom",
|
|
3125
|
+
message: "Model context contribution sources must be unique",
|
|
3126
|
+
path: [index, "source"],
|
|
3127
|
+
});
|
|
3128
|
+
}
|
|
3129
|
+
seen.add(summary.source);
|
|
3130
|
+
}
|
|
3131
|
+
});
|
|
3132
|
+
|
|
3133
|
+
export const InsightsPromptContributionRow = ModelContextContributionSummary.extend({
|
|
3134
|
+
calls: z.number().int().nonnegative(),
|
|
3135
|
+
});
|
|
3136
|
+
export type InsightsPromptContributionRow = z.infer<typeof InsightsPromptContributionRow>;
|
|
3137
|
+
|
|
3138
|
+
export const InsightsPromptContributions = z.object({
|
|
3139
|
+
/** Sum of UTF-8 byte / 4 estimates across calls with contribution receipts. */
|
|
3140
|
+
estimatedTokens: z.number().int().nonnegative(),
|
|
3141
|
+
utf8Bytes: z.number().int().nonnegative(),
|
|
3142
|
+
coveredCalls: z.number().int().nonnegative(),
|
|
3143
|
+
totalCalls: z.number().int().nonnegative(),
|
|
3144
|
+
sources: z.array(InsightsPromptContributionRow),
|
|
3145
|
+
});
|
|
3146
|
+
export type InsightsPromptContributions = z.infer<typeof InsightsPromptContributions>;
|
|
3147
|
+
|
|
2678
3148
|
export const InsightsModelUsageRow = z.object({
|
|
2679
3149
|
id: z.string().min(1),
|
|
2680
3150
|
model: z.string().min(1),
|
|
@@ -2841,6 +3311,13 @@ export const WorkspaceInsightsSnapshot = z.object({
|
|
|
2841
3311
|
drivers: z.array(InsightsSpendDriver),
|
|
2842
3312
|
schedules: z.array(InsightsScheduleRow),
|
|
2843
3313
|
recentCalls: z.array(InsightsModelCallRow),
|
|
3314
|
+
promptContributions: InsightsPromptContributions.default({
|
|
3315
|
+
estimatedTokens: 0,
|
|
3316
|
+
utf8Bytes: 0,
|
|
3317
|
+
coveredCalls: 0,
|
|
3318
|
+
totalCalls: 0,
|
|
3319
|
+
sources: [],
|
|
3320
|
+
}),
|
|
2844
3321
|
warmSeconds: z.number().nonnegative(),
|
|
2845
3322
|
priorWarmSeconds: z.number().nonnegative(),
|
|
2846
3323
|
warmGroups: z.array(InsightsWarmGroupRow),
|
|
@@ -2989,6 +3466,11 @@ export const GitCredentialRepositoryRef = z.object({
|
|
|
2989
3466
|
access: GitRepositoryAccess.optional(),
|
|
2990
3467
|
uri: z.string().min(1),
|
|
2991
3468
|
ref: z.string().min(1),
|
|
3469
|
+
/** Immutable commit the caller expects `ref` to materialize. */
|
|
3470
|
+
expectedCommitSha: z
|
|
3471
|
+
.string()
|
|
3472
|
+
.regex(/^[0-9a-f]{40}$/)
|
|
3473
|
+
.optional(),
|
|
2992
3474
|
repositoryId: GitProviderRepositoryId.optional(),
|
|
2993
3475
|
installationId: GitProviderRepositoryId.optional(),
|
|
2994
3476
|
projectId: GitProviderRepositoryId.optional(),
|
|
@@ -3113,9 +3595,25 @@ export type GitCredentials = {
|
|
|
3113
3595
|
export type SandboxSecretsRequest = {
|
|
3114
3596
|
accountId: string;
|
|
3115
3597
|
workspaceId: string;
|
|
3116
|
-
//
|
|
3117
|
-
//
|
|
3598
|
+
// Exact live attempt authority. Hosts MUST revalidate this tuple, the
|
|
3599
|
+
// session's selected resource identity, and any personal-resource grant
|
|
3600
|
+
// immediately before returning plaintext.
|
|
3601
|
+
sessionId: string;
|
|
3602
|
+
turnId: string;
|
|
3603
|
+
attemptId: string;
|
|
3604
|
+
executionGeneration: number;
|
|
3605
|
+
// Organization/workspace Variable Sets may be materialized by a pure
|
|
3606
|
+
// service turn (for example, the scheduler). Personal Variable Sets still
|
|
3607
|
+
// require this causal human and an exact personal-resource grant.
|
|
3608
|
+
initiator: TurnInitiator;
|
|
3609
|
+
initiatingHumanSubjectId: string | null;
|
|
3118
3610
|
variableSetId: string;
|
|
3611
|
+
/**
|
|
3612
|
+
* Exact accepted scheduled-occurrence generation. Present only for scheduled
|
|
3613
|
+
* attempts; ordinary live turns omit it, so hosts that predate this field keep
|
|
3614
|
+
* working unchanged for those.
|
|
3615
|
+
*/
|
|
3616
|
+
expectedGeneration?: number | null;
|
|
3119
3617
|
};
|
|
3120
3618
|
|
|
3121
3619
|
export type SandboxSecrets = {
|
|
@@ -3123,8 +3621,19 @@ export type SandboxSecrets = {
|
|
|
3123
3621
|
// `environmentsEncryptionKeyBytes` decrypt. Same shape the self-mint path
|
|
3124
3622
|
// produces (plaintext name→value).
|
|
3125
3623
|
values: Record<string, string>;
|
|
3126
|
-
//
|
|
3624
|
+
// Exact scope/resource echoes are mandatory so a host routing bug cannot
|
|
3625
|
+
// inject a sibling tenant, resource, or stale attempt's plaintext.
|
|
3626
|
+
accountId: string;
|
|
3127
3627
|
workspaceId: string;
|
|
3628
|
+
sessionId: string;
|
|
3629
|
+
turnId: string;
|
|
3630
|
+
attemptId: string;
|
|
3631
|
+
executionGeneration: number;
|
|
3632
|
+
variableSetId: string;
|
|
3633
|
+
/** Must echo the request's `expectedGeneration` when one was supplied. */
|
|
3634
|
+
expectedGeneration?: number | null;
|
|
3635
|
+
scope: VariableSetScope;
|
|
3636
|
+
generation: number;
|
|
3128
3637
|
// Optional variableSet metadata; when omitted the activity uses the
|
|
3129
3638
|
// variableSetId as both id and name (the local decrypt carries the row's
|
|
3130
3639
|
// id/name/description, but only `id` is load-bearing downstream).
|
|
@@ -3288,12 +3797,127 @@ export const McpPersonalConnectionDelegation = z
|
|
|
3288
3797
|
.object({
|
|
3289
3798
|
serverId: z.string().min(1).max(256),
|
|
3290
3799
|
connectionId: z.string().uuid(),
|
|
3800
|
+
/**
|
|
3801
|
+
* Immutable physical workspace that owns an activated common-user
|
|
3802
|
+
* connection. It is server-resolved from the selected authority and lets
|
|
3803
|
+
* provider adapters load only that exact row when the accepted turn runs
|
|
3804
|
+
* in another workspace of the same organization.
|
|
3805
|
+
*/
|
|
3806
|
+
originWorkspaceId: z.string().uuid().optional(),
|
|
3291
3807
|
ownerSubjectId: z.string().min(1).max(512),
|
|
3292
3808
|
providerDomain: z.string().min(1).max(2048),
|
|
3293
3809
|
kind: z.enum(["oauth2", "api_key", "app_install", "delegated"]).optional(),
|
|
3294
|
-
connectionType: z.enum(["mcp", "social", "atlassian"]).optional(),
|
|
3810
|
+
connectionType: z.enum(["mcp", "social", "atlassian", "github_personal"]).optional(),
|
|
3811
|
+
/**
|
|
3812
|
+
* Explicit common-authority grant selected by the owning human. Omission is
|
|
3813
|
+
* retained only for legacy_user connections that cannot yet participate in
|
|
3814
|
+
* the organization-user authority lifecycle.
|
|
3815
|
+
*/
|
|
3816
|
+
userDelegation: UserResourceDelegation.optional(),
|
|
3817
|
+
/**
|
|
3818
|
+
* Personal GitHub only: the exact repository authority frozen when this
|
|
3819
|
+
* accepted work was admitted. The credential binding is evidence, not an
|
|
3820
|
+
* authorization; physical provider use must revalidate every mutable
|
|
3821
|
+
* connection/grant/selection fence against this snapshot.
|
|
3822
|
+
*/
|
|
3823
|
+
personalGitHubRepositorySelection: z
|
|
3824
|
+
.object({
|
|
3825
|
+
credentialBindingId: z.string().uuid(),
|
|
3826
|
+
connectionAuthorityGeneration: z.number().int().positive(),
|
|
3827
|
+
selectionGeneration: z.number().int().positive(),
|
|
3828
|
+
repositories: z
|
|
3829
|
+
.array(
|
|
3830
|
+
z
|
|
3831
|
+
.object({
|
|
3832
|
+
repositoryId: z.string().regex(/^[1-9]\d*$/u),
|
|
3833
|
+
fullName: z.string().min(3).max(140),
|
|
3834
|
+
canonicalUrl: z.string().url().max(512),
|
|
3835
|
+
ref: z.string().min(1).max(255),
|
|
3836
|
+
access: GitRepositoryAccess,
|
|
3837
|
+
selectionGeneration: z.number().int().positive(),
|
|
3838
|
+
})
|
|
3839
|
+
.strict(),
|
|
3840
|
+
)
|
|
3841
|
+
.min(1)
|
|
3842
|
+
.max(100),
|
|
3843
|
+
})
|
|
3844
|
+
.strict()
|
|
3845
|
+
.optional(),
|
|
3846
|
+
/**
|
|
3847
|
+
* Google Drive publication only: the exact output destination frozen when
|
|
3848
|
+
* this delegation was accepted, so a later connection-settings change can
|
|
3849
|
+
* never redirect an already-accepted turn's publication. Structurally
|
|
3850
|
+
* mirrors GoogleDriveOutputDestination (defined in ./google-drive, which
|
|
3851
|
+
* imports this module - hence the inline shape). Absent on pre-freeze
|
|
3852
|
+
* turns, which keep the bounded legacy live-resolution behavior.
|
|
3853
|
+
*/
|
|
3854
|
+
outputDestination: z
|
|
3855
|
+
.object({
|
|
3856
|
+
folderId: z.string().min(1).max(256),
|
|
3857
|
+
folderName: z.string().min(1).max(1024),
|
|
3858
|
+
driveId: z.string().min(1).max(256).nullable(),
|
|
3859
|
+
location: z.enum(["my_drive", "shared_drive"]),
|
|
3860
|
+
selectedAt: z.string().datetime({ offset: true }),
|
|
3861
|
+
})
|
|
3862
|
+
.strict()
|
|
3863
|
+
.optional(),
|
|
3295
3864
|
})
|
|
3296
|
-
.strict()
|
|
3865
|
+
.strict()
|
|
3866
|
+
.superRefine((delegation, context) => {
|
|
3867
|
+
const personalGitHub = delegation.connectionType === "github_personal";
|
|
3868
|
+
if (personalGitHub !== (delegation.personalGitHubRepositorySelection !== undefined)) {
|
|
3869
|
+
context.addIssue({
|
|
3870
|
+
code: "custom",
|
|
3871
|
+
path: ["personalGitHubRepositorySelection"],
|
|
3872
|
+
message: "personal GitHub delegation requires one repository authority snapshot",
|
|
3873
|
+
});
|
|
3874
|
+
}
|
|
3875
|
+
if (!personalGitHub) return;
|
|
3876
|
+
if (
|
|
3877
|
+
delegation.serverId !== "github:personal" ||
|
|
3878
|
+
delegation.providerDomain !== "github.com" ||
|
|
3879
|
+
delegation.kind !== "oauth2" ||
|
|
3880
|
+
!delegation.originWorkspaceId ||
|
|
3881
|
+
!delegation.userDelegation
|
|
3882
|
+
) {
|
|
3883
|
+
context.addIssue({
|
|
3884
|
+
code: "custom",
|
|
3885
|
+
message: "personal GitHub delegation requires exact user-owned connection authority",
|
|
3886
|
+
});
|
|
3887
|
+
}
|
|
3888
|
+
const repositories = delegation.personalGitHubRepositorySelection?.repositories ?? [];
|
|
3889
|
+
const repositoryIds = new Set<string>();
|
|
3890
|
+
const canonicalUrls = new Set<string>();
|
|
3891
|
+
repositories.forEach((repository, index) => {
|
|
3892
|
+
const canonicalUrl = repository.canonicalUrl.toLowerCase();
|
|
3893
|
+
if (
|
|
3894
|
+
!/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})\/[A-Za-z0-9_.-]{1,100}$/u.test(repository.fullName) ||
|
|
3895
|
+
repository.canonicalUrl !== `https://github.com/${repository.fullName}`
|
|
3896
|
+
) {
|
|
3897
|
+
context.addIssue({
|
|
3898
|
+
code: "custom",
|
|
3899
|
+
path: ["personalGitHubRepositorySelection", "repositories", index, "canonicalUrl"],
|
|
3900
|
+
message: "personal GitHub repository identity must be canonical",
|
|
3901
|
+
});
|
|
3902
|
+
}
|
|
3903
|
+
if (repositoryIds.has(repository.repositoryId)) {
|
|
3904
|
+
context.addIssue({
|
|
3905
|
+
code: "custom",
|
|
3906
|
+
path: ["personalGitHubRepositorySelection", "repositories", index, "repositoryId"],
|
|
3907
|
+
message: "personal GitHub repositories must be unique by provider id",
|
|
3908
|
+
});
|
|
3909
|
+
}
|
|
3910
|
+
if (canonicalUrls.has(canonicalUrl)) {
|
|
3911
|
+
context.addIssue({
|
|
3912
|
+
code: "custom",
|
|
3913
|
+
path: ["personalGitHubRepositorySelection", "repositories", index, "canonicalUrl"],
|
|
3914
|
+
message: "personal GitHub repositories must be unique by canonical URL",
|
|
3915
|
+
});
|
|
3916
|
+
}
|
|
3917
|
+
repositoryIds.add(repository.repositoryId);
|
|
3918
|
+
canonicalUrls.add(canonicalUrl);
|
|
3919
|
+
});
|
|
3920
|
+
});
|
|
3297
3921
|
export type McpPersonalConnectionDelegation = z.infer<typeof McpPersonalConnectionDelegation>;
|
|
3298
3922
|
|
|
3299
3923
|
/**
|
|
@@ -3318,12 +3942,44 @@ export const McpPersonalConnectionDelegations = z
|
|
|
3318
3942
|
}
|
|
3319
3943
|
});
|
|
3320
3944
|
|
|
3321
|
-
export const McpPersonalConnectionSummary =
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3945
|
+
export const McpPersonalConnectionSummary = z
|
|
3946
|
+
.object({
|
|
3947
|
+
serverId: z.string().min(1).max(256),
|
|
3948
|
+
providerDomain: z.string().min(1).max(2048),
|
|
3949
|
+
})
|
|
3950
|
+
.strict();
|
|
3325
3951
|
export type McpPersonalConnectionSummary = z.infer<typeof McpPersonalConnectionSummary>;
|
|
3326
3952
|
|
|
3953
|
+
/**
|
|
3954
|
+
* Public, credential-free selection of one exact personal connection grant for
|
|
3955
|
+
* one selected MCP/first-party server. The owner is always derived server-side.
|
|
3956
|
+
*/
|
|
3957
|
+
export const McpConnectionAuthoritySelection = z
|
|
3958
|
+
.object({
|
|
3959
|
+
serverId: z.string().min(1).max(256),
|
|
3960
|
+
connectionId: z.string().uuid(),
|
|
3961
|
+
userDelegation: UserResourceDelegation,
|
|
3962
|
+
})
|
|
3963
|
+
.strict();
|
|
3964
|
+
export type McpConnectionAuthoritySelection = z.infer<typeof McpConnectionAuthoritySelection>;
|
|
3965
|
+
|
|
3966
|
+
export const McpConnectionAuthoritySelections = z
|
|
3967
|
+
.array(McpConnectionAuthoritySelection)
|
|
3968
|
+
.max(128)
|
|
3969
|
+
.superRefine((selections, context) => {
|
|
3970
|
+
const seen = new Set<string>();
|
|
3971
|
+
for (const [index, selection] of selections.entries()) {
|
|
3972
|
+
if (seen.has(selection.serverId)) {
|
|
3973
|
+
context.addIssue({
|
|
3974
|
+
code: "custom",
|
|
3975
|
+
message: "connection authority selections must be unique by serverId",
|
|
3976
|
+
path: [index, "serverId"],
|
|
3977
|
+
});
|
|
3978
|
+
}
|
|
3979
|
+
seen.add(selection.serverId);
|
|
3980
|
+
}
|
|
3981
|
+
});
|
|
3982
|
+
|
|
3327
3983
|
export type McpCredentialsRequest = {
|
|
3328
3984
|
accountId: string;
|
|
3329
3985
|
workspaceId: string;
|
|
@@ -3354,6 +4010,10 @@ export type McpCredentialsRequest = {
|
|
|
3354
4010
|
toolName?: string;
|
|
3355
4011
|
connectionRef: McpServerConnectionRef;
|
|
3356
4012
|
forceRefresh: boolean;
|
|
4013
|
+
/** Canonical credential-free authority frozen on the accepted turn. */
|
|
4014
|
+
connectionUseAuthority?: unknown;
|
|
4015
|
+
/** Stable idempotency key for this one physical provider request. */
|
|
4016
|
+
connectionUseRequestId?: string;
|
|
3357
4017
|
};
|
|
3358
4018
|
|
|
3359
4019
|
export type McpCredentialAuthNeededReason =
|
|
@@ -3552,13 +4212,35 @@ export const CreateCheckoutResponse = z.object({
|
|
|
3552
4212
|
});
|
|
3553
4213
|
export type CreateCheckoutResponse = z.infer<typeof CreateCheckoutResponse>;
|
|
3554
4214
|
|
|
4215
|
+
export const CreateBillingPortalRequest = z.object({
|
|
4216
|
+
accountId: z.string().uuid().optional(),
|
|
4217
|
+
returnUrl: z.string().url().optional(),
|
|
4218
|
+
});
|
|
4219
|
+
export type CreateBillingPortalRequest = z.infer<typeof CreateBillingPortalRequest>;
|
|
4220
|
+
|
|
4221
|
+
export const CreateBillingPortalResponse = z.object({
|
|
4222
|
+
portalSessionId: z.string(),
|
|
4223
|
+
url: z.string().url(),
|
|
4224
|
+
});
|
|
4225
|
+
export type CreateBillingPortalResponse = z.infer<typeof CreateBillingPortalResponse>;
|
|
4226
|
+
|
|
3555
4227
|
export const RepositoryResourceRef = z.object({
|
|
3556
4228
|
kind: z.literal("repository"),
|
|
3557
4229
|
uri: z.string().min(1),
|
|
3558
4230
|
ref: z.string().min(1),
|
|
4231
|
+
/**
|
|
4232
|
+
* Optional immutable Git object fence. Repository materialization must fail
|
|
4233
|
+
* when the checked-out HEAD is not this exact commit. Event-driven sessions
|
|
4234
|
+
* use it to prevent a mutable PR branch from changing underneath a review.
|
|
4235
|
+
*/
|
|
4236
|
+
expectedCommitSha: z
|
|
4237
|
+
.string()
|
|
4238
|
+
.regex(/^[0-9a-f]{40}$/)
|
|
4239
|
+
.optional(),
|
|
3559
4240
|
mountPath: z.string().min(1).optional(),
|
|
3560
4241
|
subpath: z.string().min(1).optional(),
|
|
3561
4242
|
provider: GitCredentialProvider.optional(),
|
|
4243
|
+
connectionType: z.literal("github_personal").optional(),
|
|
3562
4244
|
credentialBindingId: GitCredentialBindingId.optional(),
|
|
3563
4245
|
access: GitRepositoryAccess.optional(),
|
|
3564
4246
|
repositoryId: GitProviderRepositoryId.optional(),
|
|
@@ -3718,6 +4400,8 @@ export type FileResourceRef = z.infer<typeof FileResourceRef>;
|
|
|
3718
4400
|
* reconstruct the same typed attachment input after a model switch or retry.
|
|
3719
4401
|
*/
|
|
3720
4402
|
export const MODEL_ATTACHMENT_REFS_FIELD = "opengeni_attachment_refs" as const;
|
|
4403
|
+
/** Private marker for the compact attachment-reference carrier created by compaction. */
|
|
4404
|
+
export const MODEL_ATTACHMENT_CATALOG_MARKER = "opengeni_attachment_catalog" as const;
|
|
3721
4405
|
/**
|
|
3722
4406
|
* Structured timeline annotations retained beside the deterministic user-text
|
|
3723
4407
|
* projection in canonical history. Provider adapters remove this OpenGeni
|
|
@@ -3817,6 +4501,25 @@ export function defaultRepositoryMountPath(
|
|
|
3817
4501
|
);
|
|
3818
4502
|
}
|
|
3819
4503
|
|
|
4504
|
+
/** Durable SDK/UI artifact root. Provisioned boxes also mount this path;
|
|
4505
|
+
* Connected Machine execution does not treat it as an alias. */
|
|
4506
|
+
export const VIRTUAL_WORKSPACE_ROOT = "/workspace" as const;
|
|
4507
|
+
|
|
4508
|
+
/**
|
|
4509
|
+
* Cwd-relative path for shell/exec prompts. Durable receipts and `sandbox:` UI
|
|
4510
|
+
* links keep the durable `/workspace/...` form. Tool receipts use the relative
|
|
4511
|
+
* projection so they remain usable from either a provisioned box root or a
|
|
4512
|
+
* Connected Machine's truthful host-native cwd.
|
|
4513
|
+
*/
|
|
4514
|
+
export function sandboxShellPath(virtualPath: string): string {
|
|
4515
|
+
if (virtualPath === VIRTUAL_WORKSPACE_ROOT) return ".";
|
|
4516
|
+
if (virtualPath.startsWith(`${VIRTUAL_WORKSPACE_ROOT}/`)) {
|
|
4517
|
+
const relative = virtualPath.slice(VIRTUAL_WORKSPACE_ROOT.length + 1);
|
|
4518
|
+
return relative.length > 0 ? relative : ".";
|
|
4519
|
+
}
|
|
4520
|
+
return virtualPath;
|
|
4521
|
+
}
|
|
4522
|
+
|
|
3820
4523
|
/** Resolve the exact mount used by API normalization, manifests, and clone hooks. */
|
|
3821
4524
|
export const DEFAULT_FILE_RESOURCE_MOUNT_ROOT = ".opengeni/files" as const;
|
|
3822
4525
|
|
|
@@ -3985,6 +4688,9 @@ export const Document = z.object({
|
|
|
3985
4688
|
authorityKind: DocumentAuthorityKind,
|
|
3986
4689
|
authorityWorkspaceId: z.string().uuid().nullable(),
|
|
3987
4690
|
authoritySubjectId: z.string().nullable(),
|
|
4691
|
+
// Opaque handle used by the owning human to issue explicit personal-scope
|
|
4692
|
+
// grants. Organization/workspace and legacy anchored personal rows are null.
|
|
4693
|
+
authorityId: z.string().uuid().nullable().optional(),
|
|
3988
4694
|
visibility: DocumentVisibility,
|
|
3989
4695
|
createdBy: z.string().nullable(),
|
|
3990
4696
|
agentAccess: z.boolean(),
|
|
@@ -4137,6 +4843,77 @@ export const MoveDocumentRequest = z.object({
|
|
|
4137
4843
|
});
|
|
4138
4844
|
export type MoveDocumentRequest = z.infer<typeof MoveDocumentRequest>;
|
|
4139
4845
|
|
|
4846
|
+
export const DocumentAuthorityTuple = z.object({
|
|
4847
|
+
kind: DocumentAuthorityKind,
|
|
4848
|
+
workspaceId: z.string().uuid().nullable(),
|
|
4849
|
+
subjectId: z.string().nullable(),
|
|
4850
|
+
authorityId: z.string().uuid().nullable(),
|
|
4851
|
+
});
|
|
4852
|
+
export type DocumentAuthorityTuple = z.infer<typeof DocumentAuthorityTuple>;
|
|
4853
|
+
|
|
4854
|
+
export const ReclassifyDocumentAuthorityRequest = z.object({
|
|
4855
|
+
operationId: z.string().uuid(),
|
|
4856
|
+
expectedAuthority: DocumentAuthorityTuple,
|
|
4857
|
+
targetAuthorityKind: DocumentAuthorityKind,
|
|
4858
|
+
});
|
|
4859
|
+
export type ReclassifyDocumentAuthorityRequest = z.infer<typeof ReclassifyDocumentAuthorityRequest>;
|
|
4860
|
+
|
|
4861
|
+
export const DocumentAuthorityReclassification = z.object({
|
|
4862
|
+
operationId: z.string().uuid(),
|
|
4863
|
+
documentId: z.string().uuid(),
|
|
4864
|
+
previousAuthority: DocumentAuthorityTuple,
|
|
4865
|
+
authority: DocumentAuthorityTuple,
|
|
4866
|
+
createdAt: z.string().datetime({ offset: true }),
|
|
4867
|
+
});
|
|
4868
|
+
export type DocumentAuthorityReclassification = z.infer<typeof DocumentAuthorityReclassification>;
|
|
4869
|
+
|
|
4870
|
+
export const DOCUMENT_AUTHORITY_RECLASSIFICATION_LIST_DEFAULT_LIMIT = 50;
|
|
4871
|
+
export const DOCUMENT_AUTHORITY_RECLASSIFICATION_LIST_MAX_LIMIT = 100;
|
|
4872
|
+
export const DOCUMENT_AUTHORITY_RECLASSIFICATION_CURSOR_MAX_CHARS = 1_024;
|
|
4873
|
+
|
|
4874
|
+
export const ListDocumentAuthorityReclassificationsQuery = z.object({
|
|
4875
|
+
limit: z.coerce
|
|
4876
|
+
.number()
|
|
4877
|
+
.int()
|
|
4878
|
+
.positive()
|
|
4879
|
+
.max(DOCUMENT_AUTHORITY_RECLASSIFICATION_LIST_MAX_LIMIT)
|
|
4880
|
+
.default(DOCUMENT_AUTHORITY_RECLASSIFICATION_LIST_DEFAULT_LIMIT),
|
|
4881
|
+
cursor: z.string().min(1).max(DOCUMENT_AUTHORITY_RECLASSIFICATION_CURSOR_MAX_CHARS).optional(),
|
|
4882
|
+
});
|
|
4883
|
+
export type ListDocumentAuthorityReclassificationsQuery = z.infer<
|
|
4884
|
+
typeof ListDocumentAuthorityReclassificationsQuery
|
|
4885
|
+
>;
|
|
4886
|
+
|
|
4887
|
+
export const ListDocumentAuthorityReclassificationsResponse = z.object({
|
|
4888
|
+
receipts: z.array(DocumentAuthorityReclassification),
|
|
4889
|
+
hasMore: z.boolean(),
|
|
4890
|
+
nextCursor: z.string().max(DOCUMENT_AUTHORITY_RECLASSIFICATION_CURSOR_MAX_CHARS).nullable(),
|
|
4891
|
+
});
|
|
4892
|
+
export type ListDocumentAuthorityReclassificationsResponse = z.infer<
|
|
4893
|
+
typeof ListDocumentAuthorityReclassificationsResponse
|
|
4894
|
+
>;
|
|
4895
|
+
|
|
4896
|
+
export const RunDocumentDefaultCollectionBackfillRequest = z.object({
|
|
4897
|
+
runId: z.string().uuid(),
|
|
4898
|
+
operationId: z.string().uuid(),
|
|
4899
|
+
batchSize: z.number().int().min(1).max(100).default(50),
|
|
4900
|
+
});
|
|
4901
|
+
export type RunDocumentDefaultCollectionBackfillRequest = z.infer<
|
|
4902
|
+
typeof RunDocumentDefaultCollectionBackfillRequest
|
|
4903
|
+
>;
|
|
4904
|
+
|
|
4905
|
+
export const DocumentDefaultCollectionBackfill = z.object({
|
|
4906
|
+
runId: z.string().uuid(),
|
|
4907
|
+
operationId: z.string().uuid(),
|
|
4908
|
+
status: z.enum(["running", "completed"]),
|
|
4909
|
+
lastWorkspaceId: z.string().uuid().nullable(),
|
|
4910
|
+
processedCount: z.number().int().nonnegative(),
|
|
4911
|
+
createdCount: z.number().int().nonnegative(),
|
|
4912
|
+
adoptedCount: z.number().int().nonnegative(),
|
|
4913
|
+
completedAt: z.string().datetime({ offset: true }).nullable(),
|
|
4914
|
+
});
|
|
4915
|
+
export type DocumentDefaultCollectionBackfill = z.infer<typeof DocumentDefaultCollectionBackfill>;
|
|
4916
|
+
|
|
4140
4917
|
export const DocumentSearchRequest = z.object({
|
|
4141
4918
|
query: z.string().min(1),
|
|
4142
4919
|
baseIds: z.array(z.string().uuid()).optional(),
|
|
@@ -4282,9 +5059,15 @@ export type WorkspaceMemorySearchResponse = z.infer<typeof WorkspaceMemorySearch
|
|
|
4282
5059
|
export const ToolRef = z.object({
|
|
4283
5060
|
kind: z.literal("mcp"),
|
|
4284
5061
|
id: z.string().min(1),
|
|
5062
|
+
// Session-scoped startup choice. `true` prepares this server's authorized
|
|
5063
|
+
// schemas before the first model request; absent/false keeps it behind
|
|
5064
|
+
// progressive discovery. This never grants a server or tool permission.
|
|
5065
|
+
eager: z.boolean().optional(),
|
|
4285
5066
|
// Non-fatal-on-connect marker for MCP server refs that can degrade
|
|
4286
5067
|
// gracefully. On new input, absent/false is STRICT: the id must be configured
|
|
4287
|
-
// and an unavailable registered server fails
|
|
5068
|
+
// and an unavailable registered server fails closed when its preparation is
|
|
5069
|
+
// demanded. Only the independent eager marker makes that a startup failure.
|
|
5070
|
+
// Persisted refs are
|
|
4288
5071
|
// intersected with the current registry at each turn boundary, so a server
|
|
4289
5072
|
// disconnected after admission is retained in policy/audit truth but skipped
|
|
4290
5073
|
// until it is registered again. `optional:true` additionally makes runtime
|
|
@@ -4481,10 +5264,14 @@ export function mergeToolRefs(existing: ToolRef[], additions: ToolRef[]): ToolRe
|
|
|
4481
5264
|
// strict occurrence upgrades the merged ref so an unavailable server fails
|
|
4482
5265
|
// the turn. This preserves the fail-loud default when defaults, packs, and
|
|
4483
5266
|
// per-turn tool selections are combined.
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
5267
|
+
const optional = prior.optional === true && tool.optional === true ? true : undefined;
|
|
5268
|
+
const eager = prior.eager === true || tool.eager === true ? true : undefined;
|
|
5269
|
+
byKey.set(key, {
|
|
5270
|
+
kind: "mcp",
|
|
5271
|
+
id: prior.id,
|
|
5272
|
+
...(optional ? { optional } : {}),
|
|
5273
|
+
...(eager ? { eager } : {}),
|
|
5274
|
+
});
|
|
4488
5275
|
}
|
|
4489
5276
|
return order.map((key) => byKey.get(key)!);
|
|
4490
5277
|
}
|
|
@@ -4638,6 +5425,9 @@ export const SESSION_GOAL_TEXT_MAX_BYTES = 8 * 1024;
|
|
|
4638
5425
|
export const SESSION_GOAL_SUCCESS_CRITERIA_MAX_BYTES = 8 * 1024;
|
|
4639
5426
|
export const SESSION_GOAL_RATIONALE_MAX_BYTES = 2 * 1024;
|
|
4640
5427
|
export const SESSION_GOAL_PROGRESS_MAX_BYTES = 4 * 1024;
|
|
5428
|
+
export const SESSION_GOAL_ROOT_CONSTRAINT_MAX_BYTES = 512;
|
|
5429
|
+
export const SESSION_GOAL_ROOT_CONSTRAINTS_MAX_BYTES = 4 * 1024;
|
|
5430
|
+
export const SESSION_GOAL_ROOT_CONSTRAINTS_MAX_ITEMS = 16;
|
|
4641
5431
|
|
|
4642
5432
|
export function sessionGoalUtf8Bytes(value: string): number {
|
|
4643
5433
|
return new TextEncoder().encode(value).byteLength;
|
|
@@ -4652,6 +5442,43 @@ function boundedSessionGoalString(maxBytes: number, field: string) {
|
|
|
4652
5442
|
});
|
|
4653
5443
|
}
|
|
4654
5444
|
|
|
5445
|
+
function compareUtf8(left: string, right: string): number {
|
|
5446
|
+
const encoder = new TextEncoder();
|
|
5447
|
+
const leftBytes = encoder.encode(left);
|
|
5448
|
+
const rightBytes = encoder.encode(right);
|
|
5449
|
+
const length = Math.min(leftBytes.length, rightBytes.length);
|
|
5450
|
+
for (let index = 0; index < length; index += 1) {
|
|
5451
|
+
const difference = leftBytes[index]! - rightBytes[index]!;
|
|
5452
|
+
if (difference !== 0) return difference;
|
|
5453
|
+
}
|
|
5454
|
+
return leftBytes.length - rightBytes.length;
|
|
5455
|
+
}
|
|
5456
|
+
|
|
5457
|
+
export function normalizeSessionGoalRootConstraints(values: readonly string[]): string[] {
|
|
5458
|
+
// PostgreSQL btrim(text) removes U+0020 at both ends. Keep the public
|
|
5459
|
+
// projector byte-equivalent with the storage trigger instead of using
|
|
5460
|
+
// JavaScript trim(), whose Unicode whitespace set is broader.
|
|
5461
|
+
return [...new Set(values.map((value) => value.replace(/^ +| +$/g, "")))].sort(compareUtf8);
|
|
5462
|
+
}
|
|
5463
|
+
|
|
5464
|
+
export const SessionGoalRootConstraintsWrite = z
|
|
5465
|
+
.array(boundedSessionGoalString(SESSION_GOAL_ROOT_CONSTRAINT_MAX_BYTES, "goal root constraint"))
|
|
5466
|
+
.transform(normalizeSessionGoalRootConstraints)
|
|
5467
|
+
.pipe(
|
|
5468
|
+
z
|
|
5469
|
+
.array(z.string().min(1))
|
|
5470
|
+
.max(SESSION_GOAL_ROOT_CONSTRAINTS_MAX_ITEMS)
|
|
5471
|
+
.refine(
|
|
5472
|
+
(values) =>
|
|
5473
|
+
values.reduce((total, value) => total + sessionGoalUtf8Bytes(value), 0) <=
|
|
5474
|
+
SESSION_GOAL_ROOT_CONSTRAINTS_MAX_BYTES,
|
|
5475
|
+
{
|
|
5476
|
+
message: `goal root constraints exceed ${SESSION_GOAL_ROOT_CONSTRAINTS_MAX_BYTES} aggregate UTF-8 bytes`,
|
|
5477
|
+
},
|
|
5478
|
+
),
|
|
5479
|
+
);
|
|
5480
|
+
export type SessionGoalRootConstraintsWrite = z.infer<typeof SessionGoalRootConstraintsWrite>;
|
|
5481
|
+
|
|
4655
5482
|
const SessionGoalTextWrite = boundedSessionGoalString(SESSION_GOAL_TEXT_MAX_BYTES, "goal text");
|
|
4656
5483
|
const SessionGoalSuccessCriteriaWrite = boundedSessionGoalString(
|
|
4657
5484
|
SESSION_GOAL_SUCCESS_CRITERIA_MAX_BYTES,
|
|
@@ -4670,6 +5497,7 @@ export const SessionGoalSnapshot = z.discriminatedUnion("state", [
|
|
|
4670
5497
|
objectiveRevision: z.number().int().positive(),
|
|
4671
5498
|
text: SessionGoalTextWrite,
|
|
4672
5499
|
successCriteria: SessionGoalSuccessCriteriaWrite.nullable(),
|
|
5500
|
+
rootConstraints: SessionGoalRootConstraintsWrite.default([]),
|
|
4673
5501
|
mutationPolicy: SessionGoalMutationPolicy,
|
|
4674
5502
|
capturedAt: z.string(),
|
|
4675
5503
|
}),
|
|
@@ -4688,22 +5516,57 @@ export const SessionGoalRevision = z.object({
|
|
|
4688
5516
|
resultObjectiveRevision: z.number().int().positive().nullable(),
|
|
4689
5517
|
text: z.string().min(1),
|
|
4690
5518
|
successCriteria: z.string().nullable(),
|
|
5519
|
+
rootConstraints: z.array(z.string().min(1)).default([]),
|
|
4691
5520
|
mutationPolicy: SessionGoalMutationPolicy,
|
|
4692
5521
|
rationale: z.string().min(1),
|
|
4693
5522
|
actor: z.enum(["agent", "api", "scheduled_task"]),
|
|
4694
5523
|
actorTurnId: z.string().uuid().nullable(),
|
|
4695
5524
|
actorAttemptId: z.string().uuid().nullable(),
|
|
4696
5525
|
proposalId: z.string().uuid().nullable(),
|
|
5526
|
+
rollbackOfRevisionId: z.string().uuid().nullable(),
|
|
4697
5527
|
createdAt: z.string(),
|
|
4698
5528
|
});
|
|
4699
5529
|
export type SessionGoalRevision = z.infer<typeof SessionGoalRevision>;
|
|
4700
5530
|
|
|
5531
|
+
export const SESSION_GOAL_REVISION_LIST_DEFAULT_LIMIT = 50;
|
|
5532
|
+
export const SESSION_GOAL_REVISION_LIST_MAX_LIMIT = 100;
|
|
5533
|
+
|
|
5534
|
+
export const ListSessionGoalRevisionsQuery = z.object({
|
|
5535
|
+
limit: z.coerce
|
|
5536
|
+
.number()
|
|
5537
|
+
.int()
|
|
5538
|
+
.positive()
|
|
5539
|
+
.max(SESSION_GOAL_REVISION_LIST_MAX_LIMIT)
|
|
5540
|
+
.default(SESSION_GOAL_REVISION_LIST_DEFAULT_LIMIT),
|
|
5541
|
+
before: z.string().uuid().optional(),
|
|
5542
|
+
});
|
|
5543
|
+
export type ListSessionGoalRevisionsQuery = z.infer<typeof ListSessionGoalRevisionsQuery>;
|
|
5544
|
+
|
|
5545
|
+
export const ListSessionGoalRevisionsResponse = z.object({
|
|
5546
|
+
revisions: z.array(SessionGoalRevision),
|
|
5547
|
+
hasMore: z.boolean(),
|
|
5548
|
+
nextCursor: z.string().uuid().nullable(),
|
|
5549
|
+
});
|
|
5550
|
+
export type ListSessionGoalRevisionsResponse = z.infer<typeof ListSessionGoalRevisionsResponse>;
|
|
5551
|
+
|
|
4701
5552
|
export const ApplySessionGoalRevisionRequest = z.object({
|
|
4702
5553
|
expectedObjectiveRevision: z.number().int().positive(),
|
|
4703
5554
|
rationale: SessionGoalRationaleWrite.optional(),
|
|
4704
5555
|
});
|
|
4705
5556
|
export type ApplySessionGoalRevisionRequest = z.infer<typeof ApplySessionGoalRevisionRequest>;
|
|
4706
5557
|
|
|
5558
|
+
export const RejectSessionGoalRevisionRequest = z.object({
|
|
5559
|
+
expectedObjectiveRevision: z.number().int().positive(),
|
|
5560
|
+
rationale: SessionGoalRationaleWrite,
|
|
5561
|
+
});
|
|
5562
|
+
export type RejectSessionGoalRevisionRequest = z.infer<typeof RejectSessionGoalRevisionRequest>;
|
|
5563
|
+
|
|
5564
|
+
export const RollbackSessionGoalRevisionRequest = z.object({
|
|
5565
|
+
expectedObjectiveRevision: z.number().int().positive(),
|
|
5566
|
+
rationale: SessionGoalRationaleWrite,
|
|
5567
|
+
});
|
|
5568
|
+
export type RollbackSessionGoalRevisionRequest = z.infer<typeof RollbackSessionGoalRevisionRequest>;
|
|
5569
|
+
|
|
4707
5570
|
export const SessionGoalPausedReason = z.enum([
|
|
4708
5571
|
"agent",
|
|
4709
5572
|
"user_pause",
|
|
@@ -4735,10 +5598,41 @@ export const SessionGoalContinuationReason = z.enum([
|
|
|
4735
5598
|
"provider_backpressure",
|
|
4736
5599
|
"session_cancelled",
|
|
4737
5600
|
"system_work_pending",
|
|
5601
|
+
"held_for_input",
|
|
5602
|
+
// Idle backoff: consecutive no-input continuations are paced, and the next
|
|
5603
|
+
// evaluation is armed as a delayed workflow wake at `nextAttemptAt`.
|
|
5604
|
+
"backoff_pending",
|
|
4738
5605
|
"missing_obligation",
|
|
4739
5606
|
]);
|
|
4740
5607
|
export type SessionGoalContinuationReason = z.infer<typeof SessionGoalContinuationReason>;
|
|
4741
5608
|
|
|
5609
|
+
/**
|
|
5610
|
+
* Why a paused goal became active again. `api` is the operator PATCH; the
|
|
5611
|
+
* system resumes only a `max_auto_continuations` pause, and only because new
|
|
5612
|
+
* external input arrived: a child result, scheduled occurrence, media result,
|
|
5613
|
+
* Agent message, Agent Steer, or human/API Send/Steer. The cap is pacing,
|
|
5614
|
+
* never user intent, so a `user_pause`/`api`/`agent`/`limits` pause is never
|
|
5615
|
+
* auto-resumed.
|
|
5616
|
+
*/
|
|
5617
|
+
export const SessionGoalResumedReason = z.enum(["api", "external_input"]);
|
|
5618
|
+
export type SessionGoalResumedReason = z.infer<typeof SessionGoalResumedReason>;
|
|
5619
|
+
|
|
5620
|
+
export const SessionGoalResumedEventPayload = z
|
|
5621
|
+
.object({
|
|
5622
|
+
goalId: z.string().uuid(),
|
|
5623
|
+
actor: z.enum(["api", "system"]),
|
|
5624
|
+
reason: SessionGoalResumedReason,
|
|
5625
|
+
cause: z
|
|
5626
|
+
.object({
|
|
5627
|
+
kind: z.string().min(1),
|
|
5628
|
+
updateId: z.string().uuid().optional(),
|
|
5629
|
+
turnId: z.string().uuid().optional(),
|
|
5630
|
+
})
|
|
5631
|
+
.optional(),
|
|
5632
|
+
})
|
|
5633
|
+
.passthrough();
|
|
5634
|
+
export type SessionGoalResumedEventPayload = z.infer<typeof SessionGoalResumedEventPayload>;
|
|
5635
|
+
|
|
4742
5636
|
export const SessionGoalContinuation = z.object({
|
|
4743
5637
|
state: SessionGoalContinuationState,
|
|
4744
5638
|
reason: SessionGoalContinuationReason,
|
|
@@ -4746,6 +5640,12 @@ export const SessionGoalContinuation = z.object({
|
|
|
4746
5640
|
observedRevision: z.number().int().nonnegative(),
|
|
4747
5641
|
nextAttemptAt: z.string().datetime({ offset: true }).nullable(),
|
|
4748
5642
|
lastError: z.string().nullable(),
|
|
5643
|
+
/**
|
|
5644
|
+
* The agent's stated reason for a `held_for_input` hold (`goal_wait`), so a
|
|
5645
|
+
* human can see why the goal is waiting and until when (`nextAttemptAt`).
|
|
5646
|
+
* Null for every other state; omitted by older servers.
|
|
5647
|
+
*/
|
|
5648
|
+
holdReason: z.string().nullable().optional(),
|
|
4749
5649
|
});
|
|
4750
5650
|
export type SessionGoalContinuation = z.infer<typeof SessionGoalContinuation>;
|
|
4751
5651
|
|
|
@@ -4757,6 +5657,7 @@ export const SessionGoal = z.object({
|
|
|
4757
5657
|
status: SessionGoalStatus,
|
|
4758
5658
|
text: z.string(),
|
|
4759
5659
|
successCriteria: z.string().nullable(),
|
|
5660
|
+
rootConstraints: z.array(z.string().min(1)).default([]),
|
|
4760
5661
|
evidence: z.string().nullable(),
|
|
4761
5662
|
rationale: z.string().nullable(),
|
|
4762
5663
|
pausedReason: z.string().nullable(),
|
|
@@ -4779,6 +5680,7 @@ export type SessionGoal = z.infer<typeof SessionGoal>;
|
|
|
4779
5680
|
export const GoalSpec = z.object({
|
|
4780
5681
|
text: SessionGoalTextWrite,
|
|
4781
5682
|
successCriteria: SessionGoalSuccessCriteriaWrite.optional(),
|
|
5683
|
+
rootConstraints: SessionGoalRootConstraintsWrite.optional(),
|
|
4782
5684
|
maxAutoContinuations: z.number().int().positive().optional(),
|
|
4783
5685
|
mutationPolicy: SessionGoalMutationPolicy.optional(),
|
|
4784
5686
|
});
|
|
@@ -4792,6 +5694,7 @@ export const UpdateSessionGoalRequest = z.union([
|
|
|
4792
5694
|
z.object({
|
|
4793
5695
|
text: SessionGoalTextWrite,
|
|
4794
5696
|
successCriteria: SessionGoalSuccessCriteriaWrite.nullable().optional(),
|
|
5697
|
+
rootConstraints: SessionGoalRootConstraintsWrite.optional(),
|
|
4795
5698
|
mutationPolicy: SessionGoalMutationPolicy.optional(),
|
|
4796
5699
|
rationale: SessionGoalRationaleWrite,
|
|
4797
5700
|
expectedObjectiveRevision: z.number().int().positive(),
|
|
@@ -4839,6 +5742,40 @@ export const UpdateSessionPinRequest = z.object({
|
|
|
4839
5742
|
});
|
|
4840
5743
|
export type UpdateSessionPinRequest = z.infer<typeof UpdateSessionPinRequest>;
|
|
4841
5744
|
|
|
5745
|
+
/**
|
|
5746
|
+
* A member's durable follow-up state for one session. Reading the session does
|
|
5747
|
+
* not acknowledge it: `unread` changes only through this explicit mutation.
|
|
5748
|
+
* A foreground reader may provide `acknowledgedThroughSequence` with
|
|
5749
|
+
* `unread: false` so later server events remain unread instead of being
|
|
5750
|
+
* consumed by a delayed acknowledgement request.
|
|
5751
|
+
* `activelyWorking` is an independent personal label that survives read state.
|
|
5752
|
+
*/
|
|
5753
|
+
export const UpdateSessionAttentionRequest = z
|
|
5754
|
+
.object({
|
|
5755
|
+
unread: z.boolean().optional(),
|
|
5756
|
+
acknowledgedThroughSequence: z.number().int().nonnegative().optional(),
|
|
5757
|
+
activelyWorking: z.boolean().optional(),
|
|
5758
|
+
expectedVersion: z.number().int().nonnegative().optional(),
|
|
5759
|
+
})
|
|
5760
|
+
.strict()
|
|
5761
|
+
.refine((value) => value.unread !== undefined || value.activelyWorking !== undefined, {
|
|
5762
|
+
message: "unread or activelyWorking is required",
|
|
5763
|
+
})
|
|
5764
|
+
.refine((value) => value.acknowledgedThroughSequence === undefined || value.unread === false, {
|
|
5765
|
+
message: "acknowledgedThroughSequence requires unread false",
|
|
5766
|
+
path: ["acknowledgedThroughSequence"],
|
|
5767
|
+
});
|
|
5768
|
+
export type UpdateSessionAttentionRequest = z.infer<typeof UpdateSessionAttentionRequest>;
|
|
5769
|
+
|
|
5770
|
+
/** A member's personal archive state for a root chat. */
|
|
5771
|
+
export const UpdateSessionArchiveRequest = z
|
|
5772
|
+
.object({
|
|
5773
|
+
archived: z.boolean(),
|
|
5774
|
+
expectedVersion: z.number().int().nonnegative().optional(),
|
|
5775
|
+
})
|
|
5776
|
+
.strict();
|
|
5777
|
+
export type UpdateSessionArchiveRequest = z.infer<typeof UpdateSessionArchiveRequest>;
|
|
5778
|
+
|
|
4842
5779
|
// Operator context controls (slash-command palette: /clear, /compact). These
|
|
4843
5780
|
// are session/operator actions, NOT a structured way to talk to the agent —
|
|
4844
5781
|
// the human↔agent channel stays plain chat. Both require `sessions:control`.
|
|
@@ -4893,6 +5830,34 @@ export function isClearedRunStateBlob(serialized: string | null | undefined): bo
|
|
|
4893
5830
|
}
|
|
4894
5831
|
}
|
|
4895
5832
|
|
|
5833
|
+
/**
|
|
5834
|
+
* Sentinel written on a requires_action pause. Resume must not call
|
|
5835
|
+
* `RunState.fromString` on it; the open suffix on `session_pending_tool_calls`
|
|
5836
|
+
* plus paired history is the resume authority.
|
|
5837
|
+
*/
|
|
5838
|
+
export const OPEN_SUFFIX_RUN_STATE_MARKER = "$opengeniOpenSuffix" as const;
|
|
5839
|
+
|
|
5840
|
+
/** Canonical sentinel serializedRunState for a requires_action pause. */
|
|
5841
|
+
export const OPEN_SUFFIX_RUN_STATE_BLOB = JSON.stringify({
|
|
5842
|
+
[OPEN_SUFFIX_RUN_STATE_MARKER]: true,
|
|
5843
|
+
});
|
|
5844
|
+
|
|
5845
|
+
export function isOpenSuffixRunStateBlob(serialized: string | null | undefined): boolean {
|
|
5846
|
+
if (!serialized) {
|
|
5847
|
+
return false;
|
|
5848
|
+
}
|
|
5849
|
+
try {
|
|
5850
|
+
const parsed = JSON.parse(serialized) as unknown;
|
|
5851
|
+
return (
|
|
5852
|
+
typeof parsed === "object" &&
|
|
5853
|
+
parsed !== null &&
|
|
5854
|
+
(parsed as Record<string, unknown>)[OPEN_SUFFIX_RUN_STATE_MARKER] === true
|
|
5855
|
+
);
|
|
5856
|
+
} catch {
|
|
5857
|
+
return false;
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
|
|
4896
5861
|
/** Trigger conversation compaction now. No body fields today (forward-room). */
|
|
4897
5862
|
export const CompactSessionContextRequest = z.object({}).strict();
|
|
4898
5863
|
export type CompactSessionContextRequest = z.infer<typeof CompactSessionContextRequest>;
|
|
@@ -5174,7 +6139,12 @@ export type WorkspaceRealtimeModelCatalogResponse = z.infer<
|
|
|
5174
6139
|
export const SessionRealtimeState = z.enum(["active", "ended"]);
|
|
5175
6140
|
export type SessionRealtimeState = z.infer<typeof SessionRealtimeState>;
|
|
5176
6141
|
|
|
5177
|
-
export const SessionRealtimeEndReason = z.enum([
|
|
6142
|
+
export const SessionRealtimeEndReason = z.enum([
|
|
6143
|
+
"user_stop",
|
|
6144
|
+
"browser_unload",
|
|
6145
|
+
"lease_expired",
|
|
6146
|
+
"authority_revoked",
|
|
6147
|
+
]);
|
|
5178
6148
|
export type SessionRealtimeEndReason = z.infer<typeof SessionRealtimeEndReason>;
|
|
5179
6149
|
|
|
5180
6150
|
export const SessionRealtimeMode = z.object({
|
|
@@ -5242,6 +6212,9 @@ export const SessionAuthorizationOperation = z.enum([
|
|
|
5242
6212
|
"session.secret.read",
|
|
5243
6213
|
"session.codemode.call",
|
|
5244
6214
|
"session.pin.write",
|
|
6215
|
+
"session.attention.write",
|
|
6216
|
+
"session.archive.write",
|
|
6217
|
+
"session.delete",
|
|
5245
6218
|
"session.codex_account.write",
|
|
5246
6219
|
"session.realtime.start",
|
|
5247
6220
|
"session.realtime.control",
|
|
@@ -5258,6 +6231,7 @@ export const SessionAuthorizationOperation = z.enum([
|
|
|
5258
6231
|
"session.child.create",
|
|
5259
6232
|
"session.visibility.write",
|
|
5260
6233
|
"session.fork.create",
|
|
6234
|
+
"session.personal_resource.grant",
|
|
5261
6235
|
]);
|
|
5262
6236
|
export type SessionAuthorizationOperation = z.infer<typeof SessionAuthorizationOperation>;
|
|
5263
6237
|
|
|
@@ -5581,23 +6555,64 @@ export function renderTimelineAnnotationsForModel(
|
|
|
5581
6555
|
}
|
|
5582
6556
|
|
|
5583
6557
|
export const MODEL_CONTEXT_LABEL = "[Application context attached to this user message]" as const;
|
|
6558
|
+
export const SESSION_GOAL_CONTEXT_LABEL =
|
|
6559
|
+
"[Session goal frozen when this turn was accepted]" as const;
|
|
6560
|
+
|
|
6561
|
+
/**
|
|
6562
|
+
* Render the exact goal authority frozen with one accepted logical turn. Goal
|
|
6563
|
+
* state belongs at the chronological input boundary, not in the mutable
|
|
6564
|
+
* Agent.instructions prefix.
|
|
6565
|
+
*/
|
|
6566
|
+
export function renderSessionGoalContext(snapshot?: SessionGoalSnapshot): string | undefined {
|
|
6567
|
+
if (!snapshot || snapshot.state === "none") return undefined;
|
|
6568
|
+
const rootConstraints = snapshot.rootConstraints.length
|
|
6569
|
+
? `\nRoot constraints (must remain satisfied):\n${snapshot.rootConstraints.map((constraint) => `- ${constraint}`).join("\n")}`
|
|
6570
|
+
: "";
|
|
6571
|
+
if (snapshot.state === "completed") {
|
|
6572
|
+
return `Previous session goal (frozen at logical-turn acceptance; objective revision ${snapshot.objectiveRevision}; status completed): ${snapshot.text}\nSuccess criteria: ${snapshot.successCriteria ?? "none specified"}.${rootConstraints} This goal is complete and remains as historical context. If the user provides a new long-running objective, create it with opengeni__goal_set; goal_update cannot revise a completed goal.`;
|
|
6573
|
+
}
|
|
6574
|
+
const policy =
|
|
6575
|
+
snapshot.mutationPolicy === "review_changes"
|
|
6576
|
+
? "Semantic changes are proposals until a user applies them."
|
|
6577
|
+
: snapshot.mutationPolicy === "preserve_intent"
|
|
6578
|
+
? "You may directly refine wording without changing intent; adaptations and replacements are proposals until a user applies them."
|
|
6579
|
+
: "You may autonomously refine, adapt, or replace the goal when explicit user direction or material new evidence justifies it.";
|
|
6580
|
+
return `Standing session goal (frozen at logical-turn acceptance; objective revision ${snapshot.objectiveRevision}; status ${snapshot.state}): ${snapshot.text}\nSuccess criteria: ${snapshot.successCriteria ?? "none specified"}.${rootConstraints}\nMutation policy: ${snapshot.mutationPolicy}. ${policy} Treat later ordinary messages as additional context unless they explicitly redirect this objective. Root constraints are user/API authority and cannot be widened, removed, or rewritten by an agent. Semantic goal changes use opengeni__goal_update with the expected objective revision, change kind, and rationale.`;
|
|
6581
|
+
}
|
|
5584
6582
|
|
|
5585
6583
|
/**
|
|
5586
6584
|
* Build one canonical user-role message body. `modelContext` is ordinary
|
|
5587
|
-
* message content
|
|
5588
|
-
*
|
|
5589
|
-
*
|
|
6585
|
+
* message content, while `goalSnapshot` is the exact goal authority frozen at
|
|
6586
|
+
* turn acceptance. Both remain in the visible message's chronological
|
|
6587
|
+
* position, and presentation layers may omit their leading parts.
|
|
5590
6588
|
*/
|
|
5591
6589
|
export function renderUserMessageContentForModel(
|
|
5592
6590
|
text: string,
|
|
5593
6591
|
annotations: readonly TimelineAnnotation[],
|
|
5594
6592
|
modelContext?: string | null,
|
|
6593
|
+
goalSnapshot?: SessionGoalSnapshot,
|
|
5595
6594
|
): string | Array<{ type: "input_text"; text: string }> {
|
|
5596
6595
|
const visibleContent = renderTimelineAnnotationsForModel(text, annotations);
|
|
5597
6596
|
const context = modelContext?.trim();
|
|
5598
|
-
|
|
6597
|
+
const goalContext = renderSessionGoalContext(goalSnapshot);
|
|
6598
|
+
if (!context && !goalContext) return visibleContent;
|
|
5599
6599
|
return [
|
|
5600
|
-
|
|
6600
|
+
...(goalContext
|
|
6601
|
+
? [
|
|
6602
|
+
{
|
|
6603
|
+
type: "input_text" as const,
|
|
6604
|
+
text: `${SESSION_GOAL_CONTEXT_LABEL}\n${goalContext}`,
|
|
6605
|
+
},
|
|
6606
|
+
]
|
|
6607
|
+
: []),
|
|
6608
|
+
...(context
|
|
6609
|
+
? [
|
|
6610
|
+
{
|
|
6611
|
+
type: "input_text" as const,
|
|
6612
|
+
text: `${MODEL_CONTEXT_LABEL}\n${context}`,
|
|
6613
|
+
},
|
|
6614
|
+
]
|
|
6615
|
+
: []),
|
|
5601
6616
|
{ type: "input_text", text: visibleContent },
|
|
5602
6617
|
];
|
|
5603
6618
|
}
|
|
@@ -5622,7 +6637,7 @@ export const SessionTurn = z
|
|
|
5622
6637
|
toolsProvided: z.boolean().optional(),
|
|
5623
6638
|
model: z.string().min(1),
|
|
5624
6639
|
reasoningEffort: ReasoningEffort,
|
|
5625
|
-
latencyMode: LatencyMode
|
|
6640
|
+
latencyMode: LatencyMode,
|
|
5626
6641
|
sandboxBackend: SandboxBackend,
|
|
5627
6642
|
// Per-turn OS override. NULL = inherit the session's sandboxOs.
|
|
5628
6643
|
sandboxOs: SandboxOs.nullable(),
|
|
@@ -5635,6 +6650,8 @@ export const SessionTurn = z
|
|
|
5635
6650
|
initiatorContext: TurnInitiatorContext,
|
|
5636
6651
|
/** Secret-safe projection of the exact personal authority frozen on this turn. */
|
|
5637
6652
|
personalConnections: z.array(McpPersonalConnectionSummary).default([]),
|
|
6653
|
+
/** Safe summary only; opaque resource/grant identity remains private. */
|
|
6654
|
+
personalResources: PersonalResourceAttachmentSummary.nullable().default(null),
|
|
5638
6655
|
cancelledBy: z.string().nullable(),
|
|
5639
6656
|
cancelReason: z.string().nullable(),
|
|
5640
6657
|
startedAt: z.string().nullable(),
|
|
@@ -5696,10 +6713,18 @@ export const EffectiveSessionControl = z.object({
|
|
|
5696
6713
|
quiescencePendingCount: z.number().int().nonnegative(),
|
|
5697
6714
|
})
|
|
5698
6715
|
.nullable(),
|
|
6716
|
+
/** Independent command-cancellation settlement. Session pause/turn state is
|
|
6717
|
+
* intentionally not overloaded with process lifecycle. */
|
|
6718
|
+
backgroundCommandSettlement: z
|
|
6719
|
+
.object({
|
|
6720
|
+
state: z.literal("stopping"),
|
|
6721
|
+
commandCount: z.number().int().positive(),
|
|
6722
|
+
})
|
|
6723
|
+
.nullable()
|
|
6724
|
+
.optional(),
|
|
5699
6725
|
});
|
|
5700
6726
|
export type EffectiveSessionControl = z.infer<typeof EffectiveSessionControl>;
|
|
5701
6727
|
|
|
5702
|
-
export const SESSION_OPERATION_KEY_MAX_CHARS = 256;
|
|
5703
6728
|
const SessionOperationKey = z.string().min(1).max(SESSION_OPERATION_KEY_MAX_CHARS);
|
|
5704
6729
|
|
|
5705
6730
|
export const SessionCommandReceipt = z.object({
|
|
@@ -5716,6 +6741,14 @@ export const SessionCommandReceipt = z.object({
|
|
|
5716
6741
|
});
|
|
5717
6742
|
export type SessionCommandReceipt = z.infer<typeof SessionCommandReceipt>;
|
|
5718
6743
|
|
|
6744
|
+
/** The server-owned destination of an accepted human prompt at admission time. */
|
|
6745
|
+
export const SessionPromptRouting = z.enum([
|
|
6746
|
+
"accepted_for_execution",
|
|
6747
|
+
"queued_for_execution",
|
|
6748
|
+
"accepted_for_steering",
|
|
6749
|
+
]);
|
|
6750
|
+
export type SessionPromptRouting = z.infer<typeof SessionPromptRouting>;
|
|
6751
|
+
|
|
5719
6752
|
export const ComposerDraft = z.object({
|
|
5720
6753
|
revision: z.number().int().nonnegative(),
|
|
5721
6754
|
text: z.string(),
|
|
@@ -5723,7 +6756,7 @@ export const ComposerDraft = z.object({
|
|
|
5723
6756
|
resources: z.array(ResourceRef),
|
|
5724
6757
|
model: z.string().min(1),
|
|
5725
6758
|
reasoningEffort: ReasoningEffort,
|
|
5726
|
-
latencyMode: LatencyMode
|
|
6759
|
+
latencyMode: LatencyMode,
|
|
5727
6760
|
sourceTurnId: z.string().uuid().nullable(),
|
|
5728
6761
|
sourceTurnVersion: z.number().int().positive().nullable(),
|
|
5729
6762
|
updatedAt: z.string().nullable(),
|
|
@@ -5769,12 +6802,39 @@ export const SaveComposerDraftRequest = ComposerDraft.pick({
|
|
|
5769
6802
|
}).extend({ expectedRevision: z.number().int().nonnegative() });
|
|
5770
6803
|
export type SaveComposerDraftRequest = z.infer<typeof SaveComposerDraftRequest>;
|
|
5771
6804
|
|
|
6805
|
+
/**
|
|
6806
|
+
* Submit one exact established-session draft. Content is repeated only as an
|
|
6807
|
+
* integrity fence for outcome-unknown idempotent replay; the matching durable
|
|
6808
|
+
* draft revision remains authoritative and is atomically rotated on acceptance.
|
|
6809
|
+
*/
|
|
6810
|
+
export const SubmitComposerDraftRequest = ComposerDraft.pick({
|
|
6811
|
+
text: true,
|
|
6812
|
+
annotations: true,
|
|
6813
|
+
resources: true,
|
|
6814
|
+
model: true,
|
|
6815
|
+
reasoningEffort: true,
|
|
6816
|
+
latencyMode: true,
|
|
6817
|
+
})
|
|
6818
|
+
.extend({
|
|
6819
|
+
expectedDraftRevision: z.number().int().positive(),
|
|
6820
|
+
clientEventId: SessionOperationKey,
|
|
6821
|
+
delivery: z.enum(["send", "steer"]),
|
|
6822
|
+
controlEtag: z.string().min(1).optional(),
|
|
6823
|
+
modelContext: z.string().trim().min(1).max(32768).optional(),
|
|
6824
|
+
mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
|
|
6825
|
+
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
6826
|
+
personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
|
|
6827
|
+
})
|
|
6828
|
+
.superRefine(requireEstablishedPersonalResourceEpoch);
|
|
6829
|
+
export type SubmitComposerDraftRequest = z.infer<typeof SubmitComposerDraftRequest>;
|
|
6830
|
+
|
|
5772
6831
|
/**
|
|
5773
6832
|
* Create-only options saved with an actor's private pre-session draft. This is
|
|
5774
6833
|
* deliberately narrower than CreateSessionRequest: idempotency/event keys and
|
|
5775
6834
|
* credential-bearing MCP server inputs are per-attempt data, never draft state.
|
|
5776
6835
|
*/
|
|
5777
6836
|
export const NewSessionDraftOptions = z.object({
|
|
6837
|
+
visibility: SessionVisibility.optional(),
|
|
5778
6838
|
sandboxBackend: SandboxBackend.optional(),
|
|
5779
6839
|
targetSandboxId: z.string().uuid().optional(),
|
|
5780
6840
|
workingDir: z.string().min(1).optional(),
|
|
@@ -5786,6 +6846,31 @@ export const NewSessionDraftOptions = z.object({
|
|
|
5786
6846
|
});
|
|
5787
6847
|
export type NewSessionDraftOptions = z.infer<typeof NewSessionDraftOptions>;
|
|
5788
6848
|
|
|
6849
|
+
/**
|
|
6850
|
+
* Actor-private successful-create history for the new-session composer. Project
|
|
6851
|
+
* entries and their machine entries are MRU ordered. A null target means the
|
|
6852
|
+
* managed sandbox; a null working directory means the machine's launch root.
|
|
6853
|
+
*/
|
|
6854
|
+
export const NewSessionSelectionHistory = z.object({
|
|
6855
|
+
projects: z
|
|
6856
|
+
.array(
|
|
6857
|
+
z.object({
|
|
6858
|
+
channelId: z.string().uuid().nullable(),
|
|
6859
|
+
targetSandboxId: z.string().uuid().nullable(),
|
|
6860
|
+
machines: z
|
|
6861
|
+
.array(
|
|
6862
|
+
z.object({
|
|
6863
|
+
sandboxId: z.string().uuid(),
|
|
6864
|
+
workingDir: z.string().min(1).max(4096).nullable(),
|
|
6865
|
+
}),
|
|
6866
|
+
)
|
|
6867
|
+
.max(20),
|
|
6868
|
+
}),
|
|
6869
|
+
)
|
|
6870
|
+
.max(50),
|
|
6871
|
+
});
|
|
6872
|
+
export type NewSessionSelectionHistory = z.infer<typeof NewSessionSelectionHistory>;
|
|
6873
|
+
|
|
5789
6874
|
/** Actor-private, server-authoritative composer state before a session exists. */
|
|
5790
6875
|
export const NewSessionDraft = z.object({
|
|
5791
6876
|
revision: z.number().int().nonnegative(),
|
|
@@ -5796,8 +6881,9 @@ export const NewSessionDraft = z.object({
|
|
|
5796
6881
|
toolsProvided: z.boolean().default(false),
|
|
5797
6882
|
model: z.string().min(1),
|
|
5798
6883
|
reasoningEffort: ReasoningEffort,
|
|
5799
|
-
latencyMode: LatencyMode
|
|
6884
|
+
latencyMode: LatencyMode,
|
|
5800
6885
|
options: NewSessionDraftOptions,
|
|
6886
|
+
selectionHistory: NewSessionSelectionHistory.default({ projects: [] }),
|
|
5801
6887
|
updatedAt: z.string().nullable(),
|
|
5802
6888
|
});
|
|
5803
6889
|
export type NewSessionDraft = z.infer<typeof NewSessionDraft>;
|
|
@@ -6036,53 +7122,229 @@ export const SessionSystemUpdateKind = z.enum([
|
|
|
6036
7122
|
"agent_steer_instruction",
|
|
6037
7123
|
"child_terminal_result",
|
|
6038
7124
|
"media_generation_result",
|
|
7125
|
+
"child_requires_action",
|
|
7126
|
+
"child_requires_action_resolved",
|
|
7127
|
+
"child_paused",
|
|
7128
|
+
"child_waiting_capacity",
|
|
7129
|
+
"child_progress",
|
|
6039
7130
|
]);
|
|
6040
7131
|
export type SessionSystemUpdateKind = z.infer<typeof SessionSystemUpdateKind>;
|
|
6041
7132
|
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
7133
|
+
/**
|
|
7134
|
+
* How a newly pending machine input affects an idle receiving session.
|
|
7135
|
+
* `immediate` registers a workflow wake in the same commit (the behaviour of
|
|
7136
|
+
* every pre-existing kind) and ends a `goal_wait` hold at the next idle
|
|
7137
|
+
* evaluation; `deferred` only inserts the durable pending row plus its
|
|
7138
|
+
* `system.update.pending` event and is delivered coalesced with the next claim.
|
|
7139
|
+
*/
|
|
7140
|
+
export type SessionSystemUpdateWakeClass = "immediate" | "deferred";
|
|
7141
|
+
|
|
7142
|
+
export const SESSION_SYSTEM_UPDATE_WAKE_CLASS: Record<
|
|
7143
|
+
SessionSystemUpdateKind,
|
|
7144
|
+
SessionSystemUpdateWakeClass
|
|
7145
|
+
> = {
|
|
7146
|
+
scheduled_occurrence: "immediate",
|
|
7147
|
+
goal_continuation: "immediate",
|
|
7148
|
+
agent_message: "immediate",
|
|
7149
|
+
agent_steer_instruction: "immediate",
|
|
7150
|
+
child_terminal_result: "immediate",
|
|
7151
|
+
media_generation_result: "immediate",
|
|
7152
|
+
child_requires_action: "immediate",
|
|
7153
|
+
child_requires_action_resolved: "deferred",
|
|
7154
|
+
child_paused: "deferred",
|
|
7155
|
+
child_waiting_capacity: "deferred",
|
|
7156
|
+
child_progress: "deferred",
|
|
7157
|
+
};
|
|
7158
|
+
|
|
7159
|
+
/**
|
|
7160
|
+
* Kinds a child session's lifecycle produces for its parent. Every one of them
|
|
7161
|
+
* travels through `session_system_update_outbox`, and none of them may
|
|
7162
|
+
* autonomously wake a parent whose goal is not active.
|
|
7163
|
+
*/
|
|
7164
|
+
export const CHILD_LIFECYCLE_SYSTEM_UPDATE_KINDS = [
|
|
7165
|
+
"child_terminal_result",
|
|
7166
|
+
"child_requires_action",
|
|
7167
|
+
"child_requires_action_resolved",
|
|
7168
|
+
"child_paused",
|
|
7169
|
+
"child_waiting_capacity",
|
|
7170
|
+
"child_progress",
|
|
7171
|
+
] as const satisfies readonly SessionSystemUpdateKind[];
|
|
7172
|
+
export type ChildLifecycleSystemUpdateKind = (typeof CHILD_LIFECYCLE_SYSTEM_UPDATE_KINDS)[number];
|
|
7173
|
+
|
|
7174
|
+
const CHILD_LIFECYCLE_SYSTEM_UPDATE_KIND_SET: ReadonlySet<string> = new Set(
|
|
7175
|
+
CHILD_LIFECYCLE_SYSTEM_UPDATE_KINDS,
|
|
7176
|
+
);
|
|
7177
|
+
|
|
7178
|
+
export function isChildLifecycleSystemUpdateKind(
|
|
7179
|
+
kind: string,
|
|
7180
|
+
): kind is ChildLifecycleSystemUpdateKind {
|
|
7181
|
+
return CHILD_LIFECYCLE_SYSTEM_UPDATE_KIND_SET.has(kind);
|
|
7182
|
+
}
|
|
7183
|
+
|
|
7184
|
+
/** A child_paused notice requested by a human/API is action-required; an agent pause is informational. */
|
|
7185
|
+
export function childPausedClassification(
|
|
7186
|
+
actorKind: "human" | "api" | "agent",
|
|
7187
|
+
): "action_required" | "info" {
|
|
7188
|
+
return actorKind === "agent" ? "info" : "action_required";
|
|
7189
|
+
}
|
|
7190
|
+
|
|
7191
|
+
/** Whole child_requires_action payload bound (UTF-8 JSON bytes). */
|
|
7192
|
+
export const CHILD_REQUIRES_ACTION_PAYLOAD_MAX_BYTES = 8 * 1024;
|
|
7193
|
+
/** Bounded first-question preview inside a child_requires_action notice. */
|
|
7194
|
+
export const CHILD_REQUIRES_ACTION_QUESTION_PREVIEW_MAX_BYTES = 512;
|
|
7195
|
+
export const CHILD_REQUIRES_ACTION_MAX_REQUESTS = 20;
|
|
7196
|
+
export const CHILD_PAUSED_REASON_MAX_BYTES = 2 * 1024;
|
|
7197
|
+
export const CHILD_PROGRESS_NOTE_MAX_BYTES = 4 * 1024;
|
|
7198
|
+
|
|
7199
|
+
const boundedUtf8String = (maxBytes: number) =>
|
|
7200
|
+
z.string().refine((value) => new TextEncoder().encode(value).byteLength <= maxBytes, {
|
|
7201
|
+
message: `must be at most ${maxBytes} UTF-8 bytes`,
|
|
7202
|
+
});
|
|
7203
|
+
|
|
7204
|
+
export const ChildRequiresActionRequest = z.discriminatedUnion("kind", [
|
|
7205
|
+
z.object({
|
|
7206
|
+
kind: z.literal("human_input"),
|
|
7207
|
+
requestId: z.string().uuid(),
|
|
7208
|
+
questionCount: z.number().int().nonnegative(),
|
|
7209
|
+
firstQuestion: boundedUtf8String(CHILD_REQUIRES_ACTION_QUESTION_PREVIEW_MAX_BYTES),
|
|
7210
|
+
allowSkip: z.boolean(),
|
|
7211
|
+
expiresAt: z.string().nullable(),
|
|
7212
|
+
}),
|
|
7213
|
+
z.object({
|
|
7214
|
+
kind: z.literal("approval"),
|
|
7215
|
+
approvalId: boundedUtf8String(256),
|
|
7216
|
+
toolName: boundedUtf8String(128).nullable(),
|
|
7217
|
+
}),
|
|
7218
|
+
]);
|
|
7219
|
+
export type ChildRequiresActionRequest = z.infer<typeof ChildRequiresActionRequest>;
|
|
7220
|
+
|
|
7221
|
+
export const ChildRequiresActionPayload = z
|
|
7222
|
+
.object({
|
|
7223
|
+
type: z.literal("child_requires_action"),
|
|
7224
|
+
childSessionId: z.string().uuid(),
|
|
7225
|
+
childTurnId: z.string().uuid(),
|
|
7226
|
+
childTurnGeneration: z.number().int().positive(),
|
|
7227
|
+
requests: z.array(ChildRequiresActionRequest).max(CHILD_REQUIRES_ACTION_MAX_REQUESTS),
|
|
7228
|
+
truncated: z.boolean(),
|
|
7229
|
+
})
|
|
7230
|
+
.passthrough();
|
|
7231
|
+
export type ChildRequiresActionPayload = z.infer<typeof ChildRequiresActionPayload>;
|
|
7232
|
+
|
|
7233
|
+
export const ChildRequiresActionResolvedOutcome = z.enum([
|
|
7234
|
+
"answered",
|
|
7235
|
+
"skipped",
|
|
7236
|
+
"expired",
|
|
7237
|
+
"cancelled",
|
|
7238
|
+
"approved",
|
|
7239
|
+
"rejected",
|
|
7240
|
+
]);
|
|
7241
|
+
export type ChildRequiresActionResolvedOutcome = z.infer<typeof ChildRequiresActionResolvedOutcome>;
|
|
7242
|
+
|
|
7243
|
+
export const ChildRequiresActionRespondedByKind = z.enum([
|
|
7244
|
+
"human",
|
|
7245
|
+
"api",
|
|
7246
|
+
"agent_attempt",
|
|
7247
|
+
"system",
|
|
7248
|
+
]);
|
|
7249
|
+
export type ChildRequiresActionRespondedByKind = z.infer<typeof ChildRequiresActionRespondedByKind>;
|
|
7250
|
+
|
|
7251
|
+
export const ChildRequiresActionResolvedPayload = z
|
|
7252
|
+
.object({
|
|
7253
|
+
type: z.literal("child_requires_action_resolved"),
|
|
7254
|
+
childSessionId: z.string().uuid(),
|
|
7255
|
+
childTurnId: z.string().uuid(),
|
|
7256
|
+
childTurnGeneration: z.number().int().positive(),
|
|
7257
|
+
requestId: z.string().uuid().nullable(),
|
|
7258
|
+
approvalId: boundedUtf8String(256).nullable(),
|
|
7259
|
+
outcome: ChildRequiresActionResolvedOutcome,
|
|
7260
|
+
respondedByKind: ChildRequiresActionRespondedByKind,
|
|
7261
|
+
})
|
|
7262
|
+
.passthrough();
|
|
7263
|
+
export type ChildRequiresActionResolvedPayload = z.infer<typeof ChildRequiresActionResolvedPayload>;
|
|
7264
|
+
|
|
7265
|
+
export const ChildPausedPayload = z
|
|
7266
|
+
.object({
|
|
7267
|
+
type: z.literal("child_paused"),
|
|
7268
|
+
childSessionId: z.string().uuid(),
|
|
7269
|
+
operationId: z.string().uuid(),
|
|
7270
|
+
actorKind: z.enum(["human", "api", "agent"]),
|
|
7271
|
+
reason: boundedUtf8String(CHILD_PAUSED_REASON_MAX_BYTES).nullable(),
|
|
7272
|
+
})
|
|
7273
|
+
.passthrough();
|
|
7274
|
+
export type ChildPausedPayload = z.infer<typeof ChildPausedPayload>;
|
|
7275
|
+
|
|
7276
|
+
export const ChildWaitingCapacityPayload = z
|
|
7277
|
+
.object({
|
|
7278
|
+
type: z.literal("child_waiting_capacity"),
|
|
7279
|
+
childSessionId: z.string().uuid(),
|
|
7280
|
+
childTurnId: z.string().uuid(),
|
|
7281
|
+
provider: z.enum(["codex", "xai"]),
|
|
7282
|
+
nextCheckAt: z.string().nullable(),
|
|
7283
|
+
})
|
|
7284
|
+
.passthrough();
|
|
7285
|
+
export type ChildWaitingCapacityPayload = z.infer<typeof ChildWaitingCapacityPayload>;
|
|
7286
|
+
|
|
7287
|
+
export const ChildProgressPayload = z
|
|
7288
|
+
.object({
|
|
7289
|
+
type: z.literal("child_progress"),
|
|
7290
|
+
childSessionId: z.string().uuid(),
|
|
7291
|
+
goalId: z.string().uuid(),
|
|
7292
|
+
objectiveRevision: z.number().int().nonnegative(),
|
|
7293
|
+
operationId: z.string().uuid(),
|
|
7294
|
+
progressNote: boundedUtf8String(CHILD_PROGRESS_NOTE_MAX_BYTES),
|
|
7295
|
+
})
|
|
7296
|
+
.passthrough();
|
|
7297
|
+
export type ChildProgressPayload = z.infer<typeof ChildProgressPayload>;
|
|
7298
|
+
|
|
7299
|
+
export const SessionSystemUpdatePayload = z.discriminatedUnion("type", [
|
|
7300
|
+
z
|
|
7301
|
+
.object({
|
|
7302
|
+
type: z.literal("scheduled_occurrence"),
|
|
7303
|
+
text: z.string().min(1),
|
|
7304
|
+
scheduledTaskId: z.string().uuid(),
|
|
7305
|
+
scheduledTaskRunId: z.string().uuid(),
|
|
7306
|
+
resources: z.array(ResourceRef).optional(),
|
|
7307
|
+
tools: z.array(ToolRef).optional(),
|
|
7308
|
+
})
|
|
7309
|
+
.passthrough(),
|
|
7310
|
+
z
|
|
7311
|
+
.object({
|
|
7312
|
+
type: z.literal("goal_continuation"),
|
|
7313
|
+
goalId: z.string().uuid(),
|
|
7314
|
+
goalVersion: z.number().int().positive(),
|
|
7315
|
+
prompt: z.string().min(1),
|
|
7316
|
+
reason: z.string().optional(),
|
|
7317
|
+
})
|
|
7318
|
+
.passthrough(),
|
|
7319
|
+
z
|
|
7320
|
+
.object({
|
|
7321
|
+
type: z.literal("agent_message"),
|
|
7322
|
+
text: z.string().min(1),
|
|
7323
|
+
operationId: z.string().uuid(),
|
|
7324
|
+
})
|
|
7325
|
+
.passthrough(),
|
|
7326
|
+
z
|
|
7327
|
+
.object({
|
|
7328
|
+
type: z.literal("agent_steer_instruction"),
|
|
7329
|
+
instruction: z.string().min(1),
|
|
7330
|
+
operationId: z.string().uuid(),
|
|
7331
|
+
})
|
|
7332
|
+
.passthrough(),
|
|
7333
|
+
z
|
|
7334
|
+
.object({
|
|
7335
|
+
type: z.literal("child_terminal_result"),
|
|
7336
|
+
childSessionId: z.string().uuid(),
|
|
7337
|
+
status: z.enum(["idle", "failed", "cancelled"]),
|
|
7338
|
+
})
|
|
7339
|
+
.passthrough(),
|
|
7340
|
+
MediaGenerationResult,
|
|
7341
|
+
ChildRequiresActionPayload,
|
|
7342
|
+
ChildRequiresActionResolvedPayload,
|
|
7343
|
+
ChildPausedPayload,
|
|
7344
|
+
ChildWaitingCapacityPayload,
|
|
7345
|
+
ChildProgressPayload,
|
|
7346
|
+
]);
|
|
7347
|
+
export type SessionSystemUpdatePayload = z.infer<typeof SessionSystemUpdatePayload>;
|
|
6086
7348
|
|
|
6087
7349
|
export const SessionSystemUpdateState = z.enum([
|
|
6088
7350
|
"pending",
|
|
@@ -6197,11 +7459,16 @@ export function renderSessionSystemUpdateBatch(
|
|
|
6197
7459
|
|
|
6198
7460
|
export function sessionSystemUpdateBatchHistoryItem(
|
|
6199
7461
|
updates: Parameters<typeof renderSessionSystemUpdateBatch>[0],
|
|
7462
|
+
goalSnapshot?: SessionGoalSnapshot,
|
|
6200
7463
|
): { type: "message"; role: "system"; content: string } {
|
|
7464
|
+
const goalContext = renderSessionGoalContext(goalSnapshot);
|
|
6201
7465
|
return {
|
|
6202
7466
|
type: "message",
|
|
6203
7467
|
role: "system",
|
|
6204
|
-
content:
|
|
7468
|
+
content: [
|
|
7469
|
+
...(goalContext ? [`${SESSION_GOAL_CONTEXT_LABEL}\n${goalContext}`] : []),
|
|
7470
|
+
renderSessionSystemUpdateBatch(updates),
|
|
7471
|
+
].join("\n\n"),
|
|
6205
7472
|
};
|
|
6206
7473
|
}
|
|
6207
7474
|
|
|
@@ -6251,10 +7518,16 @@ export const VariableSetSecret = z.object({
|
|
|
6251
7518
|
});
|
|
6252
7519
|
export type VariableSetSecret = z.infer<typeof VariableSetSecret>;
|
|
6253
7520
|
|
|
7521
|
+
export const VariableSetScope = z.enum(["organization", "workspace", "user"]);
|
|
7522
|
+
export type VariableSetScope = z.infer<typeof VariableSetScope>;
|
|
7523
|
+
|
|
6254
7524
|
export const VariableSet = z.object({
|
|
6255
7525
|
id: z.string().uuid(),
|
|
6256
7526
|
accountId: z.string().uuid(),
|
|
6257
7527
|
workspaceId: z.string().uuid(),
|
|
7528
|
+
scope: VariableSetScope,
|
|
7529
|
+
generation: z.number().int().positive(),
|
|
7530
|
+
status: z.enum(["active", "revoked"]),
|
|
6258
7531
|
name: z.string(),
|
|
6259
7532
|
description: z.string().nullable(),
|
|
6260
7533
|
variables: z.array(VariableSetVariableMetadata),
|
|
@@ -6268,6 +7541,8 @@ export const WorkspaceEnvironment = VariableSet;
|
|
|
6268
7541
|
export type WorkspaceEnvironment = VariableSet;
|
|
6269
7542
|
|
|
6270
7543
|
export const CreateVariableSetRequest = z.object({
|
|
7544
|
+
// Omitted remains the legacy workspace-owned creation path.
|
|
7545
|
+
scope: VariableSetScope.default("workspace"),
|
|
6271
7546
|
name: z.string().min(1).max(120),
|
|
6272
7547
|
description: z.string().max(2000).optional(),
|
|
6273
7548
|
variables: z
|
|
@@ -6466,6 +7741,9 @@ export const Rig = z.object({
|
|
|
6466
7741
|
id: z.string().uuid(),
|
|
6467
7742
|
accountId: z.string().uuid(),
|
|
6468
7743
|
workspaceId: z.string().uuid(),
|
|
7744
|
+
scope: ResourceAuthorityScope,
|
|
7745
|
+
generation: z.number().int().positive(),
|
|
7746
|
+
status: z.enum(["active", "revoked"]),
|
|
6469
7747
|
name: z.string(),
|
|
6470
7748
|
description: z.string().nullable(),
|
|
6471
7749
|
createdBy: z.string().nullable(),
|
|
@@ -6524,6 +7802,8 @@ export const RigChange = z.object({
|
|
|
6524
7802
|
export type RigChange = z.infer<typeof RigChange>;
|
|
6525
7803
|
|
|
6526
7804
|
export const CreateRigRequest = z.object({
|
|
7805
|
+
// Omitted remains the compatibility workspace-owned creation path.
|
|
7806
|
+
scope: ResourceAuthorityScope.default("workspace"),
|
|
6527
7807
|
name: z.string().min(1).max(120),
|
|
6528
7808
|
description: z.string().max(2000).optional(),
|
|
6529
7809
|
// Initial (version 1) content, inline.
|
|
@@ -6550,6 +7830,8 @@ export const Channel = z.object({
|
|
|
6550
7830
|
workspaceId: z.string().uuid(),
|
|
6551
7831
|
name: z.string(),
|
|
6552
7832
|
description: z.string().nullable(),
|
|
7833
|
+
pinned: z.boolean(),
|
|
7834
|
+
sortOrder: z.number().int().nonnegative(),
|
|
6553
7835
|
createdBy: z.string().nullable(),
|
|
6554
7836
|
createdAt: z.string(),
|
|
6555
7837
|
updatedAt: z.string(),
|
|
@@ -6565,9 +7847,16 @@ export type CreateChannelRequest = z.infer<typeof CreateChannelRequest>;
|
|
|
6565
7847
|
export const UpdateChannelRequest = z.object({
|
|
6566
7848
|
name: z.string().trim().min(1).max(80).optional(),
|
|
6567
7849
|
description: z.string().max(2000).nullable().optional(),
|
|
7850
|
+
pinned: z.boolean().optional(),
|
|
6568
7851
|
});
|
|
6569
7852
|
export type UpdateChannelRequest = z.infer<typeof UpdateChannelRequest>;
|
|
6570
7853
|
|
|
7854
|
+
/** Complete workspace project order. It is replaced atomically after a drag. */
|
|
7855
|
+
export const ReorderChannelsRequest = z
|
|
7856
|
+
.object({ channelIds: z.array(z.string().uuid()).min(1).max(200) })
|
|
7857
|
+
.strict();
|
|
7858
|
+
export type ReorderChannelsRequest = z.infer<typeof ReorderChannelsRequest>;
|
|
7859
|
+
|
|
6571
7860
|
// Re-files one session (rail organization only). null moves it back to the
|
|
6572
7861
|
// unfiled inbox.
|
|
6573
7862
|
export const UpdateSessionChannelRequest = z.object({
|
|
@@ -6733,25 +8022,313 @@ export const ScheduledTaskScheduleSpec = /* @__PURE__ */ z.discriminatedUnion("t
|
|
|
6733
8022
|
]);
|
|
6734
8023
|
export type ScheduledTaskScheduleSpec = z.infer<typeof ScheduledTaskScheduleSpec>;
|
|
6735
8024
|
|
|
6736
|
-
export const
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
8025
|
+
export const IncidentTelemetryExecutionClass = z.literal("incident_telemetry");
|
|
8026
|
+
export type IncidentTelemetryExecutionClass = z.infer<typeof IncidentTelemetryExecutionClass>;
|
|
8027
|
+
|
|
8028
|
+
const IncidentTelemetryIdentifier = z.string().trim().min(1).max(200);
|
|
8029
|
+
const IncidentTelemetryMetricName = z
|
|
8030
|
+
.string()
|
|
8031
|
+
.trim()
|
|
8032
|
+
.min(1)
|
|
8033
|
+
.max(200)
|
|
8034
|
+
.regex(/^[A-Za-z_:][A-Za-z0-9_:]*$/);
|
|
8035
|
+
const IncidentTelemetryLabelName = z
|
|
8036
|
+
.string()
|
|
8037
|
+
.trim()
|
|
8038
|
+
.min(1)
|
|
8039
|
+
.max(200)
|
|
8040
|
+
.regex(/^[A-Za-z_][A-Za-z0-9_]*$/);
|
|
8041
|
+
|
|
8042
|
+
export const IncidentTelemetrySeriesMetadata = z
|
|
8043
|
+
.object({
|
|
8044
|
+
metric: IncidentTelemetryMetricName,
|
|
8045
|
+
labels: z.array(IncidentTelemetryLabelName).min(1).max(64),
|
|
8046
|
+
})
|
|
8047
|
+
.strict();
|
|
8048
|
+
export type IncidentTelemetrySeriesMetadata = z.infer<typeof IncidentTelemetrySeriesMetadata>;
|
|
8049
|
+
|
|
8050
|
+
export const IncidentTelemetryDataRoute = z.discriminatedUnion("kind", [
|
|
8051
|
+
z
|
|
8052
|
+
.object({
|
|
8053
|
+
kind: z.literal("mcp"),
|
|
8054
|
+
serverId: SessionMcpServerId,
|
|
8055
|
+
})
|
|
8056
|
+
.strict(),
|
|
8057
|
+
z
|
|
8058
|
+
.object({
|
|
8059
|
+
kind: z.literal("first_party"),
|
|
8060
|
+
tool: FirstPartyMcpToolName,
|
|
8061
|
+
})
|
|
8062
|
+
.strict(),
|
|
8063
|
+
z
|
|
8064
|
+
.object({
|
|
8065
|
+
kind: z.literal("variable_set"),
|
|
8066
|
+
variableSetName: z.string().trim().min(1).max(120),
|
|
8067
|
+
variableNames: z.array(VariableSetVariableName).min(1).max(100),
|
|
8068
|
+
})
|
|
8069
|
+
.strict(),
|
|
8070
|
+
z
|
|
8071
|
+
.object({
|
|
8072
|
+
kind: z.literal("rig_credential_hook"),
|
|
8073
|
+
credentialHookId: IncidentTelemetryIdentifier,
|
|
8074
|
+
})
|
|
8075
|
+
.strict(),
|
|
8076
|
+
]);
|
|
8077
|
+
export type IncidentTelemetryDataRoute = z.infer<typeof IncidentTelemetryDataRoute>;
|
|
8078
|
+
|
|
8079
|
+
export const IncidentTelemetryPreflight = z
|
|
8080
|
+
.object({
|
|
8081
|
+
// These are exact selected resource refs, not discovery hints. The core
|
|
8082
|
+
// validator requires every entry to already be present in agentConfig.
|
|
8083
|
+
requiredResources: z.array(ResourceRef).max(100).default([]),
|
|
8084
|
+
requiredMcpServerIds: z.array(SessionMcpServerId).max(64).default([]),
|
|
8085
|
+
requiredFirstPartyMcpTools: z.array(FirstPartyMcpToolName).max(100).default([]),
|
|
8086
|
+
requiredFirstPartyMcpPermissions: z.array(Permission).max(100).default([]),
|
|
8087
|
+
requiredRig: z
|
|
8088
|
+
.object({
|
|
8089
|
+
name: z.string().trim().min(1).max(120),
|
|
8090
|
+
credentialHookIds: z.array(IncidentTelemetryIdentifier).max(50).default([]),
|
|
8091
|
+
})
|
|
8092
|
+
.strict()
|
|
8093
|
+
.nullable()
|
|
8094
|
+
.default(null),
|
|
8095
|
+
// Names only. The dispatch preflight never reads or decrypts values.
|
|
8096
|
+
requiredVariableSetNames: z.array(z.string().trim().min(1).max(120)).max(25).default([]),
|
|
8097
|
+
requiredVariableNames: z.array(VariableSetVariableName).max(100).default([]),
|
|
8098
|
+
dataSource: z
|
|
8099
|
+
.object({
|
|
8100
|
+
kind: z.literal("prometheus"),
|
|
8101
|
+
// Exposition endpoints such as /metrics are deliberately excluded.
|
|
8102
|
+
queryPath: z.enum(["/api/v1/query", "/api/v1/query_range"]),
|
|
8103
|
+
workspaceLabel: IncidentTelemetryLabelName,
|
|
8104
|
+
// Exact non-workspace labels whose values come from the validated
|
|
8105
|
+
// structured alert occurrence and bound every telemetry query.
|
|
8106
|
+
alertSelectorLabels: z.array(IncidentTelemetryLabelName).min(1).max(16),
|
|
8107
|
+
route: IncidentTelemetryDataRoute,
|
|
8108
|
+
requiredSeries: z.array(IncidentTelemetrySeriesMetadata).min(1).max(100),
|
|
8109
|
+
availableSeries: z.array(IncidentTelemetrySeriesMetadata).min(1).max(500),
|
|
8110
|
+
})
|
|
8111
|
+
.strict(),
|
|
8112
|
+
})
|
|
8113
|
+
.strict()
|
|
8114
|
+
.superRefine((value, context) => {
|
|
8115
|
+
for (const [index, label] of value.dataSource.alertSelectorLabels.entries()) {
|
|
8116
|
+
if (label === value.dataSource.workspaceLabel) {
|
|
8117
|
+
context.addIssue({
|
|
8118
|
+
code: "custom",
|
|
8119
|
+
path: ["dataSource", "alertSelectorLabels", index],
|
|
8120
|
+
message: "alert selector labels must be non-workspace labels",
|
|
8121
|
+
});
|
|
8122
|
+
}
|
|
8123
|
+
}
|
|
8124
|
+
for (const [index, series] of value.dataSource.requiredSeries.entries()) {
|
|
8125
|
+
if (!series.labels.includes(value.dataSource.workspaceLabel)) {
|
|
8126
|
+
context.addIssue({
|
|
8127
|
+
code: "custom",
|
|
8128
|
+
path: ["dataSource", "requiredSeries", index, "labels"],
|
|
8129
|
+
message: "required incident series must include the workspace label",
|
|
8130
|
+
});
|
|
8131
|
+
}
|
|
8132
|
+
for (const label of value.dataSource.alertSelectorLabels) {
|
|
8133
|
+
if (!series.labels.includes(label)) {
|
|
8134
|
+
context.addIssue({
|
|
8135
|
+
code: "custom",
|
|
8136
|
+
path: ["dataSource", "requiredSeries", index, "labels"],
|
|
8137
|
+
message: "required incident series must include every alert selector label",
|
|
8138
|
+
});
|
|
8139
|
+
}
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
});
|
|
8143
|
+
export type IncidentTelemetryPreflight = z.infer<typeof IncidentTelemetryPreflight>;
|
|
8144
|
+
|
|
8145
|
+
/**
|
|
8146
|
+
* Canonical UTF-8 ingress limits for newly written scheduled execution truth.
|
|
8147
|
+
* They bound create/update requests and freshly accepted occurrence snapshots;
|
|
8148
|
+
* already-stored tasks are read back through the unbounded storage shape so a
|
|
8149
|
+
* legacy row can never become unreadable or undispatchable by a later cap.
|
|
8150
|
+
*/
|
|
8151
|
+
export const SCHEDULED_TASK_NAME_MAX_BYTES = 512;
|
|
8152
|
+
export const SCHEDULED_TASK_PROMPT_MAX_BYTES = 64 * 1024;
|
|
8153
|
+
export const SCHEDULED_TASK_METADATA_MAX_BYTES = 32 * 1024;
|
|
8154
|
+
export const SCHEDULED_TASK_AGENT_CONFIG_MAX_BYTES = 128 * 1024;
|
|
8155
|
+
export const SCHEDULED_TASK_ACCEPTED_EXECUTION_MAX_BYTES = 512 * 1024;
|
|
8156
|
+
/**
|
|
8157
|
+
* A scheduled occurrence is delivered as one durable internal update whose
|
|
8158
|
+
* payload (`scheduled_occurrence` text + resources + tools + ids) must fit the
|
|
8159
|
+
* canonical internal-update bound. Bounding it here at ingress means every
|
|
8160
|
+
* stored task that passed validation can also be delivered.
|
|
8161
|
+
*/
|
|
8162
|
+
export const SCHEDULED_TASK_OCCURRENCE_PAYLOAD_MAX_BYTES = 64 * 1024;
|
|
8163
|
+
/**
|
|
8164
|
+
* Ingress reserves headroom below that bound for what the worker adds to the
|
|
8165
|
+
* delivered payload (the first-party `opengeni` MCP tool ref and real ids), so
|
|
8166
|
+
* a request that passes validation can always be delivered.
|
|
8167
|
+
*/
|
|
8168
|
+
export const SCHEDULED_TASK_OCCURRENCE_PAYLOAD_INGRESS_HEADROOM_BYTES = 1024;
|
|
8169
|
+
export const SCHEDULED_TASK_PRODUCER_KEY_MAX_BYTES = 512;
|
|
8170
|
+
export const SCHEDULED_TASK_RESOURCE_MAX_COUNT = 100;
|
|
8171
|
+
export const SCHEDULED_TASK_TOOL_MAX_COUNT = 128;
|
|
8172
|
+
|
|
8173
|
+
const scheduledTaskUtf8Encoder = new TextEncoder();
|
|
8174
|
+
|
|
8175
|
+
function scheduledTaskUtf8Bytes(value: string): number {
|
|
8176
|
+
return scheduledTaskUtf8Encoder.encode(value).byteLength;
|
|
8177
|
+
}
|
|
8178
|
+
|
|
8179
|
+
function scheduledTaskJsonUtf8Bytes(value: unknown): number {
|
|
8180
|
+
try {
|
|
8181
|
+
const encoded = JSON.stringify(value);
|
|
8182
|
+
return encoded === undefined ? Number.POSITIVE_INFINITY : scheduledTaskUtf8Bytes(encoded);
|
|
8183
|
+
} catch {
|
|
8184
|
+
return Number.POSITIVE_INFINITY;
|
|
8185
|
+
}
|
|
8186
|
+
}
|
|
8187
|
+
|
|
8188
|
+
/**
|
|
8189
|
+
* UTF-8 size of the exact `scheduled_occurrence` internal-update payload the
|
|
8190
|
+
* worker delivers for one occurrence of this agent config (ids use fixed-width
|
|
8191
|
+
* placeholder UUIDs). Shared by ingress validation and worker admission.
|
|
8192
|
+
*/
|
|
8193
|
+
export function scheduledOccurrencePayloadUtf8Bytes(agentConfig: {
|
|
8194
|
+
prompt: string;
|
|
8195
|
+
resources?: readonly unknown[] | undefined;
|
|
8196
|
+
tools?: readonly unknown[] | undefined;
|
|
8197
|
+
}): number {
|
|
8198
|
+
const placeholder = "00000000-0000-4000-8000-000000000000";
|
|
8199
|
+
return scheduledTaskJsonUtf8Bytes({
|
|
8200
|
+
type: "scheduled_occurrence",
|
|
8201
|
+
text: agentConfig.prompt,
|
|
8202
|
+
scheduledTaskId: placeholder,
|
|
8203
|
+
scheduledTaskRunId: placeholder,
|
|
8204
|
+
...(agentConfig.resources?.length ? { resources: agentConfig.resources } : {}),
|
|
8205
|
+
...(agentConfig.tools?.length ? { tools: agentConfig.tools } : {}),
|
|
8206
|
+
});
|
|
8207
|
+
}
|
|
8208
|
+
|
|
8209
|
+
function scheduledTaskBoundedJsonObject(maxBytes: number, label: string) {
|
|
8210
|
+
return z.record(z.string(), z.unknown()).superRefine((value, context) => {
|
|
8211
|
+
if (scheduledTaskJsonUtf8Bytes(value) > maxBytes) {
|
|
8212
|
+
context.addIssue({
|
|
8213
|
+
code: "custom",
|
|
8214
|
+
message: `${label} exceeds ${maxBytes} UTF-8 bytes`,
|
|
8215
|
+
});
|
|
8216
|
+
}
|
|
8217
|
+
});
|
|
8218
|
+
}
|
|
8219
|
+
|
|
8220
|
+
function scheduledTaskBoundedString(maxBytes: number, label: string) {
|
|
8221
|
+
return z
|
|
8222
|
+
.string()
|
|
8223
|
+
.min(1)
|
|
8224
|
+
.superRefine((value, context) => {
|
|
8225
|
+
if (scheduledTaskUtf8Bytes(value) > maxBytes) {
|
|
8226
|
+
context.addIssue({
|
|
8227
|
+
code: "custom",
|
|
8228
|
+
message: `${label} exceeds ${maxBytes} UTF-8 bytes`,
|
|
8229
|
+
});
|
|
8230
|
+
}
|
|
8231
|
+
});
|
|
8232
|
+
}
|
|
8233
|
+
|
|
8234
|
+
/** Ingress-bounded task name for create/update requests. */
|
|
8235
|
+
export const ScheduledTaskNameInput = /* @__PURE__ */ scheduledTaskBoundedString(
|
|
8236
|
+
SCHEDULED_TASK_NAME_MAX_BYTES,
|
|
8237
|
+
"scheduled task name",
|
|
8238
|
+
);
|
|
8239
|
+
/** Ingress-bounded task metadata for create/update requests. */
|
|
8240
|
+
export const ScheduledTaskMetadataInput = /* @__PURE__ */ scheduledTaskBoundedJsonObject(
|
|
8241
|
+
SCHEDULED_TASK_METADATA_MAX_BYTES,
|
|
8242
|
+
"scheduled task metadata",
|
|
8243
|
+
);
|
|
8244
|
+
|
|
8245
|
+
function scheduledTaskAgentConfigShape(bounded: boolean) {
|
|
8246
|
+
return {
|
|
8247
|
+
prompt: bounded
|
|
8248
|
+
? scheduledTaskBoundedString(SCHEDULED_TASK_PROMPT_MAX_BYTES, "scheduled task prompt")
|
|
8249
|
+
: z.string().min(1),
|
|
8250
|
+
resources: bounded
|
|
8251
|
+
? z.array(ResourceRef).max(SCHEDULED_TASK_RESOURCE_MAX_COUNT).default([])
|
|
8252
|
+
: z.array(ResourceRef).default([]),
|
|
8253
|
+
tools: bounded
|
|
8254
|
+
? z
|
|
8255
|
+
.array(ToolRef)
|
|
8256
|
+
.max(SCHEDULED_TASK_TOOL_MAX_COUNT - 1)
|
|
8257
|
+
.default([])
|
|
8258
|
+
: z.array(ToolRef).default([]),
|
|
8259
|
+
metadata: bounded
|
|
8260
|
+
? ScheduledTaskMetadataInput.default({})
|
|
8261
|
+
: z.record(z.string(), z.unknown()).default({}),
|
|
8262
|
+
// Explicit workspace-shared OpenGeni Slack bot binding for scheduled runs.
|
|
8263
|
+
// The worker copies this non-secret pointer into session metadata; the
|
|
8264
|
+
// first-party Slack tools never fall back to a personal hosted-MCP grant.
|
|
8265
|
+
slackBotConnectionId: z.string().uuid().optional(),
|
|
8266
|
+
model: bounded
|
|
8267
|
+
? scheduledTaskBoundedString(512, "scheduled task model").optional()
|
|
8268
|
+
: z.string().min(1).optional(),
|
|
8269
|
+
reasoningEffort: ReasoningEffort.optional(),
|
|
8270
|
+
sandboxBackend: SandboxBackend.optional(),
|
|
8271
|
+
goal: GoalSpec.optional(),
|
|
8272
|
+
// Incident telemetry is the only special execution class. Omission keeps
|
|
8273
|
+
// every existing task on the byte-compatible ordinary dispatch path.
|
|
8274
|
+
executionClass: IncidentTelemetryExecutionClass.optional(),
|
|
8275
|
+
incidentTelemetryPreflight: IncidentTelemetryPreflight.optional(),
|
|
8276
|
+
// Durable task override. Scheduled dispatch is trusted to preserve this
|
|
8277
|
+
// snapshot even if the workspace/deployment policy narrows later.
|
|
8278
|
+
maxNestedAgentDepth: NestedAgentDepthValue.optional(),
|
|
8279
|
+
};
|
|
8280
|
+
}
|
|
8281
|
+
|
|
8282
|
+
function refineScheduledTaskAgentConfig(
|
|
8283
|
+
value: { executionClass?: unknown; incidentTelemetryPreflight?: unknown },
|
|
8284
|
+
context: z.RefinementCtx,
|
|
8285
|
+
): void {
|
|
8286
|
+
if (value.executionClass === "incident_telemetry" && !value.incidentTelemetryPreflight) {
|
|
8287
|
+
context.addIssue({
|
|
8288
|
+
code: "custom",
|
|
8289
|
+
path: ["incidentTelemetryPreflight"],
|
|
8290
|
+
message: "incident telemetry tasks require incidentTelemetryPreflight",
|
|
8291
|
+
});
|
|
8292
|
+
}
|
|
8293
|
+
if (value.executionClass !== "incident_telemetry" && value.incidentTelemetryPreflight) {
|
|
8294
|
+
context.addIssue({
|
|
8295
|
+
code: "custom",
|
|
8296
|
+
path: ["executionClass"],
|
|
8297
|
+
message: "incidentTelemetryPreflight requires executionClass=incident_telemetry",
|
|
8298
|
+
});
|
|
8299
|
+
}
|
|
8300
|
+
}
|
|
8301
|
+
|
|
8302
|
+
/** Storage/projection shape. Deliberately unbounded so stored rows always parse. */
|
|
8303
|
+
export const ScheduledTaskAgentConfig = /* @__PURE__ */ z
|
|
8304
|
+
.object(scheduledTaskAgentConfigShape(false))
|
|
8305
|
+
.superRefine(refineScheduledTaskAgentConfig);
|
|
6753
8306
|
export type ScheduledTaskAgentConfig = z.infer<typeof ScheduledTaskAgentConfig>;
|
|
6754
8307
|
|
|
8308
|
+
/** Ingress-bounded agent config for create/update requests. */
|
|
8309
|
+
export const ScheduledTaskAgentConfigInput = /* @__PURE__ */ z
|
|
8310
|
+
.object(scheduledTaskAgentConfigShape(true))
|
|
8311
|
+
.superRefine((value, context) => {
|
|
8312
|
+
if (scheduledTaskJsonUtf8Bytes(value) > SCHEDULED_TASK_AGENT_CONFIG_MAX_BYTES) {
|
|
8313
|
+
context.addIssue({
|
|
8314
|
+
code: "custom",
|
|
8315
|
+
message: `scheduled task agent config exceeds ${SCHEDULED_TASK_AGENT_CONFIG_MAX_BYTES} UTF-8 bytes`,
|
|
8316
|
+
});
|
|
8317
|
+
}
|
|
8318
|
+
if (
|
|
8319
|
+
scheduledOccurrencePayloadUtf8Bytes(value) >
|
|
8320
|
+
SCHEDULED_TASK_OCCURRENCE_PAYLOAD_MAX_BYTES -
|
|
8321
|
+
SCHEDULED_TASK_OCCURRENCE_PAYLOAD_INGRESS_HEADROOM_BYTES
|
|
8322
|
+
) {
|
|
8323
|
+
context.addIssue({
|
|
8324
|
+
code: "custom",
|
|
8325
|
+
message: `scheduled task prompt, resources, and tools exceed the ${SCHEDULED_TASK_OCCURRENCE_PAYLOAD_MAX_BYTES - SCHEDULED_TASK_OCCURRENCE_PAYLOAD_INGRESS_HEADROOM_BYTES} UTF-8 byte occurrence payload`,
|
|
8326
|
+
});
|
|
8327
|
+
}
|
|
8328
|
+
refineScheduledTaskAgentConfig(value, context);
|
|
8329
|
+
});
|
|
8330
|
+
export type ScheduledTaskAgentConfigInput = z.infer<typeof ScheduledTaskAgentConfigInput>;
|
|
8331
|
+
|
|
6755
8332
|
export const ScheduledTask = /* @__PURE__ */ z.object({
|
|
6756
8333
|
id: z.string().uuid(),
|
|
6757
8334
|
accountId: z.string().uuid(),
|
|
@@ -6770,6 +8347,8 @@ export const ScheduledTask = /* @__PURE__ */ z.object({
|
|
|
6770
8347
|
}),
|
|
6771
8348
|
createdByContext: TurnInitiatorContext.default({}),
|
|
6772
8349
|
personalConnections: z.array(McpPersonalConnectionSummary).default([]),
|
|
8350
|
+
authorityRevision: z.number().int().positive().default(1),
|
|
8351
|
+
executionDigest: z.string().regex(/^[0-9a-f]{64}$/u),
|
|
6773
8352
|
reusableSessionId: z.string().uuid().nullable(),
|
|
6774
8353
|
targetSessionId: z.string().uuid().nullable().default(null),
|
|
6775
8354
|
variableSetId: z.string().uuid().nullable().default(null),
|
|
@@ -6785,18 +8364,164 @@ export const ScheduledTask = /* @__PURE__ */ z.object({
|
|
|
6785
8364
|
});
|
|
6786
8365
|
export type ScheduledTask = z.infer<typeof ScheduledTask>;
|
|
6787
8366
|
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
8367
|
+
/**
|
|
8368
|
+
* Complete credential-free execution truth accepted for one scheduled agent
|
|
8369
|
+
* occurrence. Retries consume this immutable snapshot instead of a mutable
|
|
8370
|
+
* scheduled-task head.
|
|
8371
|
+
*/
|
|
8372
|
+
export const ScheduledTaskRunAcceptedExecution = /* @__PURE__ */ z
|
|
8373
|
+
.object({
|
|
8374
|
+
version: z.literal(1),
|
|
8375
|
+
task: ScheduledTask,
|
|
8376
|
+
resolvedModel: z.string().min(1),
|
|
8377
|
+
resolvedReasoningEffort: ReasoningEffort,
|
|
8378
|
+
resolvedLatencyMode: LatencyMode,
|
|
8379
|
+
resolvedSandboxBackend: SandboxBackend,
|
|
8380
|
+
resolvedSandboxOs: SandboxOs,
|
|
8381
|
+
resolvedTools: z.array(ToolRef).max(SCHEDULED_TASK_TOOL_MAX_COUNT),
|
|
8382
|
+
resolvedFirstPartyMcpTools: z.array(FirstPartyMcpToolName),
|
|
8383
|
+
resolvedFirstPartyMcpPermissions: z.array(Permission),
|
|
8384
|
+
resolvedVariableSet: z
|
|
8385
|
+
.object({
|
|
8386
|
+
id: z.string().uuid(),
|
|
8387
|
+
generation: z.number().int().positive(),
|
|
8388
|
+
})
|
|
8389
|
+
.strict()
|
|
8390
|
+
.nullable(),
|
|
8391
|
+
resolvedRig: z
|
|
8392
|
+
.object({
|
|
8393
|
+
id: z.string().uuid(),
|
|
8394
|
+
versionId: z.string().uuid(),
|
|
8395
|
+
defaultVariableSets: z
|
|
8396
|
+
.array(
|
|
8397
|
+
z
|
|
8398
|
+
.object({
|
|
8399
|
+
id: z.string().uuid(),
|
|
8400
|
+
generation: z.number().int().positive(),
|
|
8401
|
+
})
|
|
8402
|
+
.strict(),
|
|
8403
|
+
)
|
|
8404
|
+
.max(25),
|
|
8405
|
+
})
|
|
8406
|
+
.strict()
|
|
8407
|
+
.nullable(),
|
|
8408
|
+
resolvedSlackBotConnection: z
|
|
8409
|
+
.object({
|
|
8410
|
+
id: z.string().uuid(),
|
|
8411
|
+
version: z.number().int().positive(),
|
|
8412
|
+
verifiedInstallVersion: z.number().int().positive(),
|
|
8413
|
+
metadata: z
|
|
8414
|
+
.object({
|
|
8415
|
+
credentialRole: z.literal("opengeni_slack_bot"),
|
|
8416
|
+
credentialLabel: z.literal("OpenGeni Slack bot"),
|
|
8417
|
+
slackTeamId: z.string().min(1).max(64),
|
|
8418
|
+
slackTeamName: z.string().min(1).max(256),
|
|
8419
|
+
botUserId: z.string().min(1).max(64),
|
|
8420
|
+
botId: z.string().min(1).max(64),
|
|
8421
|
+
botDisplayName: z.enum(["OpenGeni", "OpenGeni Staging"]),
|
|
8422
|
+
verifiedAt: z.string().datetime({ offset: true }),
|
|
8423
|
+
})
|
|
8424
|
+
.passthrough(),
|
|
8425
|
+
})
|
|
8426
|
+
.strict()
|
|
8427
|
+
.nullable(),
|
|
8428
|
+
/**
|
|
8429
|
+
* The effective policy that an existing or already-materialized reusable
|
|
8430
|
+
* session will execute. Generated sessions carry null because their
|
|
8431
|
+
* accepted task policy is used to create the session itself.
|
|
8432
|
+
*/
|
|
8433
|
+
targetSessionExecution: z
|
|
8434
|
+
.object({
|
|
8435
|
+
sessionId: z.string().uuid(),
|
|
8436
|
+
visibility: z.enum(["user_private", "workspace_shared"]),
|
|
8437
|
+
authorityEpoch: z.number().int().positive(),
|
|
8438
|
+
model: z.string().min(1),
|
|
8439
|
+
reasoningEffort: ReasoningEffort,
|
|
8440
|
+
latencyMode: LatencyMode,
|
|
8441
|
+
tools: z.array(ToolRef).max(SCHEDULED_TASK_TOOL_MAX_COUNT),
|
|
8442
|
+
sandboxBackend: SandboxBackend,
|
|
8443
|
+
sandboxOs: SandboxOs,
|
|
8444
|
+
firstPartyMcpTools: z.array(FirstPartyMcpToolName),
|
|
8445
|
+
firstPartyMcpPermissions: z.array(Permission).nullable(),
|
|
8446
|
+
toolPolicy: SessionToolPolicy,
|
|
8447
|
+
mcpServerIds: z.array(z.string().min(1).max(256)).max(SCHEDULED_TASK_TOOL_MAX_COUNT),
|
|
8448
|
+
effectiveMcpServerIds: z
|
|
8449
|
+
.array(z.string().min(1).max(256))
|
|
8450
|
+
.max(SCHEDULED_TASK_TOOL_MAX_COUNT),
|
|
8451
|
+
toolPolicyVersion: z.number().int().nonnegative(),
|
|
8452
|
+
variableSetId: z.string().uuid().nullable(),
|
|
8453
|
+
variableSetGeneration: z.number().int().positive().nullable(),
|
|
8454
|
+
rigId: z.string().uuid().nullable(),
|
|
8455
|
+
rigVersionId: z.string().uuid().nullable(),
|
|
8456
|
+
rigDefaultVariableSets: z
|
|
8457
|
+
.array(
|
|
8458
|
+
z
|
|
8459
|
+
.object({
|
|
8460
|
+
id: z.string().uuid(),
|
|
8461
|
+
generation: z.number().int().positive(),
|
|
8462
|
+
})
|
|
8463
|
+
.strict(),
|
|
8464
|
+
)
|
|
8465
|
+
.max(25),
|
|
8466
|
+
maxNestedAgentDepthOverride: NestedAgentDepthValue.nullable(),
|
|
8467
|
+
effectiveMaxNestedAgentDepth: NestedAgentDepthValue,
|
|
8468
|
+
})
|
|
8469
|
+
.strict()
|
|
8470
|
+
.nullable(),
|
|
8471
|
+
generatedSessionBinding: z
|
|
8472
|
+
.object({
|
|
8473
|
+
createIdempotencyKey: z.string().min(1).max(512),
|
|
8474
|
+
effectiveMaxNestedAgentDepth: NestedAgentDepthValue,
|
|
8475
|
+
nestedAgentDepthPolicySource: NestedAgentDepthPolicySource,
|
|
8476
|
+
codexCompactionMode: CodexCompactionMode,
|
|
8477
|
+
})
|
|
8478
|
+
.strict()
|
|
8479
|
+
.nullable(),
|
|
8480
|
+
personalConnectionDelegations: McpPersonalConnectionDelegations,
|
|
8481
|
+
personalResourceAuthoritySubjectId: z.string().min(1).nullable(),
|
|
8482
|
+
/** One accepted human principal for every resource-bearing scheduled run. */
|
|
8483
|
+
causalHumanSubjectId: z.string().min(1).nullable().default(null),
|
|
8484
|
+
/** Exact revision-bound human membership proof; never inferred at execution. */
|
|
8485
|
+
causalHumanAuthority: z
|
|
8486
|
+
.object({
|
|
8487
|
+
subjectId: z.string().min(1),
|
|
8488
|
+
organizationMembershipId: z.string().uuid(),
|
|
8489
|
+
membershipAuthorizationRevision: z.number().int().positive(),
|
|
8490
|
+
})
|
|
8491
|
+
.strict()
|
|
8492
|
+
.nullable()
|
|
8493
|
+
.default(null),
|
|
8494
|
+
xaiProviderAccountAuthoritySnapshot: XaiProviderAccountAuthoritySnapshotV1,
|
|
8495
|
+
xaiAuthoritySubjectId: z.string().min(1).nullable(),
|
|
8496
|
+
connectionAuthoritySubjectId: z.string().min(1).nullable(),
|
|
8497
|
+
triggerInitiator: TurnInitiator,
|
|
8498
|
+
agentRunUsageIdempotencyKey: z.string().min(1).max(512).nullable(),
|
|
8499
|
+
incidentPreflightRequired: z.boolean(),
|
|
8500
|
+
alertOccurrenceLabels: z.record(z.string(), z.string()).nullable(),
|
|
8501
|
+
})
|
|
8502
|
+
.strict()
|
|
8503
|
+
.superRefine((value, context) => {
|
|
8504
|
+
if (scheduledTaskJsonUtf8Bytes(value) > SCHEDULED_TASK_ACCEPTED_EXECUTION_MAX_BYTES) {
|
|
8505
|
+
context.addIssue({
|
|
8506
|
+
code: "custom",
|
|
8507
|
+
message: `scheduled accepted execution exceeds ${SCHEDULED_TASK_ACCEPTED_EXECUTION_MAX_BYTES} UTF-8 bytes`,
|
|
8508
|
+
});
|
|
8509
|
+
}
|
|
8510
|
+
});
|
|
8511
|
+
export type ScheduledTaskRunAcceptedExecution = z.infer<typeof ScheduledTaskRunAcceptedExecution>;
|
|
8512
|
+
|
|
8513
|
+
export const KnowledgeSourceSyncFailure = /* @__PURE__ */ z.object({
|
|
8514
|
+
externalObjectId: KnowledgeSourceSyncSubject,
|
|
8515
|
+
code: z.enum([
|
|
8516
|
+
"authority_changed",
|
|
8517
|
+
"connection_reconnect_required",
|
|
8518
|
+
"provider_unavailable",
|
|
8519
|
+
"provider_rejected",
|
|
8520
|
+
"provider_payload_invalid",
|
|
8521
|
+
"content_unsupported",
|
|
8522
|
+
"content_too_large",
|
|
8523
|
+
"resource_limit",
|
|
8524
|
+
"item_processing_failed",
|
|
6800
8525
|
"indexing_failed",
|
|
6801
8526
|
"internal_failure",
|
|
6802
8527
|
]),
|
|
@@ -6835,6 +8560,12 @@ export const ScheduledTaskRun = /* @__PURE__ */ z.object({
|
|
|
6835
8560
|
accountId: z.string().uuid(),
|
|
6836
8561
|
workspaceId: z.string().uuid(),
|
|
6837
8562
|
taskId: z.string().uuid(),
|
|
8563
|
+
taskAuthorityRevision: z.number().int().positive().nullable().default(null),
|
|
8564
|
+
taskExecutionDigest: z
|
|
8565
|
+
.string()
|
|
8566
|
+
.regex(/^[0-9a-f]{64}$/u)
|
|
8567
|
+
.nullable()
|
|
8568
|
+
.default(null),
|
|
6838
8569
|
status: ScheduledTaskRunStatus,
|
|
6839
8570
|
triggerType: ScheduledTaskTriggerType,
|
|
6840
8571
|
scheduledAt: z.string().nullable(),
|
|
@@ -6852,7 +8583,7 @@ export const ScheduledTaskRun = /* @__PURE__ */ z.object({
|
|
|
6852
8583
|
export type ScheduledTaskRun = z.infer<typeof ScheduledTaskRun>;
|
|
6853
8584
|
|
|
6854
8585
|
const CreateAgentScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias({
|
|
6855
|
-
name:
|
|
8586
|
+
name: ScheduledTaskNameInput,
|
|
6856
8587
|
schedule: ScheduledTaskScheduleSpec,
|
|
6857
8588
|
action: z
|
|
6858
8589
|
.object({ kind: z.literal("agent_turn") })
|
|
@@ -6861,13 +8592,14 @@ const CreateAgentScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias({
|
|
|
6861
8592
|
runMode: ScheduledTaskRunMode.default("new_session_per_run"),
|
|
6862
8593
|
overlapPolicy: ScheduledTaskOverlapPolicy.default("allow_concurrent"),
|
|
6863
8594
|
targetSessionId: z.string().uuid().nullable().optional(),
|
|
6864
|
-
|
|
8595
|
+
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
8596
|
+
agentConfig: ScheduledTaskAgentConfigInput,
|
|
6865
8597
|
status: ScheduledTaskStatus.default("active"),
|
|
6866
8598
|
variableSetId: z.string().uuid().nullable().optional(),
|
|
6867
8599
|
environmentId: z.string().uuid().nullable().optional(),
|
|
6868
8600
|
// The rig each run binds to (M3); its active version is resolved per fire.
|
|
6869
8601
|
rigId: z.string().uuid().nullable().optional(),
|
|
6870
|
-
metadata:
|
|
8602
|
+
metadata: ScheduledTaskMetadataInput.default({}),
|
|
6871
8603
|
}).superRefine((value, context) => {
|
|
6872
8604
|
if (value.runMode === "existing_session" && !value.targetSessionId) {
|
|
6873
8605
|
context.addIssue({
|
|
@@ -6915,6 +8647,7 @@ const CreateKnowledgeSourceSyncScheduledTaskRequest = /* @__PURE__ */ z
|
|
|
6915
8647
|
variableSetId: null,
|
|
6916
8648
|
environmentId: null,
|
|
6917
8649
|
rigId: null,
|
|
8650
|
+
connectionAuthorities: [],
|
|
6918
8651
|
}));
|
|
6919
8652
|
|
|
6920
8653
|
export const CreateScheduledTaskRequest = /* @__PURE__ */ z.union([
|
|
@@ -6923,59 +8656,393 @@ export const CreateScheduledTaskRequest = /* @__PURE__ */ z.union([
|
|
|
6923
8656
|
]);
|
|
6924
8657
|
export type CreateScheduledTaskRequest = z.infer<typeof CreateScheduledTaskRequest>;
|
|
6925
8658
|
|
|
6926
|
-
export const UpdateScheduledTaskRequest =
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
8659
|
+
export const UpdateScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias({
|
|
8660
|
+
name: ScheduledTaskNameInput.optional(),
|
|
8661
|
+
schedule: ScheduledTaskScheduleSpec.optional(),
|
|
8662
|
+
runMode: ScheduledTaskRunMode.optional(),
|
|
8663
|
+
overlapPolicy: ScheduledTaskOverlapPolicy.optional(),
|
|
8664
|
+
action: ScheduledTaskAction.optional(),
|
|
8665
|
+
targetSessionId: z.string().uuid().nullable().optional(),
|
|
8666
|
+
connectionAuthorities: McpConnectionAuthoritySelections.optional(),
|
|
8667
|
+
agentConfig: ScheduledTaskAgentConfigInput.optional(),
|
|
8668
|
+
status: ScheduledTaskStatus.optional(),
|
|
8669
|
+
variableSetId: z.string().uuid().nullable().optional(),
|
|
8670
|
+
environmentId: z.string().uuid().nullable().optional(),
|
|
8671
|
+
// The rig each run binds to (M3); null clears it. Its active version is
|
|
8672
|
+
// resolved per fire, so an update takes effect on the next dispatch.
|
|
8673
|
+
rigId: z.string().uuid().nullable().optional(),
|
|
8674
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
8675
|
+
}).superRefine((value, context) => {
|
|
8676
|
+
if (value.targetSessionId && value.runMode && value.runMode !== "existing_session") {
|
|
8677
|
+
context.addIssue({
|
|
8678
|
+
code: "custom",
|
|
8679
|
+
path: ["targetSessionId"],
|
|
8680
|
+
message: "targetSessionId requires runMode=existing_session",
|
|
8681
|
+
});
|
|
8682
|
+
}
|
|
8683
|
+
if (value.runMode === "existing_session" && value.targetSessionId === null) {
|
|
8684
|
+
context.addIssue({
|
|
8685
|
+
code: "custom",
|
|
8686
|
+
path: ["targetSessionId"],
|
|
8687
|
+
message: "targetSessionId cannot be null when runMode=existing_session",
|
|
8688
|
+
});
|
|
8689
|
+
}
|
|
8690
|
+
if (
|
|
8691
|
+
value.agentConfig?.goal &&
|
|
8692
|
+
(value.runMode === "existing_session" || Boolean(value.targetSessionId))
|
|
8693
|
+
) {
|
|
8694
|
+
context.addIssue({
|
|
8695
|
+
code: "custom",
|
|
8696
|
+
path: ["agentConfig", "goal"],
|
|
8697
|
+
message: "agentConfig.goal cannot be used with an existing-session target",
|
|
8698
|
+
});
|
|
8699
|
+
}
|
|
8700
|
+
});
|
|
8701
|
+
export type UpdateScheduledTaskRequest = z.infer<typeof UpdateScheduledTaskRequest>;
|
|
8702
|
+
|
|
8703
|
+
/**
|
|
8704
|
+
* Manual-trigger body. `triggerId` is a client-supplied idempotency token: a
|
|
8705
|
+
* retried trigger that reuses the same token charges once and starts one run.
|
|
8706
|
+
* Omitting it makes each call a distinct trigger (the server mints a token).
|
|
8707
|
+
*/
|
|
8708
|
+
export const TriggerScheduledTaskRequest = z.object({
|
|
8709
|
+
triggerId: z.string().min(1).max(128).optional(),
|
|
8710
|
+
});
|
|
8711
|
+
export type TriggerScheduledTaskRequest = z.infer<typeof TriggerScheduledTaskRequest>;
|
|
8712
|
+
|
|
8713
|
+
// ============ Event-triggered automations ============
|
|
8714
|
+
|
|
8715
|
+
export const AUTOMATION_WEBHOOK_MAX_BYTES = 2 * 1024 * 1024;
|
|
8716
|
+
export const AUTOMATION_EVENT_PAYLOAD_MAX_BYTES = 256 * 1024;
|
|
8717
|
+
export const AUTOMATION_SESSION_TEMPLATE_MAX_BYTES = 512 * 1024;
|
|
8718
|
+
export const AUTOMATION_MAX_MATCHED_TRIGGERS = 32;
|
|
8719
|
+
|
|
8720
|
+
const AutomationBoundedJson = z.record(z.string(), z.unknown()).superRefine((value, context) => {
|
|
8721
|
+
let bytes = Number.POSITIVE_INFINITY;
|
|
8722
|
+
try {
|
|
8723
|
+
bytes = new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
8724
|
+
} catch {
|
|
8725
|
+
// The shared JSON/protocol boundary reports the exact runtime path later;
|
|
8726
|
+
// this public ingress still fails closed on an unserializable value.
|
|
8727
|
+
}
|
|
8728
|
+
if (bytes > AUTOMATION_EVENT_PAYLOAD_MAX_BYTES) {
|
|
8729
|
+
context.addIssue({
|
|
8730
|
+
code: "custom",
|
|
8731
|
+
message: `automation JSON exceeds ${AUTOMATION_EVENT_PAYLOAD_MAX_BYTES} UTF-8 bytes`,
|
|
8732
|
+
});
|
|
8733
|
+
}
|
|
8734
|
+
});
|
|
8735
|
+
|
|
8736
|
+
export const AutomationAdapterId = z
|
|
8737
|
+
.string()
|
|
8738
|
+
.min(1)
|
|
8739
|
+
.max(128)
|
|
8740
|
+
.regex(/^[a-z0-9](?:[a-z0-9._/-]*[a-z0-9])?$/);
|
|
8741
|
+
export type AutomationAdapterId = z.infer<typeof AutomationAdapterId>;
|
|
8742
|
+
|
|
8743
|
+
export const AutomationSourceStatus = z.enum(["active", "disabled"]);
|
|
8744
|
+
export type AutomationSourceStatus = z.infer<typeof AutomationSourceStatus>;
|
|
8745
|
+
|
|
8746
|
+
export const AutomationTriggerStatus = z.enum(["active", "paused", "disabled"]);
|
|
8747
|
+
export type AutomationTriggerStatus = z.infer<typeof AutomationTriggerStatus>;
|
|
8748
|
+
|
|
8749
|
+
export const AutomationRunStatus = z.enum([
|
|
8750
|
+
"queued",
|
|
8751
|
+
"dispatching",
|
|
8752
|
+
"dispatched",
|
|
8753
|
+
"skipped",
|
|
8754
|
+
"failed",
|
|
8755
|
+
]);
|
|
8756
|
+
export type AutomationRunStatus = z.infer<typeof AutomationRunStatus>;
|
|
8757
|
+
|
|
8758
|
+
export const AutomationEventStatus = z.enum(["accepted", "ignored", "failed"]);
|
|
8759
|
+
export type AutomationEventStatus = z.infer<typeof AutomationEventStatus>;
|
|
8760
|
+
|
|
8761
|
+
export const SignedJsonAutomationEnvelope = z
|
|
8762
|
+
.object({
|
|
8763
|
+
id: z.string().trim().min(1).max(1024).optional(),
|
|
8764
|
+
type: z.string().trim().min(1).max(256),
|
|
8765
|
+
occurrenceKey: z.string().trim().min(1).max(1024).optional(),
|
|
8766
|
+
occurredAt: z.string().datetime({ offset: true }).nullable().optional(),
|
|
8767
|
+
subject: z.string().trim().min(1).max(512).nullable().optional(),
|
|
8768
|
+
resource: z.string().trim().min(1).max(1024).nullable().optional(),
|
|
8769
|
+
data: z.record(z.string(), z.unknown()).default({}),
|
|
8770
|
+
})
|
|
8771
|
+
.strict();
|
|
8772
|
+
export type SignedJsonAutomationEnvelope = z.infer<typeof SignedJsonAutomationEnvelope>;
|
|
8773
|
+
|
|
8774
|
+
const AutomationSessionSkill = z
|
|
8775
|
+
.object({
|
|
8776
|
+
name: z
|
|
8777
|
+
.string()
|
|
8778
|
+
.min(1)
|
|
8779
|
+
.max(64)
|
|
8780
|
+
.regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/),
|
|
8781
|
+
description: z.string().min(1).max(2048).optional(),
|
|
8782
|
+
files: z
|
|
8783
|
+
.array(
|
|
8784
|
+
z.object({
|
|
8785
|
+
path: z
|
|
8786
|
+
.string()
|
|
8787
|
+
.min(1)
|
|
8788
|
+
.max(512)
|
|
8789
|
+
.refine(
|
|
8790
|
+
(path) =>
|
|
8791
|
+
!path.startsWith("/") &&
|
|
8792
|
+
!path.includes("\\") &&
|
|
8793
|
+
path
|
|
8794
|
+
.split("/")
|
|
8795
|
+
.every((segment) => segment.length > 0 && segment !== "." && segment !== ".."),
|
|
8796
|
+
"automation skill file path must be a safe relative POSIX path",
|
|
8797
|
+
),
|
|
8798
|
+
content: z.string().max(256 * 1024),
|
|
8799
|
+
}),
|
|
8800
|
+
)
|
|
8801
|
+
.min(1)
|
|
8802
|
+
.max(64),
|
|
8803
|
+
})
|
|
8804
|
+
.superRefine((skill, context) => {
|
|
8805
|
+
if (!skill.files.some((file) => file.path === "SKILL.md")) {
|
|
6944
8806
|
context.addIssue({
|
|
6945
8807
|
code: "custom",
|
|
6946
|
-
path: ["
|
|
6947
|
-
message: "
|
|
8808
|
+
path: ["files"],
|
|
8809
|
+
message: "automation skill must include a top-level SKILL.md file",
|
|
6948
8810
|
});
|
|
6949
8811
|
}
|
|
6950
|
-
|
|
8812
|
+
});
|
|
8813
|
+
|
|
8814
|
+
export const AutomationSessionTemplate = z
|
|
8815
|
+
.object({
|
|
8816
|
+
prompt: z
|
|
8817
|
+
.string()
|
|
8818
|
+
.trim()
|
|
8819
|
+
.min(1)
|
|
8820
|
+
.max(64 * 1024),
|
|
8821
|
+
instructions: z
|
|
8822
|
+
.string()
|
|
8823
|
+
.trim()
|
|
8824
|
+
.min(1)
|
|
8825
|
+
.max(64 * 1024)
|
|
8826
|
+
.nullable()
|
|
8827
|
+
.default(null),
|
|
8828
|
+
resources: z.array(ResourceRef).max(100).default([]),
|
|
8829
|
+
skills: z.array(AutomationSessionSkill).max(32).default([]),
|
|
8830
|
+
tools: z.array(ToolRef).max(128).default([]),
|
|
8831
|
+
firstPartyMcpTools: z.array(FirstPartyMcpToolName).max(128).default([]),
|
|
8832
|
+
firstPartyMcpPermissions: z.array(Permission).max(128).default([]),
|
|
8833
|
+
model: z.string().trim().min(1).max(512).nullable().default(null),
|
|
8834
|
+
reasoningEffort: ReasoningEffort.nullable().default(null),
|
|
8835
|
+
sandboxBackend: SandboxBackend.nullable().default(null),
|
|
8836
|
+
policyRole: z.string().trim().min(1).max(128).nullable().default(null),
|
|
8837
|
+
metadata: AutomationBoundedJson.default({}),
|
|
8838
|
+
})
|
|
8839
|
+
.strict()
|
|
8840
|
+
.superRefine((value, context) => {
|
|
8841
|
+
let bytes = Number.POSITIVE_INFINITY;
|
|
8842
|
+
try {
|
|
8843
|
+
bytes = new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
8844
|
+
} catch {
|
|
8845
|
+
// Fail through the size issue below.
|
|
8846
|
+
}
|
|
8847
|
+
if (bytes > AUTOMATION_SESSION_TEMPLATE_MAX_BYTES) {
|
|
6951
8848
|
context.addIssue({
|
|
6952
8849
|
code: "custom",
|
|
6953
|
-
|
|
6954
|
-
message: "targetSessionId cannot be null when runMode=existing_session",
|
|
8850
|
+
message: `automation session template exceeds ${AUTOMATION_SESSION_TEMPLATE_MAX_BYTES} UTF-8 bytes`,
|
|
6955
8851
|
});
|
|
6956
8852
|
}
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
8853
|
+
});
|
|
8854
|
+
export type AutomationSessionTemplate = z.infer<typeof AutomationSessionTemplate>;
|
|
8855
|
+
|
|
8856
|
+
export const AutomationNormalizedEvent = z
|
|
8857
|
+
.object({
|
|
8858
|
+
adapterId: AutomationAdapterId,
|
|
8859
|
+
eventType: z.string().trim().min(1).max(256),
|
|
8860
|
+
occurrenceKey: z.string().trim().min(1).max(1024),
|
|
8861
|
+
occurredAt: z.string().datetime({ offset: true }).nullable().default(null),
|
|
8862
|
+
subject: z.string().trim().min(1).max(512).nullable().default(null),
|
|
8863
|
+
resource: z.string().trim().min(1).max(1024).nullable().default(null),
|
|
8864
|
+
payload: AutomationBoundedJson,
|
|
8865
|
+
})
|
|
8866
|
+
.strict();
|
|
8867
|
+
export type AutomationNormalizedEvent = z.infer<typeof AutomationNormalizedEvent>;
|
|
8868
|
+
|
|
8869
|
+
export const AutomationAcceptedExecution = z
|
|
8870
|
+
.object({
|
|
8871
|
+
version: z.literal(1),
|
|
8872
|
+
accountId: z.string().uuid(),
|
|
8873
|
+
workspaceId: z.string().uuid(),
|
|
8874
|
+
sourceId: z.string().uuid(),
|
|
8875
|
+
sourceVersion: z.number().int().positive(),
|
|
8876
|
+
triggerId: z.string().uuid(),
|
|
8877
|
+
triggerRevision: z.number().int().positive(),
|
|
8878
|
+
eventId: z.string().uuid(),
|
|
8879
|
+
adapterId: AutomationAdapterId,
|
|
8880
|
+
occurrenceKey: z.string().min(1).max(1024),
|
|
8881
|
+
initialMessage: z
|
|
8882
|
+
.string()
|
|
8883
|
+
.min(1)
|
|
8884
|
+
.max(256 * 1024),
|
|
8885
|
+
sessionTemplate: AutomationSessionTemplate,
|
|
8886
|
+
serviceSubjectId: z.string().min(1).max(512),
|
|
8887
|
+
serviceLabel: z.string().min(1).max(200),
|
|
8888
|
+
provenance: AutomationBoundedJson,
|
|
8889
|
+
})
|
|
8890
|
+
.strict();
|
|
8891
|
+
export type AutomationAcceptedExecution = z.infer<typeof AutomationAcceptedExecution>;
|
|
8892
|
+
|
|
8893
|
+
export const CreateAutomationSourceRequest = z
|
|
8894
|
+
.object({
|
|
8895
|
+
name: z.string().trim().min(1).max(200),
|
|
8896
|
+
adapterId: AutomationAdapterId.default("signed-json.v1"),
|
|
8897
|
+
webhookSecret: z.string().min(16).max(65_536),
|
|
8898
|
+
configuration: AutomationBoundedJson.default({}),
|
|
8899
|
+
})
|
|
8900
|
+
.strict();
|
|
8901
|
+
export type CreateAutomationSourceRequest = z.infer<typeof CreateAutomationSourceRequest>;
|
|
8902
|
+
|
|
8903
|
+
export const UpdateAutomationSourceRequest = z
|
|
8904
|
+
.object({
|
|
8905
|
+
name: z.string().trim().min(1).max(200).optional(),
|
|
8906
|
+
webhookSecret: z.string().min(16).max(65_536).optional(),
|
|
8907
|
+
configuration: AutomationBoundedJson.optional(),
|
|
8908
|
+
status: AutomationSourceStatus.optional(),
|
|
8909
|
+
})
|
|
8910
|
+
.strict()
|
|
8911
|
+
.refine((value) => Object.keys(value).length > 0, "automation source update is empty");
|
|
8912
|
+
export type UpdateAutomationSourceRequest = z.infer<typeof UpdateAutomationSourceRequest>;
|
|
8913
|
+
|
|
8914
|
+
export const AutomationSource = z.object({
|
|
8915
|
+
id: z.string().uuid(),
|
|
8916
|
+
accountId: z.string().uuid(),
|
|
8917
|
+
workspaceId: z.string().uuid(),
|
|
8918
|
+
name: z.string(),
|
|
8919
|
+
adapterId: AutomationAdapterId,
|
|
8920
|
+
configuration: z.record(z.string(), z.unknown()),
|
|
8921
|
+
status: AutomationSourceStatus,
|
|
8922
|
+
version: z.number().int().positive(),
|
|
8923
|
+
packInstallationId: z.string().uuid().nullable(),
|
|
8924
|
+
packConnectorId: z.string().min(1).max(128).nullable(),
|
|
8925
|
+
hasWebhookSecret: z.boolean(),
|
|
8926
|
+
webhookPath: z.string().min(1),
|
|
8927
|
+
createdBySubjectId: z.string(),
|
|
8928
|
+
createdAt: z.string(),
|
|
8929
|
+
updatedAt: z.string(),
|
|
8930
|
+
});
|
|
8931
|
+
export type AutomationSource = z.infer<typeof AutomationSource>;
|
|
8932
|
+
|
|
8933
|
+
export const CreateAutomationTriggerRequest = z
|
|
8934
|
+
.object({
|
|
8935
|
+
sourceId: z.string().uuid(),
|
|
8936
|
+
name: z.string().trim().min(1).max(200),
|
|
8937
|
+
eventTypes: z.array(z.string().trim().min(1).max(256)).min(1).max(64),
|
|
8938
|
+
configuration: AutomationBoundedJson.default({}),
|
|
8939
|
+
parameters: AutomationBoundedJson.default({}),
|
|
8940
|
+
sessionTemplate: AutomationSessionTemplate,
|
|
8941
|
+
status: AutomationTriggerStatus.default("active"),
|
|
8942
|
+
packInstallationId: z.string().uuid().nullable().default(null),
|
|
8943
|
+
packTemplateId: z.string().trim().min(1).max(128).nullable().default(null),
|
|
8944
|
+
})
|
|
8945
|
+
.strict()
|
|
8946
|
+
.superRefine((value, context) => {
|
|
8947
|
+
if ((value.packInstallationId === null) !== (value.packTemplateId === null)) {
|
|
6961
8948
|
context.addIssue({
|
|
6962
8949
|
code: "custom",
|
|
6963
|
-
path: ["
|
|
6964
|
-
message: "
|
|
8950
|
+
path: ["packTemplateId"],
|
|
8951
|
+
message: "packInstallationId and packTemplateId must be supplied together",
|
|
6965
8952
|
});
|
|
6966
8953
|
}
|
|
6967
8954
|
});
|
|
6968
|
-
export type
|
|
8955
|
+
export type CreateAutomationTriggerRequest = z.infer<typeof CreateAutomationTriggerRequest>;
|
|
6969
8956
|
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
8957
|
+
export const UpdateAutomationTriggerRequest = z
|
|
8958
|
+
.object({
|
|
8959
|
+
expectedRevision: z.number().int().positive(),
|
|
8960
|
+
name: z.string().trim().min(1).max(200).optional(),
|
|
8961
|
+
eventTypes: z.array(z.string().trim().min(1).max(256)).min(1).max(64).optional(),
|
|
8962
|
+
configuration: AutomationBoundedJson.optional(),
|
|
8963
|
+
parameters: AutomationBoundedJson.optional(),
|
|
8964
|
+
sessionTemplate: AutomationSessionTemplate.optional(),
|
|
8965
|
+
status: AutomationTriggerStatus.optional(),
|
|
8966
|
+
})
|
|
8967
|
+
.strict()
|
|
8968
|
+
.refine((value) => Object.keys(value).some((key) => key !== "expectedRevision"), {
|
|
8969
|
+
message: "automation trigger update is empty",
|
|
8970
|
+
});
|
|
8971
|
+
export type UpdateAutomationTriggerRequest = z.infer<typeof UpdateAutomationTriggerRequest>;
|
|
8972
|
+
|
|
8973
|
+
export const AutomationTrigger = z.object({
|
|
8974
|
+
id: z.string().uuid(),
|
|
8975
|
+
accountId: z.string().uuid(),
|
|
8976
|
+
workspaceId: z.string().uuid(),
|
|
8977
|
+
sourceId: z.string().uuid(),
|
|
8978
|
+
name: z.string(),
|
|
8979
|
+
adapterId: AutomationAdapterId,
|
|
8980
|
+
eventTypes: z.array(z.string()),
|
|
8981
|
+
configuration: z.record(z.string(), z.unknown()),
|
|
8982
|
+
parameters: z.record(z.string(), z.unknown()),
|
|
8983
|
+
sessionTemplate: AutomationSessionTemplate,
|
|
8984
|
+
status: AutomationTriggerStatus,
|
|
8985
|
+
revision: z.number().int().positive(),
|
|
8986
|
+
packInstallationId: z.string().uuid().nullable(),
|
|
8987
|
+
packTemplateId: z.string().nullable(),
|
|
8988
|
+
createdBySubjectId: z.string(),
|
|
8989
|
+
createdAt: z.string(),
|
|
8990
|
+
updatedAt: z.string(),
|
|
6977
8991
|
});
|
|
6978
|
-
export type
|
|
8992
|
+
export type AutomationTrigger = z.infer<typeof AutomationTrigger>;
|
|
8993
|
+
|
|
8994
|
+
export const AutomationRun = z.object({
|
|
8995
|
+
id: z.string().uuid(),
|
|
8996
|
+
accountId: z.string().uuid(),
|
|
8997
|
+
workspaceId: z.string().uuid(),
|
|
8998
|
+
sourceId: z.string().uuid(),
|
|
8999
|
+
triggerId: z.string().uuid(),
|
|
9000
|
+
triggerRevision: z.number().int().positive(),
|
|
9001
|
+
eventId: z.string().uuid(),
|
|
9002
|
+
occurrenceKey: z.string(),
|
|
9003
|
+
status: AutomationRunStatus,
|
|
9004
|
+
sessionId: z.string().uuid().nullable(),
|
|
9005
|
+
errorCode: z.string().nullable(),
|
|
9006
|
+
createdAt: z.string(),
|
|
9007
|
+
updatedAt: z.string(),
|
|
9008
|
+
});
|
|
9009
|
+
export type AutomationRun = z.infer<typeof AutomationRun>;
|
|
9010
|
+
|
|
9011
|
+
export const AutomationWebhookResult = z.object({
|
|
9012
|
+
accepted: z.boolean(),
|
|
9013
|
+
duplicate: z.boolean(),
|
|
9014
|
+
ignoredReason: z.string().nullable(),
|
|
9015
|
+
eventId: z.string().uuid().nullable(),
|
|
9016
|
+
runIds: z.array(z.string().uuid()),
|
|
9017
|
+
});
|
|
9018
|
+
export type AutomationWebhookResult = z.infer<typeof AutomationWebhookResult>;
|
|
9019
|
+
|
|
9020
|
+
export const TriggerAutomationManuallyRequest = z
|
|
9021
|
+
.object({
|
|
9022
|
+
deliveryId: z.string().trim().min(1).max(512).optional(),
|
|
9023
|
+
eventType: z.string().trim().min(1).max(256),
|
|
9024
|
+
occurrenceKey: z.string().trim().min(1).max(1024),
|
|
9025
|
+
payload: AutomationBoundedJson.default({}),
|
|
9026
|
+
occurredAt: z.string().datetime({ offset: true }).nullable().default(null),
|
|
9027
|
+
subject: z.string().trim().min(1).max(512).nullable().default(null),
|
|
9028
|
+
resource: z.string().trim().min(1).max(1024).nullable().default(null),
|
|
9029
|
+
})
|
|
9030
|
+
.strict();
|
|
9031
|
+
export type TriggerAutomationManuallyRequest = z.infer<typeof TriggerAutomationManuallyRequest>;
|
|
9032
|
+
|
|
9033
|
+
export const CapabilityPackAutomationTemplate = z
|
|
9034
|
+
.object({
|
|
9035
|
+
id: z.string().min(1).max(128),
|
|
9036
|
+
name: z.string().min(1).max(200),
|
|
9037
|
+
description: z.string().min(1).max(4096),
|
|
9038
|
+
adapterId: AutomationAdapterId,
|
|
9039
|
+
eventTypes: z.array(z.string().min(1).max(256)).min(1).max(64),
|
|
9040
|
+
sessionTemplate: AutomationSessionTemplate,
|
|
9041
|
+
configuration: AutomationBoundedJson.default({}),
|
|
9042
|
+
connectionRequirement: z.string().min(1).max(128).nullable().default(null),
|
|
9043
|
+
})
|
|
9044
|
+
.strict();
|
|
9045
|
+
export type CapabilityPackAutomationTemplate = z.infer<typeof CapabilityPackAutomationTemplate>;
|
|
6979
9046
|
|
|
6980
9047
|
export const CapabilityPackConnectorAuthModel = z.enum([
|
|
6981
9048
|
"oauth2_authorization_code_pkce",
|
|
@@ -7282,6 +9349,7 @@ export const CapabilityPack = z.preprocess(
|
|
|
7282
9349
|
connectors: z.array(CapabilityPackConnector).default([]),
|
|
7283
9350
|
knowledge: z.array(CapabilityPackKnowledge).default([]),
|
|
7284
9351
|
scheduledTaskTemplates: z.array(CapabilityPackScheduledTaskTemplate).default([]),
|
|
9352
|
+
automationTemplates: z.array(CapabilityPackAutomationTemplate).max(64).optional(),
|
|
7285
9353
|
variableSet: CapabilityPackVariableSet.optional(),
|
|
7286
9354
|
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
7287
9355
|
})
|
|
@@ -7308,6 +9376,17 @@ export const CapabilityPack = z.preprocess(
|
|
|
7308
9376
|
}
|
|
7309
9377
|
componentKeys.add(key);
|
|
7310
9378
|
});
|
|
9379
|
+
const automationTemplateIds = new Set<string>();
|
|
9380
|
+
pack.automationTemplates?.forEach((template, index) => {
|
|
9381
|
+
if (automationTemplateIds.has(template.id)) {
|
|
9382
|
+
ctx.addIssue({
|
|
9383
|
+
code: "custom",
|
|
9384
|
+
message: `duplicate Pack automation template id: ${template.id}`,
|
|
9385
|
+
path: ["automationTemplates", index, "id"],
|
|
9386
|
+
});
|
|
9387
|
+
}
|
|
9388
|
+
automationTemplateIds.add(template.id);
|
|
9389
|
+
});
|
|
7311
9390
|
if (!pack.sandboxProviderImages?.modal) {
|
|
7312
9391
|
return;
|
|
7313
9392
|
}
|
|
@@ -7345,33 +9424,231 @@ export const WorkspaceRegisteredPack = z.object({
|
|
|
7345
9424
|
});
|
|
7346
9425
|
export type WorkspaceRegisteredPack = z.infer<typeof WorkspaceRegisteredPack>;
|
|
7347
9426
|
|
|
7348
|
-
export const PackInstallationStatus = z.enum([
|
|
7349
|
-
"installing",
|
|
7350
|
-
"active",
|
|
7351
|
-
"needs_attention",
|
|
7352
|
-
"disabled",
|
|
7353
|
-
]);
|
|
7354
|
-
export type PackInstallationStatus = z.infer<typeof PackInstallationStatus>;
|
|
9427
|
+
export const PackInstallationStatus = z.enum([
|
|
9428
|
+
"installing",
|
|
9429
|
+
"active",
|
|
9430
|
+
"needs_attention",
|
|
9431
|
+
"disabled",
|
|
9432
|
+
]);
|
|
9433
|
+
export type PackInstallationStatus = z.infer<typeof PackInstallationStatus>;
|
|
9434
|
+
|
|
9435
|
+
export const PackInstallation = z.object({
|
|
9436
|
+
id: z.string().uuid(),
|
|
9437
|
+
accountId: z.string().uuid(),
|
|
9438
|
+
workspaceId: z.string().uuid(),
|
|
9439
|
+
packId: z.string().min(1),
|
|
9440
|
+
status: PackInstallationStatus,
|
|
9441
|
+
version: z.number().int().positive(),
|
|
9442
|
+
manifestSnapshot: CapabilityPack.nullable(),
|
|
9443
|
+
manifestDigest: z
|
|
9444
|
+
.string()
|
|
9445
|
+
.regex(/^[0-9a-f]{64}$/)
|
|
9446
|
+
.nullable(),
|
|
9447
|
+
selectedRigId: z.string().uuid().nullable(),
|
|
9448
|
+
installedBySubjectId: z.string().min(1).max(1024).nullable(),
|
|
9449
|
+
metadata: z.record(z.string(), z.unknown()),
|
|
9450
|
+
enabledAt: z.string(),
|
|
9451
|
+
updatedAt: z.string(),
|
|
9452
|
+
});
|
|
9453
|
+
export type PackInstallation = z.infer<typeof PackInstallation>;
|
|
9454
|
+
|
|
9455
|
+
// ============ OpenGeni Review Bot — provider-neutral pull-request review automation ============
|
|
9456
|
+
|
|
9457
|
+
export const OPENGENI_PR_REVIEW_PACK_ID = "pr-review" as const;
|
|
9458
|
+
export const OPENGENI_PR_REVIEW_SESSION_ROLE = "pull_request_review" as const;
|
|
9459
|
+
|
|
9460
|
+
export const PrReviewProvider = GitCredentialProvider;
|
|
9461
|
+
export type PrReviewProvider = z.infer<typeof PrReviewProvider>;
|
|
9462
|
+
|
|
9463
|
+
export const PrReviewCredentialKind = /* @__PURE__ */ z.enum(["github_app", "provider_token"]);
|
|
9464
|
+
export type PrReviewCredentialKind = z.infer<typeof PrReviewCredentialKind>;
|
|
9465
|
+
|
|
9466
|
+
export const PrReviewWebhookAuthKind = /* @__PURE__ */ z.enum([
|
|
9467
|
+
"hmac_sha256",
|
|
9468
|
+
"shared_token",
|
|
9469
|
+
"basic",
|
|
9470
|
+
]);
|
|
9471
|
+
export type PrReviewWebhookAuthKind = z.infer<typeof PrReviewWebhookAuthKind>;
|
|
9472
|
+
|
|
9473
|
+
const PrReviewSecretInput = /* @__PURE__ */ (() => z.string().min(16).max(65_536))();
|
|
9474
|
+
|
|
9475
|
+
export const CreatePrReviewAppRegistrationRequest = /* @__PURE__ */ (() =>
|
|
9476
|
+
z
|
|
9477
|
+
.object({
|
|
9478
|
+
name: z.string().trim().min(1).max(200),
|
|
9479
|
+
provider: PrReviewProvider,
|
|
9480
|
+
providerBaseUrl: z.string().url().max(2048).optional(),
|
|
9481
|
+
appId: z.string().trim().min(1).max(512).optional(),
|
|
9482
|
+
credentialKind: PrReviewCredentialKind,
|
|
9483
|
+
privateKey: PrReviewSecretInput.optional(),
|
|
9484
|
+
accessToken: PrReviewSecretInput.optional(),
|
|
9485
|
+
accessTokenExpiresAt: z.string().datetime().nullable().optional(),
|
|
9486
|
+
webhookSecret: PrReviewSecretInput,
|
|
9487
|
+
webhookUsername: z.string().min(1).max(512).optional(),
|
|
9488
|
+
})
|
|
9489
|
+
.strict()
|
|
9490
|
+
.superRefine((value, context) => {
|
|
9491
|
+
if (value.provider === "github" && value.credentialKind !== "github_app") {
|
|
9492
|
+
context.addIssue({
|
|
9493
|
+
code: "custom",
|
|
9494
|
+
path: ["credentialKind"],
|
|
9495
|
+
message: "GitHub PR Review registrations require a dedicated GitHub App",
|
|
9496
|
+
});
|
|
9497
|
+
}
|
|
9498
|
+
if (value.provider === "github" && (!value.appId || !value.privateKey)) {
|
|
9499
|
+
context.addIssue({
|
|
9500
|
+
code: "custom",
|
|
9501
|
+
path: [!value.appId ? "appId" : "privateKey"],
|
|
9502
|
+
message: "GitHub PR Review registrations require the dedicated App ID and private key",
|
|
9503
|
+
});
|
|
9504
|
+
}
|
|
9505
|
+
if (value.provider !== "github" && value.credentialKind !== "provider_token") {
|
|
9506
|
+
context.addIssue({
|
|
9507
|
+
code: "custom",
|
|
9508
|
+
path: ["credentialKind"],
|
|
9509
|
+
message: "GitLab and Azure DevOps PR Review registrations require a provider token",
|
|
9510
|
+
});
|
|
9511
|
+
}
|
|
9512
|
+
if (value.credentialKind === "provider_token" && !value.accessToken) {
|
|
9513
|
+
context.addIssue({
|
|
9514
|
+
code: "custom",
|
|
9515
|
+
path: ["accessToken"],
|
|
9516
|
+
message: "provider_token credentials require accessToken",
|
|
9517
|
+
});
|
|
9518
|
+
}
|
|
9519
|
+
if (
|
|
9520
|
+
value.credentialKind === "github_app" &&
|
|
9521
|
+
(value.accessToken !== undefined || value.privateKey === undefined)
|
|
9522
|
+
) {
|
|
9523
|
+
context.addIssue({
|
|
9524
|
+
code: "custom",
|
|
9525
|
+
path: [value.accessToken !== undefined ? "accessToken" : "privateKey"],
|
|
9526
|
+
message: "GitHub App credentials require privateKey and cannot include accessToken",
|
|
9527
|
+
});
|
|
9528
|
+
}
|
|
9529
|
+
if (value.credentialKind === "provider_token" && value.privateKey !== undefined) {
|
|
9530
|
+
context.addIssue({
|
|
9531
|
+
code: "custom",
|
|
9532
|
+
path: ["privateKey"],
|
|
9533
|
+
message: "provider_token credentials cannot include a GitHub privateKey",
|
|
9534
|
+
});
|
|
9535
|
+
}
|
|
9536
|
+
if (value.provider === "github" && value.accessTokenExpiresAt !== undefined) {
|
|
9537
|
+
context.addIssue({
|
|
9538
|
+
code: "custom",
|
|
9539
|
+
path: ["accessTokenExpiresAt"],
|
|
9540
|
+
message: "GitHub App registrations do not use accessTokenExpiresAt",
|
|
9541
|
+
});
|
|
9542
|
+
}
|
|
9543
|
+
if (value.provider === "azure_devops" && !value.webhookUsername) {
|
|
9544
|
+
context.addIssue({
|
|
9545
|
+
code: "custom",
|
|
9546
|
+
path: ["webhookUsername"],
|
|
9547
|
+
message: "Azure DevOps service hooks require a Basic authentication username",
|
|
9548
|
+
});
|
|
9549
|
+
}
|
|
9550
|
+
}))();
|
|
9551
|
+
export type CreatePrReviewAppRegistrationRequest = z.infer<
|
|
9552
|
+
typeof CreatePrReviewAppRegistrationRequest
|
|
9553
|
+
>;
|
|
9554
|
+
|
|
9555
|
+
export const UpdatePrReviewAppRegistrationRequest = /* @__PURE__ */ (() =>
|
|
9556
|
+
z
|
|
9557
|
+
.object({
|
|
9558
|
+
name: z.string().trim().min(1).max(200).optional(),
|
|
9559
|
+
accessToken: PrReviewSecretInput.optional(),
|
|
9560
|
+
privateKey: PrReviewSecretInput.optional(),
|
|
9561
|
+
accessTokenExpiresAt: z.string().datetime().nullable().optional(),
|
|
9562
|
+
webhookSecret: PrReviewSecretInput.optional(),
|
|
9563
|
+
webhookUsername: z.string().min(1).max(512).optional(),
|
|
9564
|
+
status: z.enum(["active", "disabled"]).optional(),
|
|
9565
|
+
})
|
|
9566
|
+
.strict()
|
|
9567
|
+
.refine((value) => Object.keys(value).length > 0, {
|
|
9568
|
+
message: "PR Review registration update must change at least one field",
|
|
9569
|
+
}))();
|
|
9570
|
+
export type UpdatePrReviewAppRegistrationRequest = z.infer<
|
|
9571
|
+
typeof UpdatePrReviewAppRegistrationRequest
|
|
9572
|
+
>;
|
|
9573
|
+
|
|
9574
|
+
export const PrReviewAppRegistration = /* @__PURE__ */ (() =>
|
|
9575
|
+
z.object({
|
|
9576
|
+
id: z.string().uuid(),
|
|
9577
|
+
sourceId: z.string().uuid(),
|
|
9578
|
+
accountId: z.string().uuid(),
|
|
9579
|
+
workspaceId: z.string().uuid(),
|
|
9580
|
+
name: z.string(),
|
|
9581
|
+
provider: PrReviewProvider,
|
|
9582
|
+
providerBaseUrl: z.string().url(),
|
|
9583
|
+
appId: z.string().nullable(),
|
|
9584
|
+
credentialKind: PrReviewCredentialKind,
|
|
9585
|
+
hasCredential: z.boolean(),
|
|
9586
|
+
accessTokenExpiresAt: z.string().nullable(),
|
|
9587
|
+
webhookAuthKind: PrReviewWebhookAuthKind,
|
|
9588
|
+
hasWebhookSecret: z.boolean(),
|
|
9589
|
+
webhookUsername: z.string().nullable(),
|
|
9590
|
+
webhookPath: z.string(),
|
|
9591
|
+
status: z.enum(["active", "disabled"]),
|
|
9592
|
+
createdBySubjectId: z.string(),
|
|
9593
|
+
createdAt: z.string(),
|
|
9594
|
+
updatedAt: z.string(),
|
|
9595
|
+
}))();
|
|
9596
|
+
export type PrReviewAppRegistration = z.infer<typeof PrReviewAppRegistration>;
|
|
9597
|
+
|
|
9598
|
+
export const CreatePrReviewRepositoryBindingRequest = /* @__PURE__ */ (() =>
|
|
9599
|
+
z
|
|
9600
|
+
.object({
|
|
9601
|
+
registrationId: z.string().uuid(),
|
|
9602
|
+
repositoryUri: z.string().url().max(2048),
|
|
9603
|
+
repositoryFullName: z.string().trim().min(1).max(1024),
|
|
9604
|
+
providerRepositoryId: z.union([z.string().min(1).max(512), z.number().int().positive()]),
|
|
9605
|
+
installationId: z.union([z.string().min(1).max(512), z.number().int().positive()]).optional(),
|
|
9606
|
+
projectId: z.union([z.string().min(1).max(512), z.number().int().positive()]).optional(),
|
|
9607
|
+
model: z.string().min(1).max(512).nullable().optional(),
|
|
9608
|
+
additionalInstructions: z.string().max(16_384).nullable().optional(),
|
|
9609
|
+
status: z.enum(["active", "disabled"]).default("active"),
|
|
9610
|
+
})
|
|
9611
|
+
.strict())();
|
|
9612
|
+
export type CreatePrReviewRepositoryBindingRequest = z.infer<
|
|
9613
|
+
typeof CreatePrReviewRepositoryBindingRequest
|
|
9614
|
+
>;
|
|
7355
9615
|
|
|
7356
|
-
export const
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
9616
|
+
export const UpdatePrReviewRepositoryBindingRequest = /* @__PURE__ */ (() =>
|
|
9617
|
+
z
|
|
9618
|
+
.object({
|
|
9619
|
+
model: z.string().min(1).max(512).nullable().optional(),
|
|
9620
|
+
additionalInstructions: z.string().max(16_384).nullable().optional(),
|
|
9621
|
+
status: z.enum(["active", "disabled"]).optional(),
|
|
9622
|
+
})
|
|
9623
|
+
.strict()
|
|
9624
|
+
.refine((value) => Object.keys(value).length > 0, {
|
|
9625
|
+
message: "PR Review repository update must change at least one field",
|
|
9626
|
+
}))();
|
|
9627
|
+
export type UpdatePrReviewRepositoryBindingRequest = z.infer<
|
|
9628
|
+
typeof UpdatePrReviewRepositoryBindingRequest
|
|
9629
|
+
>;
|
|
9630
|
+
|
|
9631
|
+
export const PrReviewRepositoryBinding = /* @__PURE__ */ (() =>
|
|
9632
|
+
z.object({
|
|
9633
|
+
id: z.string().uuid(),
|
|
9634
|
+
triggerId: z.string().uuid(),
|
|
9635
|
+
accountId: z.string().uuid(),
|
|
9636
|
+
workspaceId: z.string().uuid(),
|
|
9637
|
+
registrationId: z.string().uuid(),
|
|
9638
|
+
provider: PrReviewProvider,
|
|
9639
|
+
repositoryUri: z.string(),
|
|
9640
|
+
repositoryFullName: z.string(),
|
|
9641
|
+
providerRepositoryId: z.string(),
|
|
9642
|
+
installationId: z.string().nullable(),
|
|
9643
|
+
projectId: z.string().nullable(),
|
|
9644
|
+
model: z.string().nullable(),
|
|
9645
|
+
additionalInstructions: z.string().nullable(),
|
|
9646
|
+
status: z.enum(["active", "disabled"]),
|
|
9647
|
+
createdBySubjectId: z.string(),
|
|
9648
|
+
createdAt: z.string(),
|
|
9649
|
+
updatedAt: z.string(),
|
|
9650
|
+
}))();
|
|
9651
|
+
export type PrReviewRepositoryBinding = z.infer<typeof PrReviewRepositoryBinding>;
|
|
7375
9652
|
|
|
7376
9653
|
export const EnablePackRequest = withVariableSetIdAlias({
|
|
7377
9654
|
variableSetId: z.string().uuid().optional(),
|
|
@@ -7594,6 +9871,8 @@ export const OPENGENI_PERSONAL_SLACK_MCP_URL = "https://mcp.slack.com/mcp" as co
|
|
|
7594
9871
|
export const OPENGENI_SLACK_BOT_CREDENTIAL_ROLE = "opengeni_slack_bot" as const;
|
|
7595
9872
|
export const OPENGENI_SLACK_BOT_CREDENTIAL_LABEL = "OpenGeni Slack bot" as const;
|
|
7596
9873
|
export const OPENGENI_SLACK_BOT_SESSION_METADATA_KEY = "opengeniSlackBotConnectionId" as const;
|
|
9874
|
+
export const OpenGeniSlackBotDisplayName = z.enum(["OpenGeni", "OpenGeni Staging"]);
|
|
9875
|
+
export type OpenGeniSlackBotDisplayName = z.infer<typeof OpenGeniSlackBotDisplayName>;
|
|
7597
9876
|
export const OpenGeniSlackBotConnectionMetadata = z
|
|
7598
9877
|
.object({
|
|
7599
9878
|
credentialRole: z.literal(OPENGENI_SLACK_BOT_CREDENTIAL_ROLE),
|
|
@@ -7602,7 +9881,7 @@ export const OpenGeniSlackBotConnectionMetadata = z
|
|
|
7602
9881
|
slackTeamName: z.string().min(1).max(256),
|
|
7603
9882
|
botUserId: z.string().min(1).max(64),
|
|
7604
9883
|
botId: z.string().min(1).max(64),
|
|
7605
|
-
botDisplayName:
|
|
9884
|
+
botDisplayName: OpenGeniSlackBotDisplayName,
|
|
7606
9885
|
verifiedAt: z.string().datetime({ offset: true }),
|
|
7607
9886
|
})
|
|
7608
9887
|
.passthrough();
|
|
@@ -7652,6 +9931,8 @@ export type FikenOAuthStartResponse = z.infer<typeof FikenOAuthStartResponse>;
|
|
|
7652
9931
|
|
|
7653
9932
|
export const ConnectionMetadata = z.object({
|
|
7654
9933
|
id: z.string().uuid(),
|
|
9934
|
+
/** Opaque owner-only handle used to manage this personal connection's grants. */
|
|
9935
|
+
authorityId: z.string().uuid().optional(),
|
|
7655
9936
|
accountId: z.string().uuid(),
|
|
7656
9937
|
workspaceId: z.string().uuid(),
|
|
7657
9938
|
subjectId: z.string().nullable(),
|
|
@@ -7781,7 +10062,7 @@ export const SlackInstallationBinding = z.object({
|
|
|
7781
10062
|
slackTeamName: z.string().min(1).max(256),
|
|
7782
10063
|
botId: z.string().min(1).max(64),
|
|
7783
10064
|
botUserId: z.string().min(1).max(64),
|
|
7784
|
-
botDisplayName:
|
|
10065
|
+
botDisplayName: OpenGeniSlackBotDisplayName,
|
|
7785
10066
|
state: SlackInstallationBindingState,
|
|
7786
10067
|
quarantineReason: z.string().min(1).nullable(),
|
|
7787
10068
|
version: z.number().int().positive(),
|
|
@@ -8287,6 +10568,43 @@ export const IntegrationFacetDefinitionSummary = z
|
|
|
8287
10568
|
.strict();
|
|
8288
10569
|
export type IntegrationFacetDefinitionSummary = z.infer<typeof IntegrationFacetDefinitionSummary>;
|
|
8289
10570
|
|
|
10571
|
+
/**
|
|
10572
|
+
* Presentation-only consent copy for an integration or connector. Never grants
|
|
10573
|
+
* a scope, selects a connection, or replaces server-side authorization; the UI
|
|
10574
|
+
* falls back to generic copy for any omitted field.
|
|
10575
|
+
*/
|
|
10576
|
+
export const IntegrationPresentation = z
|
|
10577
|
+
.object({
|
|
10578
|
+
providerName: z.string().min(1).max(120).optional(),
|
|
10579
|
+
icon: z.enum(["calendar", "cloud", "contacts", "files", "mail"]).optional(),
|
|
10580
|
+
introduction: z.string().min(1).max(500).optional(),
|
|
10581
|
+
capabilities: z
|
|
10582
|
+
.array(
|
|
10583
|
+
z
|
|
10584
|
+
.object({
|
|
10585
|
+
title: z.string().min(1).max(160),
|
|
10586
|
+
description: z.string().min(1).max(500),
|
|
10587
|
+
})
|
|
10588
|
+
.strict(),
|
|
10589
|
+
)
|
|
10590
|
+
.max(8)
|
|
10591
|
+
.optional(),
|
|
10592
|
+
permissionSummary: z.string().min(1).max(500).optional(),
|
|
10593
|
+
scopeLabels: z
|
|
10594
|
+
.record(
|
|
10595
|
+
z.string().min(1).max(1024),
|
|
10596
|
+
z
|
|
10597
|
+
.object({
|
|
10598
|
+
label: z.string().min(1).max(160),
|
|
10599
|
+
description: z.string().min(1).max(500),
|
|
10600
|
+
})
|
|
10601
|
+
.strict(),
|
|
10602
|
+
)
|
|
10603
|
+
.optional(),
|
|
10604
|
+
})
|
|
10605
|
+
.strict();
|
|
10606
|
+
export type IntegrationPresentation = z.infer<typeof IntegrationPresentation>;
|
|
10607
|
+
|
|
8290
10608
|
export const IntegrationDefinitionSummary = z
|
|
8291
10609
|
.object({
|
|
8292
10610
|
id: z.string().min(1).max(128),
|
|
@@ -8305,6 +10623,7 @@ export const IntegrationDefinitionSummary = z
|
|
|
8305
10623
|
scopes: z.array(z.string().min(1).max(1024)).max(256),
|
|
8306
10624
|
})
|
|
8307
10625
|
.strict(),
|
|
10626
|
+
presentation: IntegrationPresentation.optional(),
|
|
8308
10627
|
facets: z.array(IntegrationFacetDefinitionSummary).max(128),
|
|
8309
10628
|
})
|
|
8310
10629
|
.strict();
|
|
@@ -8338,6 +10657,8 @@ export const IntegrationFacetBindingSummary = z
|
|
|
8338
10657
|
lastErrorCode: z.string().min(1).max(120).nullable(),
|
|
8339
10658
|
createdAt: z.string().datetime({ offset: true }),
|
|
8340
10659
|
updatedAt: z.string().datetime({ offset: true }),
|
|
10660
|
+
directlyOwned: z.boolean(),
|
|
10661
|
+
owners: z.array(CapabilityComponentOwner),
|
|
8341
10662
|
})
|
|
8342
10663
|
.strict();
|
|
8343
10664
|
export type IntegrationFacetBindingSummary = z.infer<typeof IntegrationFacetBindingSummary>;
|
|
@@ -8860,11 +11181,59 @@ export const UninstallPluginResult = z
|
|
|
8860
11181
|
.strict();
|
|
8861
11182
|
export type UninstallPluginResult = z.infer<typeof UninstallPluginResult>;
|
|
8862
11183
|
|
|
11184
|
+
export const SessionBackgroundCommandState = z.enum(["running", "stopping", "exited", "lost"]);
|
|
11185
|
+
export type SessionBackgroundCommandState = z.infer<typeof SessionBackgroundCommandState>;
|
|
11186
|
+
|
|
11187
|
+
export const SessionBackgroundCommandProvider = z.enum(["managed", "connected_machine"]);
|
|
11188
|
+
export type SessionBackgroundCommandProvider = z.infer<typeof SessionBackgroundCommandProvider>;
|
|
11189
|
+
|
|
11190
|
+
export const SessionBackgroundCommandActivity = z
|
|
11191
|
+
.object({
|
|
11192
|
+
state: z.enum(["running", "stopping"]),
|
|
11193
|
+
count: z.number().int().positive(),
|
|
11194
|
+
})
|
|
11195
|
+
.strict();
|
|
11196
|
+
export type SessionBackgroundCommandActivity = z.infer<typeof SessionBackgroundCommandActivity>;
|
|
11197
|
+
|
|
11198
|
+
export const SessionBackgroundCommand = z
|
|
11199
|
+
.object({
|
|
11200
|
+
id: z.string().uuid(),
|
|
11201
|
+
workspaceId: z.string().uuid(),
|
|
11202
|
+
sessionId: z.string().uuid(),
|
|
11203
|
+
provider: SessionBackgroundCommandProvider,
|
|
11204
|
+
state: SessionBackgroundCommandState,
|
|
11205
|
+
commandPreview: z.string().max(512),
|
|
11206
|
+
cancelRequestedAt: z.string().nullable(),
|
|
11207
|
+
exitCode: z.number().int().nullable(),
|
|
11208
|
+
settlementReason: z.string().nullable(),
|
|
11209
|
+
startedAt: z.string(),
|
|
11210
|
+
settledAt: z.string().nullable(),
|
|
11211
|
+
updatedAt: z.string(),
|
|
11212
|
+
})
|
|
11213
|
+
.strict();
|
|
11214
|
+
export type SessionBackgroundCommand = z.infer<typeof SessionBackgroundCommand>;
|
|
11215
|
+
|
|
11216
|
+
export const SessionBackgroundCommandListResponse = z
|
|
11217
|
+
.object({ commands: z.array(SessionBackgroundCommand).max(1000) })
|
|
11218
|
+
.strict();
|
|
11219
|
+
export type SessionBackgroundCommandListResponse = z.infer<
|
|
11220
|
+
typeof SessionBackgroundCommandListResponse
|
|
11221
|
+
>;
|
|
11222
|
+
|
|
11223
|
+
export const CancelSessionBackgroundCommandResult = z
|
|
11224
|
+
.object({ command: SessionBackgroundCommand, accepted: z.boolean() })
|
|
11225
|
+
.strict();
|
|
11226
|
+
export type CancelSessionBackgroundCommandResult = z.infer<
|
|
11227
|
+
typeof CancelSessionBackgroundCommandResult
|
|
11228
|
+
>;
|
|
11229
|
+
|
|
8863
11230
|
export const Session = z.object({
|
|
8864
11231
|
id: z.string().uuid(),
|
|
8865
11232
|
workspaceId: z.string().uuid(),
|
|
8866
11233
|
accountId: z.string().uuid(),
|
|
8867
11234
|
status: SessionStatus,
|
|
11235
|
+
/** Additive list projection. Detail reads may omit it. */
|
|
11236
|
+
backgroundCommandActivity: SessionBackgroundCommandActivity.optional(),
|
|
8868
11237
|
initialMessage: z.string(),
|
|
8869
11238
|
title: z.string().nullable(),
|
|
8870
11239
|
titleSource: z.enum(["user", "agent"]).nullable(),
|
|
@@ -8893,6 +11262,8 @@ export const Session = z.object({
|
|
|
8893
11262
|
createdBy: TurnInitiator,
|
|
8894
11263
|
createdByContext: TurnInitiatorContext,
|
|
8895
11264
|
model: z.string(),
|
|
11265
|
+
reasoningEffort: ReasoningEffort,
|
|
11266
|
+
latencyMode: LatencyMode,
|
|
8896
11267
|
sandboxBackend: SandboxBackend,
|
|
8897
11268
|
// The OS the session's box runs. Defaults to 'linux' (today's only OS).
|
|
8898
11269
|
sandboxOs: SandboxOs,
|
|
@@ -8976,6 +11347,17 @@ export const Session = z.object({
|
|
|
8976
11347
|
pinnedAt: z.string().nullable().default(null),
|
|
8977
11348
|
/** Optimistic pin-state revision; zero represents an absent pin relation. */
|
|
8978
11349
|
pinVersion: z.number().int().nonnegative().default(0),
|
|
11350
|
+
/** Personal explicit acknowledgment state; opening the session never clears it. */
|
|
11351
|
+
unread: z.boolean().default(false),
|
|
11352
|
+
/** Personal power-user label for work the member intends to continue. */
|
|
11353
|
+
activelyWorking: z.boolean().default(false),
|
|
11354
|
+
/** Optimistic revision for unread/actively-working state. */
|
|
11355
|
+
attentionVersion: z.number().int().nonnegative().default(0),
|
|
11356
|
+
/** Personal archive state. Archived roots and their descendants leave the ordinary list. */
|
|
11357
|
+
archived: z.boolean().default(false),
|
|
11358
|
+
archivedAt: z.string().nullable().default(null),
|
|
11359
|
+
/** Optimistic archive-state revision; zero represents an absent personal relation. */
|
|
11360
|
+
archiveVersion: z.number().int().nonnegative().default(0),
|
|
8979
11361
|
/**
|
|
8980
11362
|
* Server-authoritative hierarchy summary populated on session-list reads.
|
|
8981
11363
|
* Detail reads may omit it. The rail uses this instead of guessing a tree
|
|
@@ -8990,10 +11372,24 @@ export const Session = z.object({
|
|
|
8990
11372
|
attentionDescendants: z.number().int().nonnegative(),
|
|
8991
11373
|
pausedDescendants: z.number().int().nonnegative(),
|
|
8992
11374
|
failedDescendants: z.number().int().nonnegative(),
|
|
11375
|
+
unreadDescendants: z.number().int().nonnegative().optional(),
|
|
11376
|
+
activelyWorkingDescendants: z.number().int().nonnegative().optional(),
|
|
11377
|
+
/**
|
|
11378
|
+
* Earliest moment one of the counted `attentionDescendants` entered
|
|
11379
|
+
* `requires_action` (the oldest still-open `requires_action` turn among
|
|
11380
|
+
* those descendants). Null when none is waiting; omitted by older servers.
|
|
11381
|
+
*/
|
|
11382
|
+
attentionSince: z.string().nullable().optional(),
|
|
8993
11383
|
/** Counts are lower bounds rather than exact totals when true. */
|
|
8994
11384
|
truncated: z.boolean().default(false),
|
|
8995
11385
|
})
|
|
8996
11386
|
.optional(),
|
|
11387
|
+
/**
|
|
11388
|
+
* When this session's own open turn entered `requires_action`. Populated by
|
|
11389
|
+
* list and lineage reads for sessions whose status is `requires_action`;
|
|
11390
|
+
* null otherwise and omitted by older servers or detail reads.
|
|
11391
|
+
*/
|
|
11392
|
+
requiresActionSince: z.string().nullable().optional(),
|
|
8997
11393
|
createdAt: z.string(),
|
|
8998
11394
|
updatedAt: z.string(),
|
|
8999
11395
|
});
|
|
@@ -9102,6 +11498,7 @@ export type SessionLineageResponse = z.infer<typeof SessionLineageResponse>;
|
|
|
9102
11498
|
|
|
9103
11499
|
export const SessionEventType = z.enum([
|
|
9104
11500
|
"session.created",
|
|
11501
|
+
"session.personal_resources.attached",
|
|
9105
11502
|
"session.visibility.changed",
|
|
9106
11503
|
// Defensive read/transport projection for a malformed or historically
|
|
9107
11504
|
// oversized retained event envelope. The original row stays durable; this
|
|
@@ -9130,13 +11527,20 @@ export const SessionEventType = z.enum([
|
|
|
9130
11527
|
"turn.superseded",
|
|
9131
11528
|
"turn.recovery.requested",
|
|
9132
11529
|
"turn.capacity_waiting",
|
|
11530
|
+
// Compact, attempt-fenced user-visible worker preparation checkpoints. The
|
|
11531
|
+
// payload phase is a closed enum and terminal events carry durationMs; no
|
|
11532
|
+
// session-specific value is ever promoted into Prometheus labels.
|
|
11533
|
+
"turn.startup.phase.started",
|
|
11534
|
+
"turn.startup.phase.completed",
|
|
11535
|
+
"turn.startup.phase.failed",
|
|
9133
11536
|
"agent.message.delta",
|
|
9134
11537
|
"agent.message.completed",
|
|
9135
11538
|
"agent.reasoning.delta",
|
|
9136
11539
|
"agent.toolCall.created",
|
|
9137
11540
|
"agent.toolCall.output",
|
|
9138
|
-
// Attempt-fenced
|
|
9139
|
-
//
|
|
11541
|
+
// Attempt-fenced provider Responses lifecycle metadata (request identity,
|
|
11542
|
+
// liveness policy, first-event/terminal phase, provider request id). Never
|
|
11543
|
+
// request body, credentials, or model output.
|
|
9140
11544
|
"agent.model.request",
|
|
9141
11545
|
"agent.model.usage",
|
|
9142
11546
|
"tool.auth_needed",
|
|
@@ -9149,6 +11553,8 @@ export const SessionEventType = z.enum([
|
|
|
9149
11553
|
"sandbox.operation.started",
|
|
9150
11554
|
"sandbox.operation.completed",
|
|
9151
11555
|
"sandbox.operation.failed",
|
|
11556
|
+
"session.command.backgrounded",
|
|
11557
|
+
"session.command.finished",
|
|
9152
11558
|
"sandbox.command.output.delta",
|
|
9153
11559
|
"artifact.created",
|
|
9154
11560
|
"goal.set",
|
|
@@ -9160,6 +11566,7 @@ export const SessionEventType = z.enum([
|
|
|
9160
11566
|
"goal.paused",
|
|
9161
11567
|
"goal.resumed",
|
|
9162
11568
|
"goal.cleared",
|
|
11569
|
+
"goal.held",
|
|
9163
11570
|
"goal.continuation",
|
|
9164
11571
|
"system.update.pending",
|
|
9165
11572
|
"system.update.delivered",
|
|
@@ -9352,6 +11759,7 @@ export const SESSION_EVENT_RAW_DELTA_TYPES = [
|
|
|
9352
11759
|
export const SESSION_EVENT_SEMANTIC_CLASS_TYPES = {
|
|
9353
11760
|
control: [
|
|
9354
11761
|
"session.status.changed",
|
|
11762
|
+
"session.command.backgrounded",
|
|
9355
11763
|
"session.requiresAction",
|
|
9356
11764
|
"session.humanInput.requested",
|
|
9357
11765
|
"user.pause",
|
|
@@ -9366,6 +11774,7 @@ export const SESSION_EVENT_SEMANTIC_CLASS_TYPES = {
|
|
|
9366
11774
|
"goal.paused",
|
|
9367
11775
|
"goal.resumed",
|
|
9368
11776
|
"goal.cleared",
|
|
11777
|
+
"goal.held",
|
|
9369
11778
|
"goal.continuation",
|
|
9370
11779
|
"system.update.pending",
|
|
9371
11780
|
"system.update.delivered",
|
|
@@ -9398,6 +11807,7 @@ export const SESSION_EVENT_SEMANTIC_CLASS_TYPES = {
|
|
|
9398
11807
|
"recording.available",
|
|
9399
11808
|
"recording.failed",
|
|
9400
11809
|
"terminal.pty.exited",
|
|
11810
|
+
"session.command.finished",
|
|
9401
11811
|
],
|
|
9402
11812
|
failure: [
|
|
9403
11813
|
"session.event.envelope_omitted",
|
|
@@ -9724,7 +12134,9 @@ export type FsNodeType = z.infer<typeof FsNodeType>;
|
|
|
9724
12134
|
// depth>0; the tree lazy-expands via repeated depth-1 lists at deeper paths.
|
|
9725
12135
|
export interface FsTreeNode {
|
|
9726
12136
|
name: string;
|
|
9727
|
-
|
|
12137
|
+
// Same namespace as the request: workspace-relative for relative requests,
|
|
12138
|
+
// canonical target path for requests rooted at FileSystem.root.
|
|
12139
|
+
path: string;
|
|
9728
12140
|
type: z.infer<typeof FsNodeType>;
|
|
9729
12141
|
sizeBytes: number | null; // null for dirs
|
|
9730
12142
|
mtimeMs: number | null;
|
|
@@ -9746,7 +12158,9 @@ export const FsTreeNode: z.ZodType<FsTreeNode> = z.lazy(() =>
|
|
|
9746
12158
|
) as z.ZodType<FsTreeNode>;
|
|
9747
12159
|
|
|
9748
12160
|
export const FsListRequest = z.object({
|
|
9749
|
-
|
|
12161
|
+
// "" = workspace root; canonical absolute paths must stay within the
|
|
12162
|
+
// selected target's advertised FileSystem.root.
|
|
12163
|
+
path: z.string().default(""),
|
|
9750
12164
|
depth: z.number().int().min(0).max(8).default(1),
|
|
9751
12165
|
maxEntries: z.number().int().positive().max(20_000).default(2_000),
|
|
9752
12166
|
includeHidden: z.boolean().default(true),
|
|
@@ -11268,6 +13682,8 @@ export const SessionControlResponse = z.object({
|
|
|
11268
13682
|
});
|
|
11269
13683
|
export type SessionControlResponse = z.infer<typeof SessionControlResponse>;
|
|
11270
13684
|
|
|
13685
|
+
export const SESSION_INSTRUCTIONS_MAX_CHARACTERS = 65_536;
|
|
13686
|
+
|
|
11271
13687
|
export const CreateSessionRequest = withVariableSetIdAlias(
|
|
11272
13688
|
{
|
|
11273
13689
|
/**
|
|
@@ -11277,6 +13693,12 @@ export const CreateSessionRequest = withVariableSetIdAlias(
|
|
|
11277
13693
|
* identity or authorization from the UUID.
|
|
11278
13694
|
*/
|
|
11279
13695
|
requestedSessionId: z.string().uuid().optional(),
|
|
13696
|
+
/** Top-level omission is workspace-visible. Agent-child omission inherits
|
|
13697
|
+
* the exact parent visibility; cross-visibility child creation is rejected.
|
|
13698
|
+
* Top-level private creation is an activated managed-cookie owning-human
|
|
13699
|
+
* capability, while a private child uses an exact live-parent-attempt
|
|
13700
|
+
* database capability. Both commit atomically. */
|
|
13701
|
+
visibility: SessionVisibility.default("workspace"),
|
|
11280
13702
|
initialMessage: z.string().min(1).optional(),
|
|
11281
13703
|
// Creates the durable session shell without fabricating a user message or
|
|
11282
13704
|
// starting an underlying agent turn. Realtime can then become the first
|
|
@@ -11291,10 +13713,10 @@ export const CreateSessionRequest = withVariableSetIdAlias(
|
|
|
11291
13713
|
// agentInstructions rides, composed AFTER the workspace persona so it refines
|
|
11292
13714
|
// it for this one session — how a host delivers per-agent-type prompts without
|
|
11293
13715
|
// leaking them into the user-visible timeline (it is NEVER emitted as an
|
|
11294
|
-
// event, unlike goal/initialMessage). Trimmed, non-empty
|
|
11295
|
-
//
|
|
11296
|
-
//
|
|
11297
|
-
instructions: z.string().trim().min(1).max(
|
|
13716
|
+
// event, unlike goal/initialMessage). Trimmed, non-empty, and bounded by the
|
|
13717
|
+
// shared durable session-instruction contract. Absent ⇒ byte-identical to
|
|
13718
|
+
// today.
|
|
13719
|
+
instructions: z.string().trim().min(1).max(SESSION_INSTRUCTIONS_MAX_CHARACTERS).optional(),
|
|
11298
13720
|
// Immutable prompt-policy role binding for matching one activated role
|
|
11299
13721
|
// policy. This never derives from or grants a human workspace membership
|
|
11300
13722
|
// role. Existing callers may continue to use normalized metadata.role as a
|
|
@@ -11322,11 +13744,11 @@ export const CreateSessionRequest = withVariableSetIdAlias(
|
|
|
11322
13744
|
// machine (race-free: the pointer is committed before the worker turn
|
|
11323
13745
|
// workflow can read it). An invalid/unowned/offline target fails the create.
|
|
11324
13746
|
targetSandboxId: z.string().uuid().optional(),
|
|
11325
|
-
// The working directory the targeted machine runs the session under
|
|
11326
|
-
//
|
|
11327
|
-
//
|
|
11328
|
-
//
|
|
11329
|
-
//
|
|
13747
|
+
// The working directory the targeted machine runs the session under. It may
|
|
13748
|
+
// be absolute or relative to the machine's persisted Hello root; the server
|
|
13749
|
+
// stores the resolved absolute value. Tilde is rejected because the control
|
|
13750
|
+
// plane has no authenticated home-directory fact. Only valid WITH
|
|
13751
|
+
// targetSandboxId; omitted selects the reported root.
|
|
11330
13752
|
workingDir: z.string().min(1).optional(),
|
|
11331
13753
|
// Variable set attachment is fixed at session creation; follow-up
|
|
11332
13754
|
// user.message events cannot switch or add one.
|
|
@@ -11351,9 +13773,10 @@ export const CreateSessionRequest = withVariableSetIdAlias(
|
|
|
11351
13773
|
// is an independent create).
|
|
11352
13774
|
idempotencyKey: z.string().min(1).max(200).optional(),
|
|
11353
13775
|
// The exact actor-private pre-session draft revision represented by this
|
|
11354
|
-
// create.
|
|
11355
|
-
//
|
|
11356
|
-
//
|
|
13776
|
+
// create. An ordinary create consumes only this revision. A realtime create
|
|
13777
|
+
// preserves the editable draft and atomically updates only successful-create
|
|
13778
|
+
// selection history. A newer sibling draft survives, while every failed
|
|
13779
|
+
// pre-initialization create leaves the submitted draft intact.
|
|
11357
13780
|
expectedNewSessionDraftRevision: z.number().int().nonnegative().optional(),
|
|
11358
13781
|
// A child may lower its inherited limit freely; an increase requires
|
|
11359
13782
|
// workspace:admin and is checked again at the DB transaction boundary.
|
|
@@ -11377,9 +13800,16 @@ export const CreateSessionRequest = withVariableSetIdAlias(
|
|
|
11377
13800
|
// permission. Credential headers are write-only: create responses and events
|
|
11378
13801
|
// expose only SessionMcpServerMetadata.
|
|
11379
13802
|
mcpServers: z.array(SessionMcpServerInput).max(SESSION_MCP_SERVERS_MAX).default([]),
|
|
13803
|
+
/** Explicit personal-connection grants for the initial accepted turn. */
|
|
13804
|
+
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
13805
|
+
/** Atomic owner issuance for the selected personal Variable Set/Rig closure. */
|
|
13806
|
+
personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
|
|
11380
13807
|
// Shared-sandbox placement (addendum 05 §D.1). Three-way union; OMITTED ⇒
|
|
11381
13808
|
// today's behavior (a context-dependent default resolved server-side: from
|
|
11382
|
-
// inside a session → "shared" with the creator's box, top-level → "new")
|
|
13809
|
+
// inside a session → "shared" with the creator's box, top-level → "new"),
|
|
13810
|
+
// except a named targetSandboxId is always an own-box create ("new") because
|
|
13811
|
+
// a machine target is a different compute home. Explicit "shared"/{groupId}
|
|
13812
|
+
// plus a machine target is a 422.
|
|
11383
13813
|
// - "shared": join the CREATOR's box. Requires a parent session (inferred
|
|
11384
13814
|
// from the worker-signed sessionId claim, never caller-supplied);
|
|
11385
13815
|
// top-level "shared" is a 422.
|
|
@@ -11421,9 +13851,39 @@ export const CreateSessionRequest = withVariableSetIdAlias(
|
|
|
11421
13851
|
message: "modelContext requires an initialMessage; attach it to a realtime entry instead",
|
|
11422
13852
|
});
|
|
11423
13853
|
}
|
|
13854
|
+
if (value.startMode === "realtime" && value.connectionAuthorities.length > 0) {
|
|
13855
|
+
context.addIssue({
|
|
13856
|
+
code: z.ZodIssueCode.custom,
|
|
13857
|
+
path: ["connectionAuthorities"],
|
|
13858
|
+
message:
|
|
13859
|
+
"connectionAuthorities require an accepted initial turn and are not supported by realtime session staging",
|
|
13860
|
+
});
|
|
13861
|
+
}
|
|
13862
|
+
if (value.startMode === "realtime" && value.personalResourceAttachment !== undefined) {
|
|
13863
|
+
context.addIssue({
|
|
13864
|
+
code: z.ZodIssueCode.custom,
|
|
13865
|
+
path: ["personalResourceAttachment"],
|
|
13866
|
+
message:
|
|
13867
|
+
"personalResourceAttachment requires an accepted initial turn and is not supported by realtime session staging",
|
|
13868
|
+
});
|
|
13869
|
+
}
|
|
13870
|
+
if (value.personalResourceAttachment?.expectedAuthorityEpoch !== undefined) {
|
|
13871
|
+
context.addIssue({
|
|
13872
|
+
code: z.ZodIssueCode.custom,
|
|
13873
|
+
path: ["personalResourceAttachment", "expectedAuthorityEpoch"],
|
|
13874
|
+
message: "new-session attachment authority epoch is derived by the server",
|
|
13875
|
+
});
|
|
13876
|
+
}
|
|
11424
13877
|
});
|
|
11425
13878
|
export type CreateSessionRequest = z.infer<typeof CreateSessionRequest>;
|
|
11426
13879
|
|
|
13880
|
+
export const SessionTenancyCreateCapabilities = z.object({
|
|
13881
|
+
activated: z.boolean(),
|
|
13882
|
+
canCreatePrivate: z.boolean(),
|
|
13883
|
+
reason: z.enum(["available", "not_activated", "managed_session_required", "unavailable"]),
|
|
13884
|
+
});
|
|
13885
|
+
export type SessionTenancyCreateCapabilities = z.infer<typeof SessionTenancyCreateCapabilities>;
|
|
13886
|
+
|
|
11427
13887
|
// Generic, host-neutral structured human input. One model tool call creates one
|
|
11428
13888
|
// request containing one or more questions; the durable response resumes that
|
|
11429
13889
|
// exact call. This is deliberately distinct from tool approval: an answer,
|
|
@@ -11447,6 +13907,9 @@ export const HumanInputQuestion = z
|
|
|
11447
13907
|
helpText: z.string().max(2048).nullable().optional(),
|
|
11448
13908
|
options: z.array(HumanInputOption).max(20).default([]),
|
|
11449
13909
|
required: z.boolean().default(true),
|
|
13910
|
+
// Retained on the wire for older hosts. OpenGeni's stock runtime and
|
|
13911
|
+
// surfaces always expose Other for choice questions, including requests
|
|
13912
|
+
// that were persisted before that became the default behavior.
|
|
11450
13913
|
allowOther: z.boolean().default(false),
|
|
11451
13914
|
// Selection bounds only — agents invent useless text char mins/maxes.
|
|
11452
13915
|
// Answer strings stay platform-capped on HumanInputAnswer (~8192).
|
|
@@ -11619,9 +14082,13 @@ export const SessionUserMessagePayload = z
|
|
|
11619
14082
|
// Header-value rotation only. URL/name/tool settings are immutable after
|
|
11620
14083
|
// session create; persisted events expose metadata, never header values.
|
|
11621
14084
|
mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
|
|
14085
|
+
/** Explicit personal-connection grants for this exact logical turn. */
|
|
14086
|
+
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
14087
|
+
personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
|
|
11622
14088
|
})
|
|
11623
14089
|
.strict()
|
|
11624
|
-
.superRefine(requireMessageTextOrAnnotations)
|
|
14090
|
+
.superRefine(requireMessageTextOrAnnotations)
|
|
14091
|
+
.superRefine(requireEstablishedPersonalResourceEpoch);
|
|
11625
14092
|
export type SessionUserMessagePayload = z.infer<typeof SessionUserMessagePayload>;
|
|
11626
14093
|
|
|
11627
14094
|
export const ClientSessionEvent = z.discriminatedUnion("type", [
|
|
@@ -11664,17 +14131,36 @@ export const SteerSessionMessageRequest = z
|
|
|
11664
14131
|
controlEtag: z.string().min(1).optional(),
|
|
11665
14132
|
expectedDraftRevision: z.number().int().nonnegative().optional(),
|
|
11666
14133
|
mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
|
|
14134
|
+
/** Explicit personal-connection grants for this exact steered turn. */
|
|
14135
|
+
connectionAuthorities: McpConnectionAuthoritySelections.default([]),
|
|
14136
|
+
personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
|
|
11667
14137
|
})
|
|
11668
14138
|
.strict()
|
|
11669
|
-
.superRefine(requireMessageTextOrAnnotations)
|
|
14139
|
+
.superRefine(requireMessageTextOrAnnotations)
|
|
14140
|
+
.superRefine(requireEstablishedPersonalResourceEpoch);
|
|
11670
14141
|
export type SteerSessionMessageRequest = z.infer<typeof SteerSessionMessageRequest>;
|
|
11671
14142
|
|
|
11672
14143
|
export const SteerSessionMessageResponse = z.object({
|
|
11673
14144
|
accepted: SessionEvent,
|
|
11674
14145
|
turn: SessionTurn,
|
|
14146
|
+
receipt: SessionCommandReceipt,
|
|
14147
|
+
routing: SessionPromptRouting,
|
|
14148
|
+
interruptionCount: z.number().int().nonnegative(),
|
|
14149
|
+
replay: z.boolean(),
|
|
11675
14150
|
});
|
|
11676
14151
|
export type SteerSessionMessageResponse = z.infer<typeof SteerSessionMessageResponse>;
|
|
11677
14152
|
|
|
14153
|
+
export const SubmitComposerDraftResponse = z.object({
|
|
14154
|
+
accepted: SessionEvent,
|
|
14155
|
+
turn: SessionTurn,
|
|
14156
|
+
draft: ComposerDraft,
|
|
14157
|
+
receipt: SessionCommandReceipt,
|
|
14158
|
+
routing: SessionPromptRouting,
|
|
14159
|
+
interruptionCount: z.number().int().nonnegative(),
|
|
14160
|
+
replay: z.boolean(),
|
|
14161
|
+
});
|
|
14162
|
+
export type SubmitComposerDraftResponse = z.infer<typeof SubmitComposerDraftResponse>;
|
|
14163
|
+
|
|
11678
14164
|
export const SessionBusMessage = z.object({
|
|
11679
14165
|
workspaceId: z.string().uuid(),
|
|
11680
14166
|
sessionId: z.string().uuid(),
|
|
@@ -11765,6 +14251,7 @@ export const ClientAuthConfig = z.discriminatedUnion("mode", [
|
|
|
11765
14251
|
z.object({
|
|
11766
14252
|
mode: z.literal("managedSession"),
|
|
11767
14253
|
session: z.literal("cookie"),
|
|
14254
|
+
emailVerificationRequired: z.boolean().default(true),
|
|
11768
14255
|
}),
|
|
11769
14256
|
]);
|
|
11770
14257
|
export type ClientAuthConfig = z.infer<typeof ClientAuthConfig>;
|
|
@@ -12029,6 +14516,9 @@ export type DeviceEnrollmentStartResponse = z.infer<typeof DeviceEnrollmentStart
|
|
|
12029
14516
|
export const DeviceEnrollmentApproveRequest = z.object({
|
|
12030
14517
|
userCode: z.string().min(1).max(64),
|
|
12031
14518
|
allowScreenControl: z.boolean().default(false),
|
|
14519
|
+
// Human-approved machines are private by default. Workspace/organization
|
|
14520
|
+
// publication is an explicit consent choice at this same loud boundary.
|
|
14521
|
+
scope: ResourceAuthorityScope.default("user"),
|
|
12032
14522
|
});
|
|
12033
14523
|
export type DeviceEnrollmentApproveRequest = z.infer<typeof DeviceEnrollmentApproveRequest>;
|
|
12034
14524
|
|
|
@@ -12101,6 +14591,8 @@ export type DeviceEnrollmentPollResponse = z.infer<typeof DeviceEnrollmentPollRe
|
|
|
12101
14591
|
// GET /enrollments — a workspace's machines (the Machines dashboard surface).
|
|
12102
14592
|
export const EnrollmentSummary = z.object({
|
|
12103
14593
|
id: z.string().uuid(),
|
|
14594
|
+
scope: ResourceAuthorityScope,
|
|
14595
|
+
generation: z.number().int().positive(),
|
|
12104
14596
|
pubkey: z.string(),
|
|
12105
14597
|
exposure: z.literal("whole-machine"),
|
|
12106
14598
|
hasDisplay: z.boolean(),
|
|
@@ -12297,9 +14789,137 @@ export const MachineState = z.enum([
|
|
|
12297
14789
|
]);
|
|
12298
14790
|
export type MachineState = z.infer<typeof MachineState>;
|
|
12299
14791
|
|
|
12300
|
-
export const MachineKind = z.enum(["modal", "selfhosted"]);
|
|
14792
|
+
export const MachineKind = z.enum(["modal", "selfhosted", "opensandbox"]);
|
|
12301
14793
|
export type MachineKind = z.infer<typeof MachineKind>;
|
|
12302
14794
|
|
|
14795
|
+
/** Diagnostic projection of the single live Connected-Machine runner authority.
|
|
14796
|
+
* It contains no bearer or NATS subject material. `supersededCount` is derived
|
|
14797
|
+
* from the monotonic generation; duplicate-denial evidence records valid
|
|
14798
|
+
* competing processes that were prevented from receiving work. */
|
|
14799
|
+
export const MachineConnectionAuthority = z.object({
|
|
14800
|
+
state: z.enum(["not_applicable", "unclaimed", "active", "expired"]),
|
|
14801
|
+
generation: z.number().int().nonnegative(),
|
|
14802
|
+
supersededCount: z.number().int().nonnegative(),
|
|
14803
|
+
leaseExpiresAt: z.string().nullable(),
|
|
14804
|
+
duplicateRunnerDeniedCount: z.number().int().nonnegative(),
|
|
14805
|
+
duplicateRunnerDeniedAt: z.string().nullable(),
|
|
14806
|
+
});
|
|
14807
|
+
export type MachineConnectionAuthority = z.infer<typeof MachineConnectionAuthority>;
|
|
14808
|
+
|
|
14809
|
+
export const MachineRuntimeCapabilities = z.object({
|
|
14810
|
+
exec: z.boolean(),
|
|
14811
|
+
filesystem: z.boolean(),
|
|
14812
|
+
git: z.boolean(),
|
|
14813
|
+
pty: z.boolean(),
|
|
14814
|
+
desktop: z.boolean(),
|
|
14815
|
+
opStream: z.boolean(),
|
|
14816
|
+
browserBridge: z.boolean(),
|
|
14817
|
+
operationResourcePolicy: z.boolean(),
|
|
14818
|
+
operationCpuQuota: z.boolean(),
|
|
14819
|
+
});
|
|
14820
|
+
export type MachineRuntimeCapabilities = z.infer<typeof MachineRuntimeCapabilities>;
|
|
14821
|
+
|
|
14822
|
+
export const MachineUpdateStatus = z.enum([
|
|
14823
|
+
"requested",
|
|
14824
|
+
"accepted",
|
|
14825
|
+
"waiting_for_idle",
|
|
14826
|
+
"downloading",
|
|
14827
|
+
"verifying",
|
|
14828
|
+
"applying",
|
|
14829
|
+
"restarting",
|
|
14830
|
+
"succeeded",
|
|
14831
|
+
"failed",
|
|
14832
|
+
]);
|
|
14833
|
+
export type MachineUpdateStatus = z.infer<typeof MachineUpdateStatus>;
|
|
14834
|
+
|
|
14835
|
+
export const MachineUpdateState = z.object({
|
|
14836
|
+
operationId: z.string().uuid(),
|
|
14837
|
+
status: MachineUpdateStatus,
|
|
14838
|
+
targetVersion: z.string(),
|
|
14839
|
+
expectedBinarySha256: z
|
|
14840
|
+
.string()
|
|
14841
|
+
.regex(/^[0-9a-f]{64}$/)
|
|
14842
|
+
.nullable(),
|
|
14843
|
+
errorCode: z.string().nullable(),
|
|
14844
|
+
retryable: z.boolean(),
|
|
14845
|
+
rolledBack: z.boolean(),
|
|
14846
|
+
requestedAt: z.string(),
|
|
14847
|
+
updatedAt: z.string(),
|
|
14848
|
+
completedAt: z.string().nullable(),
|
|
14849
|
+
});
|
|
14850
|
+
export type MachineUpdateState = z.infer<typeof MachineUpdateState>;
|
|
14851
|
+
|
|
14852
|
+
export const MachineRuntime = z.object({
|
|
14853
|
+
installedVersion: z.string().nullable(),
|
|
14854
|
+
binarySha256: z
|
|
14855
|
+
.string()
|
|
14856
|
+
.regex(/^[0-9a-f]{64}$/)
|
|
14857
|
+
.nullable(),
|
|
14858
|
+
updateChannel: z.enum(["stable", "beta"]).nullable(),
|
|
14859
|
+
desiredVersion: z.string().nullable(),
|
|
14860
|
+
versionState: z.enum(["unknown", "current", "outdated", "ahead", "updating", "update_failed"]),
|
|
14861
|
+
capabilities: MachineRuntimeCapabilities,
|
|
14862
|
+
update: MachineUpdateState.nullable(),
|
|
14863
|
+
});
|
|
14864
|
+
export type MachineRuntime = z.infer<typeof MachineRuntime>;
|
|
14865
|
+
|
|
14866
|
+
export const UpdateMachineAgentResponse = z.object({
|
|
14867
|
+
operationId: z.string().uuid(),
|
|
14868
|
+
accepted: z.boolean(),
|
|
14869
|
+
targetVersion: z.string(),
|
|
14870
|
+
});
|
|
14871
|
+
export type UpdateMachineAgentResponse = z.infer<typeof UpdateMachineAgentResponse>;
|
|
14872
|
+
|
|
14873
|
+
const OperationMemoryBytes = z.number().int().positive().max(Number.MAX_SAFE_INTEGER).nullable();
|
|
14874
|
+
const OperationCpuMillicores = z.number().int().positive().max(0xffff_ffff).nullable();
|
|
14875
|
+
|
|
14876
|
+
function operationPolicyShape(
|
|
14877
|
+
value: {
|
|
14878
|
+
memoryMaxBytes: number | null;
|
|
14879
|
+
memoryHighBytes: number | null;
|
|
14880
|
+
cpuMaxMillicores?: number | null | undefined;
|
|
14881
|
+
},
|
|
14882
|
+
ctx: z.RefinementCtx,
|
|
14883
|
+
): void {
|
|
14884
|
+
if (
|
|
14885
|
+
value.memoryMaxBytes !== null &&
|
|
14886
|
+
value.memoryHighBytes !== null &&
|
|
14887
|
+
value.memoryHighBytes > value.memoryMaxBytes
|
|
14888
|
+
) {
|
|
14889
|
+
ctx.addIssue({
|
|
14890
|
+
code: z.ZodIssueCode.custom,
|
|
14891
|
+
path: ["memoryHighBytes"],
|
|
14892
|
+
message: "memoryHighBytes cannot exceed memoryMaxBytes",
|
|
14893
|
+
});
|
|
14894
|
+
}
|
|
14895
|
+
}
|
|
14896
|
+
|
|
14897
|
+
/** Optional per-connection command resource policy. CPU is a period-independent
|
|
14898
|
+
* millicore ratio; runners choose a documented representable cgroup period. Null
|
|
14899
|
+
* values are unrestricted; revision is the optimistic concurrency fence. */
|
|
14900
|
+
export const MachineOperationPolicy = z
|
|
14901
|
+
.object({
|
|
14902
|
+
memoryMaxBytes: OperationMemoryBytes,
|
|
14903
|
+
memoryHighBytes: OperationMemoryBytes,
|
|
14904
|
+
cpuMaxMillicores: OperationCpuMillicores,
|
|
14905
|
+
revision: z.number().int().nonnegative(),
|
|
14906
|
+
updatedAt: z.string().nullable(),
|
|
14907
|
+
})
|
|
14908
|
+
.superRefine(operationPolicyShape);
|
|
14909
|
+
export type MachineOperationPolicy = z.infer<typeof MachineOperationPolicy>;
|
|
14910
|
+
|
|
14911
|
+
export const UpdateMachineOperationPolicyRequest = z
|
|
14912
|
+
.object({
|
|
14913
|
+
memoryMaxBytes: OperationMemoryBytes,
|
|
14914
|
+
memoryHighBytes: OperationMemoryBytes,
|
|
14915
|
+
cpuMaxMillicores: OperationCpuMillicores.optional(),
|
|
14916
|
+
expectedRevision: z.number().int().nonnegative(),
|
|
14917
|
+
})
|
|
14918
|
+
.superRefine(operationPolicyShape);
|
|
14919
|
+
export type UpdateMachineOperationPolicyRequest = z.infer<
|
|
14920
|
+
typeof UpdateMachineOperationPolicyRequest
|
|
14921
|
+
>;
|
|
14922
|
+
|
|
12303
14923
|
/**
|
|
12304
14924
|
* A machine as the Machines dashboard renders it. The workspace's enrolled
|
|
12305
14925
|
* selfhosted machines PLUS the session's synthetic Modal group box
|
|
@@ -12311,6 +14931,8 @@ export type MachineKind = z.infer<typeof MachineKind>;
|
|
|
12311
14931
|
export const MachineView = z.object({
|
|
12312
14932
|
sandboxId: z.string(),
|
|
12313
14933
|
enrollmentId: z.string().nullable(),
|
|
14934
|
+
scope: ResourceAuthorityScope.default("workspace"),
|
|
14935
|
+
generation: z.number().int().positive().default(1),
|
|
12314
14936
|
name: z.string(),
|
|
12315
14937
|
kind: MachineKind,
|
|
12316
14938
|
state: MachineState,
|
|
@@ -12329,6 +14951,12 @@ export const MachineView = z.object({
|
|
|
12329
14951
|
allowScreenControl: z.boolean(),
|
|
12330
14952
|
sharedSessionCount: z.number().int(),
|
|
12331
14953
|
lastSeenAt: z.string().nullable(),
|
|
14954
|
+
connectionAuthority: MachineConnectionAuthority,
|
|
14955
|
+
// Exact connected-agent build/capabilities and current update operation. Null
|
|
14956
|
+
// for managed/session sandboxes and pre-runtime-reporting synthetic rows.
|
|
14957
|
+
runtime: MachineRuntime.nullable().default(null),
|
|
14958
|
+
// Per-enrollment desired policy. Null for managed/session sandboxes.
|
|
14959
|
+
operationPolicy: MachineOperationPolicy.nullable().default(null),
|
|
12332
14960
|
metrics: MetricSample.nullable(),
|
|
12333
14961
|
});
|
|
12334
14962
|
export type MachineView = z.infer<typeof MachineView>;
|
|
@@ -12405,8 +15033,9 @@ function defineModelContractSchema<Schema>(factory: () => Schema): Schema {
|
|
|
12405
15033
|
return factory();
|
|
12406
15034
|
}
|
|
12407
15035
|
|
|
12408
|
-
export const ModelCapabilitySupportV1 =
|
|
12409
|
-
|
|
15036
|
+
export const ModelCapabilitySupportV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15037
|
+
z.enum(["supported", "unsupported", "unknown"]),
|
|
15038
|
+
);
|
|
12410
15039
|
export type ModelCapabilitySupportV1 = z.infer<typeof ModelCapabilitySupportV1>;
|
|
12411
15040
|
|
|
12412
15041
|
export const ModelCapabilityStateV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
@@ -12454,60 +15083,65 @@ export const ModelCapabilitiesV1 = /* @__PURE__ */ defineModelContractSchema(()
|
|
|
12454
15083
|
);
|
|
12455
15084
|
export type ModelCapabilitiesV1 = z.infer<typeof ModelCapabilitiesV1>;
|
|
12456
15085
|
|
|
12457
|
-
export const ModelCredentialSourceV1 =
|
|
12458
|
-
|
|
12459
|
-
z.union([
|
|
12460
|
-
z
|
|
12461
|
-
.object({
|
|
12462
|
-
kind: z.literal("deployment"),
|
|
12463
|
-
mechanism: z.enum(["api_key", "azure_ad_bearer"]),
|
|
12464
|
-
})
|
|
12465
|
-
.strict(),
|
|
12466
|
-
z
|
|
12467
|
-
.object({
|
|
12468
|
-
kind: z.literal("connected_subscription"),
|
|
12469
|
-
provider: z.enum(["codex", "xai"]),
|
|
12470
|
-
})
|
|
12471
|
-
.strict(),
|
|
12472
|
-
z
|
|
12473
|
-
.object({
|
|
12474
|
-
kind: z.literal("workspace_connection"),
|
|
12475
|
-
mechanism: z.literal("api_key"),
|
|
12476
|
-
})
|
|
12477
|
-
.strict(),
|
|
12478
|
-
]),
|
|
12479
|
-
);
|
|
12480
|
-
export type ModelCredentialSourceV1 = z.infer<typeof ModelCredentialSourceV1>;
|
|
12481
|
-
|
|
12482
|
-
export const ModelBillingAttributionV1 =
|
|
12483
|
-
/* @__PURE__ */ defineModelContractSchema(() =>
|
|
15086
|
+
export const ModelCredentialSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15087
|
+
z.union([
|
|
12484
15088
|
z
|
|
12485
15089
|
.object({
|
|
12486
|
-
|
|
12487
|
-
|
|
15090
|
+
kind: z.literal("deployment"),
|
|
15091
|
+
mechanism: z.enum(["api_key", "azure_ad_bearer"]),
|
|
12488
15092
|
})
|
|
12489
15093
|
.strict(),
|
|
12490
|
-
|
|
15094
|
+
z
|
|
15095
|
+
.object({
|
|
15096
|
+
kind: z.literal("connected_subscription"),
|
|
15097
|
+
provider: z.enum(["codex", "xai"]),
|
|
15098
|
+
})
|
|
15099
|
+
.strict(),
|
|
15100
|
+
z
|
|
15101
|
+
.object({
|
|
15102
|
+
kind: z.literal("workspace_connection"),
|
|
15103
|
+
mechanism: z.literal("api_key"),
|
|
15104
|
+
})
|
|
15105
|
+
.strict(),
|
|
15106
|
+
]),
|
|
15107
|
+
);
|
|
15108
|
+
export type ModelCredentialSourceV1 = z.infer<typeof ModelCredentialSourceV1>;
|
|
15109
|
+
|
|
15110
|
+
const TurnExecutionCredentialSourceV1 = z.union([
|
|
15111
|
+
ModelCredentialSourceV1,
|
|
15112
|
+
z
|
|
15113
|
+
.object({
|
|
15114
|
+
kind: z.literal("deployment"),
|
|
15115
|
+
mechanism: z.literal("none"),
|
|
15116
|
+
})
|
|
15117
|
+
.strict(),
|
|
15118
|
+
]);
|
|
15119
|
+
|
|
15120
|
+
export const ModelBillingAttributionV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15121
|
+
z
|
|
15122
|
+
.object({
|
|
15123
|
+
upstreamPayer: z.enum(["deployment", "workspace", "connected_subscription"]),
|
|
15124
|
+
metering: z.enum(["opengeni_credits", "external"]),
|
|
15125
|
+
})
|
|
15126
|
+
.strict(),
|
|
15127
|
+
);
|
|
12491
15128
|
export type ModelBillingAttributionV1 = z.infer<typeof ModelBillingAttributionV1>;
|
|
12492
15129
|
|
|
12493
15130
|
export const TURN_EXECUTION_POLICY_METADATA_KEY = "turnExecutionPolicyV1" as const;
|
|
12494
15131
|
|
|
12495
|
-
export const TurnExecutionModelSourceV1 =
|
|
12496
|
-
|
|
12497
|
-
|
|
12498
|
-
);
|
|
15132
|
+
export const TurnExecutionModelSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15133
|
+
z.enum(["explicit", "session", "deployment", "continuation"]),
|
|
15134
|
+
);
|
|
12499
15135
|
export type TurnExecutionModelSourceV1 = z.infer<typeof TurnExecutionModelSourceV1>;
|
|
12500
15136
|
|
|
12501
|
-
export const TurnExecutionReasoningSourceV1 =
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
);
|
|
15137
|
+
export const TurnExecutionReasoningSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15138
|
+
z.enum(["explicit", "session", "deployment", "continuation"]),
|
|
15139
|
+
);
|
|
12505
15140
|
export type TurnExecutionReasoningSourceV1 = z.infer<typeof TurnExecutionReasoningSourceV1>;
|
|
12506
15141
|
|
|
12507
|
-
export const TurnExecutionLatencyModeSourceV1 =
|
|
12508
|
-
|
|
12509
|
-
|
|
12510
|
-
);
|
|
15142
|
+
export const TurnExecutionLatencyModeSourceV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15143
|
+
z.enum(["explicit", "session", "deployment", "continuation"]),
|
|
15144
|
+
);
|
|
12511
15145
|
export type TurnExecutionLatencyModeSourceV1 = z.infer<typeof TurnExecutionLatencyModeSourceV1>;
|
|
12512
15146
|
|
|
12513
15147
|
/**
|
|
@@ -12535,7 +15169,7 @@ export const TurnExecutionPolicyV1 = /* @__PURE__ */ defineModelContractSchema((
|
|
|
12535
15169
|
providerId: z.string().min(1),
|
|
12536
15170
|
upstreamModelId: z.string().min(1),
|
|
12537
15171
|
wireApi: z.enum(["responses", "chat"]),
|
|
12538
|
-
credentialSource:
|
|
15172
|
+
credentialSource: TurnExecutionCredentialSourceV1,
|
|
12539
15173
|
billing: ModelBillingAttributionV1,
|
|
12540
15174
|
definitionVersion: z.string().regex(/^sha256:[a-f0-9]{64}$/u),
|
|
12541
15175
|
})
|
|
@@ -12709,60 +15343,59 @@ export const ClientModel = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
|
12709
15343
|
);
|
|
12710
15344
|
export type ClientModel = z.infer<typeof ClientModel>;
|
|
12711
15345
|
|
|
12712
|
-
export const ModelCredentialReadinessV1 =
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
.
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
);
|
|
15346
|
+
export const ModelCredentialReadinessV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15347
|
+
z
|
|
15348
|
+
.object({
|
|
15349
|
+
status: z.enum(["ready", "not_ready", "error"]),
|
|
15350
|
+
reason: z
|
|
15351
|
+
.enum([
|
|
15352
|
+
"missing_credential",
|
|
15353
|
+
"needs_reauth",
|
|
15354
|
+
"prerequisites_missing",
|
|
15355
|
+
"resolver_error",
|
|
15356
|
+
"observation_stale",
|
|
15357
|
+
])
|
|
15358
|
+
.nullable(),
|
|
15359
|
+
basis: z.enum(["configuration", "connection", "resolver"]),
|
|
15360
|
+
checkedAt: z.string().datetime().nullable(),
|
|
15361
|
+
})
|
|
15362
|
+
.strict()
|
|
15363
|
+
.superRefine((readiness, context) => {
|
|
15364
|
+
if ((readiness.status === "ready") !== (readiness.reason === null)) {
|
|
15365
|
+
context.addIssue({
|
|
15366
|
+
code: "custom",
|
|
15367
|
+
path: ["reason"],
|
|
15368
|
+
message: "ready credential state requires no reason; non-ready state requires a reason",
|
|
15369
|
+
});
|
|
15370
|
+
}
|
|
15371
|
+
if ((readiness.status === "error") !== (readiness.reason === "resolver_error")) {
|
|
15372
|
+
context.addIssue({
|
|
15373
|
+
code: "custom",
|
|
15374
|
+
path: ["reason"],
|
|
15375
|
+
message:
|
|
15376
|
+
"credential errors require resolver_error and resolver_error requires error status",
|
|
15377
|
+
});
|
|
15378
|
+
}
|
|
15379
|
+
if (
|
|
15380
|
+
readiness.basis === "resolver" &&
|
|
15381
|
+
readiness.status === "ready" &&
|
|
15382
|
+
readiness.checkedAt === null
|
|
15383
|
+
) {
|
|
15384
|
+
context.addIssue({
|
|
15385
|
+
code: "custom",
|
|
15386
|
+
path: ["checkedAt"],
|
|
15387
|
+
message: "resolver readiness requires an observation timestamp",
|
|
15388
|
+
});
|
|
15389
|
+
}
|
|
15390
|
+
if (readiness.reason === "observation_stale" && readiness.checkedAt === null) {
|
|
15391
|
+
context.addIssue({
|
|
15392
|
+
code: "custom",
|
|
15393
|
+
path: ["checkedAt"],
|
|
15394
|
+
message: "a stale observation requires its observation timestamp",
|
|
15395
|
+
});
|
|
15396
|
+
}
|
|
15397
|
+
}),
|
|
15398
|
+
);
|
|
12766
15399
|
export type ModelCredentialReadinessV1 = z.infer<typeof ModelCredentialReadinessV1>;
|
|
12767
15400
|
|
|
12768
15401
|
export const ModelAvailabilityV1 = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
@@ -12785,21 +15418,21 @@ export const ModelAvailabilityV1 = /* @__PURE__ */ defineModelContractSchema(()
|
|
|
12785
15418
|
);
|
|
12786
15419
|
export type ModelAvailabilityV1 = z.infer<typeof ModelAvailabilityV1>;
|
|
12787
15420
|
|
|
12788
|
-
export const WorkspaceModelCatalogModel =
|
|
12789
|
-
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
)
|
|
15421
|
+
export const WorkspaceModelCatalogModel = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15422
|
+
ClientModel.extend({
|
|
15423
|
+
credentialReadiness: ModelCredentialReadinessV1,
|
|
15424
|
+
/** Exact workspace-policy verdict without exposing provider identity. */
|
|
15425
|
+
policyAllowed: z.boolean().optional(),
|
|
15426
|
+
availability: ModelAvailabilityV1,
|
|
15427
|
+
}),
|
|
15428
|
+
);
|
|
12795
15429
|
export type WorkspaceModelCatalogModel = z.infer<typeof WorkspaceModelCatalogModel>;
|
|
12796
15430
|
|
|
12797
|
-
export const WorkspaceModelCatalogResponse =
|
|
12798
|
-
|
|
12799
|
-
z.
|
|
12800
|
-
|
|
12801
|
-
|
|
12802
|
-
);
|
|
15431
|
+
export const WorkspaceModelCatalogResponse = /* @__PURE__ */ defineModelContractSchema(() =>
|
|
15432
|
+
z.object({
|
|
15433
|
+
models: z.array(WorkspaceModelCatalogModel),
|
|
15434
|
+
}),
|
|
15435
|
+
);
|
|
12803
15436
|
export type WorkspaceModelCatalogResponse = z.infer<typeof WorkspaceModelCatalogResponse>;
|
|
12804
15437
|
|
|
12805
15438
|
/**
|
|
@@ -12810,7 +15443,7 @@ export type WorkspaceModelCatalogResponse = z.infer<typeof WorkspaceModelCatalog
|
|
|
12810
15443
|
* that rollout boundary. Mutating clients send this value in
|
|
12811
15444
|
* `x-opengeni-api-contract`; the API rejects any other value before routing.
|
|
12812
15445
|
*/
|
|
12813
|
-
export const OPENGENI_API_CONTRACT_REVISION = "2026-08-
|
|
15446
|
+
export const OPENGENI_API_CONTRACT_REVISION = "2026-08-atomic-session-fork-visibility-v1" as const;
|
|
12814
15447
|
export const OPENGENI_API_CONTRACT_HEADER = "x-opengeni-api-contract" as const;
|
|
12815
15448
|
/** Bounded request/response identifier shared by browser, ingress, and API diagnostics. */
|
|
12816
15449
|
export const OPENGENI_CORRELATION_HEADER = "x-opengeni-correlation-id" as const;
|
|
@@ -12984,10 +15617,18 @@ export * from "./codex-fleet-policy";
|
|
|
12984
15617
|
export * from "./xai-provider-account-authority";
|
|
12985
15618
|
export * from "./workspace-instruction-policies";
|
|
12986
15619
|
export * from "./company-profile";
|
|
15620
|
+
export * from "./company-brain";
|
|
12987
15621
|
export * from "./workspace-learning-policy";
|
|
15622
|
+
export * from "./workspace-learning-administration";
|
|
12988
15623
|
export * from "./workspace-state";
|
|
12989
15624
|
export * from "./preference-registry";
|
|
12990
15625
|
export * from "./scoped-knowledge";
|
|
15626
|
+
export * from "./company-brain-governed-writes";
|
|
15627
|
+
export * from "./governed-learning-evaluator";
|
|
15628
|
+
export * from "./governed-learning-activation";
|
|
12991
15629
|
export * from "./knowledge";
|
|
12992
15630
|
export * from "./task-notes";
|
|
12993
15631
|
export * from "./canonical-human-identities";
|
|
15632
|
+
export * from "./organization-membership-lifecycle";
|
|
15633
|
+
export * from "./remember";
|
|
15634
|
+
export * from "./agent-authored-durable-text";
|