@flanksource/clicky-ui 0.3.16 → 0.3.17

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 (158) hide show
  1. package/dist/data/DataTable.cjs +30 -10
  2. package/dist/data/DataTable.cjs.map +1 -1
  3. package/dist/data/DataTable.d.ts +2 -0
  4. package/dist/data/DataTable.d.ts.map +1 -1
  5. package/dist/data/DataTable.js +30 -10
  6. package/dist/data/DataTable.js.map +1 -1
  7. package/dist/data/ServerTimingBadge.cjs +64 -0
  8. package/dist/data/ServerTimingBadge.cjs.map +1 -0
  9. package/dist/data/ServerTimingBadge.d.ts +9 -0
  10. package/dist/data/ServerTimingBadge.d.ts.map +1 -0
  11. package/dist/data/ServerTimingBadge.js +64 -0
  12. package/dist/data/ServerTimingBadge.js.map +1 -0
  13. package/dist/data/ai/ChatWindow.cjs +9 -1
  14. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  15. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  16. package/dist/data/ai/ChatWindow.js +9 -1
  17. package/dist/data/ai/ChatWindow.js.map +1 -1
  18. package/dist/data/ai/ChatWindow.thread-status.cjs +14 -0
  19. package/dist/data/ai/ChatWindow.thread-status.cjs.map +1 -0
  20. package/dist/data/ai/ChatWindow.thread-status.d.ts +5 -0
  21. package/dist/data/ai/ChatWindow.thread-status.d.ts.map +1 -0
  22. package/dist/data/ai/ChatWindow.thread-status.js +14 -0
  23. package/dist/data/ai/ChatWindow.thread-status.js.map +1 -0
  24. package/dist/data/ai/ChatWindow.thread.cjs +68 -0
  25. package/dist/data/ai/ChatWindow.thread.cjs.map +1 -0
  26. package/dist/data/ai/ChatWindow.thread.d.ts +16 -0
  27. package/dist/data/ai/ChatWindow.thread.d.ts.map +1 -0
  28. package/dist/data/ai/ChatWindow.thread.js +68 -0
  29. package/dist/data/ai/ChatWindow.thread.js.map +1 -0
  30. package/dist/data/ai/PromptRunEditor/index.cjs +100 -88
  31. package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
  32. package/dist/data/ai/PromptRunEditor/index.d.ts +5 -9
  33. package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
  34. package/dist/data/ai/PromptRunEditor/index.js +103 -91
  35. package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
  36. package/dist/data/ai/PromptRunEditor/model.cjs +47 -0
  37. package/dist/data/ai/PromptRunEditor/model.cjs.map +1 -0
  38. package/dist/data/ai/PromptRunEditor/model.d.ts +17 -0
  39. package/dist/data/ai/PromptRunEditor/model.d.ts.map +1 -0
  40. package/dist/data/ai/PromptRunEditor/model.js +47 -0
  41. package/dist/data/ai/PromptRunEditor/model.js.map +1 -0
  42. package/dist/data/ai/RuntimeBar.cjs +104 -32
  43. package/dist/data/ai/RuntimeBar.cjs.map +1 -1
  44. package/dist/data/ai/RuntimeBar.d.ts +4 -11
  45. package/dist/data/ai/RuntimeBar.d.ts.map +1 -1
  46. package/dist/data/ai/RuntimeBar.js +107 -35
  47. package/dist/data/ai/RuntimeBar.js.map +1 -1
  48. package/dist/data/ai/RuntimeBar.model.cjs +14 -0
  49. package/dist/data/ai/RuntimeBar.model.cjs.map +1 -0
  50. package/dist/data/ai/RuntimeBar.model.d.ts +10 -0
  51. package/dist/data/ai/RuntimeBar.model.d.ts.map +1 -0
  52. package/dist/data/ai/RuntimeBar.model.js +14 -0
  53. package/dist/data/ai/RuntimeBar.model.js.map +1 -0
  54. package/dist/data/ai/RuntimeBarCombo.cjs +359 -0
  55. package/dist/data/ai/RuntimeBarCombo.cjs.map +1 -0
  56. package/dist/data/ai/RuntimeBarCombo.d.ts +22 -0
  57. package/dist/data/ai/RuntimeBarCombo.d.ts.map +1 -0
  58. package/dist/data/ai/RuntimeBarCombo.js +359 -0
  59. package/dist/data/ai/RuntimeBarCombo.js.map +1 -0
  60. package/dist/data/ai/SessionViewer.header.cjs +17 -9
  61. package/dist/data/ai/SessionViewer.header.cjs.map +1 -1
  62. package/dist/data/ai/SessionViewer.header.d.ts.map +1 -1
  63. package/dist/data/ai/SessionViewer.header.js +17 -9
  64. package/dist/data/ai/SessionViewer.header.js.map +1 -1
  65. package/dist/data/ai/SessionViewer.model.cjs +2 -0
  66. package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
  67. package/dist/data/ai/SessionViewer.model.d.ts +4 -0
  68. package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
  69. package/dist/data/ai/SessionViewer.model.js +2 -0
  70. package/dist/data/ai/SessionViewer.model.js.map +1 -1
  71. package/dist/data/ai/SessionViewer.unified.d.ts +1 -0
  72. package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
  73. package/dist/data/ai/SpecRuntimeEditor/fields.js +1 -1
  74. package/dist/data/ai/ThreadPicker.cjs.map +1 -1
  75. package/dist/data/ai/ThreadPicker.d.ts +2 -0
  76. package/dist/data/ai/ThreadPicker.d.ts.map +1 -1
  77. package/dist/data/ai/ThreadPicker.js.map +1 -1
  78. package/dist/data/ai/index.d.ts +1 -0
  79. package/dist/data/ai/index.d.ts.map +1 -1
  80. package/dist/data/ai/model-capabilities.cjs +12 -1
  81. package/dist/data/ai/model-capabilities.cjs.map +1 -1
  82. package/dist/data/ai/model-capabilities.d.ts +2 -6
  83. package/dist/data/ai/model-capabilities.d.ts.map +1 -1
  84. package/dist/data/ai/model-capabilities.js +12 -1
  85. package/dist/data/ai/model-capabilities.js.map +1 -1
  86. package/dist/data/ai/runtime-mode.cjs +10 -1
  87. package/dist/data/ai/runtime-mode.cjs.map +1 -1
  88. package/dist/data/ai/runtime-mode.d.ts +1 -0
  89. package/dist/data/ai/runtime-mode.d.ts.map +1 -1
  90. package/dist/data/ai/runtime-mode.js +11 -2
  91. package/dist/data/ai/runtime-mode.js.map +1 -1
  92. package/dist/data/chat/Chat.cjs +90 -21
  93. package/dist/data/chat/Chat.cjs.map +1 -1
  94. package/dist/data/chat/Chat.d.ts +4 -1
  95. package/dist/data/chat/Chat.d.ts.map +1 -1
  96. package/dist/data/chat/Chat.js +90 -21
  97. package/dist/data/chat/Chat.js.map +1 -1
  98. package/dist/data/chat/ContextMeter.cjs +144 -73
  99. package/dist/data/chat/ContextMeter.cjs.map +1 -1
  100. package/dist/data/chat/ContextMeter.d.ts +8 -3
  101. package/dist/data/chat/ContextMeter.d.ts.map +1 -1
  102. package/dist/data/chat/ContextMeter.js +144 -73
  103. package/dist/data/chat/ContextMeter.js.map +1 -1
  104. package/dist/data/chat/approval.cjs +21 -0
  105. package/dist/data/chat/approval.cjs.map +1 -0
  106. package/dist/data/chat/approval.d.ts +11 -0
  107. package/dist/data/chat/approval.d.ts.map +1 -0
  108. package/dist/data/chat/approval.js +21 -0
  109. package/dist/data/chat/approval.js.map +1 -0
  110. package/dist/data/chat/types.cjs.map +1 -1
  111. package/dist/data/chat/types.d.ts +12 -0
  112. package/dist/data/chat/types.d.ts.map +1 -1
  113. package/dist/data/chat/types.js.map +1 -1
  114. package/dist/data/server-timing.cjs +120 -0
  115. package/dist/data/server-timing.cjs.map +1 -0
  116. package/dist/data/server-timing.d.ts +11 -0
  117. package/dist/data/server-timing.d.ts.map +1 -0
  118. package/dist/data/server-timing.js +120 -0
  119. package/dist/data/server-timing.js.map +1 -0
  120. package/dist/data/version-info.cjs +3 -3
  121. package/dist/data/version-info.js +3 -3
  122. package/dist/data.cjs +7 -0
  123. package/dist/data.cjs.map +1 -1
  124. package/dist/data.d.ts +2 -0
  125. package/dist/data.d.ts.map +1 -1
  126. package/dist/data.js +7 -0
  127. package/dist/data.js.map +1 -1
  128. package/dist/index.cjs +7 -0
  129. package/dist/index.cjs.map +1 -1
  130. package/dist/index.js +7 -0
  131. package/dist/index.js.map +1 -1
  132. package/dist/layout/AppShell.cjs +1 -1
  133. package/dist/layout/AppShell.cjs.map +1 -1
  134. package/dist/layout/AppShell.js +1 -1
  135. package/dist/layout/AppShell.js.map +1 -1
  136. package/dist/overlay/HoverCard.cjs.map +1 -1
  137. package/dist/overlay/HoverCard.d.ts +2 -2
  138. package/dist/overlay/HoverCard.d.ts.map +1 -1
  139. package/dist/overlay/HoverCard.js.map +1 -1
  140. package/dist/rpc/OperationCatalog.cjs +28 -51
  141. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  142. package/dist/rpc/OperationCatalog.d.ts +1 -6
  143. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  144. package/dist/rpc/OperationCatalog.js +29 -52
  145. package/dist/rpc/OperationCatalog.js.map +1 -1
  146. package/dist/rpc/OperationResultView.cjs +42 -0
  147. package/dist/rpc/OperationResultView.cjs.map +1 -1
  148. package/dist/rpc/OperationResultView.d.ts +2 -1
  149. package/dist/rpc/OperationResultView.d.ts.map +1 -1
  150. package/dist/rpc/OperationResultView.js +42 -0
  151. package/dist/rpc/OperationResultView.js.map +1 -1
  152. package/dist/styles.css +1 -1
  153. package/dist/tailwind-preset.cjs +4 -0
  154. package/dist/tailwind-preset.cjs.map +1 -1
  155. package/dist/tailwind-preset.d.ts.map +1 -1
  156. package/dist/tailwind-preset.js +4 -0
  157. package/dist/tailwind-preset.js.map +1 -1
  158. package/package.json +1 -1
