@expandai/mcp-server 0.1.4 → 0.2.0

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.
package/dist/Server.cjs CHANGED
@@ -40,7 +40,7 @@ var S__namespace = /*#__PURE__*/_interopNamespace(S);
40
40
 
41
41
  // package.json
42
42
  var package_default = {
43
- version: "0.1.4"};
43
+ version: "0.2.0"};
44
44
  var ExpandDocs = ai.McpServer.resource({
45
45
  uri: "expand://about",
46
46
  name: "About expand.ai",
@@ -104,10 +104,14 @@ var HttpApiDecodeError = class extends S__namespace.Class("HttpApiDecodeError")(
104
104
  _tag: HttpApiDecodeErrorTag
105
105
  }) {
106
106
  };
107
- var UnauthorizedAccessTag = class extends S__namespace.Literal("UnauthorizedAccess") {
107
+ var AuthFailedReason = class extends S__namespace.Literal("InvalidApiKey", "InvalidToken", "InvalidSession", "InvalidTenant") {
108
108
  };
109
- var UnauthorizedAccess = class extends S__namespace.Class("UnauthorizedAccess")({
110
- _tag: UnauthorizedAccessTag
109
+ var AuthFailedTag = class extends S__namespace.Literal("AuthFailed") {
110
+ };
111
+ var AuthFailed = class extends S__namespace.Class("AuthFailed")({
112
+ reason: AuthFailedReason,
113
+ description: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
114
+ _tag: AuthFailedTag
111
115
  }) {
112
116
  };
113
117
  var AssetNotFoundTag = class extends S__namespace.Literal("AssetNotFound") {
@@ -150,7 +154,13 @@ var AssetRetrievalError = class extends S__namespace.Class("AssetRetrievalError"
150
154
  _tag: AssetRetrievalErrorTag
151
155
  }) {
152
156
  };
153
- var AssetsGetByUrl500 = class extends S__namespace.Union(AssetReadError, InvalidWaczFormat, AssetRetrievalError) {
157
+ var InternalErrorTag = class extends S__namespace.Literal("InternalError") {
158
+ };
159
+ var InternalError = class extends S__namespace.Class("InternalError")({
160
+ _tag: InternalErrorTag
161
+ }) {
162
+ };
163
+ var AssetsGetByUrl500 = class extends S__namespace.Union(InternalError, AssetReadError, InvalidWaczFormat, AssetRetrievalError) {
154
164
  };
155
165
  var CurlErrorInputMethod = class extends S__namespace.Literal(
156
166
  "GET",
@@ -164,6 +174,8 @@ var CurlErrorInputMethod = class extends S__namespace.Literal(
164
174
  "PATCH"
165
175
  ) {
166
176
  };
177
+ var URL = class extends S__namespace.String {
178
+ };
167
179
  var CurlErrorTag = class extends S__namespace.Literal("CurlError") {
168
180
  };
169
181
  var CurlError = class extends S__namespace.Class("CurlError")({
@@ -174,11 +186,14 @@ var CurlError = class extends S__namespace.Class("CurlError")({
174
186
  body: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
175
187
  headers: S__namespace.optionalWith(S__namespace.Struct({}), { nullable: true }),
176
188
  proxy: S__namespace.optionalWith(
177
- S__namespace.Struct({
178
- server: S__namespace.String,
179
- username: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
180
- password: S__namespace.optionalWith(S__namespace.String, { nullable: true })
181
- }),
189
+ S__namespace.Union(
190
+ S__namespace.Struct({
191
+ server: S__namespace.String,
192
+ username: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
193
+ password: S__namespace.optionalWith(S__namespace.String, { nullable: true })
194
+ }),
195
+ URL
196
+ ),
182
197
  { nullable: true }
183
198
  ),
184
199
  timeout: S__namespace.optionalWith(S__namespace.Number, { nullable: true }),
@@ -198,9 +213,20 @@ var AssetListResponse = class extends S__namespace.Class("AssetListResponse")({
198
213
  assets: S__namespace.Array(AssetListItem)
199
214
  }) {
200
215
  };
201
- var AssetsList500 = class extends S__namespace.Union(AssetReadError, InvalidWaczFormat) {
216
+ var AssetsList500 = class extends S__namespace.Union(InternalError, AssetReadError, InvalidWaczFormat) {
202
217
  };
203
- var URL = class extends S__namespace.String {
218
+ var AssetsGetWacz500 = class extends S__namespace.Union(InternalError, AssetReadError) {
219
+ };
220
+ var DatasetNotFoundTag = class extends S__namespace.Literal("DatasetNotFound") {
221
+ };
222
+ var DatasetNotFound = class extends S__namespace.Class("DatasetNotFound")({
223
+ path: S__namespace.String,
224
+ _tag: DatasetNotFoundTag
225
+ }) {
226
+ };
227
+ var DatasetsGetDataset500 = class extends S__namespace.Union(InternalError, DatasetNotFound) {
228
+ };
229
+ var DatasetsGetFinetuneDataset500 = class extends S__namespace.Union(InternalError, DatasetNotFound) {
204
230
  };
205
231
  var SelectHtmlConfig = class extends S__namespace.Record({ key: S__namespace.String, value: S__namespace.Unknown }) {
206
232
  };
@@ -293,6 +319,29 @@ var Int2 = class extends S__namespace.Int {
293
319
  }),
294
320
  { nullable: true }
295
321
  ),
322
+ links: S__namespace.optionalWith(
323
+ S__namespace.Union(
324
+ S__namespace.Boolean,
325
+ /**
326
+ * Options for customizing link extraction from the page
327
+ */
328
+ S__namespace.Struct({
329
+ /**
330
+ * Only include links from the same domain as the fetched URL
331
+ */
332
+ sameDomainOnly: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => true }),
333
+ /**
334
+ * Regex patterns - only include links matching at least one pattern
335
+ */
336
+ includePatterns: S__namespace.optionalWith(S__namespace.Array(S__namespace.String), { nullable: true }),
337
+ /**
338
+ * Regex patterns - exclude links matching any pattern
339
+ */
340
+ excludePatterns: S__namespace.optionalWith(S__namespace.Array(S__namespace.String), { nullable: true })
341
+ })
342
+ ),
343
+ { nullable: true }
344
+ ),
296
345
  /**
297
346
  * Include page metadata in the response
298
347
  */
@@ -308,7 +357,15 @@ var Int2 = class extends S__namespace.Int {
308
357
  includeHeaders: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => false })
309
358
  }),
310
359
  { nullable: true }
311
- )
360
+ ),
361
+ /**
362
+ * Include pruned JSON in the response (opt-in)
363
+ */
364
+ json: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => false }),
365
+ /**
366
+ * Set to true to include extracted links and sidebar content
367
+ */
368
+ appendix: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true })
312
369
  }),
