@fallen-8/studio 0.0.37 → 0.0.38

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 (40) hide show
  1. package/dist-lib/{Canvas3D-CmDAo5BT.js → Canvas3D-DEWoiNMD.js} +1 -1
  2. package/dist-lib/{F8GraphCanvas-COQKIUas.js → F8GraphCanvas-Cu6dtIgq.js} +667 -659
  3. package/dist-lib/canvas.js +1 -1
  4. package/dist-lib/{cssMode-Cm-p9yGb.js → cssMode-1gdBAwNQ.js} +1 -1
  5. package/dist-lib/f8-studio.css +1 -1
  6. package/dist-lib/f8-studio.js +2 -2
  7. package/dist-lib/{freemarker2-DU-Ctapi.js → freemarker2-DOQZLtnt.js} +1 -1
  8. package/dist-lib/{handlebars-BsqZtC5a.js → handlebars-CIXlymxU.js} +1 -1
  9. package/dist-lib/{html-CUyknR5b.js → html--Bi9VDgI.js} +1 -1
  10. package/dist-lib/{htmlMode-DjyPljE2.js → htmlMode-BqCrpeeP.js} +1 -1
  11. package/dist-lib/{index-BQbFjItv.js → index-0ioFtrZM.js} +24086 -23585
  12. package/dist-lib/{javascript-CVQBymBa.js → javascript-BL3tIzUw.js} +1 -1
  13. package/dist-lib/{jsonMode-B3hcJ0l3.js → jsonMode-FxM7KRm5.js} +1 -1
  14. package/dist-lib/{liquid-DLrt4Cls.js → liquid-wB7unZht.js} +1 -1
  15. package/dist-lib/{mdx-DePkemui.js → mdx-DmS41r19.js} +1 -1
  16. package/dist-lib/{python-CUe0bWsE.js → python-C24igqMV.js} +1 -1
  17. package/dist-lib/{razor-DD_zUh3z.js → razor-BRvioLVk.js} +1 -1
  18. package/dist-lib/{tsMode-Ae3UtOmp.js → tsMode-zMn1qnUE.js} +1 -1
  19. package/dist-lib/types/api/client.d.ts +49 -0
  20. package/dist-lib/types/api/endpoints.d.ts +49 -3
  21. package/dist-lib/types/api/types.d.ts +65 -3
  22. package/dist-lib/types/components/ConfigurationSurface.d.ts +23 -2
  23. package/dist-lib/types/components/ErrorBox.d.ts +6 -0
  24. package/dist-lib/types/components/SemanticBlockEditor.d.ts +4 -1
  25. package/dist-lib/types/components/SemanticQueryEditor.d.ts +8 -1
  26. package/dist-lib/types/components/SettingRow.d.ts +14 -0
  27. package/dist-lib/types/delegate/nl/NlDraftStats.d.ts +13 -0
  28. package/dist-lib/types/delegate/nl/config.d.ts +5 -4
  29. package/dist-lib/types/delegate/nl/generate.d.ts +6 -0
  30. package/dist-lib/types/lib/fieldHelp.d.ts +3 -1
  31. package/dist-lib/types/lib/fileLimits.d.ts +69 -0
  32. package/dist-lib/types/lib/format.d.ts +8 -0
  33. package/dist-lib/types/lib/modelProvenance.d.ts +26 -0
  34. package/dist-lib/types/lib/vectorIndexCreate.d.ts +49 -0
  35. package/dist-lib/types/state/instanceStore.d.ts +28 -2
  36. package/dist-lib/types/state/integrations.d.ts +11 -1
  37. package/dist-lib/{typescript-LNGesWYR.js → typescript-BIjKKvsW.js} +1 -1
  38. package/dist-lib/{xml-BuD_-6ib.js → xml-CT-uMOiT.js} +1 -1
  39. package/dist-lib/{yaml-DCzPbyTS.js → yaml-Dezcc_VH.js} +1 -1
  40. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { conf as t, language as e } from "./typescript-LNGesWYR.js";