@@ -1,20 +1,20 @@
1
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useState, useMemo, useId } from "react";
3
3
  import { Button } from "../../../components/button.js";
4
4
  import { JsonSchemaForm } from "../../../components/JsonSchemaForm.js";
5
5
  import { cn } from "../../../lib/utils.js";
6
6
  import { Modal } from "../../../overlay/Modal.js";
7
7
  import { Icon } from "../../Icon.js";
8
- import { ModelSelector, EffortSelector } from "../../chat/ModelSelector.js";
9
8
  import { DEFAULT_REASONING_EFFORTS } from "../../chat/effort-icons.js";
10
9
  import { AttachmentList, AttachmentButton } from "../../chat/Attachment.js";
11
10
  import { createAttachmentUploadAdapter } from "../../chat/attachment-upload.js";
12
- import { effortOptionsForModel, reconcileModelCapabilities } from "../model-capabilities.js";
13
- import { RuntimeModePicker } from "../RuntimeModePicker.js";
14
- import { selectionForBackend, SPEC_RUNTIME_FAMILIES, familyById, modelsForFamily, labelForBackend } from "../runtime-mode.js";
11
+ import { RuntimeBar } from "../RuntimeBar.js";
12
+ import { SPEC_RUNTIME_FAMILIES, labelForBackend } from "../runtime-mode.js";
15
13
  import { SpecRuntimeEditor } from "../SpecRuntimeEditor/index.js";
16
- import { SpecField, SpecInput } from "../SpecRuntimeEditor/fields.js";
17
- import { withRoot, withOptionalRoot, withPrompt } from "../SpecRuntimeEditor/update.js";
14
+ import { withPrompt } from "../SpecRuntimeEditor/update.js";
15
+ import { runtimeRows, withRuntimeRows } from "./model.js";
16
+ import { UiTrash } from "../../../icons/components/UiTrash.js";
17
+ import { UiAdd } from "../../../icons/components/UiAdd.js";
18
18
  import { UiGearSix } from "../../../icons/components/UiGearSix.js";
