@executor-js/plugin-openapi 1.5.16 → 1.5.18

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 (28) hide show
  1. package/dist/{AddOpenApiSource-U7AYB224.js → AddOpenApiSource-IBZQRCTW.js} +4 -4
  2. package/dist/{OpenApiAccountsPanel-GHFHHE6P.js → OpenApiAccountsPanel-U47OVLYG.js} +3 -3
  3. package/dist/{UpdateSpecSection-PLCBUU4I.js → UpdateSpecSection-FFYVB3VH.js} +3 -3
  4. package/dist/{chunk-CPPTKUOW.js → chunk-2RNIMASA.js} +2 -2
  5. package/dist/{chunk-CKBX4SXK.js → chunk-5IDND4UF.js} +2 -2
  6. package/dist/{chunk-3FM2SWM4.js → chunk-ELCKZJE4.js} +236 -210
  7. package/dist/chunk-ELCKZJE4.js.map +1 -0
  8. package/dist/{chunk-KVPUDOJZ.js → chunk-R3X27XS6.js} +587 -77
  9. package/dist/chunk-R3X27XS6.js.map +1 -0
  10. package/dist/client.js +3 -3
  11. package/dist/core.js +27 -3
  12. package/dist/core.js.map +1 -1
  13. package/dist/index.js +3 -3
  14. package/dist/sdk/backing.d.ts +91 -1
  15. package/dist/sdk/definitions.d.ts +33 -1
  16. package/dist/sdk/extract.d.ts +66 -0
  17. package/dist/sdk/index.d.ts +3 -2
  18. package/dist/sdk/request-user-agent.test.d.ts +1 -0
  19. package/dist/sdk/split.d.ts +84 -0
  20. package/dist/sdk/store.d.ts +19 -0
  21. package/package.json +3 -3
  22. package/dist/chunk-3FM2SWM4.js.map +0 -1
  23. package/dist/chunk-KVPUDOJZ.js.map +0 -1
  24. /package/dist/{AddOpenApiSource-U7AYB224.js.map → AddOpenApiSource-IBZQRCTW.js.map} +0 -0
  25. /package/dist/{OpenApiAccountsPanel-GHFHHE6P.js.map → OpenApiAccountsPanel-U47OVLYG.js.map} +0 -0
  26. /package/dist/{UpdateSpecSection-PLCBUU4I.js.map → UpdateSpecSection-FFYVB3VH.js.map} +0 -0
  27. /package/dist/{chunk-CPPTKUOW.js.map → chunk-2RNIMASA.js.map} +0 -0
  28. /package/dist/{chunk-CKBX4SXK.js.map → chunk-5IDND4UF.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  deriveAuthenticationTemplateFromPreview,
3
3
  firstBaseUrlForPreview
4
- } from "./chunk-CKBX4SXK.js";
4
+ } from "./chunk-5IDND4UF.js";
5
5
  import {
6
6
  openApiPresets
7
7
  } from "./chunk-QQFCICLX.js";
@@ -11,13 +11,19 @@ import {
11
11
  OpenApiInvocationError,
12
12
  OpenApiParseError,
13
13
  OperationBinding,
14
+ buildInputSchema,
15
+ compileToolDefinitions,
14
16
  extract,
15
17
  normalizeOpenApiAuthInputs,
16
18
  parse,
19
+ parseEntry,
17
20
  previewSpecText,
18
21
  resolveServerUrl,
19
- resolveSpecText
20
- } from "./chunk-KVPUDOJZ.js";
22
+ resolveSpecText,
23
+ streamOperationBindings,
24
+ streamOperationBindingsFromStructure,
25
+ structuralSplit
26
+ } from "./chunk-R3X27XS6.js";
21
27
 
22
28
  // src/sdk/config.ts
23
29
  import { Option, Schema } from "effect";
@@ -78,7 +84,12 @@ var toJsonRecord = (value) => value;
78
84
  var OperationStorage = Schema2.Struct({
79
85
  integration: Schema2.String,
80
86
  toolName: Schema2.String,
81
- binding: Schema2.Unknown
87
+ binding: Schema2.Unknown,
88
+ // Resolved tool description (operation description / summary / method+path
89
+ // fallback), persisted so the serve path can rebuild the tool def without
90
+ // re-parsing the spec. Optional: legacy rows predate it and resolve via the
91
+ // parse fallback.
92
+ description: Schema2.optional(Schema2.String)
82
93
  });
83
94
  var decodeOperationStorage = Schema2.decodeUnknownOption(OperationStorage);
84
95
  var rowToOperation = (row) => {
@@ -90,7 +101,8 @@ var rowToOperation = (row) => {
90
101
  toolName: operation.toolName,
91
102
  binding: decodeBinding(
92
103
  typeof operation.binding === "string" ? decodeBindingJson(operation.binding) : operation.binding
93
- )
104
+ ),
105
+ ...operation.description !== void 0 ? { description: operation.description } : {}
94
106
  };
95
107
  };
