@humain/ui 2.1.63 → 2.1.65

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 (160) hide show
  1. package/dist/components/organisms/ai/AIToolCall/AIToolCall.d.ts +9 -3
  2. package/dist/components/organisms/ai/AIToolRun/index.d.ts +1 -1
  3. package/dist/components/organisms/ai/AIToolRun/validation.d.ts +24 -3
  4. package/dist/components/organisms/ai/_shared/format-ai-duration.d.ts +1 -0
  5. package/dist/components/organisms/ai/_shared/workflow-step-renderer.d.ts +1 -0
  6. package/dist/index.js +52 -52
  7. package/dist/index151.js +1 -1
  8. package/dist/index174.js +7 -339
  9. package/dist/index174.js.map +1 -1
  10. package/dist/index175.js +310 -137
  11. package/dist/index175.js.map +1 -1
  12. package/dist/index176.js +148 -174
  13. package/dist/index176.js.map +1 -1
  14. package/dist/index177.js +186 -78
  15. package/dist/index177.js.map +1 -1
  16. package/dist/index178.js +74 -124
  17. package/dist/index178.js.map +1 -1
  18. package/dist/index179.js +133 -1
  19. package/dist/index179.js.map +1 -0
  20. package/dist/index180.js +2 -201
  21. package/dist/index181.js +201 -0
  22. package/dist/{index180.js.map → index181.js.map} +1 -1
  23. package/dist/index183.js +130 -166
  24. package/dist/index183.js.map +1 -1
  25. package/dist/index184.js +195 -983
  26. package/dist/index184.js.map +1 -1
  27. package/dist/index185.js +1069 -369
  28. package/dist/index185.js.map +1 -1
  29. package/dist/index186.js +395 -197
  30. package/dist/index186.js.map +1 -1
  31. package/dist/index187.js +198 -243
  32. package/dist/index187.js.map +1 -1
  33. package/dist/index188.js +263 -3
  34. package/dist/index188.js.map +1 -1
  35. package/dist/index189.js +3 -209
  36. package/dist/index189.js.map +1 -1
  37. package/dist/index190.js +190 -777
  38. package/dist/index190.js.map +1 -1
  39. package/dist/index191.js +771 -252
  40. package/dist/index191.js.map +1 -1
  41. package/dist/index192.js +250 -65
  42. package/dist/index192.js.map +1 -1
  43. package/dist/index193.js +72 -523
  44. package/dist/index193.js.map +1 -1
  45. package/dist/index194.js +537 -144
  46. package/dist/index194.js.map +1 -1
  47. package/dist/index195.js +139 -720
  48. package/dist/index195.js.map +1 -1
  49. package/dist/index196.js +707 -167
  50. package/dist/index196.js.map +1 -1
  51. package/dist/index197.js +175 -151
  52. package/dist/index197.js.map +1 -1
  53. package/dist/index198.js +152 -487
  54. package/dist/index198.js.map +1 -1
  55. package/dist/index199.js +472 -225
  56. package/dist/index199.js.map +1 -1
  57. package/dist/index200.js +236 -260
  58. package/dist/index200.js.map +1 -1
  59. package/dist/index201.js +265 -215
  60. package/dist/index201.js.map +1 -1
  61. package/dist/index202.js +207 -307
  62. package/dist/index202.js.map +1 -1
  63. package/dist/index203.js +302 -135
  64. package/dist/index203.js.map +1 -1
  65. package/dist/index204.js +140 -271
  66. package/dist/index204.js.map +1 -1
  67. package/dist/index205.js +263 -253
  68. package/dist/index205.js.map +1 -1
  69. package/dist/index206.js +244 -137
  70. package/dist/index206.js.map +1 -1
  71. package/dist/index207.js +100 -238
  72. package/dist/index207.js.map +1 -1
  73. package/dist/index208.js +278 -74
  74. package/dist/index208.js.map +1 -1
  75. package/dist/index209.js +56 -97
  76. package/dist/index209.js.map +1 -1
  77. package/dist/index210.js +142 -47
  78. package/dist/index210.js.map +1 -1
  79. package/dist/index211.js +38 -84
  80. package/dist/index211.js.map +1 -1
  81. package/dist/index212.js +72 -252
  82. package/dist/index212.js.map +1 -1
  83. package/dist/index213.js +274 -26
  84. package/dist/index213.js.map +1 -1
  85. package/dist/index214.js +29 -94
  86. package/dist/index214.js.map +1 -1
  87. package/dist/index215.js +98 -25
  88. package/dist/index215.js.map +1 -1
  89. package/dist/index216.js +20 -565
  90. package/dist/index216.js.map +1 -1
  91. package/dist/index217.js +564 -17
  92. package/dist/index217.js.map +1 -1
  93. package/dist/index218.js +20 -23
  94. package/dist/index218.js.map +1 -1
  95. package/dist/index219.js +20 -95
  96. package/dist/index219.js.map +1 -1
  97. package/dist/index220.js +92 -88
  98. package/dist/index220.js.map +1 -1
  99. package/dist/index221.js +97 -29
  100. package/dist/index221.js.map +1 -1
  101. package/dist/index222.js +24 -470
  102. package/dist/index222.js.map +1 -1
  103. package/dist/index223.js +446 -196
  104. package/dist/index223.js.map +1 -1
  105. package/dist/index224.js +199 -729
  106. package/dist/index224.js.map +1 -1
  107. package/dist/index225.js +750 -61
  108. package/dist/index225.js.map +1 -1
  109. package/dist/index226.js +58 -181
  110. package/dist/index226.js.map +1 -1
  111. package/dist/index227.js +175 -259
  112. package/dist/index227.js.map +1 -1
  113. package/dist/index228.js +246 -172
  114. package/dist/index228.js.map +1 -1
  115. package/dist/index229.js +195 -32
  116. package/dist/index229.js.map +1 -1
  117. package/dist/index230.js +12 -40
  118. package/dist/index230.js.map +1 -1
  119. package/dist/index231.js +23 -26
  120. package/dist/index231.js.map +1 -1
  121. package/dist/index232.js +45 -22
  122. package/dist/index232.js.map +1 -1
  123. package/dist/index233.js +27 -48
  124. package/dist/index233.js.map +1 -1
  125. package/dist/index234.js +52 -26
  126. package/dist/index234.js.map +1 -1
  127. package/dist/index235.js +40 -225
  128. package/dist/index235.js.map +1 -1
  129. package/dist/index236.js +217 -39
  130. package/dist/index236.js.map +1 -1
  131. package/dist/index237.js +50 -0
  132. package/dist/index237.js.map +1 -0
  133. package/dist/styles.css +1 -1
  134. package/dist/wc/AIToolCall.js +218 -0
  135. package/dist/wc/AIToolCall.js.map +1 -0
  136. package/dist/wc/hf-ai-tool-call.js +34 -219
  137. package/dist/wc/hf-ai-tool-call.js.map +1 -1
  138. package/dist/wc/hf-ai-tool-run.js +673 -576
  139. package/dist/wc/hf-ai-tool-run.js.map +1 -1
  140. package/dist/wc/workflow-step-renderer.js +79 -78
  141. package/dist/wc/workflow-step-renderer.js.map +1 -1
  142. package/dist/wc-react/AIToolCall.js +218 -0
  143. package/dist/wc-react/AIToolCall.js.map +1 -0
  144. package/dist/wc-react/hf-ai-tool-call.js +32 -217
  145. package/dist/wc-react/hf-ai-tool-call.js.map +1 -1
  146. package/dist/wc-react/hf-ai-tool-run.js +698 -601
  147. package/dist/wc-react/hf-ai-tool-run.js.map +1 -1
  148. package/dist/wc-react/workflow-step-renderer.js +58 -57
  149. package/dist/wc-react/workflow-step-renderer.js.map +1 -1
  150. package/package.json +1 -1
  151. package/skills/humain-ui/SKILL.md +1 -1
  152. package/skills/humain-ui-wc/SKILL.md +1 -1
  153. package/skills/humain-ui-wc.skill +0 -0
  154. package/skills/humain-ui.skill +0 -0
  155. package/dist/index182.js +0 -143
  156. package/dist/index182.js.map +0 -1
  157. package/dist/wc/wrench.js +0 -10
  158. package/dist/wc/wrench.js.map +0 -1
  159. package/dist/wc-react/wrench.js +0 -10
  160. package/dist/wc-react/wrench.js.map +0 -1