19
19
  function PromptRunEditor({
20
20
  value,
@@ -26,10 +26,7 @@ function PromptRunEditor({
26
26
  secretSelector,
27
27
  cliOptions,
28
28
  reasoningEfforts = DEFAULT_REASONING_EFFORTS,
29
- runtimeControls,
30
29
  variablesSchema,
31
- variables,
32
- onVariablesChange,
33
30
  onVariablesValidityChange,
34
31
  promptEditor,
35
32
  promptLabel = "User prompt",
@@ -47,17 +44,16 @@ function PromptRunEditor({
47
44
  }) {
48
45
  var _a, _b;
49
46
  const [specOpen, setSpecOpen] = useState(false);
50
- const selection = selectionForBackend(families, value.backend);
51
- const family = familyById(families, selection.family);
52
- const familyModels = modelsForFamily(models, family, value.backend);
53
- const selectedModel = models.find((m) => m.id === value.model);
54
- const modelEfforts = effortOptionsForModel(selectedModel, reasoningEfforts);
55
- const showEffort = modelEfforts.length > 0;
47
+ const spec = value.spec ?? {};
48
+ const rows = runtimeRows(value);
49
+ const selectedModel = models.find(
50
+ (model) => model.id === spec.id || model.id === spec.model
51
+ );
56
52
  const resolvedAttachmentUpload = useMemo(
57
53
  () => attachmentUpload ?? createAttachmentUploadAdapter(),
58
54
  [attachmentUpload]
59
55
  );
60
- const attachmentFiles = (((_a = value.prompt) == null ? void 0 : _a.attachments) ?? []).map(
56
+ const attachmentFiles = (((_a = spec.prompt) == null ? void 0 : _a.attachments) ?? []).map(
61
57
  (attachment) => ({
62
58
  type: "file",
63
59
  url: attachment.id ? `/api/attachments/${attachment.id}` : attachment.url ?? "",
@@ -71,76 +67,87 @@ function PromptRunEditor({
71
67
  return /* @__PURE__ */ jsxs("div", { className: cn("grid gap-density-4", className), children: [
72
68
  header,
73
69
  /* @__PURE__ */ jsxs(Block, { title: "Runtime", children: [
74
- runtimeControls ?? /* @__PURE__ */ jsxs(Fragment, { children: [
75
- /* @__PURE__ */ jsx(
76
- RuntimeModePicker,
70
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-density-2", children: [
71
+ rows.map((runtime, index) => /* @__PURE__ */ jsxs(
72
+ "div",
77
73
  {
78
- value,
79
- onChange,
80
- families,
81
- models
82
- }
83
- ),
84
- /* @__PURE__ */ jsxs("div", { className: "grid gap-density-2 sm:grid-cols-2", children: [
85
- /* @__PURE__ */ jsx(SpecField, { label: "Model", children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-density-2", children: [
86
- familyModels.length > 0 ? /* @__PURE__ */ jsx(
87
- ModelSelector,
88
- {
89
- models: familyModels,
90
- value: value.model,
91
- onChange: (model) => onChange(
92
- reconcileModelCapabilities(
93
- value,
94
- models.find((item) => item.id === model),
95
- reasoningEfforts
96
- )
97
- ),
98
- size: "md",
99
- className: "w-full"
100
- }
101
- ) : /* @__PURE__ */ jsx(
102
- SpecInput,
103
- {
104
- value: value.model,
105
- onChange: (model) => onChange(withRoot(value, { model })),
106
- placeholder: "frontmatter/default",
107
- mono: true
108
- }
109
- ),
110
- value.model && /* @__PURE__ */ jsx(
111
- Button,
112
- {
113
- size: "sm",
114
- variant: "ghost",
115
- onClick: () => onChange(withOptionalRoot(value, "model", void 0)),
116
- children: "Default"
117
- }
118
- )
119
- ] }) }),
120
- showEffort && /* @__PURE__ */ jsx(SpecField, { label: "Effort", children: /* @__PURE__ */ jsx(
121
- EffortSelector,
74
+ role: "group",
75
+ "aria-label": `Runtime ${index + 1}`,
76
+ className: "flex min-w-0 items-center gap-density-2",
77
+ children: [
78
+ /* @__PURE__ */ jsx(
79
+ RuntimeBar,
80
+ {
81
+ value: runtime,
82
+ onChange: (next) => onChange(
83
+ withRuntimeRows(
84
+ value,
85
+ rows.map(
86
+ (item, itemIndex) => itemIndex === index ? next : item
87
+ )
88
+ )
89
+ ),
90
+ models,
91
+ families,
92
+ reasoningEfforts,
93
+ ariaLabel: `Runtime ${index + 1} controls`
94
+ }
95
+ ),
96
+ rows.length > 1 && /* @__PURE__ */ jsx(
97
+ Button,
98
+ {
99
+ size: "sm",
100
+ variant: "ghost",
101
+ "aria-label": `Remove runtime ${index + 1}`,
102
+ onClick: () => onChange(
103
+ withRuntimeRows(
104
+ value,
105
+ rows.filter((_, itemIndex) => itemIndex !== index)
106
+ )
107
+ ),
108
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiTrash, className: "size-4" })
109
+ }
110
+ )
111
+ ]
112
+ },
113
+ index
114
+ )),
115
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-density-2", children: [
116
+ /* @__PURE__ */ jsxs(
117
+ Button,
122
118
  {
123
- efforts: modelEfforts,
124
- value: value.effort ?? "",
125
- onChange: (effort) => onChange(withRoot(value, { effort })),
126
- size: "md",
127
- className: "w-full"
119
+ size: "sm",
120
+ variant: "outline",
121
+ "aria-label": "Add runtime",
122
+ onClick: () => {
123
+ var _a2;
124
+ return onChange(
125
+ withRuntimeRows(value, [
126
+ ...rows,
127
+ ((_a2 = rows[0]) == null ? void 0 : _a2.backend) ? { backend: rows[0].backend } : {}
128
+ ])
129
+ );
130
+ },
131
+ children: [
132
+ /* @__PURE__ */ jsx(Icon, { icon: UiAdd, className: "size-4" }),
133
+ "Add runtime"
134
+ ]
128
135
  }
129
- ) })
136
+ ),
137
+ /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", onClick: () => setSpecOpen(true), children: [
138
+ /* @__PURE__ */ jsx(Icon, { icon: UiGearSix, className: "size-4" }),
139
+ editSpecLabel
140
+ ] })
130
141
  ] })
131
142
  ] }),
132
- children,
133
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", onClick: () => setSpecOpen(true), children: [
134
- /* @__PURE__ */ jsx(Icon, { icon: UiGearSix, className: "size-4" }),
135
- editSpecLabel
136
- ] }) })
143
+ children
137
144
  ] }),