96
108
  var stableKeyHash = (value) => {
@@ -106,11 +118,13 @@ var stableKeyHash = (value) => {
106
118
  var operationKey = (integration, toolName) => `${OPERATION_KEY_VERSION}.${stableKeyHash(integration)}.${stableKeyHash(toolName)}`;
107
119
  var legacyOperationKey = (integration, toolName) => `${integration}.${toolName}`;
108
120
  var specBlobKey = (specHash) => `spec/${specHash}`;
121
+ var defsBlobKey = (specHash) => `defs/${specHash}`;
109
122
  var makeDefaultOpenapiStore = ({ pluginStorage, blobs }) => {
110
123
  const operationData = (operation) => ({
111
124
  integration: operation.integration,
112
125
  toolName: operation.toolName,
113
- binding: toJsonRecord(encodeBinding(operation.binding))
126
+ binding: toJsonRecord(encodeBinding(operation.binding)),
127
+ ...operation.description !== void 0 ? { description: operation.description } : {}
114
128
  });
115
129
  const listRows = (integration) => pluginStorage.list({ collection: OPERATION_COLLECTION }).pipe(
116
130
  Effect.map(
@@ -124,18 +138,20 @@ var makeDefaultOpenapiStore = ({ pluginStorage, blobs }) => {
124
138
  entries: rows.map((row) => ({ collection: OPERATION_COLLECTION, key: row.key }))
125
139
  });
126
140
  });
141
+ const appendOperations = (integration, operations) => pluginStorage.putMany({
142
+ owner: STORE_OWNER,
143
+ entries: operations.map((operation) => ({
144
+ collection: OPERATION_COLLECTION,
145
+ key: operationKey(integration, operation.toolName),
146
+ data: operationData(operation)
147
+ }))
148
+ });
127
149
  return {
128
150
  putOperations: (integration, operations) => Effect.gen(function* () {
129
151
  yield* removeOperations(integration);
130
- yield* pluginStorage.putMany({
131
- owner: STORE_OWNER,
132
- entries: operations.map((operation) => ({
133
- collection: OPERATION_COLLECTION,
134
- key: operationKey(integration, operation.toolName),
135
- data: operationData(operation)
136
- }))
137
- });
152
+ yield* appendOperations(integration, operations);
138
153
  }),
154
+ appendOperations,
139
155
  getOperation: (integration, toolName) => Effect.gen(function* () {
140
156
  const row = yield* pluginStorage.get({
141
157
  collection: OPERATION_COLLECTION,
@@ -155,7 +171,9 @@ var makeDefaultOpenapiStore = ({ pluginStorage, blobs }) => {
155
171
  ),
156
172
  removeOperations,
157
173
  putSpec: (specHash, specText) => blobs.put(specBlobKey(specHash), specText, { owner: STORE_OWNER }),
158
- getSpec: (specHash) => blobs.get(specBlobKey(specHash))
174
+ getSpec: (specHash) => blobs.get(specBlobKey(specHash)),
175
+ putDefs: (specHash, defsJson) => blobs.put(defsBlobKey(specHash), defsJson, { owner: STORE_OWNER }),
176
+ getDefs: (specHash) => blobs.get(defsBlobKey(specHash))
159
177
  };
160
178
  };
161
179
 
@@ -236,6 +254,7 @@ var resolvePath = Effect2.fn("OpenApi.resolvePath")(function* (pathTemplate, arg
236
254
  }
237
255
  return resolved;
238
256
  });
257
+ var DEFAULT_USER_AGENT = "executor";
239
258
  var applyHeaders = (request, headers) => {
240
259
  let req = request;
241
260
  for (const [name, value] of Object.entries(headers)) {
@@ -535,6 +554,7 @@ var invoke = Effect2.fn("OpenApi.invoke")(function* (operation, args, resolvedHe
535
554
  const resolvedPath = yield* resolvePath(operation.pathTemplate, args, operation.parameters);
536
555
  const path = resolvedPath.startsWith("/") ? resolvedPath : `/${resolvedPath}`;
537
556
  let request = HttpClientRequest.make(operation.method.toUpperCase())(path);
557
+ request = HttpClientRequest.setHeader(request, "User-Agent", DEFAULT_USER_AGENT);
538
558
  for (const [name, value] of Object.entries(sourceQueryParams)) {
539
559
  request = HttpClientRequest.setUrlParam(request, name, value);
540
560
  }
@@ -654,160 +674,13 @@ var annotationsForOperation = (method, pathTemplate) => {
654
674
  };
655
675
 
656
676
  // src/sdk/backing.ts
657
- import { Effect as Effect3, Option as Option5, Schema as Schema3 } from "effect";
677
+ import { Effect as Effect3, Option as Option4, Schema as Schema3 } from "effect";
658
678
  import {
659
679
  ToolFileJsonSchema,
660
680
  ToolName,
661
681
  ToolResult,
662
682
  authToolFailure
663
683
  } from "@executor-js/sdk/core";
664
-
665
- // src/sdk/definitions.ts
666
- import { Option as Option4 } from "effect";
667
- var splitWords = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z0-9]+)/g, "$1 $2").replace(/[^a-zA-Z0-9]+/g, " ").trim().split(/\s+/).filter((part) => part.length > 0);
668
- var normalizeWord = (value) => value.toLowerCase();
669
- var toCamelCase = (value) => {
670
- const words = splitWords(value).map(normalizeWord);
671
- if (words.length === 0) return "tool";
672
- const [first, ...rest] = words;
673
- return `${first}${rest.map((p) => `${p[0]?.toUpperCase() ?? ""}${p.slice(1)}`).join("")}`;
674
- };
675
- var toPascalCase = (value) => {
676
- const camel = toCamelCase(value);
677
- return `${camel[0]?.toUpperCase() ?? ""}${camel.slice(1)}`;
678
- };
679
- var VERSION_SEGMENT_REGEX = /^v\d+(?:[._-]\d+)?$/i;
680
- var IGNORED_PATH_SEGMENTS = /* @__PURE__ */ new Set(["api"]);
681
- var pathSegmentsFromTemplate = (pathTemplate) => pathTemplate.split("/").map((s) => s.trim()).filter((s) => s.length > 0);
682
- var isPathParameterSegment = (segment) => segment.startsWith("{") && segment.endsWith("}");
683
- var normalizeGroupSegment = (value) => {
684
- const candidate = value?.trim();
685
- if (!candidate) return null;
686
- return toCamelCase(candidate);
687
- };
688
- var deriveVersionSegment = (pathTemplate) => pathSegmentsFromTemplate(pathTemplate).map((s) => s.toLowerCase()).find((s) => VERSION_SEGMENT_REGEX.test(s));
689
- var derivePathGroup = (pathTemplate) => {
690
- for (const segment of pathSegmentsFromTemplate(pathTemplate)) {
691
- const lower = segment.toLowerCase();
692
- if (VERSION_SEGMENT_REGEX.test(lower)) continue;
693
- if (IGNORED_PATH_SEGMENTS.has(lower)) continue;
694
- if (isPathParameterSegment(segment)) continue;
695
- return normalizeGroupSegment(segment) ?? "root";
696
- }
697
- return "root";
698
- };
699
- var splitOperationIdSegments = (value) => value.split(/[/.]+/).map((s) => s.trim()).filter((s) => s.length > 0);
700
- var deriveLeafSeed = (operationId, group) => {
701
- const segments = splitOperationIdSegments(operationId);
702
- if (segments.length > 1) {
703
- const [first, ...rest] = segments;
704
- if ((normalizeGroupSegment(first) ?? first) === group && rest.length > 0) {
705
- return rest.join(" ");
706
- }
707
- }
708
- return operationId;
709
- };
710
- var fallbackLeafSeed = (method, pathTemplate, group) => {
711
- const relevantSegments = pathSegmentsFromTemplate(pathTemplate).filter((s) => !VERSION_SEGMENT_REGEX.test(s.toLowerCase())).filter((s) => !IGNORED_PATH_SEGMENTS.has(s.toLowerCase())).filter((s) => !isPathParameterSegment(s)).map((s) => normalizeGroupSegment(s) ?? s).filter((s) => s !== group);
712
- const segmentSuffix = relevantSegments.map((s) => toPascalCase(s)).join("");
713
- return `${method}${segmentSuffix || "Operation"}`;
714
- };
715
- var deriveLeaf = (operationId, method, pathTemplate, group) => {
716
- const preferred = toCamelCase(deriveLeafSeed(operationId, group));
717
- if (preferred.length > 0 && preferred !== group) return preferred;
718
- return toCamelCase(fallbackLeafSeed(method, pathTemplate, group));
719
- };
720
- var resolveCollisions = (definitions) => {
721
- const staged = definitions.map((d) => ({ ...d }));
722
- const applyFactory = (items, factory) => {
723
- const byPath = /* @__PURE__ */ new Map();
724
- for (const item of items) {
725
- const bucket = byPath.get(item.toolPath) ?? [];
726
- bucket.push(item);
727
- byPath.set(item.toolPath, bucket);
728
- }
729
- for (const bucket of byPath.values()) {
730
- if (bucket.length < 2) continue;
731
- for (const d of bucket) {
732
- d.toolPath = factory(d);
733
- }
734
- }
735
- };
736
- applyFactory(
737
- staged,
738
- (d) => d.versionSegment ? `${d.group}.${d.versionSegment}.${d.leaf}` : d.toolPath
739
- );
740
- applyFactory(staged, (d) => {
741
- const prefix = d.versionSegment ? `${d.group}.${d.versionSegment}` : d.group;
742
- return `${prefix}.${d.leaf}${toPascalCase(d.method)}`;
743
- });
744
- applyFactory(staged, (d) => {
745
- const prefix = d.versionSegment ? `${d.group}.${d.versionSegment}` : d.group;
746
- return `${prefix}.${d.leaf}${toPascalCase(d.method)}${d.operationHash.slice(0, 8)}`;
747
- });
748
- return staged.map((d) => ({
749
- toolPath: d.toolPath,
750
- group: d.group,
751
- leaf: d.leaf,
752
- operationIndex: d.operationIndex,
753
- operation: d.operation
754
- }));
755
- };
756
- var stableHash = (value) => {
757
- const str = JSON.stringify(value, Object.keys(value).sort());
758
- let hash = 0;
759
- for (let i = 0; i < str.length; i++) {
760
- hash = (hash << 5) - hash + str.charCodeAt(i) | 0;
761
- }
762
- return Math.abs(hash).toString(36).padStart(8, "0");
763
- };
764
- var compileToolDefinitions = (operations) => {
765
- const raw = operations.map((op, index) => {
766
- const operationId = op.operationId;
767
- const explicitToolPath = Option4.getOrUndefined(op.toolPath);
768
- if (explicitToolPath) {
769
- const [group2 = "root", ...leafParts] = explicitToolPath.split(".").filter(Boolean);
770
- const leaf2 = leafParts.join(".") || group2;
771
- const versionSegment2 = deriveVersionSegment(op.pathTemplate);
772
- const operationHash2 = stableHash({
773
- method: op.method,
774
- path: op.pathTemplate,
775
- operationId
776
- });
777
- return {
778
- toolPath: explicitToolPath,
779
- group: group2,
780
- leaf: leaf2,
781
- versionSegment: versionSegment2,
782
- method: op.method,
783
- operationHash: operationHash2,
784
- operationIndex: index,
785
- operation: op
786
- };
787
- }
788
- const group = normalizeGroupSegment(op.tags[0]) ?? derivePathGroup(op.pathTemplate);
789
- const leaf = deriveLeaf(operationId, op.method, op.pathTemplate, group);
790
- const versionSegment = deriveVersionSegment(op.pathTemplate);
791
- const operationHash = stableHash({
792
- method: op.method,
793
- path: op.pathTemplate,
794
- operationId
795
- });
796
- return {
797
- toolPath: `${group}.${leaf}`,
798
- group,
799
- leaf,
800
- versionSegment,
801
- method: op.method,
802
- operationHash,
803
- operationIndex: index,
804
- operation: op
805
- };
806
- });
807
- return resolveCollisions(raw).sort((a, b) => a.toolPath.localeCompare(b.toolPath));
808
- };
809
-
810
- // src/sdk/backing.ts
811
684
  var STRINGIFIED_BODY_CAP = 1024;
812
685
  var UpstreamMessageBody = Schema3.Struct({ message: Schema3.String });
813
686
  var UpstreamErrorMessageBody = Schema3.Struct({ errorMessage: Schema3.String });
@@ -845,11 +718,11 @@ var extractOpenApiUpstreamMessage = (body, status) => {
845
718
  if (typeof body === "string") {
846
719
  return body.length > 0 ? body : `Upstream returned HTTP ${status}`;
847
720
  }
848
- const nested = Option5.getOrUndefined(decodeUpstreamNestedErrorBody(body));
849
- const messageBody = Option5.getOrUndefined(decodeUpstreamMessageBody(body));
850
- const errorMessageBody = Option5.getOrUndefined(decodeUpstreamErrorMessageBody(body));
851
- const errorsBody = Option5.getOrUndefined(decodeUpstreamErrorsArrayBody(body));
852
- const descriptionBody = Option5.getOrUndefined(decodeUpstreamDescriptionBody(body));
721
+ const nested = Option4.getOrUndefined(decodeUpstreamNestedErrorBody(body));
722
+ const messageBody = Option4.getOrUndefined(decodeUpstreamMessageBody(body));
723
+ const errorMessageBody = Option4.getOrUndefined(decodeUpstreamErrorMessageBody(body));
724
+ const errorsBody = Option4.getOrUndefined(decodeUpstreamErrorsArrayBody(body));
725
+ const descriptionBody = Option4.getOrUndefined(decodeUpstreamDescriptionBody(body));
853
726
  const arrayMessage = errorsBody?.errors.map(
854
727
  ({
855
728
  detail,
@@ -924,11 +797,15 @@ var toBinding = (def) => OperationBinding.make({
924
797
  });
925
798
  var descriptionFor = (def) => {
926
799
  const op = def.operation;
927
- return Option5.getOrElse(
800
+ return Option4.getOrElse(
928
801
  op.description,
929
- () => Option5.getOrElse(op.summary, () => `${op.method.toUpperCase()} ${op.pathTemplate}`)
802
+ () => Option4.getOrElse(op.summary, () => `${op.method.toUpperCase()} ${op.pathTemplate}`)
930
803
  );
931
804
  };
805
+ var FILE_OUTPUT_HINT = `Returns a ToolFile: the file bytes already decoded into { _tag: "ToolFile", mimeType, encoding, data, byteLength }. To display or forward it, pass the result's data straight to emit(result.data). Do not rebuild the envelope or read upstream fields like size.`;
806
+ var withFileEmitHint = (description, returnsFile) => returnsFile ? `${description}
807
+
808
+ ${FILE_OUTPUT_HINT}` : description;
932
809
  var compileOpenApiDocument = (doc) => Effect3.gen(function* () {
933
810
  const result = yield* extract(doc);
934
811
  const hoistedDefs = {};
@@ -940,38 +817,181 @@ var compileOpenApiDocument = (doc) => Effect3.gen(function* () {
940
817
  return {
941
818
  definitions: compileToolDefinitions(result.operations),
942
819
  hoistedDefs,
943
- title: Option5.getOrUndefined(result.title),
944
- description: Option5.getOrUndefined(result.description)
820
+ title: Option4.getOrUndefined(result.title),
821
+ description: Option4.getOrUndefined(result.description)
945
822
  };
946
823
  });
947
824
  var compileOpenApiSpec = (specText) => Effect3.gen(function* () {
948
825
  const doc = yield* parse(specText);
949
826
  return yield* compileOpenApiDocument(doc);
950
827
  });
951
- var openApiToolDefsFromCompiled = (compiled) => compiled.definitions.map(
952
- (def) => ({
828
+ var openApiToolDefsFromCompiled = (compiled) => compiled.definitions.map((def) => {
829
+ const returnsFile = Option4.match(def.operation.responseBody, {
830
+ onNone: () => false,
831
+ onSome: (responseBody) => Option4.isSome(responseBody.fileHint)
832
+ });
833
+ return {
953
834
  name: ToolName.make(def.toolPath),
954
- description: descriptionFor(def),
955
- inputSchema: normalizeOpenApiRefs(Option5.getOrUndefined(def.operation.inputSchema)),
956
- outputSchema: Option5.match(def.operation.responseBody, {
957
- onNone: () => normalizeOpenApiRefs(Option5.getOrUndefined(def.operation.outputSchema)),
958
- onSome: (responseBody) => Option5.isSome(responseBody.fileHint) ? ToolFileJsonSchema : normalizeOpenApiRefs(Option5.getOrUndefined(def.operation.outputSchema))
959
- }),
835
+ description: withFileEmitHint(descriptionFor(def), returnsFile),
836
+ inputSchema: normalizeOpenApiRefs(Option4.getOrUndefined(def.operation.inputSchema)),
837
+ outputSchema: returnsFile ? ToolFileJsonSchema : normalizeOpenApiRefs(Option4.getOrUndefined(def.operation.outputSchema)),
960
838
  annotations: annotationsForOperation(def.operation.method, def.operation.pathTemplate)
961
- })
962
- );
839
+ };
840
+ });
963
841
  var openApiStoredOperationsFromCompiled = (integration, compiled) => compiled.definitions.map((def) => ({
964
842
  integration,
965
843
  toolName: def.toolPath,
966
- binding: toBinding(def)
844
+ binding: toBinding(def),
845
+ description: descriptionFor(def)
967
846
  }));
847
+ var buildDefsJson = (doc) => {
848
+ const schemas = doc.components?.schemas;
849
+ if (!schemas) return "{}";
850
+ let json = "{";
851
+ let first = true;
852
+ for (const [name, schema] of Object.entries(schemas)) {
853
+ const serialized = JSON.stringify(normalizeOpenApiRefs(schema));
854
+ if (serialized === void 0) continue;
855
+ json += `${first ? "" : ","}${JSON.stringify(name)}:${serialized}`;
856
+ first = false;
857
+ }
858
+ return `${json}}`;
859
+ };
860
+ var buildDefsJsonStreaming = (structure) => {
861
+ let json = "{";
862
+ let first = true;
863
+ for (const range of structure.schemas) {
864
+ const entry = parseEntry(structure.text, range, 4);
865
+ if (!entry) continue;
866
+ const [name, schema] = entry;
867
+ const serialized = JSON.stringify(normalizeOpenApiRefs(schema));
868
+ if (serialized === void 0) continue;
869
+ json += `${first ? "" : ","}${JSON.stringify(name)}:${serialized}`;
870
+ first = false;
871
+ }
872
+ return `${json}}`;
873
+ };
874
+ var DefsJson = Schema3.Record(Schema3.String, Schema3.Unknown);
875
+ var decodeDefsJson = Schema3.decodeUnknownOption(Schema3.fromJsonString(DefsJson));
876
+ var toolDefFromStoredOperation = (op) => {
877
+ const binding = op.binding;
878
+ const returnsFile = Option4.match(binding.responseBody, {
879
+ onNone: () => false,
880
+ onSome: (responseBody) => Option4.isSome(responseBody.fileHint)
881
+ });
882
+ return {
883
+ name: ToolName.make(op.toolName),
884
+ description: withFileEmitHint(
885
+ op.description ?? `${binding.method.toUpperCase()} ${binding.pathTemplate}`,
886
+ returnsFile
887
+ ),
888
+ inputSchema: normalizeOpenApiRefs(
889
+ buildInputSchema(
890
+ binding.parameters,
891
+ Option4.getOrUndefined(binding.requestBody),
892
+ binding.servers ?? []
893
+ )
894
+ ),
895
+ outputSchema: returnsFile ? ToolFileJsonSchema : Option4.match(binding.responseBody, {
896
+ onNone: () => void 0,
897
+ onSome: (responseBody) => normalizeOpenApiRefs(Option4.getOrUndefined(responseBody.schema))
898
+ }),
899
+ annotations: annotationsForOperation(binding.method, binding.pathTemplate)
900
+ };
901
+ };
902
+ var compileAndPersistOpenApiOperations = ({
903
+ doc,
904
+ integration,
905
+ storage,
906
+ specHash,
907
+ chunkSize
908
+ }) => Effect3.gen(function* () {
909
+ yield* storage.removeOperations(integration);
910
+ const result = yield* streamOperationBindings(
911
+ doc,
912
+ chunkSize ?? 500,
913
+ (chunk) => storage.appendOperations(
914
+ integration,
915
+ chunk.map((item) => ({
916
+ integration,
917
+ toolName: item.toolName,
918
+ binding: item.binding,
919
+ description: item.description
920
+ }))
921
+ )
922
+ );
923
+ if (specHash != null) {
924
+ yield* storage.putDefs(specHash, buildDefsJson(doc));
925
+ }
926
+ return result;
927
+ });
928
+ var compileAndPersistOpenApiSpec = ({
929
+ specText,
930
+ integration,
931
+ storage,
932
+ specHash,
933
+ chunkSize
934
+ }) => Effect3.gen(function* () {
935
+ const doc = yield* parse(specText);
936
+ return yield* compileAndPersistOpenApiOperations({
937
+ doc,
938
+ integration,
939
+ storage,
940
+ specHash,
941
+ chunkSize
942
+ });
943
+ });
944
+ var compileAndPersistOpenApiSpecStreaming = ({
945
+ specText,
946
+ integration,
947
+ storage,
948
+ specHash,
949
+ chunkSize,
950
+ keepPathItem
951
+ }) => Effect3.gen(function* () {
952
+ const structure = structuralSplit(specText);
953
+ if (!structure) {
954
+ return yield* new OpenApiExtractionError({
955
+ message: "OpenAPI spec is not in the streamable block-YAML profile (no top-level `paths:` block); cannot stream-compile a spec this large in-band."
956
+ });
957
+ }
958
+ yield* storage.removeOperations(integration);
959
+ const result = yield* streamOperationBindingsFromStructure(
960
+ structure,
961
+ { chunkSize: chunkSize ?? 500, keepPathItem },
962
+ (chunk) => storage.appendOperations(
963
+ integration,
964
+ chunk.map((item) => ({
965
+ integration,
966
+ toolName: item.toolName,
967
+ binding: item.binding,
968
+ description: item.description
969
+ }))
970
+ )
971
+ );
972
+ if (specHash != null) {
973
+ yield* storage.putDefs(specHash, buildDefsJsonStreaming(structure));
974
+ }
975
+ return result;
976
+ });
968
977
  var loadOpenApiSpecText = (storage, config) => config.specHash != null ? storage.getSpec(config.specHash) : Effect3.succeed(null);
969
978
  var resolveOpenApiBackedTools = ({
979
+ integration,
970
980
  config,
971
981
  storage
972
982
  }) => Effect3.gen(function* () {
973
983
  const openApiConfig = decodeOpenApiIntegrationConfig(config);
974
984
  if (!openApiConfig) return { tools: [], definitions: {} };
985
+ if (openApiConfig.specHash != null) {
986
+ const defsJson = yield* storage.getDefs(openApiConfig.specHash);
987
+ if (defsJson != null) {
988
+ const definitions = Option4.getOrNull(decodeDefsJson(defsJson));
989
+ if (definitions != null) {
990
+ const ops = yield* storage.listOperations(String(integration.slug));
991
+ return { tools: ops.map(toolDefFromStoredOperation), definitions };
992
+ }
993
+ }
994
+ }
975
995
  const specText = yield* loadOpenApiSpecText(storage, openApiConfig);
976
996
  if (specText == null) return { tools: [], definitions: {} };
977
997
  const compiled = yield* compileOpenApiSpec(specText).pipe(
@@ -987,7 +1007,7 @@ var invokeOpenApiBackedTool = (input) => Effect3.gen(function* () {
987
1007
  const integration = input.toolRow.integration;
988
1008
  const config = decodeOpenApiIntegrationConfig(input.credential.config);
989
1009
  let binding = (yield* input.ctx.storage.getOperation(integration, input.toolRow.name))?.binding;
990
- if ((!binding || Option5.isNone(binding.responseBody)) && config) {
1010
+ if (!binding && config) {
991
1011
  const specText = yield* loadOpenApiSpecText(input.ctx.storage, config).pipe(
992
1012
  Effect3.catch(() => Effect3.succeed(null))
993
1013
  );
@@ -1076,7 +1096,7 @@ var resolveOpenApiBackedAnnotations = (input) => Effect3.gen(function* () {
1076
1096
  });
1077
1097
 
1078
1098
  // src/sdk/plugin.ts
1079
- import { Effect as Effect4, Option as Option6, Schema as Schema4 } from "effect";
1099
+ import { Effect as Effect4, Option as Option5, Schema as Schema4 } from "effect";
1080
1100
  import {
1081
1101
  IntegrationAlreadyExistsError,
1082
1102
  IntegrationDetectionResult,
@@ -1207,18 +1227,18 @@ var openApiToolFailure = (code, message, details) => ToolResult2.fail({
1207
1227
  ...details === void 0 ? {} : { details }
1208
1228
  });
1209
1229
  var staticPreviewOutput = (preview) => ({
1210
- title: Option6.getOrNull(preview.title),
1211
- version: Option6.getOrNull(preview.version),
1230
+ title: Option5.getOrNull(preview.title),
1231
+ version: Option5.getOrNull(preview.version),
1212
1232
  servers: preview.servers.map((server) => ({
1213
1233
  url: server.url,
1214
- description: Option6.getOrNull(server.description),
1215
- variables: Option6.getOrNull(server.variables) ? Object.fromEntries(
1216
- Object.entries(Option6.getOrNull(server.variables) ?? {}).map(([name, variable]) => [
1234
+ description: Option5.getOrNull(server.description),
1235
+ variables: Option5.getOrNull(server.variables) ? Object.fromEntries(
1236
+ Object.entries(Option5.getOrNull(server.variables) ?? {}).map(([name, variable]) => [
1217
1237
  name,
1218
1238
  {
1219
1239
  default: variable.default,
1220
- enum: Option6.getOrNull(variable.enum),
1221
- description: Option6.getOrNull(variable.description)
1240
+ enum: Option5.getOrNull(variable.enum),
1241
+ description: Option5.getOrNull(variable.description)
1222
1242
  }
1223
1243
  ])
1224
1244
  ) : null
@@ -1228,25 +1248,25 @@ var staticPreviewOutput = (preview) => ({
1228
1248
  securitySchemes: preview.securitySchemes.map((scheme) => ({
1229
1249
  name: scheme.name,
1230
1250
  type: scheme.type,
1231
- scheme: Option6.getOrNull(scheme.scheme),
1232
- bearerFormat: Option6.getOrNull(scheme.bearerFormat),
1233
- in: Option6.getOrNull(scheme.in),
1234
- headerName: Option6.getOrNull(scheme.headerName),
1235
- description: Option6.getOrNull(scheme.description),
1236
- flows: Option6.isSome(scheme.flows) ? {
1237
- authorizationCode: Option6.isSome(scheme.flows.value.authorizationCode) ? {
1251
+ scheme: Option5.getOrNull(scheme.scheme),
1252
+ bearerFormat: Option5.getOrNull(scheme.bearerFormat),
1253
+ in: Option5.getOrNull(scheme.in),
1254
+ headerName: Option5.getOrNull(scheme.headerName),
1255
+ description: Option5.getOrNull(scheme.description),
1256
+ flows: Option5.isSome(scheme.flows) ? {
1257
+ authorizationCode: Option5.isSome(scheme.flows.value.authorizationCode) ? {
1238
1258
  authorizationUrl: scheme.flows.value.authorizationCode.value.authorizationUrl,
1239
1259
  tokenUrl: scheme.flows.value.authorizationCode.value.tokenUrl,
1240
- refreshUrl: Option6.getOrNull(scheme.flows.value.authorizationCode.value.refreshUrl),
1260
+ refreshUrl: Option5.getOrNull(scheme.flows.value.authorizationCode.value.refreshUrl),
1241
1261
  scopes: scheme.flows.value.authorizationCode.value.scopes
1242
1262
  } : null,
1243
- clientCredentials: Option6.isSome(scheme.flows.value.clientCredentials) ? {
1263
+ clientCredentials: Option5.isSome(scheme.flows.value.clientCredentials) ? {
1244
1264
  tokenUrl: scheme.flows.value.clientCredentials.value.tokenUrl,
1245
- refreshUrl: Option6.getOrNull(scheme.flows.value.clientCredentials.value.refreshUrl),
1265
+ refreshUrl: Option5.getOrNull(scheme.flows.value.clientCredentials.value.refreshUrl),
1246
1266
  scopes: scheme.flows.value.clientCredentials.value.scopes
1247
1267
  } : null
1248
1268
  } : null,
1249
- openIdConnectUrl: Option6.getOrNull(scheme.openIdConnectUrl)
1269
+ openIdConnectUrl: Option5.getOrNull(scheme.openIdConnectUrl)
1250
1270
  })),
1251
1271
  authStrategies: preview.authStrategies,
1252
1272
  headerPresets: preview.headerPresets,
@@ -1254,9 +1274,9 @@ var staticPreviewOutput = (preview) => ({
1254
1274
  label: preset.label,
1255
1275
  securitySchemeName: preset.securitySchemeName,
1256
1276
  flow: preset.flow,
1257
- authorizationUrl: Option6.getOrNull(preset.authorizationUrl),
1277
+ authorizationUrl: Option5.getOrNull(preset.authorizationUrl),
1258
1278
  tokenUrl: preset.tokenUrl,
1259
- refreshUrl: Option6.getOrNull(preset.refreshUrl),
1279
+ refreshUrl: Option5.getOrNull(preset.refreshUrl),
1260
1280
  scopes: preset.scopes,
1261
1281
  identityScopes: preset.identityScopes
1262
1282
  }))
@@ -1342,6 +1362,7 @@ var openApiPlugin = definePlugin((options) => {
1342
1362
  } : derivedAuthenticationTemplate && derivedAuthenticationTemplate.length > 0 ? { authenticationTemplate: derivedAuthenticationTemplate } : {}
1343
1363
  };
1344
1364
  yield* ctx.storage.putSpec(specHash, resolved.specText);
1365
+ yield* ctx.storage.putDefs(specHash, JSON.stringify(compiled.hoistedDefs));
1345
1366
  yield* ctx.transaction(
1346
1367
  Effect4.gen(function* () {
1347
1368
  yield* ctx.core.integrations.register({
@@ -1380,6 +1401,7 @@ var openApiPlugin = definePlugin((options) => {
1380
1401
  const nextNames = new Set(compiled.definitions.map((def) => def.toolPath));
1381
1402
  const specHash = yield* sha256Hex(resolved.specText);
1382
1403
  yield* ctx.storage.putSpec(specHash, resolved.specText);
1404
+ yield* ctx.storage.putDefs(specHash, JSON.stringify(compiled.hoistedDefs));
1383
1405
  const nextConfig = {
1384
1406
  ...current,
1385
1407
  specHash,
@@ -1541,7 +1563,7 @@ var openApiPlugin = definePlugin((options) => {
1541
1563
  // operation bindings invokeTool needs are persisted at addSpec time; this
1542
1564
  // hook only shapes the per-connection ToolDefs from the spec blob the
1543
1565
  // catalog config points at.
1544
- resolveTools: ({ config, storage }) => resolveOpenApiBackedTools({ config, storage }),
1566
+ resolveTools: ({ integration, config, storage }) => resolveOpenApiBackedTools({ integration, config, storage }),
1545
1567
  invokeTool: ({ ctx: invokeCtx, toolRow, credential, args }) => {
1546
1568
  const httpClientLayer = options?.httpClientLayer ?? invokeCtx.httpClientLayer;
1547
1569
  return invokeOpenApiBackedTool({
@@ -1569,7 +1591,7 @@ var openApiPlugin = definePlugin((options) => {
1569
1591
  try: () => new URL(trimmed),
1570
1592
  catch: (error) => error
1571
1593
  }).pipe(Effect4.option);
1572
- if (Option6.isNone(parsed)) return null;
1594
+ if (Option5.isNone(parsed)) return null;
1573
1595
  const specText = yield* resolveSpecText(trimmed).pipe(
1574
1596
  Effect4.provide(httpClientLayer),
1575
1597
  Effect4.catch(() => Effect4.succeed(null))
@@ -1579,8 +1601,8 @@ var openApiPlugin = definePlugin((options) => {
1579
1601
  if (!doc) return null;
1580
1602
  const result = yield* extract(doc).pipe(Effect4.catch(() => Effect4.succeed(null)));
1581
1603
  if (!result) return null;
1582
- const slug = Option6.getOrElse(result.title, () => "api").toLowerCase().replace(/[^a-z0-9]+/g, "_");
1583
- const name = Option6.getOrElse(result.title, () => slug);
1604
+ const slug = Option5.getOrElse(result.title, () => "api").toLowerCase().replace(/[^a-z0-9]+/g, "_");
1605
+ const name = Option5.getOrElse(result.title, () => slug);
1584
1606
  return IntegrationDetectionResult.make({
1585
1607
  kind: "openapi",
1586
1608
  confidence: "high",
@@ -1607,10 +1629,14 @@ export {
1607
1629
  compileOpenApiSpec,
1608
1630
  openApiToolDefsFromCompiled,
1609
1631
  openApiStoredOperationsFromCompiled,
1632
+ buildDefsJsonStreaming,
1633
+ compileAndPersistOpenApiOperations,
1634
+ compileAndPersistOpenApiSpec,
1635
+ compileAndPersistOpenApiSpecStreaming,
1610
1636
  loadOpenApiSpecText,
1611
1637
  resolveOpenApiBackedTools,
1612
1638
  invokeOpenApiBackedTool,
1613
1639
  resolveOpenApiBackedAnnotations,
1614
1640
  openApiPlugin
1615
1641
  };
1616
- //# sourceMappingURL=chunk-3FM2SWM4.js.map
1642
+ //# sourceMappingURL=chunk-ELCKZJE4.js.map