@opengeni/db 0.28.1 → 0.31.1

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.
Files changed (187) hide show
  1. package/dist/attached-browser-devices.d.ts +42 -0
  2. package/dist/attempt-tool-catalogs.d.ts +16 -0
  3. package/dist/browser-auth.d.ts +91 -0
  4. package/dist/browser-identities.d.ts +128 -0
  5. package/dist/browser-sessions.d.ts +272 -0
  6. package/dist/browser-state-artifacts.d.ts +17 -0
  7. package/dist/capability-components.d.ts +37 -0
  8. package/dist/capability-integrations.d.ts +192 -0
  9. package/dist/chunk-F5FT7BEZ.js +3535 -0
  10. package/dist/chunk-F5FT7BEZ.js.map +1 -0
  11. package/dist/chunk-ISI2TIUG.js +639 -0
  12. package/dist/chunk-ISI2TIUG.js.map +1 -0
  13. package/dist/chunk-MWDVXQOL.js +11639 -0
  14. package/dist/chunk-MWDVXQOL.js.map +1 -0
  15. package/dist/chunk-NBE6CHRI.js +955 -0
  16. package/dist/chunk-NBE6CHRI.js.map +1 -0
  17. package/dist/{chunk-DBS5HPEW.js → chunk-YHZXQ7HP.js} +760 -11
  18. package/dist/chunk-YHZXQ7HP.js.map +1 -0
  19. package/dist/codemode-operations.d.ts +117 -0
  20. package/dist/codex-token-resolver.d.ts +2 -2
  21. package/dist/company-profile-schema.d.ts +798 -0
  22. package/dist/company-profile.d.ts +268 -0
  23. package/dist/computer-sessions.d.ts +109 -0
  24. package/dist/connection-token-resolver.d.ts +9 -4
  25. package/dist/database.d.ts +52 -3
  26. package/dist/editable-artifact-durable-export.d.ts +153 -0
  27. package/dist/editable-artifact-durable-export.js +788 -0
  28. package/dist/editable-artifact-durable-export.js.map +1 -0
  29. package/dist/editable-artifact-materialization.d.ts +123 -0
  30. package/dist/editable-artifacts-schema.d.ts +4152 -0
  31. package/dist/editable-artifacts.d.ts +610 -0
  32. package/dist/editable-artifacts.js +26 -0
  33. package/dist/editable-artifacts.js.map +1 -0
  34. package/dist/environment-crypto.d.ts +8 -4
  35. package/dist/generated-images.d.ts +139 -0
  36. package/dist/index.d.ts +958 -126
  37. package/dist/index.js +31204 -12172
  38. package/dist/index.js.map +1 -1
  39. package/dist/insights.d.ts +51 -4
  40. package/dist/integration-bindings.d.ts +70 -0
  41. package/dist/integration-features.d.ts +99 -0
  42. package/dist/interaction-revisions.d.ts +3 -0
  43. package/dist/interaction-schema.d.ts +5372 -0
  44. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  45. package/dist/knowledge-source-sync.d.ts +274 -0
  46. package/dist/lossless-columns.d.ts +58 -0
  47. package/dist/lossless-json.d.ts +39 -0
  48. package/dist/memory-domain.d.ts +3 -6
  49. package/dist/memory-governance.d.ts +2 -2
  50. package/dist/memory-slack-delivery.d.ts +101 -0
  51. package/dist/new-session-drafts.d.ts +2 -2
  52. package/dist/pack-components.d.ts +76 -0
  53. package/dist/pack-installations.d.ts +86 -0
  54. package/dist/persistence-errors.d.ts +7 -14
  55. package/dist/plugin-packages.d.ts +126 -0
  56. package/dist/preference-registry.d.ts +1 -1
  57. package/dist/provision-roles.d.ts +9 -1
  58. package/dist/provision-roles.js +1 -1
  59. package/dist/runtime-posture.d.ts +18 -6
  60. package/dist/schema.d.ts +19122 -8731
  61. package/dist/schema.js +173 -1
  62. package/dist/scoped-knowledge.d.ts +97 -1
  63. package/dist/session-control.d.ts +4 -4
  64. package/dist/session-queue-commands.d.ts +19 -11
  65. package/dist/session-realtime-context.d.ts +2 -2
  66. package/dist/session-realtime-ledger.d.ts +4 -4
  67. package/dist/session-realtime-mirror.d.ts +2 -2
  68. package/dist/session-realtime-state.d.ts +1 -1
  69. package/dist/session-realtime-terminal.d.ts +8 -1
  70. package/dist/session-realtime.d.ts +7 -7
  71. package/dist/session-tool-call-settlement.d.ts +1 -1
  72. package/dist/slack-user-link-access.d.ts +54 -0
  73. package/dist/transcription-recordings-schema.d.ts +44 -6
  74. package/dist/transcription-recordings.d.ts +3 -3
  75. package/dist/turn-initiator.d.ts +2 -2
  76. package/dist/video-generation.d.ts +216 -0
  77. package/dist/video-generation.js +66 -0
  78. package/dist/video-generation.js.map +1 -0
  79. package/dist/workspace-artifacts.d.ts +1 -1
  80. package/dist/workspace-instruction-policies.d.ts +1 -1
  81. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  82. package/dist/workspace-learning-policy.d.ts +161 -0
  83. package/drizzle/0065_enrollment_credential_generation.sql +10 -0
  84. package/drizzle/0140_retained_screenshot_artifacts.sql +192 -0
  85. package/drizzle/0176_lossless_canonical_json.sql +975 -0
  86. package/drizzle/0177_session_events_workspace_turn_type_index.sql +5 -0
  87. package/drizzle/0178_permissioned_secret_reads.sql +14 -0
  88. package/drizzle/0179_slack_private_shortcut_delivery_gate.sql +85 -0
  89. package/drizzle/0180_retained_screenshot_lifecycle_fences.sql +273 -0
  90. package/drizzle/0181_connected_machine_removal.sql +52 -0
  91. package/drizzle/0182_connected_machine_remove_session_default.sql +77 -0
  92. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  93. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  94. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  95. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  96. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  97. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  98. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  99. package/drizzle/0190_timeline_annotations.sql +31 -0
  100. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  101. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  102. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  103. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  104. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  105. package/drizzle/0196_rig_provider_images.sql +152 -0
  106. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  107. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  108. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  109. package/drizzle/0201_company_profile_authority.sql +849 -0
  110. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  111. package/drizzle/0203_durable_video_generation.sql +353 -0
  112. package/drizzle/0204_video_generation_funding.sql +44 -0
  113. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  114. package/drizzle/0206_browser_sessions.sql +646 -0
  115. package/drizzle/0207_browser_identities.sql +379 -0
  116. package/drizzle/0208_attached_browser_devices.sql +165 -0
  117. package/drizzle/0209_computer_sessions.sql +575 -0
  118. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  119. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  120. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  121. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  122. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  123. package/drizzle/0215_capabilities_platform.sql +980 -0
  124. package/drizzle/0216_pack_component_ownership.sql +235 -0
  125. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  126. package/package.json +18 -5
  127. package/src/attached-browser-devices.ts +371 -0
  128. package/src/attempt-tool-catalogs.ts +131 -0
  129. package/src/browser-auth.ts +1896 -0
  130. package/src/browser-identities.ts +1168 -0
  131. package/src/browser-sessions.ts +2005 -0
  132. package/src/browser-state-artifacts.ts +59 -0
  133. package/src/capability-components.ts +166 -0
  134. package/src/capability-integrations.ts +1663 -0
  135. package/src/codemode-operations.ts +674 -0
  136. package/src/company-profile-schema.ts +143 -0
  137. package/src/company-profile.ts +968 -0
  138. package/src/computer-sessions.ts +1130 -0
  139. package/src/connection-token-resolver.ts +270 -25
  140. package/src/database.ts +434 -24
  141. package/src/editable-artifact-durable-export.ts +1201 -0
  142. package/src/editable-artifact-materialization.ts +893 -0
  143. package/src/editable-artifacts-schema.ts +879 -0
  144. package/src/editable-artifacts.ts +5404 -0
  145. package/src/environment-crypto.ts +22 -9
  146. package/src/generated-images.ts +740 -0
  147. package/src/index.ts +10117 -2730
  148. package/src/insights.ts +160 -13
  149. package/src/integration-bindings.ts +455 -0
  150. package/src/integration-features.ts +859 -0
  151. package/src/interaction-revisions.ts +40 -0
  152. package/src/interaction-schema.ts +1303 -0
  153. package/src/knowledge-source-sync-schema.ts +192 -0
  154. package/src/knowledge-source-sync.ts +1922 -0
  155. package/src/lossless-columns.ts +35 -0
  156. package/src/lossless-json.ts +322 -0
  157. package/src/memory-domain.ts +5 -44
  158. package/src/memory-slack-delivery.ts +801 -0
  159. package/src/pack-components.ts +954 -0
  160. package/src/pack-installations.ts +929 -0
  161. package/src/persistence-errors.ts +26 -34
  162. package/src/plugin-packages.ts +1186 -0
  163. package/src/provision-roles.ts +302 -1
  164. package/src/runtime-posture-cli.ts +9 -0
  165. package/src/runtime-posture.ts +514 -5
  166. package/src/schema.ts +5177 -2957
  167. package/src/scoped-knowledge-schema.ts +1 -1
  168. package/src/scoped-knowledge.ts +655 -3
  169. package/src/session-control.ts +133 -81
  170. package/src/session-queue-commands.ts +511 -247
  171. package/src/session-realtime-context.ts +20 -7
  172. package/src/session-realtime-ledger.ts +32 -10
  173. package/src/session-realtime-mirror.ts +4 -2
  174. package/src/session-realtime-terminal.ts +89 -21
  175. package/src/session-realtime.ts +10 -9
  176. package/src/session-tool-call-settlement.ts +38 -15
  177. package/src/slack-user-link-access.ts +702 -0
  178. package/src/transcription-recordings-schema.ts +5 -2
  179. package/src/transcription-recordings.ts +70 -40
  180. package/src/video-generation.ts +1452 -0
  181. package/src/workspace-learning-policy-schema.ts +139 -0
  182. package/src/workspace-learning-policy.ts +595 -0
  183. package/dist/chunk-DBS5HPEW.js.map +0 -1
  184. package/dist/chunk-HT5T62CC.js +0 -6803
  185. package/dist/chunk-HT5T62CC.js.map +0 -1
  186. package/dist/event-payload-sanitizer.d.ts +0 -32
  187. package/src/event-payload-sanitizer.ts +0 -377