package/dist/index185.js CHANGED
@@ -1,387 +1,1087 @@
1
- "use client";
2
- import { assertNever, cn } from "./index2.js";
3
- import { Button } from "./index5.js";
4
- import { Progress } from "./index17.js";
5
- import { Card } from "./index48.js";
6
- import { AISource } from "./index173.js";
7
- import { WorkflowStepRenderer } from "./index174.js";
8
- import { validateAIToolRunSnapshot } from "./index184.js";
9
- import { AlertCircle, Check, ChevronDown, ChevronRight, CirclePause, Clock, Wrench } from "lucide-react";
10
- import * as React from "react";
11
- import { jsx, jsxs } from "react/jsx-runtime";
12
- //#region src/components/organisms/ai/AIToolRun/AIToolRun.tsx
13
- var MAX_RUNTIME_EXPANDED_STEP_IDS = 1e4;
14
- var INVALID_RUNTIME_STRING_ARRAY = Symbol("invalid-runtime-string-array");
15
- var ARRAY_PROTOTYPE_MEMBER_KEYS = Reflect.ownKeys(Array.prototype).filter((key) => key !== "length");
16
- function cloneRuntimeStringArray(value) {
1
+ import { assertNever } from "./index2.js";
2
+ //#region src/components/organisms/ai/AIToolRun/validation.ts
3
+ var ROOT_KEYS = /* @__PURE__ */ new Set([
4
+ "runId",
5
+ "status",
6
+ "header",
7
+ "steps",
8
+ "sources",
9
+ "actions",
10
+ "progress",
11
+ "activeStepId",
12
+ "error",
13
+ "durationMs"
14
+ ]);
15
+ var HEADER_KEYS = /* @__PURE__ */ new Set([
16
+ "title",
17
+ "description",
18
+ "metadata"
19
+ ]);
20
+ var METADATA_KEYS = /* @__PURE__ */ new Set(["label", "value"]);
21
+ var PROGRESS_KEYS = /* @__PURE__ */ new Set([
22
+ "value",
23
+ "label",
24
+ "meta"
25
+ ]);
26
+ var ROOT_ERROR_KEYS = /* @__PURE__ */ new Set(["message"]);
27
+ var SOURCE_KEYS = /* @__PURE__ */ new Set([
28
+ "id",
29
+ "url",
30
+ "title",
31
+ "description",
32
+ "favicon",
33
+ "siteName",
34
+ "kind"
35
+ ]);
36
+ var ACTION_KEYS = /* @__PURE__ */ new Set([
37
+ "id",
38
+ "kind",
39
+ "label",
40
+ "disabled",
41
+ "loading"
42
+ ]);
43
+ var STEP_KEYS = /* @__PURE__ */ new Set([
44
+ "toolCall",
45
+ "title",
46
+ "description",
47
+ "progress",
48
+ "sourceIds",
49
+ "currentSourceId",
50
+ "durationMs",
51
+ "context",
52
+ "technicalDetails"
53
+ ]);
54
+ var TOOL_CALL_KEYS = /* @__PURE__ */ new Set([
55
+ "toolCallId",
56
+ "toolName",
57
+ "status",
58
+ "error"
59
+ ]);
60
+ var CONTEXT_KEYS = /* @__PURE__ */ new Set(["id", "label"]);
61
+ var TECHNICAL_DETAILS_KEYS = /* @__PURE__ */ new Set(["label", "toolCalls"]);
62
+ var TECHNICAL_TOOL_CALL_KEYS = /* @__PURE__ */ new Set([
63
+ "toolCallId",
64
+ "toolName",
65
+ "args",
66
+ "result",
67
+ "status",
68
+ "error"
69
+ ]);
70
+ var REFERENCE_SOURCE_KEYS = /* @__PURE__ */ new Set([
71
+ "id",
72
+ "kind",
73
+ "title",
74
+ "description"
75
+ ]);
76
+ var TOOL_STATUSES = {
77
+ error: true,
78
+ pending: true,
79
+ running: true,
80
+ success: true
81
+ };
82
+ var RUN_STATUSES = {
83
+ completed: true,
84
+ error: true,
85
+ paused: true,
86
+ ready: true,
87
+ running: true
88
+ };
89
+ var ACTION_KINDS = {
90
+ custom: true,
91
+ dismiss: true,
92
+ pause: true,
93
+ resume: true,
94
+ retry: true,
95
+ start: true
96
+ };
97
+ var ACTIONS_BY_STATUS = {
98
+ ready: [
99
+ "start",
100
+ "dismiss",
101
+ "custom"
102
+ ],
103
+ running: [
104
+ "pause",
105
+ "dismiss",
106
+ "custom"
107
+ ],
108
+ paused: [
109
+ "resume",
110
+ "dismiss",
111
+ "custom"
112
+ ],
113
+ completed: ["dismiss", "custom"],
114
+ error: [
115
+ "retry",
116
+ "dismiss",
117
+ "custom"
118
+ ]
119
+ };
120
+ var STEP_KEYS_BY_STATUS = {
121
+ pending: /* @__PURE__ */ new Set([
122
+ "toolCall",
123
+ "title",
124
+ "description",
125
+ "context",
126
+ "technicalDetails"
127
+ ]),
128
+ running: /* @__PURE__ */ new Set([
129
+ "toolCall",
130
+ "title",
131
+ "description",
132
+ "context",
133
+ "technicalDetails",
134
+ "progress",
135
+ "sourceIds",
136
+ "currentSourceId",
137
+ "durationMs"
138
+ ]),
139
+ success: /* @__PURE__ */ new Set([
140
+ "toolCall",
141
+ "title",
142
+ "description",
143
+ "context",
144
+ "technicalDetails",
145
+ "durationMs",
146
+ "sourceIds"
147
+ ]),
148
+ error: /* @__PURE__ */ new Set([
149
+ "toolCall",
150
+ "title",
151
+ "description",
152
+ "context",
153
+ "technicalDetails",
154
+ "sourceIds",
155
+ "durationMs"
156
+ ])
157
+ };
158
+ var TOOL_CALL_KEYS_BY_STATUS = {
159
+ pending: /* @__PURE__ */ new Set([
160
+ "toolCallId",
161
+ "toolName",
162
+ "status"
163
+ ]),
164
+ running: /* @__PURE__ */ new Set([
165
+ "toolCallId",
166
+ "toolName",
167
+ "status"
168
+ ]),
169
+ success: /* @__PURE__ */ new Set([
170
+ "toolCallId",
171
+ "toolName",
172
+ "status"
173
+ ]),
174
+ error: /* @__PURE__ */ new Set([
175
+ "toolCallId",
176
+ "toolName",
177
+ "status",
178
+ "error"
179
+ ])
180
+ };
181
+ var MAX_JSON_DEPTH = 100;
182
+ var MAX_JSON_NODES = 1e4;
183
+ var MAX_VALIDATION_ISSUES = 100;
184
+ var INSPECTION_FAILURE_MESSAGE = "Value could not be inspected safely";
185
+ var INVALID_FIELD = Symbol("invalid-shape-field");
186
+ function addIssue(issues, path, message) {
187
+ if (issues.length < MAX_VALIDATION_ISSUES) issues.push({
188
+ path,
189
+ message
190
+ });
191
+ }
192
+ function hasIssuesSince(issues, issueCount) {
193
+ return issues.length > issueCount || issues.length >= MAX_VALIDATION_ISSUES;
194
+ }
195
+ function addInspectionIssue(issues, path) {
196
+ addIssue(issues, path, INSPECTION_FAILURE_MESSAGE);
197
+ }
198
+ function getContainerKind(value, path, issues) {
199
+ if (value === null || typeof value !== "object") return "other";
17
200
  try {
18
- if (!Array.isArray(value)) return INVALID_RUNTIME_STRING_ARRAY;
19
- const lengthDescriptor = Reflect.getOwnPropertyDescriptor(value, "length");
20
- if (lengthDescriptor === void 0 || lengthDescriptor.enumerable || !Object.hasOwn(lengthDescriptor, "value") || typeof lengthDescriptor.value !== "number" || !Number.isInteger(lengthDescriptor.value) || lengthDescriptor.value < 0 || lengthDescriptor.value > MAX_RUNTIME_EXPANDED_STEP_IDS || !Object.is(Reflect.get(value, "length"), lengthDescriptor.value)) return INVALID_RUNTIME_STRING_ARRAY;
21
- for (const key of ARRAY_PROTOTYPE_MEMBER_KEYS) if (Reflect.getOwnPropertyDescriptor(value, key) !== void 0) return INVALID_RUNTIME_STRING_ARRAY;
22
- const copy = [];
23
- for (let index = 0; index < lengthDescriptor.value; index += 1) {
24
- const key = String(index);
25
- const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
26
- if (descriptor === void 0 || descriptor.enumerable !== true || !Object.hasOwn(descriptor, "value") || typeof descriptor.value !== "string" || !Object.is(Reflect.get(value, key), descriptor.value)) return INVALID_RUNTIME_STRING_ARRAY;
27
- copy.push(descriptor.value);
28
- }
29
- return copy;
201
+ const prototype = Reflect.getPrototypeOf(value);
202
+ if (Array.isArray(value)) return prototype === Array.prototype ? "array" : "other";
203
+ return prototype === Object.prototype || prototype === null ? "record" : "other";
30
204
  } catch {
31
- return INVALID_RUNTIME_STRING_ARRAY;
205
+ addInspectionIssue(issues, path);
206
+ return "uninspectable";
32
207
  }
33
208
  }
34
- function validateRuntimeViewProps({ headingLevel, open, defaultOpen, expandedStepIds, defaultExpandedStepIds }) {
35
- const issues = [];
36
- let validatedExpandedStepIds;
37
- let validatedDefaultExpandedStepIds;
38
- if (headingLevel !== void 0 && (typeof headingLevel !== "number" || !Number.isInteger(headingLevel) || headingLevel < 2 || headingLevel > 6)) issues.push("headingLevel must be an integer from 2 through 6");
39
- if (open !== void 0 && typeof open !== "boolean") issues.push("open must be a boolean");
40
- if (defaultOpen !== void 0 && typeof defaultOpen !== "boolean") issues.push("defaultOpen must be a boolean");
41
- if (expandedStepIds !== void 0) {
42
- const cloned = cloneRuntimeStringArray(expandedStepIds);
43
- if (cloned === INVALID_RUNTIME_STRING_ARRAY) issues.push("expandedStepIds must be an array of strings");
44
- else validatedExpandedStepIds = cloned;
45
- }
46
- if (defaultExpandedStepIds !== void 0) {
47
- const cloned = cloneRuntimeStringArray(defaultExpandedStepIds);
48
- if (cloned === INVALID_RUNTIME_STRING_ARRAY) issues.push("defaultExpandedStepIds must be an array of strings");
49
- else validatedDefaultExpandedStepIds = cloned;
50
- }
51
- if (issues.length > 0) return {
52
- valid: false,
53
- issues
54
- };
209
+ function getOwnKeys(value, path, issues) {
210
+ try {
211
+ return Reflect.ownKeys(value);
212
+ } catch {
213
+ addInspectionIssue(issues, path);
214
+ return;
215
+ }
216
+ }
217
+ function getOwnPropertyDescriptor(value, key, path, issues) {
218
+ try {
219
+ return Reflect.getOwnPropertyDescriptor(value, key);
220
+ } catch {
221
+ addInspectionIssue(issues, path);
222
+ return null;
223
+ }
224
+ }
225
+ function readEnumerableDataDescriptor(_value, _key, descriptor, path, issues) {
226
+ if (!descriptor.enumerable || !Object.hasOwn(descriptor, "value")) {
227
+ addIssue(issues, path, "Value must be an own enumerable data property");
228
+ return { valid: false };
229
+ }
55
230
  return {
56
231
  valid: true,
57
- value: {
58
- ...headingLevel === void 0 ? {} : { headingLevel },
59
- ...open === void 0 ? {} : { open },
60
- ...defaultOpen === void 0 ? {} : { defaultOpen },
61
- ...expandedStepIds === void 0 ? {} : { expandedStepIds: validatedExpandedStepIds },
62
- ...defaultExpandedStepIds === void 0 ? {} : { defaultExpandedStepIds: validatedDefaultExpandedStepIds }
232
+ value: descriptor.value
233
+ };
234
+ }
235
+ function findReflectedPropertyDescriptor(value, key, path, issues) {
236
+ const visited = /* @__PURE__ */ new Set();
237
+ let current = value;
238
+ let isOwn = true;
239
+ while (current !== null) {
240
+ if (visited.has(current)) {
241
+ addInspectionIssue(issues, path);
242
+ return null;
243
+ }
244
+ visited.add(current);
245
+ const descriptor = getOwnPropertyDescriptor(current, key, path, issues);
246
+ if (descriptor === null) return null;
247
+ if (descriptor !== void 0) {
248
+ if (isOwn) {
249
+ const ownKeys = getOwnKeys(value, path, issues);
250
+ if (!ownKeys) return null;
251
+ if (!ownKeys.includes(key)) {
252
+ addIssue(issues, path, "Own property must be exposed by Reflect.ownKeys");
253
+ return null;
254
+ }
255
+ }
256
+ return {
257
+ descriptor,
258
+ isOwn
259
+ };
260
+ }
261
+ try {
262
+ current = Reflect.getPrototypeOf(current);
263
+ } catch {
264
+ addInspectionIssue(issues, path);
265
+ return null;
63
266
  }
267
+ isOwn = false;
268
+ }
269
+ }
270
+ function inspectProperty(value, key, path, issues) {
271
+ const descriptor = findReflectedPropertyDescriptor(value, key, path, issues);
272
+ if (descriptor === null) return void 0;
273
+ if (descriptor !== void 0) return {
274
+ kind: "descriptor",
275
+ ...descriptor
64
276
  };
277
+ let present;
278
+ try {
279
+ present = Reflect.has(value, key);
280
+ } catch {
281
+ addInspectionIssue(issues, path);
282
+ return;
283
+ }
284
+ if (present) return { kind: "synthetic" };
285
+ let visibleValue;
286
+ try {
287
+ visibleValue = Reflect.get(value, key);
288
+ } catch {
289
+ addInspectionIssue(issues, path);
290
+ return;
291
+ }
292
+ return present || visibleValue !== void 0 ? { kind: "synthetic" } : { kind: "absent" };
65
293
  }
66
- var InvalidAIToolRun = React.forwardRef(({ className, ...sectionProps }, ref) => /* @__PURE__ */ jsx("section", {
67
- ...sectionProps,
68
- ref,
69
- "data-slot": "ai-tool-run",
70
- role: "alert",
71
- "aria-label": "Tool run",
72
- className: cn("w-full min-w-0", className),
73
- children: "Unable to display tool run."
74
- }));
75
- InvalidAIToolRun.displayName = "InvalidAIToolRun";
76
- var RUN_STATUS_LABELS = {
77
- ready: "Ready",
78
- running: "Running",
79
- paused: "Paused",
80
- completed: "Completed",
81
- error: "Failed"
82
- };
83
- var STANDARD_ACTION_LABELS = {
84
- start: "Start",
85
- pause: "Pause",
86
- resume: "Resume",
87
- retry: "Retry",
88
- dismiss: "Dismiss"
89
- };
90
- var PAUSED_PROGRESS_CLASS_NAME = "[&_[data-slot=progress-indicator]]:!transition-none [&_[data-slot=progress-indicator]]:!animate-none";
91
- function RunStatusIcon({ status }) {
92
- switch (status) {
93
- case "ready": return /* @__PURE__ */ jsx(Wrench, {
94
- "aria-hidden": "true",
95
- className: "size-4 text-muted-foreground"
96
- });
97
- case "running": return /* @__PURE__ */ jsx(Clock, {
98
- "aria-hidden": "true",
99
- className: "size-4 text-primary animate-pulse motion-reduce:animate-none"
100
- });
101
- case "paused": return /* @__PURE__ */ jsx(CirclePause, {
102
- "aria-hidden": "true",
103
- className: "size-4 text-warning"
104
- });
105
- case "completed": return /* @__PURE__ */ jsx(Check, {
106
- "aria-hidden": "true",
107
- className: "size-4 text-success"
294
+ function readShapeField(value, key, path, issues) {
295
+ const inspection = inspectProperty(value, key, path, issues);
296
+ if (!inspection) return INVALID_FIELD;
297
+ if (inspection.kind === "absent") return;
298
+ if (inspection.kind === "synthetic" || !inspection.isOwn) {
299
+ addIssue(issues, path, "Value must be an own enumerable data property");
300
+ return INVALID_FIELD;
301
+ }
302
+ const field = readEnumerableDataDescriptor(value, key, inspection.descriptor, path, issues);
303
+ return field.valid ? field.value : INVALID_FIELD;
304
+ }
305
+ function readRequiredField(value, key, path, issues) {
306
+ return readShapeField(value, key, path, issues);
307
+ }
308
+ function readOptionalField(value, key, path, issues) {
309
+ return readShapeField(value, key, path, issues);
310
+ }
311
+ function isInvalidField(value) {
312
+ return value === INVALID_FIELD;
313
+ }
314
+ function getOwnEnumerableDataKeys(value, path, issues) {
315
+ const keys = getOwnKeys(value, path, issues);
316
+ if (!keys) return void 0;
317
+ if (keys.length > MAX_JSON_NODES) {
318
+ addIssue(issues, path, "Value exceeds the maximum JSON node limit");
319
+ return;
320
+ }
321
+ const stringKeys = [];
322
+ for (const key of keys) {
323
+ const keyPath = typeof key === "string" ? `${path}.${key}` : path;
324
+ const descriptor = getOwnPropertyDescriptor(value, key, keyPath, issues);
325
+ if (descriptor === null) return void 0;
326
+ if (descriptor === void 0) {
327
+ addInspectionIssue(issues, keyPath);
328
+ return;
329
+ }
330
+ if (typeof key !== "string") {
331
+ addIssue(issues, path, "Symbol keys are not JSON-safe");
332
+ continue;
333
+ }
334
+ if (!readEnumerableDataDescriptor(value, key, descriptor, keyPath, issues).valid) continue;
335
+ stringKeys.push(key);
336
+ }
337
+ return stringKeys;
338
+ }
339
+ function isArrayIndexKey(key) {
340
+ const index = Number(key);
341
+ if (!Number.isInteger(index) || index < 0 || index >= 2 ** 32 - 1 || String(index) !== key) return;
342
+ return index;
343
+ }
344
+ function readArrayLength(_value, descriptor, path, issues) {
345
+ if (descriptor.enumerable || !Object.hasOwn(descriptor, "value") || typeof descriptor.value !== "number" || !Number.isInteger(descriptor.value) || descriptor.value < 0 || descriptor.value > 2 ** 32 - 1) {
346
+ addIssue(issues, path, "Array length must be a valid data property");
347
+ return;
348
+ }
349
+ return descriptor.value;
350
+ }
351
+ function readArrayItems(value, path, issues) {
352
+ const issueCount = issues.length;
353
+ const keys = getOwnKeys(value, path, issues);
354
+ if (!keys) return void 0;
355
+ if (keys.length > 10001) {
356
+ addIssue(issues, path, "Value exceeds the maximum JSON node limit");
357
+ return;
358
+ }
359
+ let length;
360
+ const items = /* @__PURE__ */ new Map();
361
+ for (const key of keys) {
362
+ const keyPath = typeof key === "string" ? `${path}.${key}` : path;
363
+ const descriptor = getOwnPropertyDescriptor(value, key, keyPath, issues);
364
+ if (descriptor === null) return void 0;
365
+ if (descriptor === void 0) {
366
+ addInspectionIssue(issues, keyPath);
367
+ return;
368
+ }
369
+ if (typeof key !== "string") {
370
+ addIssue(issues, path, "Symbol keys are not JSON-safe");
371
+ continue;
372
+ }
373
+ if (key === "length") {
374
+ length = readArrayLength(value, descriptor, path, issues);
375
+ continue;
376
+ }
377
+ const index = isArrayIndexKey(key);
378
+ if (index === void 0) {
379
+ addIssue(issues, keyPath, "Arrays must not contain custom properties");
380
+ continue;
381
+ }
382
+ const item = readEnumerableDataDescriptor(value, key, descriptor, `${path}[${index}]`, issues);
383
+ if (item.valid) items.set(index, item.value);
384
+ }
385
+ if (length === void 0) {
386
+ if (!hasIssuesSince(issues, issueCount)) addInspectionIssue(issues, path);
387
+ return;
388
+ }
389
+ if (length > MAX_JSON_NODES) {
390
+ addIssue(issues, path, "Array length exceeds the maximum JSON node limit");
391
+ return;
392
+ }
393
+ const orderedItems = [...items.entries()].sort(([left], [right]) => left - right);
394
+ let expectedIndex = 0;
395
+ for (const [index] of orderedItems) {
396
+ if (index !== expectedIndex) {
397
+ addIssue(issues, `${path}[${expectedIndex}]`, "Array holes are not JSON-safe");
398
+ return;
399
+ }
400
+ expectedIndex += 1;
401
+ }
402
+ if (expectedIndex !== length) {
403
+ addIssue(issues, `${path}[${expectedIndex}]`, "Array holes are not JSON-safe");
404
+ return;
405
+ }
406
+ if (hasIssuesSince(issues, issueCount)) return void 0;
407
+ return orderedItems.map(([index, item]) => ({
408
+ index,
409
+ value: item
410
+ }));
411
+ }
412
+ function readObjectChildren(value, path, issues) {
413
+ const issueCount = issues.length;
414
+ const keys = getOwnKeys(value, path, issues);
415
+ if (!keys) return void 0;
416
+ if (keys.length > MAX_JSON_NODES) {
417
+ addIssue(issues, path, "Value exceeds the maximum JSON node limit");
418
+ return;
419
+ }
420
+ const children = [];
421
+ for (const key of keys) {
422
+ const keyPath = typeof key === "string" ? `${path}.${key}` : path;
423
+ const descriptor = getOwnPropertyDescriptor(value, key, keyPath, issues);
424
+ if (descriptor === null) return void 0;
425
+ if (descriptor === void 0) {
426
+ addInspectionIssue(issues, keyPath);
427
+ return;
428
+ }
429
+ if (typeof key !== "string") {
430
+ addIssue(issues, path, "Symbol keys are not JSON-safe");
431
+ continue;
432
+ }
433
+ const child = readEnumerableDataDescriptor(value, key, descriptor, keyPath, issues);
434
+ if (child.valid) children.push({
435
+ path: keyPath,
436
+ value: child.value
108
437
  });
109
- case "error": return /* @__PURE__ */ jsx(AlertCircle, {
110
- "aria-hidden": "true",
111
- className: "size-4 text-destructive"
438
+ }
439
+ return hasIssuesSince(issues, issueCount) ? void 0 : children;
440
+ }
441
+ function rejectUnknownKeys(value, allowed, path, issues) {
442
+ const keys = getOwnEnumerableDataKeys(value, path, issues);
443
+ if (!keys) return;
444
+ for (const key of keys) if (!allowed.has(key)) addIssue(issues, `${path}.${key}`, `Unknown key "${key}"`);
445
+ }
446
+ function rejectDisallowedKeys(value, known, allowed, path, issues) {
447
+ for (const key of known) if (!allowed.has(key)) {
448
+ const inspection = inspectProperty(value, key, `${path}.${key}`, issues);
449
+ if (!inspection) return;
450
+ if (inspection.kind === "absent") continue;
451
+ addIssue(issues, `${path}.${key}`, "Field is not allowed for this status");
452
+ }
453
+ }
454
+ function rejectPresentKeys(value, keys, path, issues) {
455
+ for (const key of keys) {
456
+ const inspection = inspectProperty(value, key, `${path}.${key}`, issues);
457
+ if (!inspection) return;
458
+ if (inspection.kind === "absent") continue;
459
+ addIssue(issues, `${path}.${key}`, "Field is not allowed for this status");
460
+ }
461
+ }
462
+ function isFiniteNumber(value) {
463
+ return typeof value === "number" && Number.isFinite(value);
464
+ }
465
+ function hasSafeToJSON(value, path, issues) {
466
+ const descriptor = findReflectedPropertyDescriptor(value, "toJSON", path, issues);
467
+ if (descriptor === null) return false;
468
+ if (descriptor !== void 0) {
469
+ addIssue(issues, path, "Value must not define toJSON");
470
+ return false;
471
+ }
472
+ return true;
473
+ }
474
+ function validateJsonSafe(value, path, issues) {
475
+ const ancestors = /* @__PURE__ */ new Set();
476
+ const stack = [{
477
+ kind: "visit",
478
+ value,
479
+ path,
480
+ depth: 0
481
+ }];
482
+ let nodeCount = 0;
483
+ while (stack.length > 0 && issues.length < MAX_VALIDATION_ISSUES) {
484
+ const frame = stack.pop();
485
+ if (!frame) break;
486
+ if (frame.kind === "leave") {
487
+ ancestors.delete(frame.value);
488
+ continue;
489
+ }
490
+ if (frame.depth > MAX_JSON_DEPTH) {
491
+ addIssue(issues, frame.path, "Value exceeds the maximum JSON depth limit");
492
+ continue;
493
+ }
494
+ nodeCount += 1;
495
+ if (nodeCount > MAX_JSON_NODES) {
496
+ addIssue(issues, frame.path, "Value exceeds the maximum JSON node limit");
497
+ break;
498
+ }
499
+ const currentValue = frame.value;
500
+ if (currentValue === void 0 || typeof currentValue === "function" || typeof currentValue === "symbol" || typeof currentValue === "bigint") {
501
+ addIssue(issues, frame.path, "Value must be JSON-safe");
502
+ continue;
503
+ }
504
+ if (typeof currentValue === "number" && !isFiniteNumber(currentValue)) {
505
+ addIssue(issues, frame.path, "Number must be finite");
506
+ continue;
507
+ }
508
+ if (currentValue === null || typeof currentValue !== "object") continue;
509
+ if (ancestors.has(currentValue)) {
510
+ addIssue(issues, frame.path, "Value must not contain cycles");
511
+ continue;
512
+ }
513
+ const containerKind = getContainerKind(currentValue, frame.path, issues);
514
+ if (containerKind === "uninspectable") continue;
515
+ if (containerKind === "other") {
516
+ addIssue(issues, frame.path, "Value must contain only plain objects and arrays");
517
+ continue;
518
+ }
519
+ if (!hasSafeToJSON(currentValue, frame.path, issues)) continue;
520
+ ancestors.add(currentValue);
521
+ stack.push({
522
+ kind: "leave",
523
+ value: currentValue
112
524
  });
113
- default: return assertNever(status);
114
- }
115
- }
116
- RunStatusIcon.displayName = "RunStatusIcon";
117
- function getActionLabel(action) {
118
- if (action.kind === "custom") return action.label;
119
- return action.label ?? STANDARD_ACTION_LABELS[action.kind];
120
- }
121
- function getPoliteAnnouncement(run) {
122
- if (run.status === "error") return "";
123
- const activeStep = run.activeStepId === void 0 ? void 0 : run.steps.find((step) => step.toolCall.toolCallId === run.activeStepId);
124
- const statusLabel = RUN_STATUS_LABELS[run.status];
125
- return activeStep ? `${statusLabel}. Current step: ${activeStep.title ?? activeStep.toolCall.toolName}.` : `${statusLabel}.`;
126
- }
127
- function getWorkflowStepStatus(runStatus, step) {
128
- const toolStatus = step.toolCall.status;
129
- switch (toolStatus) {
130
- case "pending": return "pending";
131
- case "running": return runStatus === "paused" ? "suspended" : "running";
132
- case "success": return "completed";
133
- case "error": return "error";
134
- default: return assertNever(toolStatus);
135
- }
136
- }
137
- function AIToolRunStepContent({ progress, sources, title, paused }) {
138
- return /* @__PURE__ */ jsxs("div", {
139
- className: "grid min-w-0 gap-3",
140
- children: [progress && /* @__PURE__ */ jsx(Progress, {
141
- value: progress.value,
142
- label: progress.label,
143
- subLabel: progress.meta,
144
- className: paused ? PAUSED_PROGRESS_CLASS_NAME : void 0
145
- }), sources.length > 0 && /* @__PURE__ */ jsx("ul", {
146
- "aria-label": `Sources for ${title}`,
147
- className: "grid min-w-0 gap-2",
148
- children: sources.map((item, index) => /* @__PURE__ */ jsx("li", {
149
- className: "flex min-w-0 items-center gap-2",
150
- children: /* @__PURE__ */ jsx(AISource, {
151
- source: item,
152
- variant: "minimal",
153
- showTooltip: false,
154
- className: "min-w-0 max-w-none"
155
- })
156
- }, `${item.id}-${index}`))
157
- })]
158
- });
525
+ if (containerKind === "array") {
526
+ const children = readArrayItems(currentValue, frame.path, issues);
527
+ if (!children) continue;
528
+ for (let index = children.length - 1; index >= 0; index -= 1) {
529
+ const child = children[index];
530
+ stack.push({
531
+ kind: "visit",
532
+ value: child.value,
533
+ path: `${frame.path}[${child.index}]`,
534
+ depth: frame.depth + 1
535
+ });
536
+ }
537
+ continue;
538
+ }
539
+ const children = readObjectChildren(currentValue, frame.path, issues);
540
+ if (!children) continue;
541
+ for (let index = children.length - 1; index >= 0; index -= 1) {
542
+ const child = children[index];
543
+ stack.push({
544
+ kind: "visit",
545
+ value: child.value,
546
+ path: child.path,
547
+ depth: frame.depth + 1
548
+ });
549
+ }
550
+ }
159
551
  }
160
- AIToolRunStepContent.displayName = "AIToolRunStepContent";
161
- function toWorkflowStep(runStatus, step, sourcesById) {
162
- const title = step.title ?? step.toolCall.toolName;
163
- const stepSources = (step.sourceIds ?? []).flatMap((sourceId) => {
164
- const source = sourcesById.get(sourceId);
165
- return source === void 0 ? [] : [source];
166
- });
167
- const hasContent = step.progress !== void 0 || stepSources.length > 0;
552
+ var INVALID_JSON_SNAPSHOT = Symbol("invalid-json-snapshot");
553
+ function captureJsonSnapshot(value, path, issues) {
554
+ const ancestors = /* @__PURE__ */ new Set();
555
+ const snapshots = /* @__PURE__ */ new Map();
556
+ let nodeCount = 0;
557
+ function capture(currentValue, currentPath, depth) {
558
+ if (issues.length >= MAX_VALIDATION_ISSUES) return INVALID_JSON_SNAPSHOT;
559
+ if (depth > MAX_JSON_DEPTH) {
560
+ addIssue(issues, currentPath, "Value exceeds the maximum JSON depth limit");
561
+ return INVALID_JSON_SNAPSHOT;
562
+ }
563
+ nodeCount += 1;
564
+ if (nodeCount > MAX_JSON_NODES) {
565
+ addIssue(issues, currentPath, "Value exceeds the maximum JSON node limit");
566
+ return INVALID_JSON_SNAPSHOT;
567
+ }
568
+ if (currentValue === void 0 || typeof currentValue === "function" || typeof currentValue === "symbol" || typeof currentValue === "bigint") {
569
+ addIssue(issues, currentPath, "Value must be JSON-safe");
570
+ return INVALID_JSON_SNAPSHOT;
571
+ }
572
+ if (typeof currentValue === "number" && !isFiniteNumber(currentValue)) {
573
+ addIssue(issues, currentPath, "Number must be finite");
574
+ return INVALID_JSON_SNAPSHOT;
575
+ }
576
+ if (currentValue === null || typeof currentValue !== "object") return currentValue;
577
+ if (ancestors.has(currentValue)) {
578
+ addIssue(issues, currentPath, "Value must not contain cycles");
579
+ return INVALID_JSON_SNAPSHOT;
580
+ }
581
+ const containerKind = getContainerKind(currentValue, currentPath, issues);
582
+ if (containerKind === "uninspectable") return INVALID_JSON_SNAPSHOT;
583
+ if (containerKind === "other") {
584
+ addIssue(issues, currentPath, "Value must contain only plain objects and arrays");
585
+ return INVALID_JSON_SNAPSHOT;
586
+ }
587
+ if (!hasSafeToJSON(currentValue, currentPath, issues)) return INVALID_JSON_SNAPSHOT;
588
+ const existingSnapshot = snapshots.get(currentValue);
589
+ if (existingSnapshot !== void 0) return existingSnapshot;
590
+ ancestors.add(currentValue);
591
+ try {
592
+ if (containerKind === "array") {
593
+ const items = readArrayItems(currentValue, currentPath, issues);
594
+ if (!items) return INVALID_JSON_SNAPSHOT;
595
+ const snapshot = new Array(items.length);
596
+ snapshots.set(currentValue, snapshot);
597
+ for (const item of items) {
598
+ const capturedItem = capture(item.value, `${currentPath}[${item.index}]`, depth + 1);
599
+ if (capturedItem === INVALID_JSON_SNAPSHOT) return INVALID_JSON_SNAPSHOT;
600
+ snapshot[item.index] = capturedItem;
601
+ }
602
+ return snapshot;
603
+ }
604
+ const children = readObjectChildren(currentValue, currentPath, issues);
605
+ if (!children) return INVALID_JSON_SNAPSHOT;
606
+ const snapshot = Object.create(null);
607
+ snapshots.set(currentValue, snapshot);
608
+ for (const child of children) {
609
+ const key = child.path.slice(currentPath.length + 1);
610
+ const capturedChild = capture(child.value, child.path, depth + 1);
611
+ if (capturedChild === INVALID_JSON_SNAPSHOT) return INVALID_JSON_SNAPSHOT;
612
+ Object.defineProperty(snapshot, key, {
613
+ configurable: true,
614
+ enumerable: true,
615
+ value: capturedChild,
616
+ writable: true
617
+ });
618
+ }
619
+ return snapshot;
620
+ } finally {
621
+ ancestors.delete(currentValue);
622
+ }
623
+ }
624
+ return capture(value, path, 0);
625
+ }
626
+ function requireRecord(value, path, issues) {
627
+ if (isInvalidField(value)) return void 0;
628
+ const containerKind = getContainerKind(value, path, issues);
629
+ if (containerKind !== "record") {
630
+ if (containerKind !== "uninspectable") addIssue(issues, path, "Value must be a plain object");
631
+ return;
632
+ }
633
+ return value;
634
+ }
635
+ function requireString(value, path, issues) {
636
+ if (isInvalidField(value)) return void 0;
637
+ if (typeof value !== "string") {
638
+ addIssue(issues, path, "Value must be a string");
639
+ return;
640
+ }
641
+ return value;
642
+ }
643
+ function requireNonEmptyString(value, path, issues) {
644
+ const stringValue = requireString(value, path, issues);
645
+ if (stringValue !== void 0 && stringValue.length === 0) {
646
+ addIssue(issues, path, "Value must not be empty");
647
+ return;
648
+ }
649
+ return stringValue;
650
+ }
651
+ function requireNonWhitespaceString(value, path, issues) {
652
+ const stringValue = requireString(value, path, issues);
653
+ if (stringValue !== void 0 && stringValue.trim().length === 0) {
654
+ addIssue(issues, path, "Value must be non-whitespace");
655
+ return;
656
+ }
657
+ return stringValue;
658
+ }
659
+ function requireBoolean(value, path, issues) {
660
+ if (isInvalidField(value)) return void 0;
661
+ if (typeof value !== "boolean") {
662
+ addIssue(issues, path, "Value must be a boolean");
663
+ return;
664
+ }
665
+ return value;
666
+ }
667
+ function requireNumber(value, path, issues) {
668
+ if (isInvalidField(value)) return void 0;
669
+ if (typeof value !== "number") {
670
+ addIssue(issues, path, "Value must be a number");
671
+ return;
672
+ }
673
+ return value;
674
+ }
675
+ function requireArray(value, path, issues) {
676
+ if (isInvalidField(value)) return void 0;
677
+ try {
678
+ if (Array.isArray(value)) return value;
679
+ } catch {
680
+ addInspectionIssue(issues, path);
681
+ return;
682
+ }
683
+ addIssue(issues, path, "Value must be an array");
684
+ }
685
+ function requireRunStatus(value, path, issues) {
686
+ if (isInvalidField(value)) return void 0;
687
+ if (typeof value !== "string" || !Object.hasOwn(RUN_STATUSES, value)) {
688
+ addIssue(issues, path, "Value must be a supported run status");
689
+ return;
690
+ }
691
+ return value;
692
+ }
693
+ function requireToolStatus(value, path, issues) {
694
+ if (isInvalidField(value)) return void 0;
695
+ if (typeof value !== "string" || !Object.hasOwn(TOOL_STATUSES, value)) {
696
+ addIssue(issues, path, "Value is not allowed as a tool status");
697
+ return;
698
+ }
699
+ return value;
700
+ }
701
+ function requireActionKind(value, path, issues) {
702
+ if (isInvalidField(value)) return void 0;
703
+ if (typeof value !== "string" || !Object.hasOwn(ACTION_KINDS, value)) {
704
+ addIssue(issues, path, "Value must be an allowed action kind");
705
+ return;
706
+ }
707
+ return value;
708
+ }
709
+ function validateProgress(value, path, issues) {
710
+ const progress = requireRecord(value, path, issues);
711
+ if (!progress) return;
712
+ rejectUnknownKeys(progress, PROGRESS_KEYS, path, issues);
713
+ const progressValue = requireNumber(readRequiredField(progress, "value", `${path}.value`, issues), `${path}.value`, issues);
714
+ if (progressValue !== void 0 && (progressValue < 0 || progressValue > 100)) addIssue(issues, `${path}.value`, "Value must be between 0 and 100");
715
+ const label = readOptionalField(progress, "label", `${path}.label`, issues);
716
+ if (label !== void 0 && !isInvalidField(label)) requireNonWhitespaceString(label, `${path}.label`, issues);
717
+ const meta = readOptionalField(progress, "meta", `${path}.meta`, issues);
718
+ if (meta !== void 0 && !isInvalidField(meta)) requireString(meta, `${path}.meta`, issues);
719
+ }
720
+ function validateStringArray(value, path, issues) {
721
+ const issueCount = issues.length;
722
+ const values = requireArray(value, path, issues);
723
+ if (!values) return void 0;
724
+ const items = readArrayItems(values, path, issues);
725
+ if (!items) return void 0;
726
+ const strings = [];
727
+ for (const item of items) {
728
+ const stringValue = requireString(item.value, `${path}[${item.index}]`, issues);
729
+ if (stringValue !== void 0) strings.push(stringValue);
730
+ }
731
+ return hasIssuesSince(issues, issueCount) ? void 0 : strings;
732
+ }
733
+ function validateToolCall(value, path, issues) {
734
+ const issueCount = issues.length;
735
+ const toolCall = requireRecord(value, path, issues);
736
+ if (!toolCall) return void 0;
737
+ rejectUnknownKeys(toolCall, TOOL_CALL_KEYS, path, issues);
738
+ const toolCallId = requireNonEmptyString(readRequiredField(toolCall, "toolCallId", `${path}.toolCallId`, issues), `${path}.toolCallId`, issues);
739
+ requireNonWhitespaceString(readRequiredField(toolCall, "toolName", `${path}.toolName`, issues), `${path}.toolName`, issues);
740
+ const status = requireToolStatus(readRequiredField(toolCall, "status", `${path}.status`, issues), `${path}.status`, issues);
741
+ if (!status) return void 0;
742
+ rejectDisallowedKeys(toolCall, TOOL_CALL_KEYS, TOOL_CALL_KEYS_BY_STATUS[status], path, issues);
743
+ if (status === "error") {
744
+ const error = readRequiredField(toolCall, "error", `${path}.error`, issues);
745
+ if (error === void 0) addIssue(issues, `${path}.error`, "Value is required for error tool calls");
746
+ else if (!isInvalidField(error)) requireNonWhitespaceString(error, `${path}.error`, issues);
747
+ }
748
+ if (hasIssuesSince(issues, issueCount) || !toolCallId) return void 0;
168
749
  return {
169
- id: step.toolCall.toolCallId,
170
- title,
171
- description: step.description,
172
- status: getWorkflowStepStatus(runStatus, step),
173
- content: hasContent ? /* @__PURE__ */ jsx(AIToolRunStepContent, {
174
- progress: step.progress,
175
- sources: stepSources,
176
- title,
177
- paused: runStatus === "paused"
178
- }) : void 0,
179
- durationMs: step.durationMs,
180
- error: step.toolCall.status === "error" ? step.toolCall.error : void 0
750
+ toolCallId,
751
+ status
181
752
  };
182
753
  }
183
- function useAIToolRunOpenState({ open, defaultOpen, onOpenChange }) {
184
- const isControlled = open !== void 0;
185
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? true);
186
- const lastControlledOpenRef = React.useRef(open ?? uncontrolledOpen);
187
- const wasControlledRef = React.useRef(isControlled);
188
- React.useLayoutEffect(() => {
189
- if (open !== void 0) lastControlledOpenRef.current = open;
190
- }, [open]);
191
- React.useLayoutEffect(() => {
192
- const wasControlled = wasControlledRef.current;
193
- wasControlledRef.current = isControlled;
194
- if (isControlled || !wasControlled) return;
195
- setUncontrolledOpen((currentOpen) => currentOpen === lastControlledOpenRef.current ? currentOpen : lastControlledOpenRef.current);
196
- }, [isControlled]);
197
- const setOpen = React.useCallback((nextOpen) => {
198
- if (!isControlled) setUncontrolledOpen(nextOpen);
199
- onOpenChange?.(nextOpen);
200
- }, [isControlled, onOpenChange]);
201
- return [isControlled ? open : uncontrolledOpen, setOpen];
202
- }
203
- var AIToolRunPresentation = React.forwardRef(({ run, headingLevel = 2, open, defaultOpen, onOpenChange, expandedStepIds, defaultExpandedStepIds, onExpandedStepIdsChange, onAction, className, ...sectionProps }, ref) => {
204
- const headingId = React.useId();
205
- const detailsId = React.useId();
206
- const Heading = `h${headingLevel}`;
207
- const [isOpen, setIsOpen] = useAIToolRunOpenState({
208
- open,
209
- defaultOpen,
210
- onOpenChange
211
- });
212
- const sourcesById = React.useMemo(() => new Map((run.sources ?? []).map((source) => [source.id, source])), [run.sources]);
213
- const workflowSteps = React.useMemo(() => run.steps.map((step) => toWorkflowStep(run.status, step, sourcesById)), [
214
- run.status,
215
- run.steps,
216
- sourcesById
217
- ]);
218
- const rootError = run.status === "error" ? run.error.message : void 0;
219
- const politeAnnouncement = getPoliteAnnouncement(run);
220
- const { "aria-busy": _ariaBusy, ...nativeSectionProps } = sectionProps;
221
- return /* @__PURE__ */ jsxs("section", {
222
- ...nativeSectionProps,
223
- ref,
224
- "data-slot": "ai-tool-run",
225
- "aria-labelledby": headingId,
226
- className: cn("relative w-full min-w-0", className),
227
- children: [/* @__PURE__ */ jsxs(Card, {
228
- "aria-busy": run.status === "running" ? true : void 0,
229
- className: "rounded-2xl",
230
- children: [
231
- /* @__PURE__ */ jsxs(Card.Header, { children: [/* @__PURE__ */ jsxs("div", {
232
- className: "grid min-w-0 gap-1",
233
- children: [
234
- /* @__PURE__ */ jsxs("div", {
235
- className: "flex min-w-0 items-center gap-2 text-xs font-medium text-secondary-foreground",
236
- children: [/* @__PURE__ */ jsx(RunStatusIcon, { status: run.status }), /* @__PURE__ */ jsxs("span", { children: ["Status: ", RUN_STATUS_LABELS[run.status]] })]
237
- }),
238
- /* @__PURE__ */ jsx(Heading, {
239
- id: headingId,
240
- className: "min-w-0 truncate text-base font-semibold text-foreground",
241
- children: run.header.title
242
- }),
243
- run.header.description && /* @__PURE__ */ jsx("p", {
244
- className: "line-clamp-2 text-sm text-secondary-foreground",
245
- children: run.header.description
246
- }),
247
- run.header.metadata && run.header.metadata.length > 0 && /* @__PURE__ */ jsx("dl", {
248
- className: "flex flex-wrap gap-x-3 gap-y-1 text-xs text-secondary-foreground",
249
- children: run.header.metadata.map((item, index) => /* @__PURE__ */ jsxs("div", {
250
- className: "flex min-w-0 items-center gap-1",
251
- children: [/* @__PURE__ */ jsxs("dt", {
252
- className: "text-muted-foreground",
253
- children: [item.label, ":"]
254
- }), /* @__PURE__ */ jsx("dd", {
255
- className: "min-w-0 truncate",
256
- children: item.value
257
- })]
258
- }, `${item.label}-${index}`))
259
- }),
260
- !isOpen && run.progress && /* @__PURE__ */ jsx(Progress, {
261
- value: run.progress.value,
262
- label: run.progress.label,
263
- subLabel: run.progress.meta,
264
- className: run.status === "paused" ? PAUSED_PROGRESS_CLASS_NAME : void 0
265
- })
266
- ]
267
- }), /* @__PURE__ */ jsx(Card.Action, { children: /* @__PURE__ */ jsx(Button, {
268
- appearance: "ghost",
269
- variant: "secondary",
270
- size: "icon-xl",
271
- iconOnly: true,
272
- "aria-label": isOpen ? "Collapse tool run" : "Expand tool run",
273
- "aria-expanded": isOpen,
274
- "aria-controls": detailsId,
275
- onClick: () => setIsOpen(!isOpen),
276
- children: isOpen ? /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronRight, {
277
- "aria-hidden": "true",
278
- className: "rtl:rotate-180"
279
- })
280
- }) })] }),
281
- /* @__PURE__ */ jsxs(Card.Content, {
282
- id: detailsId,
283
- hidden: !isOpen,
284
- className: "grid min-w-0 gap-4",
285
- children: [
286
- run.progress && /* @__PURE__ */ jsx(Progress, {
287
- value: run.progress.value,
288
- label: run.progress.label,
289
- subLabel: run.progress.meta,
290
- className: run.status === "paused" ? PAUSED_PROGRESS_CLASS_NAME : void 0
291
- }),
292
- rootError && /* @__PURE__ */ jsxs("div", {
293
- className: "flex min-w-0 items-start gap-2 rounded-lg border border-destructive/50 bg-destructive/10 p-3",
294
- children: [/* @__PURE__ */ jsx(AlertCircle, {
295
- "aria-hidden": "true",
296
- className: "mt-0.5 size-4 shrink-0 text-destructive"
297
- }), /* @__PURE__ */ jsx("p", {
298
- className: "min-w-0 text-sm text-destructive",
299
- children: rootError
300
- })]
301
- }),
302
- /* @__PURE__ */ jsx(WorkflowStepRenderer, {
303
- appearance: "timeline",
304
- steps: workflowSteps,
305
- activeStepId: run.activeStepId,
306
- expandedStepIds,
307
- defaultExpandedStepIds,
308
- onExpandedStepIdsChange,
309
- renderItems: isOpen
310
- }, run.runId)
311
- ]
312
- }),
313
- run.actions && run.actions.length > 0 && /* @__PURE__ */ jsx(Card.Footer, {
314
- className: "flex flex-wrap gap-2",
315
- children: run.actions.map((action) => /* @__PURE__ */ jsx(Button, {
316
- appearance: "outline",
317
- variant: "secondary",
318
- disabled: action.disabled,
319
- loading: action.loading,
320
- "aria-label": getActionLabel(action),
321
- className: "min-w-0 w-full max-w-full min-[480px]:w-auto h-auto min-h-9 whitespace-normal break-words [overflow-wrap:anywhere] [&>span]:min-w-0",
322
- onClick: () => {
323
- if (action.disabled || action.loading) return;
324
- onAction?.({
325
- runId: run.runId,
326
- actionId: action.id,
327
- kind: action.kind
328
- });
329
- },
330
- children: getActionLabel(action)
331
- }, action.id))
332
- })
333
- ]
334
- }), rootError ? /* @__PURE__ */ jsx("div", {
335
- role: "alert",
336
- "aria-live": "assertive",
337
- className: "sr-only left-0 top-0",
338
- children: rootError
339
- }) : /* @__PURE__ */ jsx("div", {
340
- role: "status",
341
- "aria-live": "polite",
342
- className: "sr-only left-0 top-0",
343
- children: politeAnnouncement
344
- })]
345
- });
346
- });
347
- AIToolRunPresentation.displayName = "AIToolRunPresentation";
348
- var AIToolRunRuntimeBoundary = React.forwardRef((props, ref) => {
349
- const { run, headingLevel, open, defaultOpen, expandedStepIds, defaultExpandedStepIds, dangerouslySetInnerHTML: unsafeHtml, onOpenChange, onExpandedStepIdsChange, onAction, ...sectionProps } = props;
350
- const snapshotResult = validateAIToolRunSnapshot(run);
351
- const viewResult = validateRuntimeViewProps({
352
- headingLevel,
353
- open,
354
- defaultOpen,
355
- expandedStepIds,
356
- defaultExpandedStepIds
357
- });
358
- if (!snapshotResult.valid || !viewResult.valid) return /* @__PURE__ */ jsx(InvalidAIToolRun, {
359
- ...sectionProps,
360
- ref
361
- });
362
- return /* @__PURE__ */ jsx(AIToolRunPresentation, {
363
- ...sectionProps,
364
- ...viewResult.value,
365
- onOpenChange,
366
- onExpandedStepIdsChange,
367
- onAction,
368
- ref,
369
- run: snapshotResult.value
370
- });
371
- });
372
- /**
373
- * Displays one validated AI tool run with lifecycle, progress, sources,
374
- * disclosure, and action intents.
375
- *
376
- * @llms Validated AI tool-run timeline with lifecycle, progress, sources, disclosure, and actions
377
- */
378
- var AIToolRun = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(AIToolRunRuntimeBoundary, {
379
- ...props,
380
- ref
381
- }));
382
- AIToolRunRuntimeBoundary.displayName = "AIToolRunRuntimeBoundary";
383
- AIToolRun.displayName = "AIToolRun";
754
+ function validateContext(value, path, issues) {
755
+ const context = requireRecord(value, path, issues);
756
+ if (!context) return;
757
+ rejectUnknownKeys(context, CONTEXT_KEYS, path, issues);
758
+ requireNonWhitespaceString(readRequiredField(context, "id", `${path}.id`, issues), `${path}.id`, issues);
759
+ requireNonWhitespaceString(readRequiredField(context, "label", `${path}.label`, issues), `${path}.label`, issues);
760
+ }
761
+ function validateTechnicalToolCall(value, path, issues) {
762
+ const issueCount = issues.length;
763
+ const toolCall = requireRecord(value, path, issues);
764
+ if (!toolCall) return void 0;
765
+ rejectUnknownKeys(toolCall, TECHNICAL_TOOL_CALL_KEYS, path, issues);
766
+ const toolCallId = requireNonEmptyString(readRequiredField(toolCall, "toolCallId", `${path}.toolCallId`, issues), `${path}.toolCallId`, issues);
767
+ requireNonWhitespaceString(readRequiredField(toolCall, "toolName", `${path}.toolName`, issues), `${path}.toolName`, issues);
768
+ const statusField = readOptionalField(toolCall, "status", `${path}.status`, issues);
769
+ const status = statusField === void 0 || isInvalidField(statusField) ? void 0 : requireToolStatus(statusField, `${path}.status`, issues);
770
+ const args = readOptionalField(toolCall, "args", `${path}.args`, issues);
771
+ if (args !== void 0 && !isInvalidField(args)) requireRecord(args, `${path}.args`, issues);
772
+ readOptionalField(toolCall, "result", `${path}.result`, issues);
773
+ const error = readOptionalField(toolCall, "error", `${path}.error`, issues);
774
+ if (status === "error") {
775
+ if (error === void 0) addIssue(issues, `${path}.error`, "Value is required for error tool calls");
776
+ else if (!isInvalidField(error)) requireNonWhitespaceString(error, `${path}.error`, issues);
777
+ } else if (error !== void 0) addIssue(issues, `${path}.error`, "Field is allowed for error tool calls only");
778
+ return hasIssuesSince(issues, issueCount) ? void 0 : toolCallId;
779
+ }
780
+ function validateTechnicalDetails(value, path, issues) {
781
+ const details = requireRecord(value, path, issues);
782
+ if (!details) return;
783
+ rejectUnknownKeys(details, TECHNICAL_DETAILS_KEYS, path, issues);
784
+ const label = readOptionalField(details, "label", `${path}.label`, issues);
785
+ if (label !== void 0 && !isInvalidField(label)) requireNonWhitespaceString(label, `${path}.label`, issues);
786
+ const toolCalls = requireArray(readRequiredField(details, "toolCalls", `${path}.toolCalls`, issues), `${path}.toolCalls`, issues);
787
+ if (!toolCalls) return;
788
+ const items = readArrayItems(toolCalls, `${path}.toolCalls`, issues);
789
+ if (!items) return;
790
+ const ids = /* @__PURE__ */ new Set();
791
+ for (const item of items) {
792
+ const itemPath = `${path}.toolCalls[${item.index}]`;
793
+ const id = validateTechnicalToolCall(item.value, itemPath, issues);
794
+ if (!id) continue;
795
+ if (ids.has(id)) addIssue(issues, `${itemPath}.toolCallId`, "duplicate tool-call ID");
796
+ else ids.add(id);
797
+ }
798
+ }
799
+ function validateDuration(value, path, issues) {
800
+ const durationMs = requireNumber(value, path, issues);
801
+ if (durationMs !== void 0 && durationMs < 0) addIssue(issues, path, "Value must be non-negative");
802
+ }
803
+ function validateStep(value, path, issues) {
804
+ const issueCount = issues.length;
805
+ const step = requireRecord(value, path, issues);
806
+ if (!step) return void 0;
807
+ rejectUnknownKeys(step, STEP_KEYS, path, issues);
808
+ const title = readOptionalField(step, "title", `${path}.title`, issues);
809
+ if (title !== void 0 && !isInvalidField(title)) requireString(title, `${path}.title`, issues);
810
+ const description = readOptionalField(step, "description", `${path}.description`, issues);
811
+ if (description !== void 0 && !isInvalidField(description)) requireString(description, `${path}.description`, issues);
812
+ const context = readOptionalField(step, "context", `${path}.context`, issues);
813
+ if (context !== void 0 && !isInvalidField(context)) validateContext(context, `${path}.context`, issues);
814
+ const technicalDetails = readOptionalField(step, "technicalDetails", `${path}.technicalDetails`, issues);
815
+ if (technicalDetails !== void 0 && !isInvalidField(technicalDetails)) validateTechnicalDetails(technicalDetails, `${path}.technicalDetails`, issues);
816
+ const toolCall = validateToolCall(readRequiredField(step, "toolCall", `${path}.toolCall`, issues), `${path}.toolCall`, issues);
817
+ if (!toolCall) return void 0;
818
+ const { status } = toolCall;
819
+ rejectDisallowedKeys(step, STEP_KEYS, STEP_KEYS_BY_STATUS[status], path, issues);
820
+ const progress = readOptionalField(step, "progress", `${path}.progress`, issues);
821
+ if (progress !== void 0 && !isInvalidField(progress)) validateProgress(progress, `${path}.progress`, issues);
822
+ const sourceIdsField = readOptionalField(step, "sourceIds", `${path}.sourceIds`, issues);
823
+ const sourceIds = sourceIdsField === void 0 || isInvalidField(sourceIdsField) ? void 0 : validateStringArray(sourceIdsField, `${path}.sourceIds`, issues);
824
+ const currentSourceIdField = readOptionalField(step, "currentSourceId", `${path}.currentSourceId`, issues);
825
+ const currentSourceId = currentSourceIdField === void 0 || isInvalidField(currentSourceIdField) ? void 0 : requireString(currentSourceIdField, `${path}.currentSourceId`, issues);
826
+ const durationMsField = readOptionalField(step, "durationMs", `${path}.durationMs`, issues);
827
+ if (durationMsField !== void 0 && !isInvalidField(durationMsField)) validateDuration(durationMsField, `${path}.durationMs`, issues);
828
+ if (hasIssuesSince(issues, issueCount)) return void 0;
829
+ return {
830
+ toolCall,
831
+ ...sourceIds === void 0 ? {} : { sourceIds },
832
+ ...currentSourceId === void 0 ? {} : { currentSourceId }
833
+ };
834
+ }
835
+ function validateSource(value, path, issues) {
836
+ const issueCount = issues.length;
837
+ const source = requireRecord(value, path, issues);
838
+ if (!source) return void 0;
839
+ rejectUnknownKeys(source, SOURCE_KEYS, path, issues);
840
+ const id = requireNonEmptyString(readRequiredField(source, "id", `${path}.id`, issues), `${path}.id`, issues);
841
+ const kindField = readOptionalField(source, "kind", `${path}.kind`, issues);
842
+ const kind = kindField === void 0 || isInvalidField(kindField) ? void 0 : requireString(kindField, `${path}.kind`, issues);
843
+ if (kind !== void 0 && kind !== "link" && kind !== "reference") addIssue(issues, `${path}.kind`, "Value must be \"link\" or \"reference\"");
844
+ if (kind === "reference") {
845
+ rejectDisallowedKeys(source, SOURCE_KEYS, REFERENCE_SOURCE_KEYS, path, issues);
846
+ requireNonWhitespaceString(readRequiredField(source, "title", `${path}.title`, issues), `${path}.title`, issues);
847
+ const description = readOptionalField(source, "description", `${path}.description`, issues);
848
+ if (description !== void 0 && !isInvalidField(description)) requireString(description, `${path}.description`, issues);
849
+ return hasIssuesSince(issues, issueCount) || !id ? void 0 : id;
850
+ }
851
+ requireNonWhitespaceString(readRequiredField(source, "url", `${path}.url`, issues), `${path}.url`, issues);
852
+ for (const key of [
853
+ "title",
854
+ "description",
855
+ "favicon",
856
+ "siteName"
857
+ ]) {
858
+ const field = readOptionalField(source, key, `${path}.${key}`, issues);
859
+ if (field !== void 0 && !isInvalidField(field)) requireString(field, `${path}.${key}`, issues);
860
+ }
861
+ return hasIssuesSince(issues, issueCount) || !id ? void 0 : id;
862
+ }
863
+ function validateSources(value, path, issues) {
864
+ const sourceIds = /* @__PURE__ */ new Set();
865
+ const sources = requireArray(value, path, issues);
866
+ if (!sources) return sourceIds;
867
+ const sourceItems = readArrayItems(sources, path, issues);
868
+ if (!sourceItems) return sourceIds;
869
+ for (const item of sourceItems) {
870
+ const sourcePath = `${path}[${item.index}]`;
871
+ const sourceId = validateSource(item.value, sourcePath, issues);
872
+ if (!sourceId) continue;
873
+ if (sourceIds.has(sourceId)) {
874
+ addIssue(issues, `${sourcePath}.id`, "duplicate source ID");
875
+ continue;
876
+ }
877
+ sourceIds.add(sourceId);
878
+ }
879
+ return sourceIds;
880
+ }
881
+ function validateAction(value, path, issues) {
882
+ const issueCount = issues.length;
883
+ const action = requireRecord(value, path, issues);
884
+ if (!action) return void 0;
885
+ rejectUnknownKeys(action, ACTION_KEYS, path, issues);
886
+ const id = requireNonEmptyString(readRequiredField(action, "id", `${path}.id`, issues), `${path}.id`, issues);
887
+ const kind = requireActionKind(readRequiredField(action, "kind", `${path}.kind`, issues), `${path}.kind`, issues);
888
+ if (!kind) return void 0;
889
+ const label = kind === "custom" ? readRequiredField(action, "label", `${path}.label`, issues) : readOptionalField(action, "label", `${path}.label`, issues);
890
+ if (kind === "custom" && label === void 0) addIssue(issues, `${path}.label`, "Value is required for custom actions");
891
+ else if (label !== void 0 && !isInvalidField(label)) requireNonWhitespaceString(label, `${path}.label`, issues);
892
+ const disabled = readOptionalField(action, "disabled", `${path}.disabled`, issues);
893
+ if (disabled !== void 0 && !isInvalidField(disabled)) requireBoolean(disabled, `${path}.disabled`, issues);
894
+ const loading = readOptionalField(action, "loading", `${path}.loading`, issues);
895
+ if (loading !== void 0 && !isInvalidField(loading)) requireBoolean(loading, `${path}.loading`, issues);
896
+ return hasIssuesSince(issues, issueCount) || !id ? void 0 : {
897
+ id,
898
+ kind
899
+ };
900
+ }
901
+ function validateActions(value, path, status, issues) {
902
+ const actions = requireArray(value, path, issues);
903
+ if (!actions) return;
904
+ const actionItems = readArrayItems(actions, path, issues);
905
+ if (!actionItems) return;
906
+ const actionIds = /* @__PURE__ */ new Set();
907
+ for (const item of actionItems) {
908
+ const actionPath = `${path}[${item.index}]`;
909
+ const action = validateAction(item.value, actionPath, issues);
910
+ if (!action) continue;
911
+ if (actionIds.has(action.id)) addIssue(issues, `${actionPath}.id`, "duplicate action ID");
912
+ else actionIds.add(action.id);
913
+ if (status && !ACTIONS_BY_STATUS[status].includes(action.kind)) addIssue(issues, `${actionPath}.kind`, `Action kind "${action.kind}" is not allowed for ${status} runs`);
914
+ }
915
+ }
916
+ function validateLifecycle(status, steps, issues) {
917
+ const statuses = steps.map((step) => step.toolCall.status);
918
+ switch (status) {
919
+ case "ready":
920
+ if (statuses.some((stepStatus) => stepStatus !== "pending")) addIssue(issues, "$.steps", "Ready runs allow pending steps only");
921
+ return;
922
+ case "running":
923
+ case "paused":
924
+ if (statuses.some((stepStatus) => stepStatus !== "pending" && stepStatus !== "running" && stepStatus !== "success") || !statuses.includes("running")) addIssue(issues, "$.steps", `${status} runs require at least one running step and allow pending, running, or success only`);
925
+ return;
926
+ case "completed":
927
+ if (steps.length === 0 || statuses.some((stepStatus) => stepStatus !== "success")) addIssue(issues, "$.steps", "Completed runs require a non-empty all-success step list");
928
+ return;
929
+ case "error":
930
+ if (statuses.some((stepStatus) => stepStatus !== "pending" && stepStatus !== "success" && stepStatus !== "error")) addIssue(issues, "$.steps", "Error runs allow pending, success, or error steps only");
931
+ return;
932
+ default: assertNever(status);
933
+ }
934
+ }
935
+ function validateSourceReferences(steps, sourceIds, issues) {
936
+ for (const [stepIndex, step] of steps.entries()) {
937
+ const sourceIdPath = `$.steps[${stepIndex}].sourceIds`;
938
+ const stepSourceIds = step.sourceIds;
939
+ if (stepSourceIds) {
940
+ for (const [sourceIndex, sourceId] of stepSourceIds.entries()) if (!sourceIds.has(sourceId)) addIssue(issues, `${sourceIdPath}[${sourceIndex}]`, "Unknown source reference");
941
+ }
942
+ const currentSourceId = step.currentSourceId;
943
+ if (currentSourceId === void 0) continue;
944
+ const currentSourcePath = `$.steps[${stepIndex}].currentSourceId`;
945
+ if (!sourceIds.has(currentSourceId)) addIssue(issues, currentSourcePath, "Unknown current source reference");
946
+ else if (!stepSourceIds?.includes(currentSourceId)) addIssue(issues, currentSourcePath, "Current source ID must be included in sourceIds");
947
+ }
948
+ }
949
+ function validateActiveStepReference(status, activeStepId, steps, issues) {
950
+ if (status !== "running" && status !== "paused" || activeStepId === void 0) return;
951
+ if (!steps.some((step) => step.toolCall.status === "running" && step.toolCall.toolCallId === activeStepId)) addIssue(issues, "$.activeStepId", "Active step ID must reference a running step");
952
+ }
953
+ function validateMetadata(value, path, issues) {
954
+ const metadata = requireArray(value, path, issues);
955
+ if (!metadata) return;
956
+ const metadataItems = readArrayItems(metadata, path, issues);
957
+ if (!metadataItems) return;
958
+ for (const item of metadataItems) {
959
+ const itemPath = `${path}[${item.index}]`;
960
+ const record = requireRecord(item.value, itemPath, issues);
961
+ if (!record) continue;
962
+ rejectUnknownKeys(record, METADATA_KEYS, itemPath, issues);
963
+ requireNonWhitespaceString(readRequiredField(record, "label", `${itemPath}.label`, issues), `${itemPath}.label`, issues);
964
+ requireString(readRequiredField(record, "value", `${itemPath}.value`, issues), `${itemPath}.value`, issues);
965
+ }
966
+ }
967
+ function validateHeader(value, path, issues) {
968
+ const header = requireRecord(value, path, issues);
969
+ if (!header) return;
970
+ rejectUnknownKeys(header, HEADER_KEYS, path, issues);
971
+ requireNonWhitespaceString(readRequiredField(header, "title", `${path}.title`, issues), `${path}.title`, issues);
972
+ const description = readOptionalField(header, "description", `${path}.description`, issues);
973
+ if (description !== void 0 && !isInvalidField(description)) requireString(description, `${path}.description`, issues);
974
+ const metadata = readOptionalField(header, "metadata", `${path}.metadata`, issues);
975
+ if (metadata !== void 0 && !isInvalidField(metadata)) validateMetadata(metadata, `${path}.metadata`, issues);
976
+ }
977
+ function validateStateFields(status, snapshot, issues) {
978
+ switch (status) {
979
+ case "ready":
980
+ case "completed":
981
+ rejectPresentKeys(snapshot, [
982
+ "progress",
983
+ "activeStepId",
984
+ "error"
985
+ ], "$", issues);
986
+ return;
987
+ case "running":
988
+ case "paused": {
989
+ rejectPresentKeys(snapshot, ["error"], "$", issues);
990
+ const progress = readOptionalField(snapshot, "progress", "$.progress", issues);
991
+ if (progress !== void 0 && !isInvalidField(progress)) validateProgress(progress, "$.progress", issues);
992
+ const activeStepId = readOptionalField(snapshot, "activeStepId", "$.activeStepId", issues);
993
+ return activeStepId === void 0 || isInvalidField(activeStepId) ? void 0 : requireString(activeStepId, "$.activeStepId", issues);
994
+ }
995
+ case "error": {
996
+ rejectPresentKeys(snapshot, ["activeStepId"], "$", issues);
997
+ const progress = readOptionalField(snapshot, "progress", "$.progress", issues);
998
+ if (progress !== void 0 && !isInvalidField(progress)) validateProgress(progress, "$.progress", issues);
999
+ const error = requireRecord(readRequiredField(snapshot, "error", "$.error", issues), "$.error", issues);
1000
+ if (!error) return void 0;
1001
+ rejectUnknownKeys(error, ROOT_ERROR_KEYS, "$.error", issues);
1002
+ requireNonWhitespaceString(readRequiredField(error, "message", "$.error.message", issues), "$.error.message", issues);
1003
+ return;
1004
+ }
1005
+ default: assertNever(status);
1006
+ }
1007
+ }
1008
+ function validateAIToolRunSnapshot(value) {
1009
+ const issues = [];
1010
+ try {
1011
+ const capturedValue = captureJsonSnapshot(value, "$", issues);
1012
+ if (issues.length > 0) return {
1013
+ valid: false,
1014
+ issues
1015
+ };
1016
+ if (capturedValue === INVALID_JSON_SNAPSHOT) return {
1017
+ valid: false,
1018
+ issues: [{
1019
+ path: "$",
1020
+ message: INSPECTION_FAILURE_MESSAGE
1021
+ }]
1022
+ };
1023
+ validateJsonSafe(capturedValue, "$", issues);
1024
+ if (issues.length > 0) return {
1025
+ valid: false,
1026
+ issues
1027
+ };
1028
+ const snapshot = requireRecord(capturedValue, "$", issues);
1029
+ if (!snapshot) return {
1030
+ valid: false,
1031
+ issues
1032
+ };
1033
+ rejectUnknownKeys(snapshot, ROOT_KEYS, "$", issues);
1034
+ const status = requireRunStatus(readRequiredField(snapshot, "status", "$.status", issues), "$.status", issues);
1035
+ const activeStepId = status ? validateStateFields(status, snapshot, issues) : void 0;
1036
+ requireNonEmptyString(readRequiredField(snapshot, "runId", "$.runId", issues), "$.runId", issues);
1037
+ validateHeader(readRequiredField(snapshot, "header", "$.header", issues), "$.header", issues);
1038
+ const durationMs = readOptionalField(snapshot, "durationMs", "$.durationMs", issues);
1039
+ if (durationMs !== void 0 && !isInvalidField(durationMs)) validateDuration(durationMs, "$.durationMs", issues);
1040
+ const steps = requireArray(readRequiredField(snapshot, "steps", "$.steps", issues), "$.steps", issues);
1041
+ const validatedSteps = [];
1042
+ let stepsAreValid = false;
1043
+ if (steps) {
1044
+ const stepItems = readArrayItems(steps, "$.steps", issues);
1045
+ if (stepItems) {
1046
+ const toolCallIds = /* @__PURE__ */ new Set();
1047
+ for (const item of stepItems) {
1048
+ const validatedStep = validateStep(item.value, `$.steps[${item.index}]`, issues);
1049
+ if (!validatedStep) continue;
1050
+ if (toolCallIds.has(validatedStep.toolCall.toolCallId)) addIssue(issues, `$.steps[${item.index}].toolCall.toolCallId`, "duplicate tool-call ID");
1051
+ else toolCallIds.add(validatedStep.toolCall.toolCallId);
1052
+ validatedSteps.push(validatedStep);
1053
+ }
1054
+ stepsAreValid = validatedSteps.length === stepItems.length;
1055
+ if (status && stepsAreValid) validateLifecycle(status, validatedSteps, issues);
1056
+ }
1057
+ }
1058
+ const sources = readOptionalField(snapshot, "sources", "$.sources", issues);
1059
+ const sourceIds = sources === void 0 || isInvalidField(sources) ? /* @__PURE__ */ new Set() : validateSources(sources, "$.sources", issues);
1060
+ if (stepsAreValid) {
1061
+ validateSourceReferences(validatedSteps, sourceIds, issues);
1062
+ validateActiveStepReference(status, activeStepId, validatedSteps, issues);
1063
+ }
1064
+ const actions = readOptionalField(snapshot, "actions", "$.actions", issues);
1065
+ if (actions !== void 0 && !isInvalidField(actions)) validateActions(actions, "$.actions", status, issues);
1066
+ if (issues.length > 0) return {
1067
+ valid: false,
1068
+ issues
1069
+ };
1070
+ return {
1071
+ valid: true,
1072
+ value: capturedValue
1073
+ };
1074
+ } catch {
1075
+ return {
1076
+ valid: false,
1077
+ issues: [{
1078
+ path: "$",
1079
+ message: INSPECTION_FAILURE_MESSAGE
1080
+ }]
1081
+ };
1082
+ }
1083
+ }
384
1084
  //#endregion
385
- export { AIToolRun, AIToolRunRuntimeBoundary };
1085
+ export { validateAIToolRunSnapshot };
386
1086
 
387
1087
  //# sourceMappingURL=index185.js.map