1
+ import { conf as t, language as e } from "./typescript-BIjKKvsW.js";
2
2
  var i = t, o = {
3
3
  // Set defaultToken to invalid to see what you do not tokenize yet
4
4
  defaultToken: "invalid",
@@ -1,4 +1,4 @@
1
- import { m as Et } from "./index-BQbFjItv.js";
1
+ import { m as Et } from "./index-0ioFtrZM.js";
2
2
  var Lt = Object.defineProperty, Ot = Object.getOwnPropertyDescriptor, Nt = Object.getOwnPropertyNames, Rt = Object.prototype.hasOwnProperty, Mt = (e, r, i, n) => {
3
3
  if (r && typeof r == "object" || typeof r == "function")
4
4
  for (let t of Nt(r))
@@ -1,4 +1,4 @@
1
- import { m as l } from "./index-BQbFjItv.js";
1
+ import { m as l } from "./index-0ioFtrZM.js";
2
2
  var d = Object.defineProperty, s = Object.getOwnPropertyDescriptor, c = Object.getOwnPropertyNames, u = Object.prototype.hasOwnProperty, m = (t, e, r, n) => {
3
3
  if (e && typeof e == "object" || typeof e == "function")
4
4
  for (let i of c(e))
@@ -1,4 +1,4 @@
1
- import { m as s } from "./index-BQbFjItv.js";
1
+ import { m as s } from "./index-0ioFtrZM.js";
2
2
  var d = Object.defineProperty, c = Object.getOwnPropertyDescriptor, p = Object.getOwnPropertyNames, a = Object.prototype.hasOwnProperty, k = (n, e, i, r) => {
3
3
  if (e && typeof e == "object" || typeof e == "function")
4
4
  for (let o of p(e))
@@ -1,4 +1,4 @@
1
- import { m as o } from "./index-BQbFjItv.js";
1
+ import { m as o } from "./index-0ioFtrZM.js";
2
2
  var a = Object.defineProperty, l = Object.getOwnPropertyDescriptor, p = Object.getOwnPropertyNames, c = Object.prototype.hasOwnProperty, g = (t, e, n, s) => {
3
3
  if (e && typeof e == "object" || typeof e == "function")
4
4
  for (let r of p(e))
@@ -1,4 +1,4 @@
1
- import { m } from "./index-BQbFjItv.js";
1
+ import { m } from "./index-0ioFtrZM.js";
2
2
  var s = Object.defineProperty, c = Object.getOwnPropertyDescriptor, l = Object.getOwnPropertyNames, d = Object.prototype.hasOwnProperty, p = (t, e, o, n) => {
3
3
  if (e && typeof e == "object" || typeof e == "function")
4
4
  for (let r of l(e))
@@ -1,4 +1,4 @@
1
- import { t as O, m as I } from "./index-BQbFjItv.js";
1
+ import { t as O, m as I } from "./index-0ioFtrZM.js";
2
2
  var N = Object.defineProperty, M = Object.getOwnPropertyDescriptor, R = Object.getOwnPropertyNames, K = Object.prototype.hasOwnProperty, E = (e, t, i, o) => {
3
3
  if (t && typeof t == "object" || typeof t == "function")
4
4
  for (let n of R(t))
@@ -96,6 +96,13 @@ export declare function resolveAuthHeaders(instance: InstanceConfig): Promise<Re
96
96
  * Shared by {@link apiRequest} and the raw-fetch bulk endpoints so every failure looks the same.
97
97
  */
98
98
  export declare function throwIfNotOk(response: Response, url: string): Promise<void>;
99
+ /**
100
+ * Turns one non-ok answer into an {@link ApiError}, whatever transport read it. Separate from
101
+ * {@link throwIfNotOk} because {@link apiUpload} goes through XMLHttpRequest and has no
102
+ * `Response`, and a second copy of this would be a second place for the namespace announcement
103
+ * below to go stale.
104
+ */
105
+ export declare function raiseApiError(status: number, url: string, body: string): never;
99
106
  /**
100
107
  * One request's deadline: a signal that aborts when the caller's does OR when the timeout expires,
101
108
  * and a flag saying which of the two happened.
@@ -119,3 +126,45 @@ export declare function apiRequest<T>(instance: InstanceConfig, path: string, op
119
126
  * itself, so no Content-Type is written here.
120
127
  */
121
128
  export declare function apiForm<T>(instance: InstanceConfig, path: string, form: FormData, options?: Pick<RequestOptions, "signal" | "scope">): Promise<T | null>;
129
+ /**
130
+ * Whether a failure is somebody having cancelled rather than something having gone wrong.
131
+ *
132
+ * It exists because react-query does NOT treat an aborted MUTATION as a cancellation the way it
133
+ * treats an aborted query: the mutation moves to `isError` with the abort as its error, so a call
134
+ * site that renders `isError` puts a red box on the screen of the person who just pressed cancel.
135
+ *
136
+ * Matched on the NAME alone, deliberately. Neither `instanceof DOMException` nor `instanceof Error`
137
+ * can be relied on here: jsdom's `DOMException` does not extend `Error`, so an `instanceof Error`
138
+ * check passes in a browser and fails in the test suite - which is the worst of both, a guard that
139
+ * is only absent where it is being verified. Every abort reason carries this name, whatever its
140
+ * class.
141
+ */
142
+ export declare function wasCancelled(error: unknown): boolean;
143
+ /** How far a send has got. `total` is null when the browser will not say how much there is. */
144
+ export interface UploadProgress {
145
+ sent: number;
146
+ total: number | null;
147
+ }
148
+ /**
149
+ * Multipart POST that reports how far the SEND has got (feature integration-file-transport).
150
+ *
151
+ * XMLHttpRequest and not `fetch`, for one reason: fetch cannot report upload progress. A
152
+ * `ReadableStream` request body can, but it requires HTTP/2 and `duplex: "half"`, is unsupported in
153
+ * Safari, and would make progress depend on the transport an instance happens to be reached over.
154
+ * XHR reports it everywhere, so this is a deliberate exception rather than legacy code, and it is
155
+ * the ONLY one: everything without a progress bar goes through {@link apiForm}.
156
+ *
157
+ * The progress matters because of what this carries. An integration job may be gigabytes of
158
+ * extracts, and a send with no feedback is indistinguishable from a hang - which is exactly what
159
+ * the operator who prompted this feature reported: they pressed run, saw nothing for minutes, and
160
+ * then got an error.
161
+ *
162
+ * Failures are shaped like every other call's: an {@link ApiError} for a status, an abort rethrown
163
+ * as an abort so react-query reads it as a cancellation, and a `TypeError` for a transport failure,
164
+ * which is the same class `fetch` throws and which `ErrorBox` renders as an unreachable instance.
165
+ */
166
+ export declare function apiUpload<T>(instance: InstanceConfig, path: string, form: FormData, options?: {
167
+ signal?: AbortSignal;
168
+ scope?: "namespace" | "fallen8";
169
+ onProgress?: (progress: UploadProgress) => void;
170
+ }): Promise<T | null>;
@@ -1,5 +1,6 @@
1
+ import type { UploadProgress } from "./client";
1
2
  import type { InstanceConfig } from "../instances/types";
2
- import type { AnalyticsResultREST, DocumentBinding, DocumentDetail, DocumentEntityList, DocumentList, DocumentSearchResult, DocumentSearchSpecification, DocumentSummary, IngestTextSpecification, IntegrationJobRequest, IntegrationRunAccepted, IntegrationRunState, IntegrationProvider, NamespaceActivationREST, NamespaceEntry, NamespacesResponse, NamespaceTriState, AnalyticsSpecification, BenchmarkResult, BulkImportResultREST, GraphGenerationResult, AlgorithmPluginRegistration, DelegateKind, DelegateValidationResult, EdgeREST, EmbedElementSpecification, FunctionPluginRegistration, GraphFunctionResultREST, PluginAuthoringCategory, PluginDetailREST, PluginSummaryREST, PluginValidationResult, PluginValidationSpecification, ConfigREST, ConfigWriteREST, ConfigWriteSpec, ChatCompletionSpec, ChatCompletionResultREST, EmbeddingSearchSpecification, EmbeddingWriteSpecification, SaveGame, EdgeSpecification, FulltextIndexScanSpecification, FulltextSearchResultREST, GraphREST, GraphStatisticsREST, IndexAddToSpecification, IndexKeySpecification, IndexScanSpecification, PartitionMembersREST, PathREST, PathSpecification, PluginSpecification, PropertySearchSpecification, PropertySpecification, RangeIndexScanSpecification, ScanSpecification, SearchDistanceSpecification, GraphElementBatchREST, StatusREST, StoredQueryDetailREST, StoredQuerySpecification, StoredQuerySummaryREST, SubGraphSpecification, SubGraphSummary, VectorIndexAddSpecification, VectorIndexScanSpecification, VectorSearchResultREST, VertexREST, VertexSpecification } from "./types";
3
+ import type { AnalyticsResultREST, DocumentBinding, DocumentDetail, DocumentEntityList, DocumentList, DocumentSearchResult, DocumentSearchSpecification, DocumentSummary, FileLimits, IngestTextSpecification, IntegrationJobRequest, IntegrationRunAccepted, IntegrationRunState, IntegrationProvider, NamespaceActivationREST, NamespaceEntry, NamespacesResponse, NamespaceTriState, AnalyticsSpecification, BenchmarkResult, BulkImportResultREST, GraphGenerationResult, AlgorithmPluginRegistration, DelegateKind, DelegateValidationResult, EdgeREST, EmbedElementSpecification, FunctionPluginRegistration, GraphFunctionResultREST, PluginAuthoringCategory, PluginDetailREST, PluginSummaryREST, PluginValidationResult, PluginValidationSpecification, ConfigREST, ConfigWriteREST, ConfigWriteSpec, ChatCompletionSpec, ChatCompletionResultREST, ChatModelsREST, EmbeddingSearchSpecification, EmbeddingWriteSpecification, SaveGame, EdgeSpecification, FulltextIndexScanSpecification, FulltextSearchResultREST, GraphREST, GraphStatisticsREST, IndexAddToSpecification, IndexKeySpecification, IndexScanSpecification, PartitionMembersREST, PathREST, PathSpecification, PluginSpecification, PropertySearchSpecification, PropertySpecification, RangeIndexScanSpecification, ScanSpecification, SearchDistanceSpecification, GraphElementBatchREST, StatusREST, StoredQueryDetailREST, StoredQuerySpecification, StoredQuerySummaryREST, SubGraphSpecification, SubGraphSummary, VectorIndexAddSpecification, VectorIndexScanSpecification, VectorSearchResultREST, VertexREST, VertexSpecification } from "./types";
3
4
  /**
4
5
  * The reachability probe, and the ONE call with a deadline (see `RequestOptions.timeoutMs`).
5
6
  *
@@ -33,6 +34,15 @@ export declare const writeConfig: (i: InstanceConfig, spec: ConfigWriteSpec, sig
33
34
  * This is the DEFAULT NL-assist transport (custom endpoints stay browser-direct, off this path).
34
35
  */
35
36
  export declare const postChat: (i: InstanceConfig, spec: ChatCompletionSpec, signal?: AbortSignal) => Promise<ChatCompletionResultREST | null>;
37
+ /**
38
+ * What the RUNNING chat backend catalogues (feature chat-model-catalog): one bounded read that fans
39
+ * out to the backend's own model list. Fallen-8-level and gated exactly like POST /chat (403 when the
40
+ * chat capability is off), so Studio only calls it where the answer is actionable.
41
+ *
42
+ * The answer is not the whole resolvable set: a backend can serve a name it does not catalogue, which
43
+ * is why the picker fed from this stays free-text.
44
+ */
45
+ export declare const getChatModels: (i: InstanceConfig, signal?: AbortSignal) => Promise<ChatModelsREST | null>;
36
46
  /** Authorized iff the instance needs no key or accepted ours (server contract on StatusREST.ApiKeyRequired). */
37
47
  export declare const isAuthorized: (s: StatusREST) => boolean;
38
48
  /**
@@ -201,13 +211,49 @@ export declare const listEntities: (i: InstanceConfig, options?: {
201
211
  }, signal?: AbortSignal) => Promise<DocumentEntityList | null>;
202
212
  /** The integrations this instance's runtime ships. A 403 or 401 means the capability is off. */
203
213
  export declare const listIntegrationProviders: (i: InstanceConfig, signal?: AbortSignal) => Promise<IntegrationProvider[] | null>;
204
- /** Runs one job and returns its report. A job that RAN and failed still answers 200. */
214
+ /**
215
+ * What a job may carry on THIS instance: the ceilings already reconciled with the proxy's own
216
+ * transport bound, so there is one number per question and nothing to combine here. Read before
217
+ * staging so an oversized set is refused in the form rather than after an upload.
218
+ *
219
+ * An instance too old to serve it answers 404, which is why every caller has to treat "unknown"
220
+ * as "check nothing" rather than substituting a guess: a hardcoded ceiling here is how Studio
221
+ * came to carry one BELOW the runtime's and refuse jobs the instance would have accepted.
222
+ */
223
+ export declare const getIntegrationLimits: (i: InstanceConfig, signal?: AbortSignal) => Promise<FileLimits | null>;
205
224
  /**
206
225
  * Starts a run. Answers a run id, NOT a report: the report is read afterwards from
207
226
  * getIntegrationRun, because any real source outlives the connection that would have carried it.
208
227
  * Everything that can reject the job still fails this call, so a resolved promise means it started.
228
+ *
229
+ * Sent as a MULTIPART FORM (feature integration-file-transport): the document in a `job` part with
230
+ * its `files` map left out, and each file as its own part streamed straight from the browser's
231
+ * handle. There is deliberately no JSON fallback here, even though the instance still accepts one -
232
+ * keeping it would mean keeping a base64 encoder, and that encoder is what capped a job at about
233
+ * 384 MiB regardless of what the instance would have accepted. Against an apiApp too old to accept
234
+ * multipart the answer is a 415, which says so plainly.
235
+ *
236
+ * `onProgress` is how far the SEND has got, which for a multi-gigabyte set of extracts is the
237
+ * difference between a progress bar and an apparent hang.
238
+ */
239
+ export declare const submitIntegrationJob: (i: InstanceConfig, job: IntegrationJobRequest, options?: {
240
+ signal?: AbortSignal;
241
+ onProgress?: (progress: UploadProgress) => void;
242
+ }) => Promise<IntegrationRunAccepted | null>;
243
+ /**
244
+ * The job as a multipart form. Exported so a test can assert on the parts rather than on a mock's
245
+ * arguments: what matters is the shape that goes on the wire.
246
+ *
247
+ * The `job` part is a STRING and not a Blob. Appending a Blob makes the browser declare a filename
248
+ * on that part, which the runtime refuses by name because a value part carrying a filename is how
249
+ * the whole envelope gets sent as a file.
250
+ *
251
+ * The part naming is the runtime's grammar: `files[<key>]` for a setting given one file,
252
+ * `files[<key>][<n>]` numbered from 0 for one given several. The distinction is load-bearing rather
253
+ * than cosmetic - a list of one is a different statement from one file, and a setting the descriptor
254
+ * does not declare `multiple` refuses the list form.
209
255
  */
210
- export declare const submitIntegrationJob: (i: InstanceConfig, job: IntegrationJobRequest) => Promise<IntegrationRunAccepted | null>;
256
+ export declare function integrationJobForm(job: IntegrationJobRequest): FormData;
211
257
  /**
212
258
  * One identity's current or most recent run: the phase while it runs, the report once it ends.
213
259
  * Answers 404 when the runtime has no slot for that identity, which a caller should read as "not
@@ -435,6 +435,10 @@ export interface EmbeddingProviderStatsREST {
435
435
  export interface ChatProviderStatsREST {
436
436
  enabled: boolean;
437
437
  backend: string | null;
438
+ /**
439
+ * From the configured options, not from a probe target: reported for EVERY backend, including
440
+ * the ones with no residency API.
441
+ */
438
442
  model: string | null;
439
443
  loaded: boolean;
440
444
  resident?: boolean | null;
@@ -526,8 +530,28 @@ export interface ChatCompletionStatsREST {
526
530
  export interface ChatCompletionResultREST {
527
531
  content: string;
528
532
  model: string | null;
533
+ /**
534
+ * Which backend served THIS response (feature model-providers), stamped by the server. Null on
535
+ * a server predating the field. Per-call versus ambient: see lib/modelProvenance.ts.
536
+ */
537
+ backend?: string | null;
529
538
  stats?: ChatCompletionStatsREST | null;
530
539
  }
540
+ export interface ChatModelREST {
541
+ /** Verbatim from the backend's catalog; the server sorts ordinally for a stable contract. */
542
+ name: string;
543
+ /** Null when the backend does not say (OpenAI, Anthropic, an old sidecar, a failed lookup). */
544
+ capability: "completion" | "embedding" | null;
545
+ /** Whether a worker can serve it right now; null when the backend reports nothing. */
546
+ available: boolean | null;
547
+ /** The backend's own class string, passed through verbatim and carrying no published legend. */
548
+ class: string | null;
549
+ }
550
+ export interface ChatModelsREST {
551
+ /** The running backend's name, in the spelling ChatCompletionResultREST.backend uses. */
552
+ backend: string;
553
+ models: ChatModelREST[];
554
+ }
531
555
  export interface GraphStatisticsREST {
532
556
  vertexCount: number;
533
557
  edgeCount: number;
@@ -793,6 +817,14 @@ export interface SubGraphSemanticSummary {
793
817
  pattern: string;
794
818
  minScore: number;
795
819
  }[] | null;
820
+ /**
821
+ * Which embedding backend turned queryText into the bound vector, and that function's identity
822
+ * stamp (`name[@version]#dimension#metric`) - both stamped at registration and carried with the
823
+ * recipe, so the echo is the same on create, on read and after a recalculate. Absent for a
824
+ * vector-in registration: no embed call happened, so there is nothing honest to report.
825
+ */
826
+ embeddingBackend?: string | null;
827
+ embeddingIdentity?: string | null;
796
828
  }
797
829
  export interface SubGraphSummary {
798
830
  name: string;
@@ -1079,18 +1111,48 @@ export interface IntegrationDiagnostic {
1079
1111
  message: string;
1080
1112
  subject?: string | null;
1081
1113
  }
1082
- /** One file a job carries: its own name, and its bytes base64. */
1114
+ /**
1115
+ * One file a job carries: the browser's own handle on it.
1116
+ *
1117
+ * A `File` and NOT its bytes, which is the whole of feature integration-file-transport on this side.
1118
+ * The version this replaced carried `contentBase64`, so the tab had to hold every file's bytes, the
1119
+ * base64 expansion of them and the serialised request all at once; a set of AUTOSAR extracts left
1120
+ * 5.84 GiB resident before the send even started, and the encoder failed outright at about 384 MiB
1121
+ * of input because a JavaScript string caps at 512 MiB. A handle costs nothing until the browser
1122
+ * streams it off disk.
1123
+ *
1124
+ * The price, and it is real: the file is read at SEND time, so one moved, renamed or edited after
1125
+ * being staged fails then rather than at pick time. The form says so.
1126
+ */
1083
1127
  export interface IntegrationJobFile {
1084
1128
  /** The file's own name, used verbatim in the run's messages. Never a path. */
1085
1129
  name: string;
1086
- /** The file's BYTES, base64 - not its text, so a UTF-16 extract survives the trip. */
1087
- contentBase64: string;
1130
+ /** The handle. Nothing reads it until the request is sent. */
1131
+ file: File;
1088
1132
  }
1089
1133
  /**
1090
1134
  * The whole configuration of one run. A credential setting's value arrives in `credentialValues` and
1091
1135
  * a file setting's file in `files`, never in `settings`: the runtime leases and redacts the first,
1092
1136
  * holds the second for the run and drops it, and treats `settings` as ordinary data.
1093
1137
  */
1138
+ /**
1139
+ * What a job may carry on one instance (feature integration-file-transport), from
1140
+ * `GET /integrations/limits`. Already the ceiling that BINDS: the runtime owns the configuration,
1141
+ * but every request arrives through the apiApp's transport bound, so the proxy reconciles the two
1142
+ * and serves one number per question. Nothing here is combined client-side, on purpose - a client
1143
+ * that computes its own ceiling is how Studio ended up with one below the runtime's.
1144
+ *
1145
+ * Zero or less means that ceiling is switched off, which only `maxJobFiles` can report: the byte
1146
+ * ceilings always have the proxy's transport bound behind them.
1147
+ */
1148
+ export interface FileLimits {
1149
+ /** The most decoded bytes ONE file may carry. */
1150
+ maxFileBytes: number;
1151
+ /** The most decoded bytes one job's files may come to in TOTAL, across every file setting. */
1152
+ maxJobFileBytes: number;
1153
+ /** How many files one job may carry, counted across every file setting. */
1154
+ maxJobFiles: number;
1155
+ }
1094
1156
  export interface IntegrationJobRequest {
1095
1157
  providerId: string;
1096
1158
  integrationInstanceId: string;
@@ -1,5 +1,6 @@
1
- import type { ApiError } from "../api/client";
2
- import type { ObservabilityConfigREST, PendingRestartREST, SettingREST } from "../api/types";
1
+ import { ApiError } from "../api/client";
2
+ import type { InstanceConfig } from "../instances/types";
3
+ import type { ChatProviderStatsREST, ObservabilityConfigREST, PendingRestartREST, SettingREST } from "../api/types";
3
4
  /**
4
5
  * The configuration surface (feature configuration-surface): one dialog holding everything this
5
6
  * instance binds, reached from the single Configure button on the Connect screen's configuration card.
@@ -14,12 +15,24 @@ import type { ObservabilityConfigREST, PendingRestartREST, SettingREST } from ".
14
15
  * a value under a half-typed field here, which is exactly what the poll suspension exists to prevent.
15
16
  * What this component does own is where you are looking: the section, the query and the filter. Those
16
17
  * live under Dialog.Content, which Radix unmounts on close, so they reset without an effect.
18
+ *
19
+ * The ONE server read it does own is the chat model catalog (feature chat-model-catalog), because it
20
+ * only makes sense once the operator has navigated to one particular section: it sits on its own cache
21
+ * key, is never polled, fetches at most once per visit and unmounts with this subtree. The draft still
22
+ * belongs to the card, so this cannot replace a value under a half-typed field.
17
23
  */
18
24
  export interface ConfigurationSurfaceProps {
19
25
  open: boolean;
20
26
  onClose: () => void;
21
27
  /** Named in the header, because the settings behind it belong to one instance and not the next. */
22
28
  instanceName: string;
29
+ /**
30
+ * The instance the catalog read addresses (feature chat-model-catalog). A PROP rather than a
31
+ * registry subscription: everything else here is prop-driven, and subscribing re-rendered this
32
+ * subtree during an instance switch instead of letting it unmount, so it could paint one pass
33
+ * addressing the new instance while every other prop still described the old one.
34
+ */
35
+ instance: InstanceConfig | null;
23
36
  settings: readonly SettingREST[];
24
37
  pendingRestart: readonly PendingRestartREST[];
25
38
  observability: ObservabilityConfigREST;
@@ -38,5 +51,13 @@ export interface ConfigurationSurfaceProps {
38
51
  isRowDisabled: (key: string) => boolean;
39
52
  /** A blanked numeric field the server would refuse the whole batch over, if there is one. */
40
53
  blankNumericKey?: string;
54
+ /**
55
+ * The chat gateway's RUNNING state (feature chat-model-catalog), absent or null when the instance
56
+ * reports none. Two facts live only here: whether chat is on at all, and which backend is actually
57
+ * serving. Neither is derivable from the inventory - Fallen8:Chat:Enabled is never-writable so its
58
+ * value is withheld, and the Backend descriptor publishes the STORED value, which after a write is
59
+ * the pending one. The picker follows what is running.
60
+ */
61
+ chat?: ChatProviderStatsREST | null;
41
62
  }
42
63
  export declare function ConfigurationSurface(props: ConfigurationSurfaceProps): import("react").JSX.Element;
@@ -1,6 +1,12 @@
1
1
  /**
2
2
  * Every failed request shows HTTP status + server message (NFR: never a silent console
3
3
  * error). A network-level failure renders as the disconnected state with a retry.
4
+ *
5
+ * The fallback title is deliberately NOT about requests. This box also renders throws from the
6
+ * client side of a mutation, where no request was made at all: an integration submit that could
7
+ * not build its body reported "Request failed / Invalid string length", which sent the reader
8
+ * looking for a server fault that did not exist. A title is a claim, so the generic one claims
9
+ * only what is always true.
4
10
  */
5
11
  export declare function ErrorBox({ error, onRetry }: {
6
12
  error: unknown;
@@ -1,4 +1,5 @@
1
1
  import { type SemanticDraft } from "../lib/semantic";
2
+ import type { EmbeddingProviderStatsREST } from "../api/types";
2
3
  /**
3
4
  * The Path screen's declarative semantic block (feature element-embeddings): the shared
4
5
  * query core (SemanticQueryEditor) plus the block-local minScore filter and
@@ -11,7 +12,7 @@ import { type SemanticDraft } from "../lib/semantic";
11
12
  * Controlled: the parent owns the SemanticDraft and derives which delegate slots to
12
13
  * disable from semanticOwnsVertex{Filter,Cost}.
13
14
  */
14
- export declare function SemanticBlockEditor({ draft, onChange, allowCost, costDisabledReason, providerEnabled, embeddingNames, idPrefix, disabled, disabledReason, }: {
15
+ export declare function SemanticBlockEditor({ draft, onChange, allowCost, costDisabledReason, providerEnabled, provider, embeddingNames, idPrefix, disabled, disabledReason, }: {
15
16
  draft: SemanticDraft;
16
17
  onChange: (patch: Partial<SemanticDraft>) => void;
17
18
  /** costBySimilarity is a path concept; false disables the cost slot entirely. */
@@ -21,6 +22,8 @@ export declare function SemanticBlockEditor({ draft, onChange, allowCost, costDi
21
22
  costDisabledReason?: string;
22
23
  /** Resolved provider state; null = unknown (no graph shape computed yet). */
23
24
  providerEnabled: boolean | null;
25
+ /** Passed straight to SemanticQueryEditor, which documents it. */
26
+ provider?: EmbeddingProviderStatsREST | null;
24
27
  embeddingNames: string[];
25
28
  idPrefix: string;
26
29
  /** e.g. a stored template is selected — the block cannot apply. */
@@ -1,15 +1,22 @@
1
1
  import type { SemanticQueryDraft } from "../lib/semantic";
2
+ import type { EmbeddingProviderStatsREST } from "../api/types";
2
3
  /**
3
4
  * The semantic QUERY fields (source, vector/text, embedding name, metric) — the one query
4
5
  * every semantic decision of a request scores against. Extracted so the Path screen's
5
6
  * block editor and the Subgraph screen's per-request query section render exactly one
6
7
  * implementation. Pure data — it compiles no C#.
7
8
  */
8
- export declare function SemanticQueryEditor({ query, onChange, providerEnabled, embeddingNames, idPrefix, }: {
9
+ export declare function SemanticQueryEditor({ query, onChange, providerEnabled, provider, embeddingNames, idPrefix, }: {
9
10
  query: SemanticQueryDraft;
10
11
  onChange: (patch: Partial<SemanticQueryDraft>) => void;
11
12
  /** Resolved provider state; null = unknown (no graph shape computed yet). */
12
13
  providerEnabled: boolean | null;
14
+ /**
15
+ * The provider snapshot behind {@link providerEnabled}, when the caller holds it: it names the
16
+ * backend and embedding function that will turn the text into a vector. Optional, so a call
17
+ * site that cannot answer that question simply says nothing.
18
+ */
19
+ provider?: EmbeddingProviderStatsREST | null;
13
20
  embeddingNames: string[];
14
21
  idPrefix: string;
15
22
  }): import("react").JSX.Element;
@@ -1,4 +1,10 @@
1
1
  import type { SettingREST } from "../api/types";
2
+ /** One value a string row can OFFER without requiring it (feature chat-model-catalog). */
3
+ export interface SettingSuggestion {
4
+ value: string;
5
+ /** What is known about it, shown beside the value; omitted when nothing is known. */
6
+ label?: string;
7
+ }
2
8
  export declare const SettingRow: import("react").NamedExoticComponent<{
3
9
  setting: SettingREST;
4
10
  /** The unsaved value, or undefined when this row is untouched. */
@@ -7,4 +13,12 @@ export declare const SettingRow: import("react").NamedExoticComponent<{
7
13
  onClear: (key: string) => void;
8
14
  /** True when the whole editable region is gated off (an embed host locked it). */
9
15
  disabled?: boolean;
16
+ /**
17
+ * Values to offer on a `string` row, as a native combobox. OFFER is the whole contract: a typed
18
+ * value outside the list is not an error, because for a model name the list is not the whole
19
+ * resolvable set. Absent (or empty) leaves the row exactly as it was.
20
+ */
21
+ suggestions?: readonly SettingSuggestion[];
22
+ /** One line under the control, for whoever supplied the suggestions to say why it could not. */
23
+ note?: string;
10
24
  }>;
@@ -0,0 +1,13 @@
1
+ import type { NlGenerationStats } from "./generate";
2
+ /**
3
+ * One draft's generation stats (nl-assist-ux FR-5), the row UNDER the draft label: the summary
4
+ * line plus the provider's raw fields on demand. Both NL panels render this one component, so
5
+ * the formatter and the markup have a single home.
6
+ *
7
+ * The backend segment is whatever the stats object captured with THIS draft carries, never the
8
+ * live configuration (see lib/modelProvenance.ts). The row sits BELOW the label, not beside it:
9
+ * a same-row block costs the label width the panel's 288px sidebar does not have.
10
+ */
11
+ export declare function NlDraftStats({ stats }: {
12
+ stats: NlGenerationStats;
13
+ }): import("react").JSX.Element;
@@ -26,10 +26,11 @@ export interface NlAssistConfig {
26
26
  maxRetries: number;
27
27
  }
28
28
  /**
29
- * The default model the compose stack pulls for the instance's chat backend (produced by
30
- * nl-assist-finetune). Shown as a hint only; in instance mode the server owns the model, and
31
- * in custom mode the user picks one (see NL_PRESETS). If the chosen model is absent on the
32
- * backend, calls 404 - create it with the training pipeline or pick the stock phi4-mini preset.
29
+ * CUSTOM-MODE ONLY: the prefill for the model field, and the fine-tune the compose stack pulls
30
+ * (produced by nl-assist-finetune). It says nothing about instance mode - the server owns that
31
+ * model and reports it on /status, which is where the panels read it from. If the chosen model is
32
+ * absent on the endpoint, calls 404 - create it with the training pipeline or pick the stock
33
+ * phi4-mini preset.
33
34
  */
34
35
  export declare const DEFAULT_NL_MODEL = "phi4-f8-mini";
35
36
  export declare const DEFAULT_NL_CONFIG: NlAssistConfig;
@@ -34,6 +34,12 @@ export interface NlGenerationStats {
34
34
  completionTokens?: number;
35
35
  durationMs?: number;
36
36
  tokensPerSecond?: number;
37
+ /**
38
+ * Which server-side backend produced THIS draft, from that call's own response. Undefined in
39
+ * custom mode, deliberately: a browser-direct call reaches no Fallen-8, so there is no server
40
+ * selector to report and inventing one would sit a fabricated name beside real ones.
41
+ */
42
+ backend?: string;
37
43
  /** The provider's stats fields verbatim, for the expandable raw view. */
38
44
  raw: Record<string, unknown>;
39
45
  }
@@ -20,7 +20,7 @@ export declare const FIELD_HELP: {
20
20
  readonly lookupKind: "What the id refers to: vertex, edge, or graphelement (either — the server figures out which).";
21
21
  readonly maxElements: "Upper bound on how many elements the bulk view loads from GET /graph. Keep it modest on big graphs — this is a browser, not an export (use JSONL export for that).";
22
22
  readonly bulkFilter: "Client-side filter over the loaded elements: matches an exact id or a substring of the label.";
23
- readonly scanKind: "Property scan walks all elements (no index needed); 'ask an index' picks a registered index and offers the query forms its type answers.";
23
+ readonly scanKind: "Property scan walks all elements (no index needed); 'ask an index' picks a registered index and offers the query forms its type answers; 'semantic search' types words instead, and the embedding provider turns them into the query vector.";
24
24
  readonly propertyScope: "Specific key: scan one named property with an operator and typed literal. Any property: a case-insensitive substring search across EVERY property value (numbers and dates included, compared as text) - a cold, un-indexed full-graph discovery scan.";
25
25
  readonly searchTerm: "The substring to look for across every property value, case-insensitively. An element matches when any of its values contains it.";
26
26
  readonly searchLabel: "Optional: restrict the search to elements with exactly this label. Leave empty to search every label.";
@@ -50,6 +50,8 @@ export declare const FIELD_HELP: {
50
50
  readonly vectorBindEmbeddingName: "Optional: bind this vector index to a named element embedding. A bound index maintains itself as a projection of that embedding — you write embeddings on the elements and the index follows; explicit vector-adds are rejected. Leave empty for a raw (bring-your-own-vector) index.";
51
51
  readonly vectorModel: "Optional model-identity string this index expects its vectors to come from (e.g. 'bge-micro-v2#384#Cosine'). The embedding provider refuses to write mismatched vectors; a search whose provider identity differs answers 409. Diagnostic only for a raw index.";
52
52
  readonly embeddingSearchText: "Search text. The embedding provider embeds it once (server-side), then runs kNN — you never handle the vector. Needs the provider enabled on this instance.";
53
+ readonly semanticIndexId: "The vector index the search ranks against. The list is narrowed to the indices that report the vector family, since only they hold vectors to rank; one bound to an embedding name projects that embedding off your elements and maintains itself.";
54
+ readonly semanticBindEmbedding: "Required here, unlike on the Indexes screen: this index exists so a typed query can rank the embeddings ALREADY on your elements, and only a bound index projects them. Name the embedding they carry ('default' unless you chose otherwise). An unbound index would hold nothing until you pasted vectors into it by hand.";
53
55
  readonly embeddingName: "Name of the embedding to read/write on this element, e.g. 'default'. Letters, digits, underscore, dash; max 64 chars. Different names hold independent vectors (and may differ in dimension).";
54
56
  readonly embeddingVectorPaste: "The embedding vector, pasted as a JSON array or comma-separated floats. The element is the source of truth; any vector index bound to this name updates automatically on save.";
55
57
  readonly embeddingText: "Text to embed onto this element via the server's embedding provider (stored with a model-identity stamp). Needs the provider enabled; otherwise paste a vector.";
@@ -0,0 +1,69 @@
1
+ import type { FileLimits } from "../api/types";
2
+ /**
3
+ * Whether a job's files fit what THIS instance accepts, checked at pick time (feature
4
+ * integration-file-transport).
5
+ *
6
+ * This module is the only place in Studio allowed to reason about file ceilings, and it holds no
7
+ * numbers of its own. Every ceiling arrives from `GET /integrations/limits` already reconciled with
8
+ * the proxy's transport bound, so there is one number per question and nothing to combine. That
9
+ * matters because the version this replaced had a ceiling of its own, about 384 MiB, which sat
10
+ * BELOW the instance's: jobs the instance would have accepted were refused in the browser, and no
11
+ * amount of configuration could fix it.
12
+ *
13
+ * The corollary is the rule for the unknown case. An instance too old to serve the route, or one
14
+ * whose integrations capability is off, leaves the limits undefined, and then NOTHING is checked
15
+ * and nothing is guessed: the send goes ahead and the instance refuses it if it must. A default
16
+ * substituted here would be the same bug again.
17
+ */
18
+ /** Enough of a file to check it, whichever transport carries it later. */
19
+ export interface SizedFile {
20
+ name: string;
21
+ size: number;
22
+ }
23
+ /**
24
+ * The ceilings, or their absence. Absence has three spellings and they all mean the same thing
25
+ * here: the query has not answered yet, it failed, or the instance answered with no body.
26
+ */
27
+ export type MaybeLimits = FileLimits | null | undefined;
28
+ /**
29
+ * What one file setting is being asked to hold, and what the rest of the job already holds.
30
+ *
31
+ * Generic over the incoming type, so a caller passing real `File` handles gets `File`s back with no
32
+ * cast. That is not cosmetic: it is what makes "this only ever filters, it never constructs" a fact
33
+ * the compiler holds rather than a comment somebody has to keep true.
34
+ */
35
+ export interface StagingRequest<T extends SizedFile = SizedFile> {
36
+ /** The ceilings this instance published, or absent when they could not be read. */
37
+ limits: MaybeLimits;
38
+ /** The files being added to ONE file setting, in the order they were picked. */
39
+ incoming: T[];
40
+ /** What that setting already holds. Kept whatever this verdict says. */
41
+ staged?: SizedFile[];
42
+ /** What every OTHER file setting of the same job holds: the total and the count are job-wide. */
43
+ elsewhere?: SizedFile[];
44
+ /** True when the setting declares `multiple`, so its files are read as ONE claimed set. */
45
+ claimedSet?: boolean;
46
+ }
47
+ export interface StagingVerdict<T extends SizedFile = SizedFile> {
48
+ /** The incoming files that may be staged, in pick order. */
49
+ accepted: T[];
50
+ /** One message for the setting's problem channel, or null when there is nothing to say. */
51
+ problem: string | null;
52
+ }
53
+ /**
54
+ * The refusal that keeps a set out of the tab before it is ever sent.
55
+ *
56
+ * Granularity differs between the three ceilings on purpose. A file over the per-file ceiling is
57
+ * individually too big, so it is refused individually and its siblings still stage. A broken TOTAL
58
+ * or COUNT is a property of the whole job, so no single file is at fault and none of the incoming
59
+ * batch is accepted: picking some arbitrary prefix that fits would drop the tail on a decision the
60
+ * person picking never made, and for a claimed set it would silently split the set.
61
+ */
62
+ export declare function checkStaging<T extends SizedFile>(request: StagingRequest<T>): StagingVerdict<T>;
63
+ /**
64
+ * What the form says when it could not read the ceilings. Its job is to stop someone reading the
65
+ * absence of refusals as approval, without naming a number Studio does not know.
66
+ */
67
+ export declare const LIMITS_UNKNOWN_NOTE: string;
68
+ /** The ceilings in one line, for the form to state up front rather than only when refusing. */
69
+ export declare function describeLimits(limits: MaybeLimits): string;
@@ -2,6 +2,14 @@
2
2
  export declare function formatCompact(value: number): string;
3
3
  /** Full number with grouping, for exact values ("10,001,000"). */
4
4
  export declare function formatExact(value: number): string;
5
+ /**
6
+ * A size in bytes, in binary units up to GiB ("0 B", "512 B", "1.5 KiB", "5.8 GiB").
7
+ *
8
+ * GiB and not MiB because two callers need it: a save-game registry, and the refusal that tells
9
+ * someone their 5983 MiB of files is over the ceiling. Reporting that as "5983.0 MiB" is arithmetic
10
+ * the reader should not have to do while being told no.
11
+ */
12
+ export declare function formatBytes(bytes: number): string;
5
13
  /**
6
14
  * The one glyph this UI renders for a value the server does not have, so a row cannot mix two
7
15
  * spellings of "absent" in one table and read as two different states.
@@ -0,0 +1,26 @@
1
+ import type { ChatProviderStatsREST, EmbeddingProviderStatsREST } from "../api/types";
2
+ /**
3
+ * How Studio names the model backend that serves a request (feature model-providers).
4
+ *
5
+ * Two kinds of label, and the distinction is the feature:
6
+ * - AMBIENT ("requests will go to X") reads the polled /status block, which describes the
7
+ * CURRENT configuration. {@link chatAmbientLabel} is named so a call site cannot use it by
8
+ * accident where a per-call answer belongs.
9
+ * - PER-CALL reads the `backend` field carried on that call's own response. A draft produced
10
+ * under one backend must keep saying so after the operator switches, so nothing per-call may
11
+ * be derived from here.
12
+ *
13
+ * Neither function invents a name it cannot know: an absent field yields a sentence saying the
14
+ * value is absent, never a plausible default.
15
+ */
16
+ /**
17
+ * The ambient chat destination: `"{backend} · {model}"`, or the reason there is no pair to show.
18
+ * `undefined` means /status has not answered yet, which is a different thing from chat being off.
19
+ */
20
+ export declare function chatAmbientLabel(chat: ChatProviderStatsREST | null | undefined): string;
21
+ /**
22
+ * The embedding function's identity as a reader recognises it: `modelName[@modelVersion]`.
23
+ * A provider that reports no model name is described by its dimension instead, because that is
24
+ * the one property of the vector space still known to be true.
25
+ */
26
+ export declare function embeddingStamp(provider: EmbeddingProviderStatsREST): string;