313
370
  { nullable: true }
314
371
  ),
@@ -476,58 +533,75 @@ var PageMeta = class extends S__namespace.Class("PageMeta")({
476
533
  twitter: S__namespace.optionalWith(TwitterCardMeta, { nullable: true })
477
534
  }) {
478
535
  };
479
- var FetchData = class extends S__namespace.Class("FetchData")({
480
- response: ResponseInfo,
481
- /**
482
- * Page metadata extracted from HTML head (title, description, Open Graph, Twitter Card, icons)
483
- */
484
- meta: S__namespace.optionalWith(PageMeta, { nullable: true }),
536
+ var FetchLink = class extends S__namespace.Class("FetchLink")({
485
537
  /**
486
- * The HTML content of the fetched page
538
+ * The URL of the link
487
539
  */
488
- html: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
489
- /**
490
- * The markdown-formatted content extracted from the page
491
- */
492
- markdown: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
493
- /**
494
- * Base64-encoded data URI of the screenshot image
495
- */
496
- screenshot: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
497
- /**
498
- * AI-generated summary of the page content
499
- */
500
- summary: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
540
+ url: S__namespace.String,
501
541
  /**
502
- * Relevant snippets extracted from the page based on the search query
542
+ * The anchor text of the link
503
543
  */
504
- snippets: S__namespace.optionalWith(
505
- S__namespace.Array(
506
- S__namespace.Struct({
507
- /**
508
- * Type identifier for TextPart compatibility
509
- */
510
- type: S__namespace.optionalWith(S__namespace.Literal("text"), { nullable: true, default: () => "text" }),
511
- /**
512
- * The text content of the snippet
513
- */
514
- text: S__namespace.String,
515
- /**
516
- * Relevance score from the reranker (0-1)
517
- */
518
- score: S__namespace.Number,
519
- /**
520
- * Original chunk index
521
- */
522
- index: S__namespace.Number
523
- })
524
- ),
525
- { nullable: true }
526
- )
544
+ text: S__namespace.optionalWith(S__namespace.String, { nullable: true })
527
545
  }) {
528
546
  };
529
547
  var FetchResult = class extends S__namespace.Class("FetchResult")({
530
- data: FetchData
548
+ /**
549
+ * Contains the extracted content in the formats specified by the select configuration
550
+ */
551
+ data: S__namespace.Struct({
552
+ response: ResponseInfo,
553
+ meta: S__namespace.optionalWith(PageMeta, { nullable: true }),
554
+ /**
555
+ * The HTML content of the fetched page
556
+ */
557
+ html: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
558
+ /**
559
+ * The markdown-formatted content extracted from the page
560
+ */
561
+ markdown: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
562
+ /**
563
+ * Base64-encoded data URI of the screenshot image
564
+ */
565
+ screenshot: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
566
+ /**
567
+ * AI-generated summary of the page content
568
+ */
569
+ summary: S__namespace.optionalWith(S__namespace.String, { nullable: true }),
570
+ /**
571
+ * Relevant snippets extracted from the page based on the search query
572
+ */
573
+ snippets: S__namespace.optionalWith(
574
+ S__namespace.Array(
575
+ S__namespace.Struct({
576
+ /**
577
+ * Type identifier for TextPart compatibility
578
+ */
579
+ type: S__namespace.optionalWith(S__namespace.Literal("text"), { nullable: true, default: () => "text" }),
580
+ /**
581
+ * The text content of the snippet
582
+ */
583
+ text: S__namespace.String,
584
+ /**
585
+ * Relevance score from the reranker (0-1)
586
+ */
587
+ score: S__namespace.Number,
588
+ /**
589
+ * Original chunk index
590
+ */
591
+ index: S__namespace.Number
592
+ })
593
+ ),
594
+ { nullable: true }
595
+ ),
596
+ /**
597
+ * Links extracted from the page
598
+ */
599
+ links: S__namespace.optionalWith(S__namespace.Array(FetchLink), { nullable: true }),
600
+ /**
601
+ * Extracted links and sidebar content
602
+ */
603
+ appendix: S__namespace.optionalWith(S__namespace.String, { nullable: true })
604
+ })
531
605
  }) {
532
606
  };
533
607
  var FetchErrorTag = class extends S__namespace.Literal("FetchError") {
@@ -536,25 +610,8 @@ var FetchError = class extends S__namespace.Class("FetchError")({
536
610
  _tag: FetchErrorTag
537
611
  }) {
538
612
  };
539
- (class extends S__namespace.Class("MarkdownRequest")({
540
- /**
541
- * The URL to fetch markdown content from
542
- */
543
- url: S__namespace.String,
544
- /**
545
- * Configuration options for browser behavior during the fetch
546
- */
547
- browserConfig: S__namespace.optionalWith(
548
- S__namespace.Struct({
549
- /**
550
- * Whether to scroll the entire page to capture lazy-loaded content
551
- */
552
- scrollFullPage: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => false })
553
- }),
554
- { nullable: true }
555
- )
556
- }) {
557
- });
613
+ var Fetch500 = class extends S__namespace.Union(InternalError, FetchError) {
614
+ };
558
615
  var InvalidAssetHashTag = class extends S__namespace.Literal("InvalidAssetHash") {
559
616
  };
560
617
  var InvalidAssetHash = class extends S__namespace.Class("InvalidAssetHash")({
@@ -586,12 +643,223 @@ var AssetFetchError = class extends S__namespace.Class("AssetFetchError")({
586
643
  }) {
587
644
  };
588
645
  var LocalAssetsGetAsset500 = class extends S__namespace.Union(
646
+ InternalError,
589
647
  InvalidAssetHash,
590
648
  AssetNotFoundInHar,
591
649
  HarNotFound,
592
650
  AssetFetchError
593
651
  ) {
594
652
  };
653
+ (class extends S__namespace.Class("PlaygroundFetchRequest")({
654
+ url: URL,
655
+ /**
656
+ * Specifies which content formats to include in the response
657
+ */
658
+ select: S__namespace.optionalWith(
659
+ S__namespace.Struct({
660
+ html: S__namespace.optionalWith(
661
+ S__namespace.Union(
662
+ S__namespace.Boolean,
663
+ SelectHtmlConfig
664
+ ),
665
+ { nullable: true }
666
+ ),
667
+ /**
668
+ * Include markdown-formatted content in the response
669
+ */
670
+ markdown: S__namespace.optionalWith(
671
+ S__namespace.Union(
672
+ S__namespace.Boolean,
673
+ SelectMarkdownConfig
674
+ ),
675
+ { nullable: true }
676
+ ),
677
+ screenshot: S__namespace.optionalWith(
678
+ S__namespace.Union(
679
+ S__namespace.Boolean,
680
+ SelectScreenshotConfig
681
+ ),
682
+ { nullable: true }
683
+ ),
684
+ summary: S__namespace.optionalWith(
685
+ S__namespace.Union(
686
+ S__namespace.Boolean,
687
+ /**
688
+ * Options for AI-powered page summarization
689
+ */
690
+ S__namespace.Struct({
691
+ /**
692
+ * Custom prompt for AI summarization (max 5000 characters)
693
+ */
694
+ prompt: S__namespace.optionalWith(S__namespace.String.pipe(S__namespace.maxLength(5e3)), {
695
+ nullable: true,
696
+ default: () => "You are a helpful assistant that summarizes web page content.\nGiven the markdown content of a web page, provide a clear and concise summary.\nFocus on the main points and key information.\nKeep the summary informative but brief."
697
+ })
698
+ })
699
+ ),
700
+ { nullable: true }
701
+ ),
702
+ /**
703
+ * Options for extracting relevant snippets from page content using semantic search
704
+ */
705
+ snippets: S__namespace.optionalWith(
706
+ S__namespace.Struct({
707
+ /**
708
+ * Query to find relevant content snippets from the page (required, non-empty)
709
+ */
710
+ query: Trimmed,
711
+ /**
712
+ * Maximum number of snippets to return (1-50)
713
+ */
714
+ maxSnippets: S__namespace.optionalWith(Int2, { nullable: true, default: () => 5 }),
715
+ /**
716
+ * Minimum relevance score threshold (0-1). Snippets below this score are filtered out.
717
+ */
718
+ minScore: S__namespace.optionalWith(S__namespace.Number.pipe(S__namespace.greaterThanOrEqualTo(0), S__namespace.lessThanOrEqualTo(1)), {
719
+ nullable: true,
720
+ default: () => 0.5
721
+ }),
722
+ /**
723
+ * Target snippet size in characters (100-2000)
724
+ */
725
+ targetSnippetSize: S__namespace.optionalWith(Int2, { nullable: true, default: () => 384 })
726
+ }),
727
+ { nullable: true }
728
+ ),
729
+ links: S__namespace.optionalWith(
730
+ S__namespace.Union(
731
+ S__namespace.Boolean,
732
+ /**
733
+ * Options for customizing link extraction from the page
734
+ */
735
+ S__namespace.Struct({
736
+ /**
737
+ * Only include links from the same domain as the fetched URL
738
+ */
739
+ sameDomainOnly: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => true }),
740
+ /**
741
+ * Regex patterns - only include links matching at least one pattern
742
+ */
743
+ includePatterns: S__namespace.optionalWith(S__namespace.Array(S__namespace.String), { nullable: true }),
744
+ /**
745
+ * Regex patterns - exclude links matching any pattern
746
+ */
747
+ excludePatterns: S__namespace.optionalWith(S__namespace.Array(S__namespace.String), { nullable: true })
748
+ })
749
+ ),
750
+ { nullable: true }
751
+ ),
752
+ /**
753
+ * Include page metadata in the response
754
+ */
755
+ meta: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => true }),
756
+ /**
757
+ * Configure response info options (headers inclusion)
758
+ */
759
+ response: S__namespace.optionalWith(
760
+ S__namespace.Struct({
761
+ /**
762
+ * Whether to include HTTP response headers
763
+ */
764
+ includeHeaders: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => false })
765
+ }),
766
+ { nullable: true }
767
+ ),
768
+ /**
769
+ * Include pruned JSON in the response (opt-in)
770
+ */
771
+ json: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => false }),
772
+ /**
773
+ * Set to true to include extracted links and sidebar content
774
+ */
775
+ appendix: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true })
776
+ }),
777
+ { nullable: true }
778
+ ),
779
+ /**
780
+ * Configuration options for browser behavior during the fetch
781
+ */
782
+ browserConfig: S__namespace.optionalWith(
783
+ S__namespace.Struct({
784
+ /**
785
+ * Whether to scroll the entire page to capture lazy-loaded content
786
+ */
787
+ scrollFullPage: S__namespace.optionalWith(S__namespace.Boolean, { nullable: true, default: () => false })
788
+ }),
789
+ { nullable: true }
790
+ )
791
+ }) {
792
+ });
793
+ var PlaygroundData = class extends S__namespace.Class("PlaygroundData")({
794
+ response: ResponseInfo,
795
+ /**
796
+ * HTML with expand-id attributes on elements
797
+ */
798
+ html: S__namespace.String,
799
+ browserSessionId: S__namespace.String
800
+ }) {
801
+ };
802
+ var PlaygroundResult = class extends S__namespace.Class("PlaygroundResult")({
803
+ data: PlaygroundData
804
+ }) {
805
+ };
806
+ var PlaygroundFetch500 = class extends S__namespace.Union(InternalError, FetchError) {
807
+ };
808
+ var PlaygroundGet500 = class extends S__namespace.Union(InternalError, FetchError) {
809
+ };
810
+ var PlaygroundGetBySession500 = class extends S__namespace.Union(InternalError, FetchError) {
811
+ };
812
+ (class extends S__namespace.Class("PlaygroundSearchRequest")({
813
+ /**
814
+ * Search query to find relevant content chunks
815
+ */
816
+ query: Trimmed,
817
+ /**
818
+ * Browser session ID from the playground fetch result
819
+ */
820
+ browserSessionId: S__namespace.String,
821
+ /**
822
+ * Maximum number of results to return
823
+ */
824
+ maxResults: S__namespace.optionalWith(S__namespace.Number, { nullable: true }),
825
+ /**
826
+ * Minimum relevance score threshold (0-1). A value of 0 disables filtering.
827
+ */
828
+ minScore: S__namespace.optionalWith(S__namespace.Number, { nullable: true })
829
+ }) {
830
+ });
831
+ var PlaygroundSearchChunk = class extends S__namespace.Class("PlaygroundSearchChunk")({
832
+ /**
833
+ * The chunk text content
834
+ */
835
+ text: S__namespace.String,
836
+ /**
837
+ * Relevance score from 0-1
838
+ */
839
+ score: S__namespace.Number,
840
+ /**
841
+ * Original chunk index
842
+ */
843
+ index: S__namespace.Number,
844
+ /**
845
+ * MDAST originalNodeIds for highlighting in HTML/markdown views
846
+ */
847
+ nodeIds: S__namespace.Array(S__namespace.Number)
848
+ }) {
849
+ };
850
+ var PlaygroundSearch200 = class extends S__namespace.Struct({
851
+ /**
852
+ * Scored and ranked content chunks
853
+ */
854
+ chunks: S__namespace.Array(PlaygroundSearchChunk),
855
+ /**
856
+ * Duration of the search operation in milliseconds
857
+ */
858
+ durationMs: S__namespace.optionalWith(S__namespace.Number, { nullable: true })
859
+ }) {
860
+ };
861
+ var PlaygroundSearch500 = class extends S__namespace.Union(InternalError, FetchError) {
862
+ };
595
863
  var make = (httpClient, options = {}) => {
596
864
  const unexpectedStatus = (response) => Effect2__namespace.flatMap(
597
865
  Effect2__namespace.orElseSucceed(response.json, () => "Unexpected status code"),
@@ -620,49 +888,79 @@ var make = (httpClient, options = {}) => {
620
888
  withResponse(
621
889
  HttpClientResponse__namespace.matchStatus({
622
890
  "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
623
- "401": decodeError("UnauthorizedAccess", UnauthorizedAccess),
891
+ "401": decodeError("AuthFailed", AuthFailed),
624
892
  "404": decodeError("AssetsGetByUrl404", AssetsGetByUrl404),
625
893
  "500": decodeError("AssetsGetByUrl500", AssetsGetByUrl500),
626
894
  "502": decodeError("CurlError", CurlError),
627
895
  "429": () => Effect2__namespace.void,
896
+ "503": () => Effect2__namespace.void,
628
897
  orElse: unexpectedStatus
629
898
  })
630
899
  )
631
900
  ),
632
- assetsList: (browserSessionId) => HttpClientRequest__namespace.get(`/v1/assets/${browserSessionId}`).pipe(
901
+ assetsList: (browserSessionId) => HttpClientRequest__namespace.get(`/v1/assets/${browserSessionId}/list`).pipe(
633
902
  withResponse(
634
903
  HttpClientResponse__namespace.matchStatus({
635
904
  "2xx": decodeSuccess(AssetListResponse),
636
905
  "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
637
- "401": decodeError("UnauthorizedAccess", UnauthorizedAccess),
906
+ "401": decodeError("AuthFailed", AuthFailed),
638
907
  "404": decodeError("AssetNotFound", AssetNotFound),
639
908
  "500": decodeError("AssetsList500", AssetsList500),
640
909
  "429": () => Effect2__namespace.void,
910
+ "503": () => Effect2__namespace.void,
641
911
  orElse: unexpectedStatus
642
912
  })
643
913
  )
644
914
  ),
645
- fetch: (options2) => HttpClientRequest__namespace.post(`/v1/fetch`).pipe(
646
- HttpClientRequest__namespace.bodyUnsafeJson(options2),
915
+ assetsGetWacz: (browserSessionId) => HttpClientRequest__namespace.get(`/v1/assets/${browserSessionId}`).pipe(
916
+ withResponse(
917
+ HttpClientResponse__namespace.matchStatus({
918
+ "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
919
+ "401": decodeError("AuthFailed", AuthFailed),
920
+ "404": decodeError("AssetNotFound", AssetNotFound),
921
+ "500": decodeError("AssetsGetWacz500", AssetsGetWacz500),
922
+ "429": () => Effect2__namespace.void,
923
+ "503": () => Effect2__namespace.void,
924
+ orElse: unexpectedStatus
925
+ })
926
+ )
927
+ ),
928
+ datasetsGetDataset: () => HttpClientRequest__namespace.get(`/datasets/page-analysis`).pipe(
929
+ withResponse(
930
+ HttpClientResponse__namespace.matchStatus({
931
+ "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
932
+ "401": decodeError("AuthFailed", AuthFailed),
933
+ "500": decodeError("DatasetsGetDataset500", DatasetsGetDataset500),
934
+ "204": () => Effect2__namespace.void,
935
+ "429": () => Effect2__namespace.void,
936
+ "503": () => Effect2__namespace.void,
937
+ orElse: unexpectedStatus
938
+ })
939
+ )
940
+ ),
941
+ datasetsGetFinetuneDataset: () => HttpClientRequest__namespace.get(`/datasets/finetune`).pipe(
647
942
  withResponse(
648
943
  HttpClientResponse__namespace.matchStatus({
649
- "2xx": decodeSuccess(FetchResult),
650
944
  "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
651
- "401": decodeError("UnauthorizedAccess", UnauthorizedAccess),
652
- "500": decodeError("FetchError", FetchError),
945
+ "401": decodeError("AuthFailed", AuthFailed),
946
+ "500": decodeError("DatasetsGetFinetuneDataset500", DatasetsGetFinetuneDataset500),
947
+ "204": () => Effect2__namespace.void,
653
948
  "429": () => Effect2__namespace.void,
949
+ "503": () => Effect2__namespace.void,
654
950
  orElse: unexpectedStatus
655
951
  })
656
952
  )
657
953
  ),
658
- markdown: (options2) => HttpClientRequest__namespace.post(`/v1/fetch/markdown`).pipe(
954
+ fetch: (options2) => HttpClientRequest__namespace.post(`/v1/fetch`).pipe(
659
955
  HttpClientRequest__namespace.bodyUnsafeJson(options2),
660
956
  withResponse(
661
957
  HttpClientResponse__namespace.matchStatus({
958
+ "2xx": decodeSuccess(FetchResult),
662
959
  "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
663
- "401": decodeError("UnauthorizedAccess", UnauthorizedAccess),
664
- "500": decodeError("FetchError", FetchError),
960
+ "401": decodeError("AuthFailed", AuthFailed),
961
+ "500": decodeError("Fetch500", Fetch500),
665
962
  "429": () => Effect2__namespace.void,
963
+ "503": () => Effect2__namespace.void,
666
964
  orElse: unexpectedStatus
667
965
  })
668
966
  )
@@ -671,9 +969,65 @@ var make = (httpClient, options = {}) => {
671
969
  withResponse(
672
970
  HttpClientResponse__namespace.matchStatus({
673
971
  "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
972
+ "401": decodeError("AuthFailed", AuthFailed),
674
973
  "500": decodeError("LocalAssetsGetAsset500", LocalAssetsGetAsset500),
675
974
  "204": () => Effect2__namespace.void,
676
975
  "429": () => Effect2__namespace.void,
976
+ "503": () => Effect2__namespace.void,
977
+ orElse: unexpectedStatus
978
+ })
979
+ )
980
+ ),
981
+ playgroundFetch: (options2) => HttpClientRequest__namespace.post(`/v1/playground/fetch`).pipe(
982
+ HttpClientRequest__namespace.bodyUnsafeJson(options2),
983
+ withResponse(
984
+ HttpClientResponse__namespace.matchStatus({
985
+ "2xx": decodeSuccess(PlaygroundResult),
986
+ "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
987
+ "401": decodeError("AuthFailed", AuthFailed),
988
+ "500": decodeError("PlaygroundFetch500", PlaygroundFetch500),
989
+ "429": () => Effect2__namespace.void,
990
+ "503": () => Effect2__namespace.void,
991
+ orElse: unexpectedStatus
992
+ })
993
+ )
994
+ ),
995
+ playgroundGet: (fetchRequestId) => HttpClientRequest__namespace.get(`/v1/playground/get/${fetchRequestId}`).pipe(
996
+ withResponse(
997
+ HttpClientResponse__namespace.matchStatus({
998
+ "2xx": decodeSuccess(PlaygroundResult),
999
+ "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
1000
+ "401": decodeError("AuthFailed", AuthFailed),
1001
+ "500": decodeError("PlaygroundGet500", PlaygroundGet500),
1002
+ "429": () => Effect2__namespace.void,
1003
+ "503": () => Effect2__namespace.void,
1004
+ orElse: unexpectedStatus
1005
+ })
1006
+ )
1007
+ ),
1008
+ playgroundGetBySession: (browserSessionId) => HttpClientRequest__namespace.get(`/v1/playground/session/${browserSessionId}`).pipe(
1009
+ withResponse(
1010
+ HttpClientResponse__namespace.matchStatus({
1011
+ "2xx": decodeSuccess(PlaygroundResult),
1012
+ "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
1013
+ "401": decodeError("AuthFailed", AuthFailed),
1014
+ "500": decodeError("PlaygroundGetBySession500", PlaygroundGetBySession500),
1015
+ "429": () => Effect2__namespace.void,
1016
+ "503": () => Effect2__namespace.void,
1017
+ orElse: unexpectedStatus
1018
+ })
1019
+ )
1020
+ ),
1021
+ playgroundSearch: (options2) => HttpClientRequest__namespace.post(`/v1/playground/search`).pipe(
1022
+ HttpClientRequest__namespace.bodyUnsafeJson(options2),
1023
+ withResponse(
1024
+ HttpClientResponse__namespace.matchStatus({
1025
+ "2xx": decodeSuccess(PlaygroundSearch200),
1026
+ "400": decodeError("HttpApiDecodeError", HttpApiDecodeError),
1027
+ "401": decodeError("AuthFailed", AuthFailed),
1028
+ "500": decodeError("PlaygroundSearch500", PlaygroundSearch500),
1029
+ "429": () => Effect2__namespace.void,
1030
+ "503": () => Effect2__namespace.void,
677
1031
  orElse: unexpectedStatus
678
1032
  })
679
1033
  )
@@ -723,81 +1077,82 @@ var ExpandClient = class extends effect.Effect.Service()("ExpandClient", {
723
1077
  })
724
1078
  }) {
725
1079
  };
726
- var SnippetsFormat = class extends effect.Schema.Class("SnippetsFormat")({
1080
+ var SearchParams = class extends effect.Schema.Class("SearchParams")({
727
1081
  query: effect.Schema.String.annotations({
728
- description: "Query to find relevant content snippets from the page"
1082
+ description: "Query to find relevant content snippets"
729
1083
  }),
730
- maxSnippets: effect.Schema.optional(
731
- effect.Schema.Int.pipe(effect.Schema.greaterThanOrEqualTo(1), effect.Schema.lessThanOrEqualTo(50))
732
- ).annotations({
733
- description: "Maximum number of snippets to return (1-50, default: 5)"
1084
+ minScore: effect.Schema.optionalWith(effect.Schema.Number.pipe(effect.Schema.greaterThanOrEqualTo(0), effect.Schema.lessThanOrEqualTo(1)), {
1085
+ default: () => 0.6
1086
+ }).annotations({
1087
+ description: "Minimum relevance score (0-1)",
1088
+ default: 0.6
734
1089
  }),
735
- targetSnippetSize: effect.Schema.optional(
736
- effect.Schema.Int.pipe(effect.Schema.greaterThanOrEqualTo(100), effect.Schema.lessThanOrEqualTo(2e3))
737
- ).annotations({
738
- description: "Target snippet size in characters (100-2000, default: 384)"
1090
+ maxResults: effect.Schema.optionalWith(effect.Schema.Int.pipe(effect.Schema.greaterThanOrEqualTo(1), effect.Schema.lessThanOrEqualTo(50)), {
1091
+ default: () => 5
1092
+ }).annotations({
1093
+ description: "Maximum snippets to return",
1094
+ default: 5
739
1095
  })
740
1096
  }) {
741
1097
  };
742
- var Format = effect.Schema.Union(
743
- effect.Schema.Literal("markdown").annotations({
744
- description: "Return as cleaned markdown content"
745
- }),
746
- effect.Schema.Literal("html").annotations({
747
- description: "Return as raw HTML content"
748
- }),
749
- effect.Schema.Literal("summary").annotations({
750
- description: "Return AI-generated summary of the page content"
751
- }),
752
- SnippetsFormat
753
- ).annotations({
754
- description: "Output format for the fetched content"
755
- });
756
1098
  var FetchParams = class extends effect.Schema.Class("FetchParams")({
757
1099
  url: effect.Schema.String.annotations({
758
1100
  description: "The URL to fetch content from"
759
1101
  }),
760
- format: Format,
761
- includeMeta: effect.Schema.Boolean.annotations({
762
- description: "Whether to include page meta tags in the response"
1102
+ includeMeta: effect.Schema.optionalWith(effect.Schema.Boolean, { default: () => false }).annotations({
1103
+ description: "Include page meta tags (title, description, Open Graph)",
1104
+ default: false
1105
+ }),
1106
+ includeAppendix: effect.Schema.optionalWith(effect.Schema.Boolean, { default: () => false }).annotations({
1107
+ description: "Include extracted links and sidebar content",
1108
+ default: false
1109
+ }),
1110
+ includeJson: effect.Schema.optionalWith(effect.Schema.Boolean, { default: () => false }).annotations({
1111
+ description: "Include JSON extracted from network responses and DOM",
1112
+ default: false
1113
+ }),
1114
+ search: effect.Schema.optional(SearchParams).annotations({
1115
+ description: "Semantic search. When provided, returns snippets instead of markdown."
763
1116
  })
764
1117
  }) {
765
1118
  };
766
- var FetchResult2 = class extends effect.Schema.Class("FetchResult")({
767
- content: effect.Schema.String,
768
- url: effect.Schema.String,
769
- meta: effect.Schema.optional(PageMeta)
770
- }) {
771
- };
772
1119
  var FetchTool = ai.Tool.make("fetch", {
773
- description: "Fetch and extract content from any URL.",
774
- parameters: FetchParams.fields,
775
- success: FetchResult2
1120
+ description: `Fetch and extract content from any URL.
1121
+
1122
+ Returns markdown by default. When \`search\` is provided, returns semantically relevant snippets instead.`,
1123
+ parameters: FetchParams.fields
776
1124
  }).annotate(ai.Tool.Readonly, true).annotate(ai.Tool.Destructive, false);
777
1125
  var Fetch = class extends effect.Effect.Service()("Fetch", {
778
1126
  dependencies: [ExpandClient.Default],
779
1127
  scoped: effect.Effect.gen(function* () {
780
1128
  const client = yield* ExpandClient;
781
- const fetch = effect.Effect.fn("Fetch.fetch")(function* ({ url, format, includeMeta }) {
782
- const formatLabel = format instanceof SnippetsFormat ? "snippets" : format;
783
- yield* effect.Effect.logDebug(`Fetching: ${url}`).pipe(effect.Effect.annotateLogs({ format: formatLabel, includeMeta }));
1129
+ const fetch = effect.Effect.fn("Fetch.fetch")(function* ({
1130
+ url,
1131
+ includeMeta,
1132
+ includeAppendix,
1133
+ includeJson,
1134
+ search
1135
+ }) {
1136
+ const hasSearch = search !== void 0;
1137
+ yield* effect.Effect.logDebug(`Fetching: ${url}`).pipe(
1138
+ effect.Effect.annotateLogs({ hasSearch, includeMeta, includeAppendix, includeJson })
1139
+ );
784
1140
  const result = yield* client.fetch({
785
1141
  url,
786
1142
  select: {
787
- markdown: format === "markdown",
788
- html: format === "html",
789
- summary: format === "summary",
790
- snippets: format instanceof SnippetsFormat ? { ...format } : void 0,
791
- meta: includeMeta
1143
+ markdown: !hasSearch,
1144
+ snippets: hasSearch ? {
1145
+ query: search.query,
1146
+ maxSnippets: search.maxResults,
1147
+ minScore: search.minScore
1148
+ } : void 0,
1149
+ meta: includeMeta,
1150
+ json: includeJson,
1151
+ appendix: includeAppendix
792
1152
  }
793
1153
  });
794
- const content = result.data.markdown ?? result.data.html ?? result.data.summary ?? result.data.snippets?.map((snippet) => `${snippet.text} (Score: ${snippet.score})`).join("\n") ?? "";
795
- yield* effect.Effect.logDebug(`\u{1F4E4} Fetched successfully: ${result.data.response.url}`);
796
- return new FetchResult2({
797
- content,
798
- url: result.data.response.url,
799
- meta: result.data.meta
800
- });
1154
+ yield* effect.Effect.logDebug(`Fetched successfully: ${result.data.response.url}`);
1155
+ return result.data;
801
1156
  }, effect.Effect.orDie);
802
1157
  return { fetch };
803
1158
  })