@@ -1,32 +0,0 @@
1
- import { type SecretForRedaction } from "@opengeni/contracts";
2
- /**
3
- * Strip NUL and repair invalid/lone UTF-16 surrogates in a single string.
4
- * Returns the input unchanged (same reference) when it is already clean, so the
5
- * common case allocates nothing.
6
- */
7
- export declare function sanitizeEventString(value: string): string;
8
- /**
9
- * Deep-walk a session event payload and sanitize every string value. Mirrors the
10
- * shape of the worker redaction deep-walk: objects, arrays, and nested
11
- * combinations are traversed; non-string leaves pass through untouched. Object
12
- * keys are sanitized too -- they are jsonb-constrained the same as values.
13
- */
14
- export type SanitizeEventPayloadOptions = {
15
- /**
16
- * Separately trusted, server-created retained-output evidence. Never populate
17
- * this from a producer-controlled payload field.
18
- */
19
- fullEvidence?: unknown;
20
- /** Exact runtime credential provenance to remove from keys and values. */
21
- knownSecrets?: readonly SecretForRedaction[];
22
- };
23
- export declare function sanitizeEventPayload<T>(payload: T, options?: SanitizeEventPayloadOptions): T;
24
- /**
25
- * Make model-facing conversation data safe for Postgres and secret-redacted.
26
- *
27
- * Conversation history is the replay source for the model, so this boundary
28
- * retains protocol structure and non-sensitive diagnostics while removing
29
- * credential-bearing fields and text before durable storage. It also performs
30
- * the database-safety repair (NUL removal and UTF-16 repair).
31
- */
32
- export declare function sanitizeModelPayload<T>(payload: T, knownSecrets?: readonly SecretForRedaction[]): T;
@@ -1,377 +0,0 @@
1
- import {
2
- boundSessionEventPayload,
3
- isCredentialHeaderName,
4
- isSensitiveFieldName,
5
- redactSensitiveKey,
6
- redactSensitiveText,
7
- type SecretForRedaction,
8
- } from "@opengeni/contracts";
9
-
10
- /**
11
- * Last line of defense against a session event crashing a whole turn.
12
- *
13
- * Postgres `text`/`jsonb` cannot store a NUL byte (U+0000) nor lone UTF-16
14
- * surrogates. Raw exec output routinely carries both -- chrome/crashpad logs,
15
- * `cat` of a binary, random bytes -- and the worker persists that output verbatim
16
- * inside `agent.toolCall.output` / `sandbox.command.output` event payloads. When
17
- * such a payload reaches `INSERT INTO session_events`, the driver rejects it
18
- * ("Failed query: insert into session_events") and the turn dies.
19
- *
20
- * `sanitizeEventPayload` deep-walks any payload value (objects, arrays, nested),
21
- * repairs every string, redacts sensitive fields, then applies the canonical
22
- * byte-bounded human/audit preview. Conversation truth uses
23
- * `sanitizeModelPayload` below and remains a separate representation.
24
- */
25
-
26
- const REPLACEMENT = "�";
27
- const REDACTED = "[redacted]";
28
-
29
- /**
30
- * Strip NUL and repair invalid/lone UTF-16 surrogates in a single string.
31
- * Returns the input unchanged (same reference) when it is already clean, so the
32
- * common case allocates nothing.
33
- */
34
- export function sanitizeEventString(value: string): string {
35
- // Fast path: no NUL and no surrogate code unit at all -> nothing to do.
36
- // Surrogates live in U+D800..U+DFFF; a quick scan avoids the rebuild cost.
37
- let needsWork = false;
38
- for (let i = 0; i < value.length; i++) {
39
- const code = value.charCodeAt(i);
40
- if (code === 0x0000 || (code >= 0xd800 && code <= 0xdfff)) {
41
- needsWork = true;
42
- break;
43
- }
44
- }
45
- if (!needsWork) {
46
- return value;
47
- }
48
-
49
- let out = "";
50
- for (let i = 0; i < value.length; i++) {
51
- const code = value.charCodeAt(i);
52
- if (code === 0x0000) {
53
- // Drop NUL entirely.
54
- continue;
55
- }
56
- if (code >= 0xd800 && code <= 0xdbff) {
57
- // High surrogate: valid only when immediately followed by a low surrogate.
58
- const next = i + 1 < value.length ? value.charCodeAt(i + 1) : 0;
59
- if (next >= 0xdc00 && next <= 0xdfff) {
60
- out += value[i]! + value[i + 1]!;
61
- i += 1;
62
- continue;
63
- }
64
- out += REPLACEMENT;
65
- continue;
66
- }
67
- if (code >= 0xdc00 && code <= 0xdfff) {
68
- // Lone low surrogate (a valid pair would have been consumed above).
69
- out += REPLACEMENT;
70
- continue;
71
- }
72
- out += value[i]!;
73
- }
74
- return out;
75
- }
76
-
77
- /**
78
- * Deep-walk a session event payload and sanitize every string value. Mirrors the
79
- * shape of the worker redaction deep-walk: objects, arrays, and nested
80
- * combinations are traversed; non-string leaves pass through untouched. Object
81
- * keys are sanitized too -- they are jsonb-constrained the same as values.
82
- */
83
- export type SanitizeEventPayloadOptions = {
84
- /**
85
- * Separately trusted, server-created retained-output evidence. Never populate
86
- * this from a producer-controlled payload field.
87
- */
88
- fullEvidence?: unknown;
89
- /** Exact runtime credential provenance to remove from keys and values. */
90
- knownSecrets?: readonly SecretForRedaction[];
91
- };
92
-
93
- export function sanitizeEventPayload<T>(payload: T, options: SanitizeEventPayloadOptions = {}): T {
94
- // Bound first. The preview walker caps depth/container fan-out and replaces
95
- // inline media before this sanitizer allocates a deep clone. Reversing this
96
- // order lets a cyclic, deeply nested, or multi-megabyte tool result exhaust
97
- // the stack/heap before the durable 64 KiB event boundary can protect it.
98
- const bounded = boundSessionEventPayload(payload, {
99
- fullEvidence: options.fullEvidence,
100
- });
101
- return sanitizeEventPayloadDeep(
102
- bounded === payload ? removeProducerTruncationMetadata(bounded) : bounded,
103
- options.knownSecrets ?? [],
104
- );
105
- }
106
-
107
- /**
108
- * `truncation` is reserved durable-boundary metadata. An ordinary payload that
109
- * already fits the envelope otherwise returns by reference, so remove a
110
- * producer-supplied value before persistence rather than allowing it to forge
111
- * byte accounting or an available retained-artifact receipt. A payload changed
112
- * by `boundSessionEventPayload` already carries freshly computed metadata and
113
- * never reaches this helper.
114
- */
115
- function removeProducerTruncationMetadata<T>(payload: T): T {
116
- if (!isPlainObject(payload)) return payload;
117
- const descriptor = Object.getOwnPropertyDescriptor(payload, "truncation");
118
- if (!descriptor?.enumerable) return payload;
119
- const cleaned = { ...payload };
120
- delete cleaned.truncation;
121
- return cleaned as T;
122
- }
123
-
124
- function sanitizeEventPayloadDeep<T>(
125
- payload: T,
126
- knownSecrets: readonly SecretForRedaction[] = [],
127
- ): T {
128
- if (typeof payload === "string") {
129
- return sanitizeEventString(redactSensitiveText(payload, knownSecrets)) as unknown as T;
130
- }
131
- if (Array.isArray(payload)) {
132
- return payload.map((item) => sanitizeEventPayloadDeep(item, knownSecrets)) as unknown as T;
133
- }
134
- if (payload instanceof Date) {
135
- return safeDateIso(payload) as unknown as T;
136
- }
137
- if (payload && typeof payload === "object") {
138
- const usedKeys = new Set<string>();
139
- const entries = Object.entries(payload as Record<string, unknown>).map(([key, value]) => {
140
- const safeKey = nextUniqueKey(
141
- sanitizeEventString(redactSensitiveKey(key, knownSecrets)),
142
- usedKeys,
143
- );
144
- return [safeKey, sanitizeSensitiveEventField(key, value, knownSecrets)] as const;
145
- });
146
- return Object.fromEntries(entries) as unknown as T;
147
- }
148
- return payload;
149
- }
150
-
151
- /**
152
- * Make model-facing conversation data safe for Postgres and secret-redacted.
153
- *
154
- * Conversation history is the replay source for the model, so this boundary
155
- * retains protocol structure and non-sensitive diagnostics while removing
156
- * credential-bearing fields and text before durable storage. It also performs
157
- * the database-safety repair (NUL removal and UTF-16 repair).
158
- */
159
- export function sanitizeModelPayload<T>(
160
- payload: T,
161
- knownSecrets: readonly SecretForRedaction[] = [],
162
- ): T {
163
- return sanitizeModelPayloadDeep(payload, new WeakSet<object>(), 0, knownSecrets);
164
- }
165
-
166
- const MODEL_PAYLOAD_SANITIZE_MAX_DEPTH = 64;
167
- const MODEL_PAYLOAD_CYCLE_MARKER = "[OpenGeni omitted cyclic model payload]";
168
- const MODEL_PAYLOAD_DEPTH_MARKER = "[OpenGeni omitted model payload beyond database-safety depth]";
169
-
170
- function sanitizeModelPayloadDeep<T>(
171
- payload: T,
172
- seen: WeakSet<object>,
173
- depth: number,
174
- knownSecrets: readonly SecretForRedaction[] = [],
175
- ): T {
176
- if (typeof payload === "string") {
177
- return sanitizeEventString(redactSensitiveText(payload, knownSecrets)) as unknown as T;
178
- }
179
- if (!payload || typeof payload !== "object") return payload;
180
- if (payload instanceof Date) {
181
- return safeDateIso(payload) as unknown as T;
182
- }
183
- if (depth >= MODEL_PAYLOAD_SANITIZE_MAX_DEPTH) {
184
- return MODEL_PAYLOAD_DEPTH_MARKER as unknown as T;
185
- }
186
- if (seen.has(payload)) return MODEL_PAYLOAD_CYCLE_MARKER as unknown as T;
187
- seen.add(payload);
188
- try {
189
- if (Array.isArray(payload)) {
190
- return payload.map((item) =>
191
- sanitizeModelPayloadDeep(item, seen, depth + 1, knownSecrets),
192
- ) as unknown as T;
193
- }
194
- const usedKeys = new Set<string>();
195
- return Object.fromEntries(
196
- Object.entries(payload as Record<string, unknown>).map(([key, value]) => {
197
- const safeKey = nextUniqueKey(
198
- sanitizeEventString(redactSensitiveKey(key, knownSecrets)),
199
- usedKeys,
200
- );
201
- if (isSensitiveFieldName(key)) {
202
- return [safeKey, REDACTED] as const;
203
- }
204
- if (normalizeFieldName(key) === "headers") {
205
- return [safeKey, sanitizeModelHeaders(value, seen, depth + 1, knownSecrets)] as const;
206
- }
207
- return [safeKey, sanitizeModelPayloadDeep(value, seen, depth + 1, knownSecrets)] as const;
208
- }),
209
- ) as unknown as T;
210
- } finally {
211
- seen.delete(payload);
212
- }
213
- }
214
-
215
- function safeDateIso(value: Date): string | null {
216
- try {
217
- const epoch = Date.prototype.getTime.call(value);
218
- return Number.isFinite(epoch) ? Date.prototype.toISOString.call(value) : null;
219
- } catch {
220
- return null;
221
- }
222
- }
223
-
224
- function sanitizeSensitiveEventField(
225
- key: string,
226
- value: unknown,
227
- knownSecrets: readonly SecretForRedaction[],
228
- ): unknown {
229
- if (key === "mcpServers") {
230
- return sanitizeSessionMcpServerList(value, knownSecrets);
231
- }
232
- if (key === "mcpCredentialUpdates") {
233
- return sanitizeMcpCredentialUpdateList(value, knownSecrets);
234
- }
235
- if (normalizeFieldName(key) === "headers") {
236
- return sanitizeEventHeaders(value, knownSecrets);
237
- }
238
- if (isSensitiveFieldName(key)) {
239
- return REDACTED;
240
- }
241
- return sanitizeEventPayloadDeep(value, knownSecrets);
242
- }
243
-
244
- function sanitizeEventHeaders(
245
- value: unknown,
246
- knownSecrets: readonly SecretForRedaction[],
247
- ): unknown {
248
- if (!isPlainObject(value)) {
249
- return sanitizeEventPayloadDeep(value, knownSecrets);
250
- }
251
- const usedKeys = new Set<string>();
252
- return Object.fromEntries(
253
- Object.entries(value).map(([key, child]) => {
254
- const safeKey = nextUniqueKey(
255
- sanitizeEventString(redactSensitiveKey(key, knownSecrets)),
256
- usedKeys,
257
- );
258
- return [
259
- safeKey,
260
- isCredentialHeaderName(key) ? REDACTED : sanitizeEventPayloadDeep(child, knownSecrets),
261
- ];
262
- }),
263
- );
264
- }
265
-
266
- function sanitizeModelHeaders(
267
- value: unknown,
268
- seen: WeakSet<object>,
269
- depth: number,
270
- knownSecrets: readonly SecretForRedaction[],
271
- ): unknown {
272
- if (!isPlainObject(value)) {
273
- return sanitizeModelPayloadDeep(value, seen, depth, knownSecrets);
274
- }
275
- if (depth >= MODEL_PAYLOAD_SANITIZE_MAX_DEPTH) {
276
- return MODEL_PAYLOAD_DEPTH_MARKER;
277
- }
278
- if (seen.has(value)) return MODEL_PAYLOAD_CYCLE_MARKER;
279
- seen.add(value);
280
- try {
281
- const usedKeys = new Set<string>();
282
- return Object.fromEntries(
283
- Object.entries(value).map(([key, child]) => {
284
- const safeKey = nextUniqueKey(
285
- sanitizeEventString(redactSensitiveKey(key, knownSecrets)),
286
- usedKeys,
287
- );
288
- return [
289
- safeKey,
290
- isCredentialHeaderName(key)
291
- ? REDACTED
292
- : sanitizeModelPayloadDeep(child, seen, depth + 1, knownSecrets),
293
- ];
294
- }),
295
- );
296
- } finally {
297
- seen.delete(value);
298
- }
299
- }
300
-
301
- function sanitizeSessionMcpServerList(
302
- value: unknown,
303
- knownSecrets: readonly SecretForRedaction[],
304
- ): unknown {
305
- if (!Array.isArray(value)) {
306
- return sanitizeEventPayloadDeep(value, knownSecrets);
307
- }
308
- return value.map((item) => {
309
- if (!isPlainObject(item)) {
310
- return sanitizeEventPayloadDeep(item, knownSecrets);
311
- }
312
- const { headers, headersEncrypted, ...rest } = item;
313
- const cleaned = sanitizeEventPayloadDeep(rest, knownSecrets) as Record<string, unknown>;
314
- const headerNames =
315
- safeHeaderNames(headers, knownSecrets) ?? safeHeaderNames(headersEncrypted, knownSecrets);
316
- if (headerNames) {
317
- cleaned.headerNames = headerNames;
318
- }
319
- return cleaned;
320
- });
321
- }
322
-
323
- function sanitizeMcpCredentialUpdateList(
324
- value: unknown,
325
- knownSecrets: readonly SecretForRedaction[],
326
- ): unknown {
327
- if (!Array.isArray(value)) {
328
- return sanitizeEventPayloadDeep(value, knownSecrets);
329
- }
330
- return value.map((item) => {
331
- if (!isPlainObject(item)) {
332
- return sanitizeEventPayloadDeep(item, knownSecrets);
333
- }
334
- const { headers, headersEncrypted, ...rest } = item;
335
- const cleaned = sanitizeEventPayloadDeep(rest, knownSecrets) as Record<string, unknown>;
336
- const headerNames =
337
- safeHeaderNames(headers, knownSecrets) ?? safeHeaderNames(headersEncrypted, knownSecrets);
338
- if (headerNames) {
339
- cleaned.headerNames = headerNames;
340
- }
341
- return cleaned;
342
- });
343
- }
344
-
345
- function safeHeaderNames(
346
- value: unknown,
347
- knownSecrets: readonly SecretForRedaction[],
348
- ): string[] | null {
349
- if (!isPlainObject(value)) {
350
- return null;
351
- }
352
- const usedKeys = new Set<string>();
353
- return Object.keys(value)
354
- .map((key) =>
355
- nextUniqueKey(sanitizeEventString(redactSensitiveKey(key, knownSecrets)), usedKeys),
356
- )
357
- .sort();
358
- }
359
-
360
- function nextUniqueKey(base: string, usedKeys: Set<string>): string {
361
- let candidate = base;
362
- let suffix = 2;
363
- while (usedKeys.has(candidate)) {
364
- candidate = `${base}#${suffix}`;
365
- suffix += 1;
366
- }
367
- usedKeys.add(candidate);
368
- return candidate;
369
- }
370
-
371
- function isPlainObject(value: unknown): value is Record<string, unknown> {
372
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
373
- }
374
-
375
- function normalizeFieldName(key: string): string {
376
- return key.toLowerCase().replace(/[-_]/g, "");
377
- }