138
- onVariablesChange && /* @__PURE__ */ jsx(Block, { title: "Variables", children: /* @__PURE__ */ jsx(
145
+ /* @__PURE__ */ jsx(Block, { title: "Variables", children: /* @__PURE__ */ jsx(
139
146
  VariablesField,
140
147
  {
141
148
  ...variablesSchema ? { schema: variablesSchema } : {},
142
- value: variables ?? {},
143
- onChange: onVariablesChange,
149
+ value: value.variables ?? {},
150
+ onChange: (variables) => onChange({ ...value, variables }),
144
151
  ...onVariablesValidityChange ? { onValidityChange: onVariablesValidityChange } : {}
145
152
  }
146
153
  ) }),
@@ -148,8 +155,11 @@ function PromptRunEditor({
148
155
  promptEditor ?? /* @__PURE__ */ jsx(
149
156
  "textarea",
150
157
  {
151
- value: ((_b = value.prompt) == null ? void 0 : _b.user) ?? "",
152
- onChange: (event) => onChange(withPrompt(value, { user: event.target.value })),
158
+ value: ((_b = spec.prompt) == null ? void 0 : _b.user) ?? "",
159
+ onChange: (event) => onChange({
160
+ ...value,
161
+ spec: withPrompt(spec, { user: event.target.value })
162
+ }),
153
163
  spellCheck: false,
154
164
  placeholder: promptPlaceholder,
155
165
  "aria-label": promptLabel,
@@ -163,13 +173,14 @@ function PromptRunEditor({
163
173
  files: attachmentFiles,
164
174
  onRemove: (index) => {
165
175
  var _a2;
166
- return onChange(
167
- withPrompt(value, {
168
- attachments: (((_a2 = value.prompt) == null ? void 0 : _a2.attachments) ?? []).filter(
176
+ return onChange({
177
+ ...value,
178
+ spec: withPrompt(spec, {
179
+ attachments: (((_a2 = spec.prompt) == null ? void 0 : _a2.attachments) ?? []).filter(
169
180
  (_, itemIndex) => itemIndex !== index
170
181
  )
171
182
  })
172
- );
183
+ });
173
184
  }
174
185
  }
175
186
  ),
@@ -180,10 +191,11 @@ function PromptRunEditor({
180
191
  upload: resolvedAttachmentUpload,
181
192
  onAdd: (parts) => {
182
193
  var _a2;
183
- return onChange(
184
- withPrompt(value, {
194
+ return onChange({
195
+ ...value,
196
+ spec: withPrompt(spec, {
185
197
  attachments: [
186
- ...((_a2 = value.prompt) == null ? void 0 : _a2.attachments) ?? [],
198
+ ...((_a2 = spec.prompt) == null ? void 0 : _a2.attachments) ?? [],
187
199
  ...parts.map((part) => {
188
200
  const uploaded = part;
189
201
  return {
@@ -195,7 +207,7 @@ function PromptRunEditor({
195
207
  })
196
208
  ]
197
209
  })
198
- );
210
+ });
199
211
  },
200
212
  ...(selectedModel == null ? void 0 : selectedModel.inputMediaTypes) ? { acceptedMediaTypes: selectedModel.inputMediaTypes } : {},
201
213
  ...attachmentLimits ? { limits: attachmentLimits } : {}
@@ -216,8 +228,8 @@ function PromptRunEditor({
216
228
  children: /* @__PURE__ */ jsx(
217
229
  SpecRuntimeEditor,
218
230
  {
219
- value,
220
- onChange,
231
+ value: spec,
232
+ onChange: (next) => onChange({ ...value, spec: next }),
221
233
  models,
222
234
  families,
223
235
  tools,
@@ -228,7 +240,7 @@ function PromptRunEditor({
228
240
  onSave: () => setSpecOpen(false),
229
241
  onCancel: () => setSpecOpen(false),
230
242
  saveLabel: "Done",
231
- footerStatus: labelForBackend(value.backend, families)
243
+ footerStatus: labelForBackend(spec.backend, families)
232
244
  }
233
245
  )
234
246
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/data/ai/PromptRunEditor/index.tsx"],"sourcesContent":["import { useId, useMemo, useState, type ReactNode } from \"react\";\nimport { Button } from \"../../../components/button\";\nimport { JsonSchemaForm } from \"../../../components/JsonSchemaForm\";\nimport type { JsonSchemaObject } from \"../../../components/json-schema-form-types\";\nimport { UiGearSix } from \"../../../icons\";\nimport { cn } from \"../../../lib/utils\";\nimport { Modal } from \"../../../overlay/Modal\";\nimport { Icon } from \"../../Icon\";\nimport { EffortSelector, ModelSelector } from \"../../chat/ModelSelector\";\nimport { DEFAULT_REASONING_EFFORTS } from \"../../chat/effort-icons\";\nimport {\n AttachmentButton,\n AttachmentList,\n} from \"../../chat/Attachment\";\nimport {\n createAttachmentUploadAdapter,\n type AttachmentFilePart,\n type AttachmentLimits,\n type AttachmentUploadAdapter,\n} from \"../../chat/attachment-upload\";\nimport type { ChatModel, ToolMeta } from \"../../chat/types\";\nimport type { FileUIPart } from \"../../chat/types\";\nimport {\n effortOptionsForModel,\n reconcileModelCapabilities,\n} from \"../model-capabilities\";\nimport { RuntimeModePicker } from \"../RuntimeModePicker\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n type SpecRuntimeFamily,\n familyById,\n labelForBackend,\n modelsForFamily,\n selectionForBackend,\n} from \"../runtime-mode\";\nimport { SpecRuntimeEditor } from \"../SpecRuntimeEditor\";\nimport type { SpecRuntimeCLIOptions } from \"../SpecRuntimeEditor/CLIArgsSection\";\nimport { SpecField, SpecInput } from \"../SpecRuntimeEditor/fields\";\nimport type {\n SpecRuntimeSecretSelectorConfig,\n SpecSectionId,\n} from \"../SpecRuntimeEditor/types\";\nimport {\n withOptionalRoot,\n withPrompt,\n withRoot,\n} from \"../SpecRuntimeEditor/update\";\nimport type {\n AISpecRuntimePermissionCatalog,\n AISpecRuntimeValue,\n} from \"../SpecRuntimeEditor.model\";\n\nexport type PromptRunEditorProps = {\n value: AISpecRuntimeValue;\n onChange: (value: AISpecRuntimeValue) => void;\n models?: ChatModel[] | undefined;\n families?: SpecRuntimeFamily[] | undefined;\n tools?: ToolMeta[] | undefined;\n permissionCatalog?: AISpecRuntimePermissionCatalog | undefined;\n secretSelector?: SpecRuntimeSecretSelectorConfig | undefined;\n cliOptions?: SpecRuntimeCLIOptions | undefined;\n reasoningEfforts?: string[] | undefined;\n /** Host-provided replacement for the inline Runtime controls. */\n runtimeControls?: ReactNode | undefined;\n\n /** Schema-driven variables form; omit to render a raw-JSON editor. */\n variablesSchema?: JsonSchemaObject | undefined;\n variables?: Record<string, unknown> | undefined;\n /** The variables block only renders when this is supplied. */\n onVariablesChange?: ((next: Record<string, unknown>) => void) | undefined;\n /** Fires false while raw-JSON variables fail to parse; always true with a schema. */\n onVariablesValidityChange?: ((valid: boolean) => void) | undefined;\n\n /** Host-supplied editor for the `prompt.user` override; defaults to a textarea. */\n promptEditor?: ReactNode | undefined;\n promptLabel?: string | undefined;\n promptPlaceholder?: string | undefined;\n enableAttachments?: boolean | undefined;\n attachmentUpload?: AttachmentUploadAdapter | undefined;\n attachmentLimits?: AttachmentLimits | undefined;\n\n /** Extra fields injected inside the Runtime block, below Model/Effort. */\n children?: ReactNode | undefined;\n header?: ReactNode | undefined;\n footer?: ReactNode | undefined;\n className?: string | undefined;\n\n editSpecLabel?: string | undefined;\n specModalTitle?: string | undefined;\n /** Restrict which SpecRuntimeEditor sections the \"Edit spec\" modal shows. */\n specSections?: readonly SpecSectionId[] | undefined;\n};\n\n// The inline \"prompt + variables + runtime\" composer shared by captain's prompt\n// workbench and gavel's todo run dialog. It edits one AISpecRuntimeValue live\n// (runtime knobs + the prompt.user override) and takes variables as separate\n// props; the \"Edit spec\" button expands the same value into the full editor.\n// Hosts should mount it with a `key` per prompt/todo so internal draft state\n// (raw-JSON text, modal open) resets on selection change.\nexport function PromptRunEditor({\n value,\n onChange,\n models = [],\n families = SPEC_RUNTIME_FAMILIES,\n tools = [],\n permissionCatalog,\n secretSelector,\n cliOptions,\n reasoningEfforts = DEFAULT_REASONING_EFFORTS,\n runtimeControls,\n variablesSchema,\n variables,\n onVariablesChange,\n onVariablesValidityChange,\n promptEditor,\n promptLabel = \"User prompt\",\n promptPlaceholder = \"Override the rendered user prompt\",\n enableAttachments = false,\n attachmentUpload,\n attachmentLimits,\n children,\n header,\n footer,\n className,\n editSpecLabel = \"Edit spec\",\n specModalTitle = \"Runtime spec\",\n specSections,\n}: PromptRunEditorProps) {\n const [specOpen, setSpecOpen] = useState(false);\n const selection = selectionForBackend(families, value.backend);\n const family = familyById(families, selection.family);\n const familyModels = modelsForFamily(models, family, value.backend);\n const selectedModel = models.find((m) => m.id === value.model);\n // Hide effort for a model that does not reason; default to showing it when the\n // selection is unknown (a family alias or a not-yet-loaded catalog).\n const modelEfforts = effortOptionsForModel(selectedModel, reasoningEfforts);\n const showEffort = modelEfforts.length > 0;\n const resolvedAttachmentUpload = useMemo(\n () => attachmentUpload ?? createAttachmentUploadAdapter(),\n [attachmentUpload],\n );\n const attachmentFiles: FileUIPart[] = (value.prompt?.attachments ?? []).map(\n (attachment) => ({\n type: \"file\",\n url: attachment.id\n ? `/api/attachments/${attachment.id}`\n : (attachment.url ?? \"\"),\n mediaType: attachment.mediaType ?? \"application/octet-stream\",\n ...(attachment.id ? { attachmentId: attachment.id } : {}),\n ...(attachment.size != null ? { size: attachment.size } : {}),\n ...(attachment.filename ? { filename: attachment.filename } : {}),\n ...(!attachment.filename && attachment.path\n ? { filename: attachment.path }\n : {}),\n }),\n ) as FileUIPart[];\n\n return (\n <div className={cn(\"grid gap-density-4\", className)}>\n {header}\n\n <Block title=\"Runtime\">\n {runtimeControls ?? (\n <>\n <RuntimeModePicker\n value={value}\n onChange={onChange}\n families={families}\n models={models}\n />\n <div className=\"grid gap-density-2 sm:grid-cols-2\">\n <SpecField label=\"Model\">\n <div className=\"flex min-w-0 items-center gap-density-2\">\n {familyModels.length > 0 ? (\n <ModelSelector\n models={familyModels}\n value={value.model}\n onChange={(model) =>\n onChange(\n reconcileModelCapabilities(\n value,\n models.find((item) => item.id === model),\n reasoningEfforts,\n ),\n )\n }\n size=\"md\"\n className=\"w-full\"\n />\n ) : (\n <SpecInput\n value={value.model}\n onChange={(model) => onChange(withRoot(value, { model }))}\n placeholder=\"frontmatter/default\"\n mono\n />\n )}\n {value.model && (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() =>\n onChange(withOptionalRoot(value, \"model\", undefined))\n }\n >\n Default\n </Button>\n )}\n </div>\n </SpecField>\n {showEffort && (\n <SpecField label=\"Effort\">\n <EffortSelector\n efforts={modelEfforts}\n value={value.effort ?? \"\"}\n onChange={(effort) => onChange(withRoot(value, { effort }))}\n size=\"md\"\n className=\"w-full\"\n />\n </SpecField>\n )}\n </div>\n </>\n )}\n {children}\n <div>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setSpecOpen(true)}>\n <Icon icon={UiGearSix} className=\"size-4\" />\n {editSpecLabel}\n </Button>\n </div>\n </Block>\n\n {onVariablesChange && (\n <Block title=\"Variables\">\n <VariablesField\n {...(variablesSchema ? { schema: variablesSchema } : {})}\n value={variables ?? {}}\n onChange={onVariablesChange}\n {...(onVariablesValidityChange\n ? { onValidityChange: onVariablesValidityChange }\n : {})}\n />\n </Block>\n )}\n\n <Block title={promptLabel}>\n {promptEditor ?? (\n <textarea\n value={value.prompt?.user ?? \"\"}\n onChange={(event) =>\n onChange(withPrompt(value, { user: event.target.value }))\n }\n spellCheck={false}\n placeholder={promptPlaceholder}\n aria-label={promptLabel}\n className=\"min-h-[7rem] w-full resize-y rounded-md border border-border bg-background px-density-2 py-density-1 text-sm outline-none focus:ring-2 focus:ring-ring\"\n />\n )}\n {enableAttachments && (\n <div className=\"space-y-density-2\">\n <AttachmentList\n files={attachmentFiles}\n onRemove={(index) =>\n onChange(\n withPrompt(value, {\n attachments: (value.prompt?.attachments ?? []).filter(\n (_, itemIndex) => itemIndex !== index,\n ),\n }),\n )\n }\n />\n <AttachmentButton\n files={attachmentFiles}\n upload={resolvedAttachmentUpload}\n onAdd={(parts) =>\n onChange(\n withPrompt(value, {\n attachments: [\n ...(value.prompt?.attachments ?? []),\n ...parts.map((part) => {\n const uploaded = part as AttachmentFilePart;\n return {\n id: uploaded.attachmentId,\n mediaType: uploaded.mediaType,\n size: uploaded.size,\n ...(uploaded.filename\n ? { filename: uploaded.filename }\n : {}),\n };\n }),\n ],\n }),\n )\n }\n {...(selectedModel?.inputMediaTypes\n ? { acceptedMediaTypes: selectedModel.inputMediaTypes }\n : {})}\n {...(attachmentLimits ? { limits: attachmentLimits } : {})}\n />\n </div>\n )}\n </Block>\n\n {footer}\n\n <Modal\n open={specOpen}\n onClose={() => setSpecOpen(false)}\n title={specModalTitle}\n size=\"full\"\n closeOnEsc\n className=\"h-[95vh]\"\n >\n <SpecRuntimeEditor\n value={value}\n onChange={onChange}\n models={models}\n families={families}\n tools={tools}\n {...(permissionCatalog ? { permissionCatalog } : {})}\n {...(secretSelector ? { secretSelector } : {})}\n {...(cliOptions ? { cliOptions } : {})}\n {...(specSections ? { sections: specSections } : {})}\n onSave={() => setSpecOpen(false)}\n onCancel={() => setSpecOpen(false)}\n saveLabel=\"Done\"\n footerStatus={labelForBackend(value.backend, families)}\n />\n </Modal>\n </div>\n );\n}\n\nfunction Block({ title, children }: { title: string; children: ReactNode }) {\n return (\n <section className=\"space-y-density-2\">\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {title}\n </div>\n {children}\n </section>\n );\n}\n\n// Variables are edited via the prompt's declared schema when present, otherwise\n// as a raw JSON object; the raw text is held locally and only committed to the\n// host when it parses to an object.\nfunction VariablesField({\n schema,\n value,\n onChange,\n onValidityChange,\n}: {\n schema?: JsonSchemaObject | undefined;\n value: Record<string, unknown>;\n onChange: (next: Record<string, unknown>) => void;\n onValidityChange?: ((valid: boolean) => void) | undefined;\n}) {\n const idPrefix = useId();\n const [rawText, setRawText] = useState(() => stringifyVariables(value));\n const [rawError, setRawError] = useState<string | null>(null);\n\n if (schema) {\n return (\n <JsonSchemaForm\n idPrefix={`prompt-vars-${idPrefix}`}\n schema={schema}\n value={value}\n onChange={(next) => onChange(next as Record<string, unknown>)}\n size=\"sm\"\n />\n );\n }\n\n const commit = (text: string) => {\n setRawText(text);\n if (!text.trim()) {\n setRawError(null);\n onValidityChange?.(true);\n onChange({});\n return;\n }\n try {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n setRawError(null);\n onValidityChange?.(true);\n onChange(parsed as Record<string, unknown>);\n } else {\n setRawError(\"Expected a JSON object\");\n onValidityChange?.(false);\n }\n } catch (error) {\n setRawError(error instanceof Error ? error.message : \"Invalid JSON\");\n onValidityChange?.(false);\n }\n };\n\n return (\n <div className=\"space-y-1\">\n <textarea\n value={rawText}\n onChange={(event) => commit(event.target.value)}\n spellCheck={false}\n placeholder=\"{}\"\n aria-label=\"Variables JSON\"\n className=\"h-28 w-full resize-y rounded-md border border-border bg-background px-density-2 py-density-1 font-mono text-xs outline-none focus:ring-2 focus:ring-ring\"\n />\n {rawError && <div className=\"text-xs text-destructive\">{rawError}</div>}\n </div>\n );\n}\n\nfunction stringifyVariables(value: Record<string, unknown>) {\n if (!value || Object.keys(value).length === 0) return \"{}\";\n return JSON.stringify(value, null, 2);\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/data/ai/PromptRunEditor/index.tsx"],"sourcesContent":["import { useId, useMemo, useState, type ReactNode } from \"react\";\nimport { Button } from \"../../../components/button\";\nimport { JsonSchemaForm } from \"../../../components/JsonSchemaForm\";\nimport type { JsonSchemaObject } from \"../../../components/json-schema-form-types\";\nimport { UiAdd, UiGearSix, UiTrash } from \"../../../icons\";\nimport { cn } from \"../../../lib/utils\";\nimport { Modal } from \"../../../overlay/Modal\";\nimport { Icon } from \"../../Icon\";\nimport { DEFAULT_REASONING_EFFORTS } from \"../../chat/effort-icons\";\nimport {\n AttachmentButton,\n AttachmentList,\n} from \"../../chat/Attachment\";\nimport {\n createAttachmentUploadAdapter,\n type AttachmentFilePart,\n type AttachmentLimits,\n type AttachmentUploadAdapter,\n} from \"../../chat/attachment-upload\";\nimport type { ChatModel, ToolMeta } from \"../../chat/types\";\nimport type { FileUIPart } from \"../../chat/types\";\nimport { RuntimeBar } from \"../RuntimeBar\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n type SpecRuntimeFamily,\n labelForBackend,\n} from \"../runtime-mode\";\nimport { SpecRuntimeEditor } from \"../SpecRuntimeEditor\";\nimport type { SpecRuntimeCLIOptions } from \"../SpecRuntimeEditor/CLIArgsSection\";\nimport type {\n SpecRuntimeSecretSelectorConfig,\n SpecSectionId,\n} from \"../SpecRuntimeEditor/types\";\nimport { withPrompt } from \"../SpecRuntimeEditor/update\";\nimport type { AISpecRuntimePermissionCatalog } from \"../SpecRuntimeEditor.model\";\nimport {\n runtimeRows,\n withRuntimeRows,\n type AIPromptRunValue,\n} from \"./model\";\n\nexport type PromptRunEditorProps = {\n value: AIPromptRunValue;\n onChange: (value: AIPromptRunValue) => void;\n models?: ChatModel[] | undefined;\n families?: SpecRuntimeFamily[] | undefined;\n tools?: ToolMeta[] | undefined;\n permissionCatalog?: AISpecRuntimePermissionCatalog | undefined;\n secretSelector?: SpecRuntimeSecretSelectorConfig | undefined;\n cliOptions?: SpecRuntimeCLIOptions | undefined;\n reasoningEfforts?: string[] | undefined;\n\n /** Schema-driven variables form; omit to render a raw-JSON editor. */\n variablesSchema?: JsonSchemaObject | undefined;\n /** Fires false while raw-JSON variables fail to parse; always true with a schema. */\n onVariablesValidityChange?: ((valid: boolean) => void) | undefined;\n\n /** Host-supplied editor for the `prompt.user` override; defaults to a textarea. */\n promptEditor?: ReactNode | undefined;\n promptLabel?: string | undefined;\n promptPlaceholder?: string | undefined;\n enableAttachments?: boolean | undefined;\n attachmentUpload?: AttachmentUploadAdapter | undefined;\n attachmentLimits?: AttachmentLimits | undefined;\n\n /** Extra fields injected inside the Runtime block, below Model/Effort. */\n children?: ReactNode | undefined;\n header?: ReactNode | undefined;\n footer?: ReactNode | undefined;\n className?: string | undefined;\n\n editSpecLabel?: string | undefined;\n specModalTitle?: string | undefined;\n /** Restrict which SpecRuntimeEditor sections the \"Edit spec\" modal shows. */\n specSections?: readonly SpecSectionId[] | undefined;\n};\n\n// The inline \"prompt + variables + runtime\" composer shared by captain's prompt\n// workbench and gavel's todo run dialog. It edits Captain's complete prompt-run\n// request without making hosts project that contract into editor-specific state.\n// Hosts should mount it with a `key` per prompt/todo so internal draft state\n// (raw-JSON text, modal open) resets on selection change.\nexport function PromptRunEditor({\n value,\n onChange,\n models = [],\n families = SPEC_RUNTIME_FAMILIES,\n tools = [],\n permissionCatalog,\n secretSelector,\n cliOptions,\n reasoningEfforts = DEFAULT_REASONING_EFFORTS,\n variablesSchema,\n onVariablesValidityChange,\n promptEditor,\n promptLabel = \"User prompt\",\n promptPlaceholder = \"Override the rendered user prompt\",\n enableAttachments = false,\n attachmentUpload,\n attachmentLimits,\n children,\n header,\n footer,\n className,\n editSpecLabel = \"Edit spec\",\n specModalTitle = \"Runtime spec\",\n specSections,\n}: PromptRunEditorProps) {\n const [specOpen, setSpecOpen] = useState(false);\n const spec = value.spec ?? {};\n const rows = runtimeRows(value);\n const selectedModel = models.find(\n (model) => model.id === spec.id || model.id === spec.model,\n );\n const resolvedAttachmentUpload = useMemo(\n () => attachmentUpload ?? createAttachmentUploadAdapter(),\n [attachmentUpload],\n );\n const attachmentFiles: FileUIPart[] = (spec.prompt?.attachments ?? []).map(\n (attachment) => ({\n type: \"file\",\n url: attachment.id\n ? `/api/attachments/${attachment.id}`\n : (attachment.url ?? \"\"),\n mediaType: attachment.mediaType ?? \"application/octet-stream\",\n ...(attachment.id ? { attachmentId: attachment.id } : {}),\n ...(attachment.size != null ? { size: attachment.size } : {}),\n ...(attachment.filename ? { filename: attachment.filename } : {}),\n ...(!attachment.filename && attachment.path\n ? { filename: attachment.path }\n : {}),\n }),\n ) as FileUIPart[];\n\n return (\n <div className={cn(\"grid gap-density-4\", className)}>\n {header}\n\n <Block title=\"Runtime\">\n <div className=\"grid gap-density-2\">\n {rows.map((runtime, index) => (\n <div\n key={index}\n role=\"group\"\n aria-label={`Runtime ${index + 1}`}\n className=\"flex min-w-0 items-center gap-density-2\"\n >\n <RuntimeBar\n value={runtime}\n onChange={(next) =>\n onChange(\n withRuntimeRows(\n value,\n rows.map((item, itemIndex) =>\n itemIndex === index ? next : item,\n ),\n ),\n )\n }\n models={models}\n families={families}\n reasoningEfforts={reasoningEfforts}\n ariaLabel={`Runtime ${index + 1} controls`}\n />\n {rows.length > 1 && (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Remove runtime ${index + 1}`}\n onClick={() =>\n onChange(\n withRuntimeRows(\n value,\n rows.filter((_, itemIndex) => itemIndex !== index),\n ),\n )\n }\n >\n <Icon icon={UiTrash} className=\"size-4\" />\n </Button>\n )}\n </div>\n ))}\n <div className=\"flex flex-wrap items-center gap-density-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n aria-label=\"Add runtime\"\n onClick={() =>\n onChange(\n withRuntimeRows(value, [\n ...rows,\n rows[0]?.backend ? { backend: rows[0].backend } : {},\n ]),\n )\n }\n >\n <Icon icon={UiAdd} className=\"size-4\" />\n Add runtime\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setSpecOpen(true)}>\n <Icon icon={UiGearSix} className=\"size-4\" />\n {editSpecLabel}\n </Button>\n </div>\n </div>\n {children}\n </Block>\n\n <Block title=\"Variables\">\n <VariablesField\n {...(variablesSchema ? { schema: variablesSchema } : {})}\n value={value.variables ?? {}}\n onChange={(variables) => onChange({ ...value, variables })}\n {...(onVariablesValidityChange\n ? { onValidityChange: onVariablesValidityChange }\n : {})}\n />\n </Block>\n\n <Block title={promptLabel}>\n {promptEditor ?? (\n <textarea\n value={spec.prompt?.user ?? \"\"}\n onChange={(event) =>\n onChange({\n ...value,\n spec: withPrompt(spec, { user: event.target.value }),\n })\n }\n spellCheck={false}\n placeholder={promptPlaceholder}\n aria-label={promptLabel}\n className=\"min-h-[7rem] w-full resize-y rounded-md border border-border bg-background px-density-2 py-density-1 text-sm outline-none focus:ring-2 focus:ring-ring\"\n />\n )}\n {enableAttachments && (\n <div className=\"space-y-density-2\">\n <AttachmentList\n files={attachmentFiles}\n onRemove={(index) =>\n onChange({\n ...value,\n spec: withPrompt(spec, {\n attachments: (spec.prompt?.attachments ?? []).filter(\n (_, itemIndex) => itemIndex !== index,\n ),\n }),\n })\n }\n />\n <AttachmentButton\n files={attachmentFiles}\n upload={resolvedAttachmentUpload}\n onAdd={(parts) =>\n onChange({\n ...value,\n spec: withPrompt(spec, {\n attachments: [\n ...(spec.prompt?.attachments ?? []),\n ...parts.map((part) => {\n const uploaded = part as AttachmentFilePart;\n return {\n id: uploaded.attachmentId,\n mediaType: uploaded.mediaType,\n size: uploaded.size,\n ...(uploaded.filename\n ? { filename: uploaded.filename }\n : {}),\n };\n }),\n ],\n }),\n })\n }\n {...(selectedModel?.inputMediaTypes\n ? { acceptedMediaTypes: selectedModel.inputMediaTypes }\n : {})}\n {...(attachmentLimits ? { limits: attachmentLimits } : {})}\n />\n </div>\n )}\n </Block>\n\n {footer}\n\n <Modal\n open={specOpen}\n onClose={() => setSpecOpen(false)}\n title={specModalTitle}\n size=\"full\"\n closeOnEsc\n className=\"h-[95vh]\"\n >\n <SpecRuntimeEditor\n value={spec}\n onChange={(next) => onChange({ ...value, spec: next })}\n models={models}\n families={families}\n tools={tools}\n {...(permissionCatalog ? { permissionCatalog } : {})}\n {...(secretSelector ? { secretSelector } : {})}\n {...(cliOptions ? { cliOptions } : {})}\n {...(specSections ? { sections: specSections } : {})}\n onSave={() => setSpecOpen(false)}\n onCancel={() => setSpecOpen(false)}\n saveLabel=\"Done\"\n footerStatus={labelForBackend(spec.backend, families)}\n />\n </Modal>\n </div>\n );\n}\n\nfunction Block({ title, children }: { title: string; children: ReactNode }) {\n return (\n <section className=\"space-y-density-2\">\n <div className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {title}\n </div>\n {children}\n </section>\n );\n}\n\n// Variables are edited via the prompt's declared schema when present, otherwise\n// as a raw JSON object; the raw text is held locally and only committed to the\n// host when it parses to an object.\nfunction VariablesField({\n schema,\n value,\n onChange,\n onValidityChange,\n}: {\n schema?: JsonSchemaObject | undefined;\n value: Record<string, unknown>;\n onChange: (next: Record<string, unknown>) => void;\n onValidityChange?: ((valid: boolean) => void) | undefined;\n}) {\n const idPrefix = useId();\n const [rawText, setRawText] = useState(() => stringifyVariables(value));\n const [rawError, setRawError] = useState<string | null>(null);\n\n if (schema) {\n return (\n <JsonSchemaForm\n idPrefix={`prompt-vars-${idPrefix}`}\n schema={schema}\n value={value}\n onChange={(next) => onChange(next as Record<string, unknown>)}\n size=\"sm\"\n />\n );\n }\n\n const commit = (text: string) => {\n setRawText(text);\n if (!text.trim()) {\n setRawError(null);\n onValidityChange?.(true);\n onChange({});\n return;\n }\n try {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n setRawError(null);\n onValidityChange?.(true);\n onChange(parsed as Record<string, unknown>);\n } else {\n setRawError(\"Expected a JSON object\");\n onValidityChange?.(false);\n }\n } catch (error) {\n setRawError(error instanceof Error ? error.message : \"Invalid JSON\");\n onValidityChange?.(false);\n }\n };\n\n return (\n <div className=\"space-y-1\">\n <textarea\n value={rawText}\n onChange={(event) => commit(event.target.value)}\n spellCheck={false}\n placeholder=\"{}\"\n aria-label=\"Variables JSON\"\n className=\"h-28 w-full resize-y rounded-md border border-border bg-background px-density-2 py-density-1 font-mono text-xs outline-none focus:ring-2 focus:ring-ring\"\n />\n {rawError && <div className=\"text-xs text-destructive\">{rawError}</div>}\n </div>\n );\n}\n\nfunction stringifyVariables(value: Record<string, unknown>) {\n if (!value || Object.keys(value).length === 0) return \"{}\";\n return JSON.stringify(value, null, 2);\n}\n"],"names":["_a"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const MODEL_KEYS = [
4
+ "model",
5
+ "id",
6
+ "backend",
7
+ "temperature",
8
+ "effort",
9
+ "noCache",
10
+ "fallbacks"
11
+ ];
12
+ function runtimeModelFromSpec(spec) {
13
+ if (!spec) return {};
14
+ const model = {};
15
+ for (const key of MODEL_KEYS) {
16
+ const value = spec[key];
17
+ if (value !== void 0) {
18
+ Object.assign(model, { [key]: value });
19
+ }
20
+ }
21
+ return model;
22
+ }
23
+ function runtimeRows(value) {
24
+ var _a;
25
+ return ((_a = value.runtimes) == null ? void 0 : _a.length) ? value.runtimes : [runtimeModelFromSpec(value.spec)];
26
+ }
27
+ function withRuntimeRows(value, rows) {
28
+ const first = rows[0] ?? {};
29
+ const spec = withRuntimeModel(value.spec ?? {}, first);
30
+ if (rows.length <= 1) {
31
+ const next = { ...value, spec };
32
+ delete next.runtimes;
33
+ return next;
34
+ }
35
+ return { ...value, spec, runtimes: rows };
36
+ }
37
+ function withRuntimeModel(spec, model) {
38
+ const next = { ...spec };
39
+ for (const key of MODEL_KEYS) {
40
+ delete next[key];
41
+ }
42
+ return { ...next, ...model };
43
+ }
44
+ exports.runtimeModelFromSpec = runtimeModelFromSpec;
45
+ exports.runtimeRows = runtimeRows;
46
+ exports.withRuntimeRows = withRuntimeRows;
47
+ //# sourceMappingURL=model.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.cjs","sources":["../../../../src/data/ai/PromptRunEditor/model.ts"],"sourcesContent":["import type { AISpecRuntimeValue } from \"../SpecRuntimeEditor.model\";\n\nexport type AIPromptRunSpec = AISpecRuntimeValue & {\n messages?: unknown[];\n toolPreferences?: unknown;\n toolApproval?: unknown;\n};\n\nexport type AISpecRuntimeModel = Pick<\n AISpecRuntimeValue,\n | \"model\"\n | \"id\"\n | \"backend\"\n | \"temperature\"\n | \"effort\"\n | \"noCache\"\n | \"fallbacks\"\n>;\n\nexport type AIPromptRunValue = {\n variables?: Record<string, unknown>;\n spec?: AIPromptRunSpec;\n runtimes?: AISpecRuntimeModel[];\n chat?: boolean;\n};\n\nconst MODEL_KEYS = [\n \"model\",\n \"id\",\n \"backend\",\n \"temperature\",\n \"effort\",\n \"noCache\",\n \"fallbacks\",\n] as const satisfies readonly (keyof AISpecRuntimeModel)[];\n\nexport function runtimeModelFromSpec(\n spec: AIPromptRunSpec | undefined,\n): AISpecRuntimeModel {\n if (!spec) return {};\n const model: AISpecRuntimeModel = {};\n for (const key of MODEL_KEYS) {\n const value = spec[key];\n if (value !== undefined) {\n Object.assign(model, { [key]: value });\n }\n }\n return model;\n}\n\nexport function runtimeRows(value: AIPromptRunValue): AISpecRuntimeModel[] {\n return value.runtimes?.length\n ? value.runtimes\n : [runtimeModelFromSpec(value.spec)];\n}\n\nexport function withRuntimeRows(\n value: AIPromptRunValue,\n rows: AISpecRuntimeModel[],\n): AIPromptRunValue {\n const first = rows[0] ?? {};\n const spec = withRuntimeModel(value.spec ?? {}, first);\n if (rows.length <= 1) {\n const next = { ...value, spec };\n delete next.runtimes;\n return next;\n }\n return { ...value, spec, runtimes: rows };\n}\n\nfunction withRuntimeModel(\n spec: AIPromptRunSpec,\n model: AISpecRuntimeModel,\n): AIPromptRunSpec {\n const next = { ...spec };\n for (const key of MODEL_KEYS) {\n delete next[key];\n }\n return { ...next, ...model };\n}\n"],"names":[],"mappings":";;AA0BA,MAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,qBACd,MACoB;AACpB,MAAI,CAAC,KAAM,QAAO,CAAA;AAClB,QAAM,QAA4B,CAAA;AAClC,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,KAAK,GAAG;AACtB,QAAI,UAAU,QAAW;AACvB,aAAO,OAAO,OAAO,EAAE,CAAC,GAAG,GAAG,OAAO;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,YAAY,OAA+C;;AACzE,WAAO,WAAM,aAAN,mBAAgB,UACnB,MAAM,WACN,CAAC,qBAAqB,MAAM,IAAI,CAAC;AACvC;AAEO,SAAS,gBACd,OACA,MACkB;AAClB,QAAM,QAAQ,KAAK,CAAC,KAAK,CAAA;AACzB,QAAM,OAAO,iBAAiB,MAAM,QAAQ,CAAA,GAAI,KAAK;AACrD,MAAI,KAAK,UAAU,GAAG;AACpB,UAAM,OAAO,EAAE,GAAG,OAAO,KAAA;AACzB,WAAO,KAAK;AACZ,WAAO;AAAA,EACT;AACA,SAAO,EAAE,GAAG,OAAO,MAAM,UAAU,KAAA;AACrC;AAEA,SAAS,iBACP,MACA,OACiB;AACjB,QAAM,OAAO,EAAE,GAAG,KAAA;AAClB,aAAW,OAAO,YAAY;AAC5B,WAAO,KAAK,GAAG;AAAA,EACjB;AACA,SAAO,EAAE,GAAG,MAAM,GAAG,MAAA;AACvB;;;;"}
@@ -0,0 +1,17 @@
1
+ import { AISpecRuntimeValue } from '../SpecRuntimeEditor.model';
2
+ export type AIPromptRunSpec = AISpecRuntimeValue & {
3
+ messages?: unknown[];
4
+ toolPreferences?: unknown;
5
+ toolApproval?: unknown;
6
+ };
7
+ export type AISpecRuntimeModel = Pick<AISpecRuntimeValue, "model" | "id" | "backend" | "temperature" | "effort" | "noCache" | "fallbacks">;
8
+ export type AIPromptRunValue = {
9
+ variables?: Record<string, unknown>;
10
+ spec?: AIPromptRunSpec;
11
+ runtimes?: AISpecRuntimeModel[];
12
+ chat?: boolean;
13
+ };
14
+ export declare function runtimeModelFromSpec(spec: AIPromptRunSpec | undefined): AISpecRuntimeModel;
15
+ export declare function runtimeRows(value: AIPromptRunValue): AISpecRuntimeModel[];
16
+ export declare function withRuntimeRows(value: AIPromptRunValue, rows: AISpecRuntimeModel[]): AIPromptRunValue;
17
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../src/data/ai/PromptRunEditor/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG;IACjD,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,kBAAkB,EAChB,OAAO,GACP,IAAI,GACJ,SAAS,GACT,aAAa,GACb,QAAQ,GACR,SAAS,GACT,WAAW,CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAYF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,GAAG,SAAS,GAChC,kBAAkB,CAUpB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,kBAAkB,EAAE,CAIzE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,kBAAkB,EAAE,GACzB,gBAAgB,CASlB"}
@@ -0,0 +1,47 @@
1
+ const MODEL_KEYS = [
2
+ "model",
3
+ "id",
4
+ "backend",
5
+ "temperature",
6
+ "effort",
7
+ "noCache",
8
+ "fallbacks"
9
+ ];
10
+ function runtimeModelFromSpec(spec) {
11
+ if (!spec) return {};
12
+ const model = {};
13
+ for (const key of MODEL_KEYS) {
14
+ const value = spec[key];
15
+ if (value !== void 0) {
16
+ Object.assign(model, { [key]: value });
17
+ }
18
+ }
19
+ return model;
20
+ }
21
+ function runtimeRows(value) {
22
+ var _a;
23
+ return ((_a = value.runtimes) == null ? void 0 : _a.length) ? value.runtimes : [runtimeModelFromSpec(value.spec)];
24
+ }
25
+ function withRuntimeRows(value, rows) {
26
+ const first = rows[0] ?? {};
27
+ const spec = withRuntimeModel(value.spec ?? {}, first);
28
+ if (rows.length <= 1) {
29
+ const next = { ...value, spec };
30
+ delete next.runtimes;
31
+ return next;
32
+ }
33
+ return { ...value, spec, runtimes: rows };
34
+ }
35
+ function withRuntimeModel(spec, model) {
36
+ const next = { ...spec };
37
+ for (const key of MODEL_KEYS) {
38
+ delete next[key];
39
+ }
40
+ return { ...next, ...model };
41
+ }
42
+ export {
43
+ runtimeModelFromSpec,
44
+ runtimeRows,
45
+ withRuntimeRows
46
+ };
47
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sources":["../../../../src/data/ai/PromptRunEditor/model.ts"],"sourcesContent":["import type { AISpecRuntimeValue } from \"../SpecRuntimeEditor.model\";\n\nexport type AIPromptRunSpec = AISpecRuntimeValue & {\n messages?: unknown[];\n toolPreferences?: unknown;\n toolApproval?: unknown;\n};\n\nexport type AISpecRuntimeModel = Pick<\n AISpecRuntimeValue,\n | \"model\"\n | \"id\"\n | \"backend\"\n | \"temperature\"\n | \"effort\"\n | \"noCache\"\n | \"fallbacks\"\n>;\n\nexport type AIPromptRunValue = {\n variables?: Record<string, unknown>;\n spec?: AIPromptRunSpec;\n runtimes?: AISpecRuntimeModel[];\n chat?: boolean;\n};\n\nconst MODEL_KEYS = [\n \"model\",\n \"id\",\n \"backend\",\n \"temperature\",\n \"effort\",\n \"noCache\",\n \"fallbacks\",\n] as const satisfies readonly (keyof AISpecRuntimeModel)[];\n\nexport function runtimeModelFromSpec(\n spec: AIPromptRunSpec | undefined,\n): AISpecRuntimeModel {\n if (!spec) return {};\n const model: AISpecRuntimeModel = {};\n for (const key of MODEL_KEYS) {\n const value = spec[key];\n if (value !== undefined) {\n Object.assign(model, { [key]: value });\n }\n }\n return model;\n}\n\nexport function runtimeRows(value: AIPromptRunValue): AISpecRuntimeModel[] {\n return value.runtimes?.length\n ? value.runtimes\n : [runtimeModelFromSpec(value.spec)];\n}\n\nexport function withRuntimeRows(\n value: AIPromptRunValue,\n rows: AISpecRuntimeModel[],\n): AIPromptRunValue {\n const first = rows[0] ?? {};\n const spec = withRuntimeModel(value.spec ?? {}, first);\n if (rows.length <= 1) {\n const next = { ...value, spec };\n delete next.runtimes;\n return next;\n }\n return { ...value, spec, runtimes: rows };\n}\n\nfunction withRuntimeModel(\n spec: AIPromptRunSpec,\n model: AISpecRuntimeModel,\n): AIPromptRunSpec {\n const next = { ...spec };\n for (const key of MODEL_KEYS) {\n delete next[key];\n }\n return { ...next, ...model };\n}\n"],"names":[],"mappings":"AA0BA,MAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,qBACd,MACoB;AACpB,MAAI,CAAC,KAAM,QAAO,CAAA;AAClB,QAAM,QAA4B,CAAA;AAClC,aAAW,OAAO,YAAY;AAC5B,UAAM,QAAQ,KAAK,GAAG;AACtB,QAAI,UAAU,QAAW;AACvB,aAAO,OAAO,OAAO,EAAE,CAAC,GAAG,GAAG,OAAO;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,YAAY,OAA+C;AAxB3E;AAyBE,WAAO,WAAM,aAAN,mBAAgB,UACnB,MAAM,WACN,CAAC,qBAAqB,MAAM,IAAI,CAAC;AACvC;AAEO,SAAS,gBACd,OACA,MACkB;AAClB,QAAM,QAAQ,KAAK,CAAC,KAAK,CAAA;AACzB,QAAM,OAAO,iBAAiB,MAAM,QAAQ,CAAA,GAAI,KAAK;AACrD,MAAI,KAAK,UAAU,GAAG;AACpB,UAAM,OAAO,EAAE,GAAG,OAAO,KAAA;AACzB,WAAO,KAAK;AACZ,WAAO;AAAA,EACT;AACA,SAAO,EAAE,GAAG,OAAO,MAAM,UAAU,KAAA;AACrC;AAEA,SAAS,iBACP,MACA,OACiB;AACjB,QAAM,OAAO,EAAE,GAAG,KAAA;AAClB,aAAW,OAAO,YAAY;AAC5B,WAAO,KAAK,GAAG;AAAA,EACjB;AACA,SAAO,EAAE,GAAG,MAAM,GAAG,MAAA;AACvB;"}