@effect-uai/core 0.7.0 → 0.8.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.
@@ -298,16 +298,16 @@ declare const HistoryItem: Schema.Union<readonly [Schema.Struct<{
298
298
  }>]>;
299
299
  type HistoryItem = typeof HistoryItem.Type;
300
300
  declare const isInputText: <I>(input: I) => input is I & {
301
- readonly type: "input_text";
302
301
  readonly text: string;
302
+ readonly type: "input_text";
303
303
  };
304
304
  declare const isInputImage: <I>(input: I) => input is I & {
305
305
  readonly type: "input_image";
306
306
  readonly source: ImageSource;
307
307
  };
308
308
  declare const isOutputText: <I>(input: I) => input is I & {
309
- readonly type: "output_text";
310
309
  readonly text: string;
310
+ readonly type: "output_text";
311
311
  readonly annotations?: readonly ({
312
312
  readonly type: "url_citation";
313
313
  readonly url: string;
@@ -331,20 +331,20 @@ declare const isOutputText: <I>(input: I) => input is I & {
331
331
  })[] | undefined;
332
332
  };
333
333
  declare const isRefusal: <I>(input: I) => input is I & {
334
- readonly type: "refusal";
335
334
  readonly text: string;
335
+ readonly type: "refusal";
336
336
  };
337
337
  declare const isMessage: <I>(input: I) => input is I & {
338
338
  readonly type: "message";
339
339
  readonly content: readonly ({
340
- readonly type: "input_text";
341
340
  readonly text: string;
341
+ readonly type: "input_text";
342
342
  } | {
343
343
  readonly type: "input_image";
344
344
  readonly source: ImageSource;
345
345
  } | {
346
- readonly type: "output_text";
347
346
  readonly text: string;
347
+ readonly type: "output_text";
348
348
  readonly annotations?: readonly ({
349
349
  readonly type: "url_citation";
350
350
  readonly url: string;
@@ -367,22 +367,22 @@ declare const isMessage: <I>(input: I) => input is I & {
367
367
  readonly index: number;
368
368
  })[] | undefined;
369
369
  } | {
370
- readonly type: "refusal";
371
370
  readonly text: string;
371
+ readonly type: "refusal";
372
372
  })[];
373
373
  readonly role: "user" | "assistant" | "system";
374
374
  readonly providerData?: unknown;
375
375
  };
376
376
  declare const isToolCall: <I>(input: I) => input is I & {
377
- readonly type: "function_call";
378
377
  readonly call_id: string;
379
378
  readonly name: string;
379
+ readonly type: "function_call";
380
380
  readonly arguments: string;
381
381
  readonly providerData?: unknown;
382
382
  };
383
383
  declare const isToolCallOutput: <I>(input: I) => input is I & {
384
- readonly type: "function_call_output";
385
384
  readonly call_id: string;
385
+ readonly type: "function_call_output";
386
386
  readonly output: string;
387
387
  readonly providerData?: unknown;
388
388
  };
@@ -421,4 +421,4 @@ declare const assistantText: (text: string) => Message;
421
421
  declare const toolCallOutput: (call_id: string, output: string) => ToolCallOutput;
422
422
  //#endregion
423
423
  export { isReasoning as A, isContainerFileCitation as C, isInputText as D, isInputImage as E, systemText as F, toolCallOutput as I, userText as L, isToolCall as M, isToolCallOutput as N, isMessage as O, isUrlCitation as P, assistantText as S, isFilePath as T, StopReason as _, FilePath as a, UrlCitation as b, InputText as c, Message as d, OutputText as f, Role as g, Refusal as h, FileCitation as i, isRefusal as j, isOutputText as k, InputTokensDetails as l, Reasoning as m, ContainerFileCitation as n, HistoryItem as o, OutputTokensDetails as p, ContentBlock as r, InputImage as s, Annotation as t, Items_d_exports as u, ToolCall as v, isFileCitation as w, Usage as x, ToolCallOutput as y };
424
- //# sourceMappingURL=Items-D8UaXQx_.d.mts.map
424
+ //# sourceMappingURL=Items-7ljaVxH_.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Items-D8UaXQx_.d.mts","names":[],"sources":["../src/domain/Items.ts"],"mappings":"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"}
1
+ {"version":3,"file":"Items-7ljaVxH_.d.mts","names":[],"sources":["../src/domain/Items.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { v as ToolCall, y as ToolCallOutput } from "./Items-D8UaXQx_.mjs";
1
+ import { v as ToolCall, y as ToolCallOutput } from "./Items-7ljaVxH_.mjs";
2
2
  import { Effect, Schema, Stream } from "effect";
3
3
  import * as _$effect_Cause0 from "effect/Cause";
4
4
  import { StandardJSONSchemaV1, StandardSchemaV1 } from "@standard-schema/spec";
@@ -99,4 +99,4 @@ declare const toDescriptors: <R>(tools: ReadonlyArray<AnyTool<R>>) => ReadonlyAr
99
99
  declare const execute: <Name extends string, Input, Output, R>(tool: Tool<Name, Input, Output, R>, call: ToolCall) => Effect.Effect<ToolCallOutput, ToolError, R>;
100
100
  //#endregion
101
101
  export { Tool as a, ToolInputSchema as c, fromEffectSchema as d, fromStandardSchema as f, toDescriptors as g, streaming as h, StreamingTool as i, Tool_d_exports as l, make as m, AnyStreamingTool as n, ToolDescriptor as o, isStreamingTool as p, AnyTool as r, ToolError as s, AnyPlainTool as t, execute as u };
102
- //# sourceMappingURL=Tool-CiFXYjmR.d.mts.map
102
+ //# sourceMappingURL=Tool-BKiieFXk.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tool-CiFXYjmR.d.mts","names":[],"sources":["../src/tool/Tool.ts"],"mappings":";;;;;;;;;cAEkE,cAAA;;;;;;cAGrD,SAAA,SAAkB,cAAA;;;;;;;;;;KAmBnB,eAAA,oBAAmC,gBAAA,UAA0B,KAAA,IACvE,oBAAA,UAA8B,KAAA;;;;AAvBkC;;cA8BrD,gBAAA,aAA8B,MAAA,CAAO,KAAA,wBAChD,MAAA,EAAQ,CAAA,KACP,CAAA,GAAI,eAAA,CAAgB,CAAA;;;;;;;;;;;;;;;;cAmBV,kBAAA,aAAgC,gBAAA,GAAmB,oBAAA,EAC9D,MAAA,EAAQ,CAAA,KACP,CAAA,GAAI,eAAA,CAAgB,gBAAA,CAAiB,WAAA,CAAY,CAAA;AAAA,KAGxC,IAAA;EAAA,SACD,IAAA,EAAM,IAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,MAAA,CAAO,MAAA,WAAiB,CAAA;;;;;;;WAOtD,MAAA;AAAA;;;;;AAhEX;KAwEY,cAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA,EAAa,MAAA;EAAA,SACb,MAAA;AAAA;AAAA,cAGE,IAAA,kDACX,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,MAC/B,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,KAWjB,aAAA;EAAA,SACD,KAAA;EAAA,SACA,IAAA,EAAM,IAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,MAAA,CAAO,KAAA,WAAgB,CAAA;EAAA,SACrD,QAAA,GAAW,MAAA,EAAQ,aAAA,CAAc,KAAA,MAAW,MAAA;EAAA,SAC5C,MAAA;AAAA;AAAA,cAGE,SAAA,yDACX,IAAA,EAAM,IAAA,CAAK,aAAA,CAAc,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,CAAA,gBACpD,aAAA,CAAc,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,KAEjC,gBAAA,YAA4B,aAAA,wBAAqC,CAAA;AAAA,KACjE,YAAA,YAAwB,IAAA,mBAAuB,CAAA;AAAA,KAC/C,OAAA,YAAmB,gBAAA,CAAiB,CAAA,IAAK,YAAA,CAAa,CAAA;AAAA,cAErD,eAAA,MAAsB,CAAA,EAAG,OAAA,CAAQ,CAAA,MAAK,CAAA,IAAK,gBAAA,CAAiB,CAAA;;;;;;cAQ5D,aAAA,MAAoB,KAAA,EAAO,aAAA,CAAc,OAAA,CAAQ,CAAA,OAAM,aAAA,CAAc,cAAA;;;;;;cAkBrE,OAAA,0CACX,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,GAChC,IAAA,EAAM,QAAA,KACL,MAAA,CAAO,MAAA,CAAO,cAAA,EAAgB,SAAA,EAAW,CAAA"}
1
+ {"version":3,"file":"Tool-BKiieFXk.d.mts","names":[],"sources":["../src/tool/Tool.ts"],"mappings":";;;;;;;;;cAEkE,cAAA;;;;;;cAGrD,SAAA,SAAkB,cAAA;;;;;;;;;;KAmBnB,eAAA,oBAAmC,gBAAA,UAA0B,KAAA,IACvE,oBAAA,UAA8B,KAAA;;;;AAvBkC;;cA8BrD,gBAAA,aAA8B,MAAA,CAAO,KAAA,wBAChD,MAAA,EAAQ,CAAA,KACP,CAAA,GAAI,eAAA,CAAgB,CAAA;;;;;;;;;;;;;;;;cAmBV,kBAAA,aAAgC,gBAAA,GAAmB,oBAAA,EAC9D,MAAA,EAAQ,CAAA,KACP,CAAA,GAAI,eAAA,CAAgB,gBAAA,CAAiB,WAAA,CAAY,CAAA;AAAA,KAGxC,IAAA;EAAA,SACD,IAAA,EAAM,IAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,MAAA,CAAO,MAAA,WAAiB,CAAA;;;;;;;WAOtD,MAAA;AAAA;;;;;AAhEX;KAwEY,cAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA,EAAa,MAAA;EAAA,SACb,MAAA;AAAA;AAAA,cAGE,IAAA,kDACX,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,MAC/B,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,KAWjB,aAAA;EAAA,SACD,KAAA;EAAA,SACA,IAAA,EAAM,IAAA;EAAA,SACN,WAAA;EAAA,SACA,WAAA,EAAa,eAAA,CAAgB,KAAA;EAAA,SAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,MAAA,CAAO,KAAA,WAAgB,CAAA;EAAA,SACrD,QAAA,GAAW,MAAA,EAAQ,aAAA,CAAc,KAAA,MAAW,MAAA;EAAA,SAC5C,MAAA;AAAA;AAAA,cAGE,SAAA,yDACX,IAAA,EAAM,IAAA,CAAK,aAAA,CAAc,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,CAAA,gBACpD,aAAA,CAAc,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,KAEjC,gBAAA,YAA4B,aAAA,wBAAqC,CAAA;AAAA,KACjE,YAAA,YAAwB,IAAA,mBAAuB,CAAA;AAAA,KAC/C,OAAA,YAAmB,gBAAA,CAAiB,CAAA,IAAK,YAAA,CAAa,CAAA;AAAA,cAErD,eAAA,MAAsB,CAAA,EAAG,OAAA,CAAQ,CAAA,MAAK,CAAA,IAAK,gBAAA,CAAiB,CAAA;;;;;;cAQ5D,aAAA,MAAoB,KAAA,EAAO,aAAA,CAAc,OAAA,CAAQ,CAAA,OAAM,aAAA,CAAc,cAAA;;;;;;cAkBrE,OAAA,0CACX,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,GAChC,IAAA,EAAM,QAAA,KACL,MAAA,CAAO,MAAA,CAAO,cAAA,EAAgB,SAAA,EAAW,CAAA"}
@@ -1,2 +1,2 @@
1
- import { A as isReasoning, C as isContainerFileCitation, D as isInputText, E as isInputImage, F as systemText, I as toolCallOutput, L as userText, M as isToolCall, N as isToolCallOutput, O as isMessage, P as isUrlCitation, S as assistantText, T as isFilePath, _ as StopReason, a as FilePath, b as UrlCitation, c as InputText, d as Message, f as OutputText, g as Role, h as Refusal, i as FileCitation, j as isRefusal, k as isOutputText, l as InputTokensDetails, m as Reasoning, n as ContainerFileCitation, o as HistoryItem, p as OutputTokensDetails, r as ContentBlock, s as InputImage, t as Annotation, v as ToolCall, w as isFileCitation, x as Usage, y as ToolCallOutput } from "../Items-D8UaXQx_.mjs";
1
+ import { A as isReasoning, C as isContainerFileCitation, D as isInputText, E as isInputImage, F as systemText, I as toolCallOutput, L as userText, M as isToolCall, N as isToolCallOutput, O as isMessage, P as isUrlCitation, S as assistantText, T as isFilePath, _ as StopReason, a as FilePath, b as UrlCitation, c as InputText, d as Message, f as OutputText, g as Role, h as Refusal, i as FileCitation, j as isRefusal, k as isOutputText, l as InputTokensDetails, m as Reasoning, n as ContainerFileCitation, o as HistoryItem, p as OutputTokensDetails, r as ContentBlock, s as InputImage, t as Annotation, v as ToolCall, w as isFileCitation, x as Usage, y as ToolCallOutput } from "../Items-7ljaVxH_.mjs";
2
2
  export { Annotation, ContainerFileCitation, ContentBlock, FileCitation, FilePath, HistoryItem, InputImage, InputText, InputTokensDetails, Message, OutputText, OutputTokensDetails, Reasoning, Refusal, Role, StopReason, ToolCall, ToolCallOutput, UrlCitation, Usage, assistantText, isContainerFileCitation, isFileCitation, isFilePath, isInputImage, isInputText, isMessage, isOutputText, isReasoning, isRefusal, isToolCall, isToolCallOutput, isUrlCitation, systemText, toolCallOutput, userText };
@@ -1,5 +1,5 @@
1
1
  import { i as ImageSource } from "../Image-HNmMpMTh.mjs";
2
- import { d as Message, m as Reasoning, o as HistoryItem, v as ToolCall, x as Usage, y as ToolCallOutput } from "../Items-D8UaXQx_.mjs";
2
+ import { d as Message, m as Reasoning, o as HistoryItem, v as ToolCall, x as Usage, y as ToolCallOutput } from "../Items-7ljaVxH_.mjs";
3
3
  import { i as StructuredFormat, n as JsonParseError, r as StructuredDecodeError } from "../StructuredFormat-BbN4dosH.mjs";
4
4
  import { Data, Effect, Schema, Stream } from "effect";
5
5
  import * as _$effect_Types0 from "effect/Types";
package/dist/index.d.mts CHANGED
@@ -3,14 +3,14 @@ import { n as AiError_d_exports } from "./AiError-CAX_48RU.mjs";
3
3
  import { a as Media_d_exports } from "./Media-D_CpcM1Z.mjs";
4
4
  import { o as Audio_d_exports } from "./Audio-DPlTsNdz.mjs";
5
5
  import { o as Image_d_exports } from "./Image-HNmMpMTh.mjs";
6
- import { u as Items_d_exports } from "./Items-D8UaXQx_.mjs";
6
+ import { u as Items_d_exports } from "./Items-7ljaVxH_.mjs";
7
7
  import { t as Music_d_exports } from "./domain/Music.mjs";
8
8
  import { t as Transcript_d_exports } from "./domain/Transcript.mjs";
9
9
  import { a as StructuredFormat_d_exports } from "./StructuredFormat-BbN4dosH.mjs";
10
10
  import { t as Turn_d_exports } from "./domain/Turn.mjs";
11
11
  import { t as Embedding_d_exports } from "./embedding-model/Embedding.mjs";
12
12
  import { t as EmbeddingModel_d_exports } from "./embedding-model/EmbeddingModel.mjs";
13
- import { l as Tool_d_exports } from "./Tool-CiFXYjmR.mjs";
13
+ import { l as Tool_d_exports } from "./Tool-BKiieFXk.mjs";
14
14
  import { t as LanguageModel_d_exports } from "./language-model/LanguageModel.mjs";
15
15
  import { t as MusicGenerator_d_exports } from "./music-generator/MusicGenerator.mjs";
16
16
  import { t as Memory_d_exports } from "./sandbox/Memory.mjs";
@@ -20,6 +20,8 @@ import { t as SandboxImage_d_exports } from "./sandbox/SandboxImage.mjs";
20
20
  import { t as SandboxNetwork_d_exports } from "./sandbox/SandboxNetwork.mjs";
21
21
  import { t as SpeechSynthesizer_d_exports } from "./speech-synthesizer/SpeechSynthesizer.mjs";
22
22
  import { t as Transcriber_d_exports } from "./transcriber/Transcriber.mjs";
23
+ import { t as WebSearch_d_exports } from "./web-search/WebSearch.mjs";
24
+ import { t as WebSearchTool_d_exports } from "./web-search/WebSearchTool.mjs";
23
25
  import { t as Vector_d_exports } from "./math/Vector.mjs";
24
26
  import { t as Loop_d_exports } from "./loop/Loop.mjs";
25
27
  import { t as Retry_d_exports } from "./retry/Retry.mjs";
@@ -32,4 +34,4 @@ import { t as JSONL_d_exports } from "./streaming/JSONL.mjs";
32
34
  import { t as Lines_d_exports } from "./streaming/Lines.mjs";
33
35
  import { t as SSE_d_exports } from "./streaming/SSE.mjs";
34
36
  import { t as Metrics_d_exports } from "./observability/Metrics.mjs";
35
- export { AiError_d_exports as AiError, Approval_d_exports as Approval, Audio_d_exports as Audio, Capabilities_d_exports as Capabilities, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, Items_d_exports as Items, JSONL_d_exports as JSONL, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Memory_d_exports as Memory, Metrics_d_exports as Metrics, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Retry_d_exports as Retry, SSE_d_exports as SSE, Sandbox_d_exports as Sandbox, SandboxError_d_exports as SandboxError, SandboxImage_d_exports as SandboxImage, SandboxNetwork_d_exports as SandboxNetwork, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, ToolResult_d_exports as ToolResult, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector };
37
+ export { AiError_d_exports as AiError, Approval_d_exports as Approval, Audio_d_exports as Audio, Capabilities_d_exports as Capabilities, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, Items_d_exports as Items, JSONL_d_exports as JSONL, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Memory_d_exports as Memory, Metrics_d_exports as Metrics, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Retry_d_exports as Retry, SSE_d_exports as SSE, Sandbox_d_exports as Sandbox, SandboxError_d_exports as SandboxError, SandboxImage_d_exports as SandboxImage, SandboxNetwork_d_exports as SandboxNetwork, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, ToolResult_d_exports as ToolResult, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector, WebSearch_d_exports as WebSearch, WebSearchTool_d_exports as WebSearchTool };
package/dist/index.mjs CHANGED
@@ -19,10 +19,12 @@ import { t as SandboxImage_exports } from "./sandbox/SandboxImage.mjs";
19
19
  import { t as SandboxNetwork_exports } from "./sandbox/SandboxNetwork.mjs";
20
20
  import { t as SpeechSynthesizer_exports } from "./speech-synthesizer/SpeechSynthesizer.mjs";
21
21
  import { t as Transcriber_exports } from "./transcriber/Transcriber.mjs";
22
+ import { t as WebSearch_exports } from "./web-search/WebSearch.mjs";
23
+ import { t as Tool_exports } from "./tool/Tool.mjs";
24
+ import { t as WebSearchTool_exports } from "./web-search/WebSearchTool.mjs";
22
25
  import { t as Vector_exports } from "./math/Vector.mjs";
23
26
  import { t as Loop_exports } from "./loop/Loop.mjs";
24
27
  import { t as Retry_exports } from "./retry/Retry.mjs";
25
- import { t as Tool_exports } from "./tool/Tool.mjs";
26
28
  import { t as ToolResult_exports } from "./tool/ToolResult.mjs";
27
29
  import { t as ToolEvent_exports } from "./tool/ToolEvent.mjs";
28
30
  import { t as Toolkit_exports } from "./tool/Toolkit.mjs";
@@ -32,4 +34,4 @@ import { t as JSONL_exports } from "./streaming/JSONL.mjs";
32
34
  import { t as Lines_exports } from "./streaming/Lines.mjs";
33
35
  import { t as SSE_exports } from "./streaming/SSE.mjs";
34
36
  import { t as Metrics_exports } from "./observability/Metrics.mjs";
35
- export { AiError_exports as AiError, Approval_exports as Approval, Audio_exports as Audio, Capabilities_exports as Capabilities, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, Items_exports as Items, JSONL_exports as JSONL, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Memory_exports as Memory, Metrics_exports as Metrics, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Retry_exports as Retry, SSE_exports as SSE, Sandbox_exports as Sandbox, SandboxError_exports as SandboxError, SandboxImage_exports as SandboxImage, SandboxNetwork_exports as SandboxNetwork, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Tool_exports as Tool, ToolEvent_exports as ToolEvent, ToolResult_exports as ToolResult, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector };
37
+ export { AiError_exports as AiError, Approval_exports as Approval, Audio_exports as Audio, Capabilities_exports as Capabilities, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, Items_exports as Items, JSONL_exports as JSONL, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Memory_exports as Memory, Metrics_exports as Metrics, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Retry_exports as Retry, SSE_exports as SSE, Sandbox_exports as Sandbox, SandboxError_exports as SandboxError, SandboxImage_exports as SandboxImage, SandboxNetwork_exports as SandboxNetwork, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Tool_exports as Tool, ToolEvent_exports as ToolEvent, ToolResult_exports as ToolResult, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector, WebSearch_exports as WebSearch, WebSearchTool_exports as WebSearchTool };
@@ -1,8 +1,8 @@
1
1
  import { t as AiError } from "../AiError-CAX_48RU.mjs";
2
- import { o as HistoryItem } from "../Items-D8UaXQx_.mjs";
2
+ import { o as HistoryItem } from "../Items-7ljaVxH_.mjs";
3
3
  import { i as StructuredFormat } from "../StructuredFormat-BbN4dosH.mjs";
4
4
  import { Turn, TurnEvent } from "../domain/Turn.mjs";
5
- import { o as ToolDescriptor } from "../Tool-CiFXYjmR.mjs";
5
+ import { o as ToolDescriptor } from "../Tool-BKiieFXk.mjs";
6
6
  import { Context, Effect, Stream } from "effect";
7
7
 
8
8
  //#region src/language-model/LanguageModel.d.ts
@@ -1,4 +1,4 @@
1
- import { o as HistoryItem } from "../Items-D8UaXQx_.mjs";
1
+ import { o as HistoryItem } from "../Items-7ljaVxH_.mjs";
2
2
  import { Turn } from "../domain/Turn.mjs";
3
3
  import { LanguageModel, LanguageModelService } from "../language-model/LanguageModel.mjs";
4
4
  import { Duration, Effect, Layer } from "effect";
@@ -1,4 +1,4 @@
1
- import { v as ToolCall } from "../Items-D8UaXQx_.mjs";
1
+ import { v as ToolCall } from "../Items-7ljaVxH_.mjs";
2
2
  import { ToolResult } from "./ToolResult.mjs";
3
3
  import { ToolEvent } from "./ToolEvent.mjs";
4
4
  import { Data, Effect, Queue, Scope, Stream } from "effect";
@@ -1,4 +1,4 @@
1
- import { o as HistoryItem, v as ToolCall } from "../Items-D8UaXQx_.mjs";
1
+ import { o as HistoryItem, v as ToolCall } from "../Items-7ljaVxH_.mjs";
2
2
  import { ToolResult } from "./ToolResult.mjs";
3
3
 
4
4
  //#region src/tool/HistoryCheck.d.ts
@@ -1,2 +1,2 @@
1
- import { a as Tool, c as ToolInputSchema, d as fromEffectSchema, f as fromStandardSchema, g as toDescriptors, h as streaming, i as StreamingTool, m as make, n as AnyStreamingTool, o as ToolDescriptor, p as isStreamingTool, r as AnyTool, s as ToolError, t as AnyPlainTool, u as execute } from "../Tool-CiFXYjmR.mjs";
1
+ import { a as Tool, c as ToolInputSchema, d as fromEffectSchema, f as fromStandardSchema, g as toDescriptors, h as streaming, i as StreamingTool, m as make, n as AnyStreamingTool, o as ToolDescriptor, p as isStreamingTool, r as AnyTool, s as ToolError, t as AnyPlainTool, u as execute } from "../Tool-BKiieFXk.mjs";
2
2
  export { AnyPlainTool, AnyStreamingTool, AnyTool, StreamingTool, Tool, ToolDescriptor, ToolError, ToolInputSchema, execute, fromEffectSchema, fromStandardSchema, isStreamingTool, make, streaming, toDescriptors };
@@ -1,4 +1,4 @@
1
- import { v as ToolCall, y as ToolCallOutput } from "../Items-D8UaXQx_.mjs";
1
+ import { v as ToolCall, y as ToolCallOutput } from "../Items-7ljaVxH_.mjs";
2
2
  import { Data } from "effect";
3
3
  import * as _$effect_Unify0 from "effect/Unify";
4
4
 
@@ -1,6 +1,6 @@
1
- import { o as HistoryItem, v as ToolCall } from "../Items-D8UaXQx_.mjs";
1
+ import { o as HistoryItem, v as ToolCall } from "../Items-7ljaVxH_.mjs";
2
2
  import { Turn } from "../domain/Turn.mjs";
3
- import { a as Tool, i as StreamingTool, r as AnyTool } from "../Tool-CiFXYjmR.mjs";
3
+ import { a as Tool, i as StreamingTool, r as AnyTool } from "../Tool-BKiieFXk.mjs";
4
4
  import { Step } from "../loop/Loop.mjs";
5
5
  import { ToolResult } from "./ToolResult.mjs";
6
6
  import { ToolEvent } from "./ToolEvent.mjs";
@@ -1,7 +1,7 @@
1
1
  import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
2
  import { appendToHistory } from "../domain/Turn.mjs";
3
- import { next, value } from "../loop/Loop.mjs";
4
3
  import { isStreamingTool } from "./Tool.mjs";
4
+ import { next, value } from "../loop/Loop.mjs";
5
5
  import { ToolResult, executionError, failed, toToolCallOutput } from "./ToolResult.mjs";
6
6
  import { ToolEvent, isOutput } from "./ToolEvent.mjs";
7
7
  import { Array, Effect, Function, Ref, Schema, Stream } from "effect";
@@ -0,0 +1,119 @@
1
+ import { t as AiError } from "../AiError-CAX_48RU.mjs";
2
+ import { Context, DateTime, Effect, Schema } from "effect";
3
+
4
+ //#region src/web-search/WebSearch.d.ts
5
+ declare namespace WebSearch_d_exports {
6
+ export { CommonSearchRequest, SearchRecency, SearchResponse, SearchResult, WebSearch, WebSearchService, search };
7
+ }
8
+ /**
9
+ * Convenience freshness enum shared by every provider. A coarse "published
10
+ * within the last …" filter that maps onto each provider's native recency
11
+ * knob (Perplexity `search_recency_filter`, Brave `freshness`, Tavily
12
+ * `time_range`, You.com `freshness`), or onto a computed published-date
13
+ * range where a provider has no enum (Exa).
14
+ *
15
+ * For a precise window use {@link CommonSearchRequest.startDate} /
16
+ * {@link CommonSearchRequest.endDate} instead; `recency` is the sugar for
17
+ * the common "past week / past month" case.
18
+ *
19
+ * Exposed as a `Schema` so {@link "../web-search/WebSearchTool".webSearchTool}
20
+ * can hand it straight to a model as a tool parameter; the
21
+ * {@link SearchRecency} type is derived from it.
22
+ */
23
+ declare const SearchRecency: Schema.Literals<readonly ["hour", "day", "week", "month", "year"]>;
24
+ type SearchRecency = typeof SearchRecency.Type;
25
+ /**
26
+ * Cross-provider web-search request. A field earns a place here only if
27
+ * most of the supported providers honor it and a developer would expect it
28
+ * from a generic search interface; everything provider-specific (Exa
29
+ * `type`, Tavily `searchDepth`, Brave `goggles`, pagination `offset`,
30
+ * `safeSearch`, `topic`, …) lives on that provider's typed request.
31
+ *
32
+ * Note the one structural difference from `EmbeddingModel` /
33
+ * `Transcriber`: there is no `model`. None of the pure-`/search` endpoints
34
+ * take one - what looks model-shaped on a provider (Exa `type`, Tavily
35
+ * `searchDepth`) is a mode knob, so it stays on the provider-typed request.
36
+ */
37
+ type CommonSearchRequest = {
38
+ /** The search query. The one field every provider requires. */readonly query: string;
39
+ /**
40
+ * Upper bound on the number of results to return in this one call.
41
+ * Providers cap differently (Perplexity / Tavily / Brave at ~20, Exa /
42
+ * You.com at ~100); a value above a provider's cap is clamped by that
43
+ * provider. There is no common pagination - only two providers paginate
44
+ * and only shallowly, so `offset` is provider-typed.
45
+ */
46
+ readonly maxResults?: number; /** Restrict results to these domains (e.g. `["docs.foo.com"]`). */
47
+ readonly includeDomains?: ReadonlyArray<string>; /** Drop results from these domains. */
48
+ readonly excludeDomains?: ReadonlyArray<string>;
49
+ /**
50
+ * Coarse freshness filter - see {@link SearchRecency}. Sugar over an
51
+ * explicit `startDate`; ignored where {@link startDate} is also set and
52
+ * the provider takes only one.
53
+ */
54
+ readonly recency?: SearchRecency; /** Published-after bound. The precise alternative to {@link recency}. */
55
+ readonly startDate?: DateTime.DateTime; /** Published-before bound. */
56
+ readonly endDate?: DateTime.DateTime; /** ISO 3166-1 alpha-2 country code to localize results (e.g. `"us"`). */
57
+ readonly country?: string; /** ISO 639-1 language code to bias results toward (e.g. `"en"`). */
58
+ readonly language?: string;
59
+ };
60
+ /**
61
+ * One normalized web-search hit. A flat record with optionals rather than a
62
+ * tagged union: the providers differ by *which fields are present*, not by
63
+ * *kind*. The provider's untouched result object is always on `raw`, so a
64
+ * caller holding a typed provider tag can recover anything not promoted
65
+ * here (`author`, `favicon`, multi-chunk `snippets[]`, …).
66
+ */
67
+ type SearchResult = {
68
+ /** Canonical result URL. Always present. */readonly url: string; /** Result title / headline, when the provider returns one. */
69
+ readonly title?: string;
70
+ /**
71
+ * Primary short excerpt - the one text field all providers return (under
72
+ * various wire names: `snippet`, `content`, `description`). The richer
73
+ * extract fields (`text`, `highlights`, `summary`) belong to the
74
+ * out-of-scope extract feature and stay on the provider-typed result.
75
+ */
76
+ readonly snippet?: string; /** Publication date, when the provider reports one. */
77
+ readonly publishedDate?: DateTime.DateTime;
78
+ /**
79
+ * Relevance score, only from providers that rank (Exa, Tavily);
80
+ * `undefined` for providers that return an unscored list. Kept despite
81
+ * being non-universal because ranking is core to what a "search result"
82
+ * means - and `undefined` cleanly says "this backend doesn't score."
83
+ */
84
+ readonly score?: number; /** The provider-native result object, never lossy. */
85
+ readonly raw: unknown;
86
+ };
87
+ type SearchResponse = {
88
+ readonly results: ReadonlyArray<SearchResult>;
89
+ /**
90
+ * The provider-native top-level response object. Cost / usage reporting
91
+ * is deliberately not modeled on this surface yet: providers disagree on
92
+ * both what (Exa returns USD, Tavily credits, Brave nothing in-body) and
93
+ * where (Brave reports cost in response headers), so it is deferred to the
94
+ * unified usage design (see plans/usage-tracking.md). Anything a provider
95
+ * reports survives here on `raw`.
96
+ */
97
+ readonly raw: unknown;
98
+ };
99
+ /**
100
+ * The portable web-search surface: one operation, `search`. Pure search is
101
+ * the one thing every provider does, so - unlike `SpeechSynthesizer` /
102
+ * `Transcriber` - this capability needs no marker tags; every provider
103
+ * Layer can answer.
104
+ */
105
+ type WebSearchService = {
106
+ readonly search: (request: CommonSearchRequest) => Effect.Effect<SearchResponse, AiError>;
107
+ };
108
+ declare const WebSearch_base: Context.ServiceClass<WebSearch, "@betalyra/effect-uai/WebSearch", WebSearchService>;
109
+ /**
110
+ * Generic web-search service tag. Yield this for provider-portable code;
111
+ * yield a provider tag (`PerplexitySearch`, `ExaSearch`, …) when you need
112
+ * that provider's own knobs. A provider's `layer` registers both.
113
+ */
114
+ declare class WebSearch extends WebSearch_base {}
115
+ /** Run one web search against whichever provider Layer is in scope. */
116
+ declare const search: (request: CommonSearchRequest) => Effect.Effect<SearchResponse, AiError, WebSearch>;
117
+ //#endregion
118
+ export { CommonSearchRequest, SearchRecency, SearchResponse, SearchResult, WebSearch, WebSearchService, search, WebSearch_d_exports as t };
119
+ //# sourceMappingURL=WebSearch.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSearch.d.mts","names":[],"sources":["../../src/web-search/WebSearch.ts"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA;;;cAAa,aAAA,EAAa,MAAA,CAAA,QAAA;AAAA,KAEd,aAAA,UAAuB,aAAA,CAAc,IAAA;AAAjD;;;;;AAkBA;;;;;;;AAlBA,KAkBY,mBAAA;EAwB0B,wEAtB3B,KAAA;EAAA;;;;;;;EAAA,SAQA,UAAA,WAYA;EAAA,SAVA,cAAA,GAAiB,aAAA,UAUI;EAAA,SARrB,cAAA,GAAiB,aAAA;EAUP;;;;;EAAA,SAJV,OAAA,GAAU,aAAA,EAsBT;EAAA,SApBD,SAAA,GAAY,QAAA,CAAS,QAAA;WAErB,OAAA,GAAU,QAAA,CAAS,QAAA,EAoBnB;EAAA,SAlBA,OAAA,WA2BA;EAAA,SAzBA,QAAA;AAAA;;;;;;AAuCX;;KAzBY,YAAA;EA0BqB,qDAxBtB,GAAA,UAwBS;EAAA,SAtBT,KAAA;EA+BA;;;AAaX;;;EAbW,SAxBA,OAAA,WAsCwD;EAAA,SApCxD,aAAA,GAAgB,QAAA,CAAS,QAAA;EAoCiB;;;;;;EAAA,SA7B1C,KAAA,WA6BiD;EAAA,SA3BjD,GAAA;AAAA;AAAA,KAGC,cAAA;EAAA,SACD,OAAA,EAAS,aAAA,CAAc,YAAA;EAuBgE;AACjG;;;;;;;EADiG,SAdvF,GAAA;AAAA;;;;;;AAsBX;KATY,gBAAA;EAAA,SACD,MAAA,GAAS,OAAA,EAAS,mBAAA,KAAwB,MAAA,CAAO,MAAA,CAAO,cAAA,EAAgB,OAAA;AAAA;AAAA,cAClF,cAAA;AAYD;;;;;AAAA,cALa,SAAA,SAAkB,cAAA;;cAKlB,MAAA,GACX,OAAA,EAAS,mBAAA,KACR,MAAA,CAAO,MAAA,CAAO,cAAA,EAAgB,OAAA,EAAiB,SAAA"}
@@ -0,0 +1,42 @@
1
+ import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
+ import { Context, Effect, Schema } from "effect";
3
+ //#region src/web-search/WebSearch.ts
4
+ var WebSearch_exports = /* @__PURE__ */ __exportAll({
5
+ SearchRecency: () => SearchRecency,
6
+ WebSearch: () => WebSearch,
7
+ search: () => search
8
+ });
9
+ /**
10
+ * Convenience freshness enum shared by every provider. A coarse "published
11
+ * within the last …" filter that maps onto each provider's native recency
12
+ * knob (Perplexity `search_recency_filter`, Brave `freshness`, Tavily
13
+ * `time_range`, You.com `freshness`), or onto a computed published-date
14
+ * range where a provider has no enum (Exa).
15
+ *
16
+ * For a precise window use {@link CommonSearchRequest.startDate} /
17
+ * {@link CommonSearchRequest.endDate} instead; `recency` is the sugar for
18
+ * the common "past week / past month" case.
19
+ *
20
+ * Exposed as a `Schema` so {@link "../web-search/WebSearchTool".webSearchTool}
21
+ * can hand it straight to a model as a tool parameter; the
22
+ * {@link SearchRecency} type is derived from it.
23
+ */
24
+ const SearchRecency = Schema.Literals([
25
+ "hour",
26
+ "day",
27
+ "week",
28
+ "month",
29
+ "year"
30
+ ]);
31
+ /**
32
+ * Generic web-search service tag. Yield this for provider-portable code;
33
+ * yield a provider tag (`PerplexitySearch`, `ExaSearch`, …) when you need
34
+ * that provider's own knobs. A provider's `layer` registers both.
35
+ */
36
+ var WebSearch = class extends Context.Service()("@betalyra/effect-uai/WebSearch") {};
37
+ /** Run one web search against whichever provider Layer is in scope. */
38
+ const search = (request) => Effect.flatMap(WebSearch.asEffect(), (s) => s.search(request));
39
+ //#endregion
40
+ export { SearchRecency, WebSearch, search, WebSearch_exports as t };
41
+
42
+ //# sourceMappingURL=WebSearch.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSearch.mjs","names":[],"sources":["../../src/web-search/WebSearch.ts"],"sourcesContent":["import { Context, type DateTime, Effect, Schema } from \"effect\"\nimport type * as AiError from \"../domain/AiError.js\"\n\n// ---------------------------------------------------------------------------\n// Recency\n// ---------------------------------------------------------------------------\n\n/**\n * Convenience freshness enum shared by every provider. A coarse \"published\n * within the last …\" filter that maps onto each provider's native recency\n * knob (Perplexity `search_recency_filter`, Brave `freshness`, Tavily\n * `time_range`, You.com `freshness`), or onto a computed published-date\n * range where a provider has no enum (Exa).\n *\n * For a precise window use {@link CommonSearchRequest.startDate} /\n * {@link CommonSearchRequest.endDate} instead; `recency` is the sugar for\n * the common \"past week / past month\" case.\n *\n * Exposed as a `Schema` so {@link \"../web-search/WebSearchTool\".webSearchTool}\n * can hand it straight to a model as a tool parameter; the\n * {@link SearchRecency} type is derived from it.\n */\nexport const SearchRecency = Schema.Literals([\"hour\", \"day\", \"week\", \"month\", \"year\"])\n\nexport type SearchRecency = typeof SearchRecency.Type\n\n// ---------------------------------------------------------------------------\n// Request\n// ---------------------------------------------------------------------------\n\n/**\n * Cross-provider web-search request. A field earns a place here only if\n * most of the supported providers honor it and a developer would expect it\n * from a generic search interface; everything provider-specific (Exa\n * `type`, Tavily `searchDepth`, Brave `goggles`, pagination `offset`,\n * `safeSearch`, `topic`, …) lives on that provider's typed request.\n *\n * Note the one structural difference from `EmbeddingModel` /\n * `Transcriber`: there is no `model`. None of the pure-`/search` endpoints\n * take one - what looks model-shaped on a provider (Exa `type`, Tavily\n * `searchDepth`) is a mode knob, so it stays on the provider-typed request.\n */\nexport type CommonSearchRequest = {\n /** The search query. The one field every provider requires. */\n readonly query: string\n /**\n * Upper bound on the number of results to return in this one call.\n * Providers cap differently (Perplexity / Tavily / Brave at ~20, Exa /\n * You.com at ~100); a value above a provider's cap is clamped by that\n * provider. There is no common pagination - only two providers paginate\n * and only shallowly, so `offset` is provider-typed.\n */\n readonly maxResults?: number\n /** Restrict results to these domains (e.g. `[\"docs.foo.com\"]`). */\n readonly includeDomains?: ReadonlyArray<string>\n /** Drop results from these domains. */\n readonly excludeDomains?: ReadonlyArray<string>\n /**\n * Coarse freshness filter - see {@link SearchRecency}. Sugar over an\n * explicit `startDate`; ignored where {@link startDate} is also set and\n * the provider takes only one.\n */\n readonly recency?: SearchRecency\n /** Published-after bound. The precise alternative to {@link recency}. */\n readonly startDate?: DateTime.DateTime\n /** Published-before bound. */\n readonly endDate?: DateTime.DateTime\n /** ISO 3166-1 alpha-2 country code to localize results (e.g. `\"us\"`). */\n readonly country?: string\n /** ISO 639-1 language code to bias results toward (e.g. `\"en\"`). */\n readonly language?: string\n}\n\n// ---------------------------------------------------------------------------\n// Response\n// ---------------------------------------------------------------------------\n\n/**\n * One normalized web-search hit. A flat record with optionals rather than a\n * tagged union: the providers differ by *which fields are present*, not by\n * *kind*. The provider's untouched result object is always on `raw`, so a\n * caller holding a typed provider tag can recover anything not promoted\n * here (`author`, `favicon`, multi-chunk `snippets[]`, …).\n */\nexport type SearchResult = {\n /** Canonical result URL. Always present. */\n readonly url: string\n /** Result title / headline, when the provider returns one. */\n readonly title?: string\n /**\n * Primary short excerpt - the one text field all providers return (under\n * various wire names: `snippet`, `content`, `description`). The richer\n * extract fields (`text`, `highlights`, `summary`) belong to the\n * out-of-scope extract feature and stay on the provider-typed result.\n */\n readonly snippet?: string\n /** Publication date, when the provider reports one. */\n readonly publishedDate?: DateTime.DateTime\n /**\n * Relevance score, only from providers that rank (Exa, Tavily);\n * `undefined` for providers that return an unscored list. Kept despite\n * being non-universal because ranking is core to what a \"search result\"\n * means - and `undefined` cleanly says \"this backend doesn't score.\"\n */\n readonly score?: number\n /** The provider-native result object, never lossy. */\n readonly raw: unknown\n}\n\nexport type SearchResponse = {\n readonly results: ReadonlyArray<SearchResult>\n /**\n * The provider-native top-level response object. Cost / usage reporting\n * is deliberately not modeled on this surface yet: providers disagree on\n * both what (Exa returns USD, Tavily credits, Brave nothing in-body) and\n * where (Brave reports cost in response headers), so it is deferred to the\n * unified usage design (see plans/usage-tracking.md). Anything a provider\n * reports survives here on `raw`.\n */\n readonly raw: unknown\n}\n\n// ---------------------------------------------------------------------------\n// Service + helper\n// ---------------------------------------------------------------------------\n\n/**\n * The portable web-search surface: one operation, `search`. Pure search is\n * the one thing every provider does, so - unlike `SpeechSynthesizer` /\n * `Transcriber` - this capability needs no marker tags; every provider\n * Layer can answer.\n */\nexport type WebSearchService = {\n readonly search: (request: CommonSearchRequest) => Effect.Effect<SearchResponse, AiError.AiError>\n}\n\n/**\n * Generic web-search service tag. Yield this for provider-portable code;\n * yield a provider tag (`PerplexitySearch`, `ExaSearch`, …) when you need\n * that provider's own knobs. A provider's `layer` registers both.\n */\nexport class WebSearch extends Context.Service<WebSearch, WebSearchService>()(\n \"@betalyra/effect-uai/WebSearch\",\n) {}\n\n/** Run one web search against whichever provider Layer is in scope. */\nexport const search = (\n request: CommonSearchRequest,\n): Effect.Effect<SearchResponse, AiError.AiError, WebSearch> =>\n Effect.flatMap(WebSearch.asEffect(), (s) => s.search(request))\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,gBAAgB,OAAO,SAAS;CAAC;CAAQ;CAAO;CAAQ;CAAS;CAAO,CAAC;;;;;;AAuHtF,IAAa,YAAb,cAA+B,QAAQ,SAAsC,CAC3E,iCACD,CAAC;;AAGF,MAAa,UACX,YAEA,OAAO,QAAQ,UAAU,UAAU,GAAG,MAAM,EAAE,OAAO,QAAQ,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { a as Tool } from "../Tool-BKiieFXk.mjs";
2
+ import { SearchResult, WebSearch } from "./WebSearch.mjs";
3
+ import { Schema } from "effect";
4
+
5
+ //#region src/web-search/WebSearchTool.d.ts
6
+ declare namespace WebSearchTool_d_exports {
7
+ export { WebSearchToolArgs, WebSearchToolOptions, webSearchTool };
8
+ }
9
+ /**
10
+ * Model-facing argument schema. Deliberately narrow: `query` plus the one
11
+ * filter that is genuinely the model's call - `recency` (it knows whether a
12
+ * question is about current events or evergreen). App-policy scoping
13
+ * (`includeDomains` / `excludeDomains`) and the `maxResults` cost ceiling
14
+ * are pinned on the constructor instead, so they are guaranteed rather than
15
+ * left to the model to remember each call.
16
+ */
17
+ declare const WebSearchToolArgs: Schema.Struct<{
18
+ readonly query: Schema.String;
19
+ readonly recency: Schema.optional<Schema.Literals<readonly ["hour", "day", "week", "month", "year"]>>;
20
+ }>;
21
+ type WebSearchToolArgs = typeof WebSearchToolArgs.Type;
22
+ type WebSearchToolOptions = {
23
+ /** Tool name the model sees. Default `"web_search"`. */readonly name?: string;
24
+ /**
25
+ * App-fixed ceiling on results per call - a cost guard, not exposed to
26
+ * the model. Default `5`.
27
+ */
28
+ readonly maxResults?: number;
29
+ /**
30
+ * App-fixed allowlist applied to every search. A policy scope ("only
31
+ * search our docs"), not a model knob - so it is enforced, not requested.
32
+ */
33
+ readonly includeDomains?: ReadonlyArray<string>; /** App-fixed denylist applied to every search ("never return X"). */
34
+ readonly excludeDomains?: ReadonlyArray<string>;
35
+ /**
36
+ * Override how results are rendered into the model-facing string.
37
+ * Default: a numbered `title / url / snippet` list.
38
+ */
39
+ readonly render?: (results: ReadonlyArray<SearchResult>) => string;
40
+ };
41
+ /**
42
+ * The canonical web-search tool. Its `R` is just `WebSearch`, so providing
43
+ * any search-provider Layer satisfies it and the model-facing contract
44
+ * (name, description, schema) is identical no matter which backend answers
45
+ * - swap `PerplexitySearch.layer` for `ExaSearch.layer` and the tool the
46
+ * model sees does not change. Drops straight into a `Toolkit` and the
47
+ * `LanguageModel` tool-calling loop.
48
+ *
49
+ * The model controls only `query` and `recency`; domain scoping and the
50
+ * result cap are app policy, fixed here on the constructor. `Output` is
51
+ * rendered text, not raw `SearchResult[]`: the model reads the list, while
52
+ * the app still gets the structured results through the normal tool-result
53
+ * channel. Pass `render` to change the format.
54
+ */
55
+ declare const webSearchTool: (options?: WebSearchToolOptions) => Tool<string, WebSearchToolArgs, string, WebSearch>;
56
+ //#endregion
57
+ export { WebSearchToolArgs, WebSearchToolOptions, WebSearchTool_d_exports as t, webSearchTool };
58
+ //# sourceMappingURL=WebSearchTool.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSearchTool.d.mts","names":[],"sources":["../../src/web-search/WebSearchTool.ts"],"mappings":";;;;;;;;;;;;;;;;cAYM,iBAAA,EAAiB,MAAA,CAAA,MAAA;EAAA;;;KAKX,iBAAA,UAA2B,iBAAA,CAAkB,IAAA;AAAA,KAa7C,oBAAA;EAlBW,iEAoBZ,IAAA;EApBY;;;;EAAA,SAyBZ,UAAA;;;;;WAKA,cAAA,GAAiB,aAAA;WAEjB,cAAA,GAAiB,aAAA;;AA3B5B;;;WAgCW,MAAA,IAAU,OAAA,EAAS,aAAA,CAAc,YAAA;AAAA;AAnB5C;;;;;;;;;;;;;;AAAA,cAoCa,aAAA,GACX,OAAA,GAAU,oBAAA,KACT,IAAA,SAAkB,iBAAA,UAA2B,SAAA"}
@@ -0,0 +1,69 @@
1
+ import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
2
+ import { SearchRecency, search } from "./WebSearch.mjs";
3
+ import { fromEffectSchema, make } from "../tool/Tool.mjs";
4
+ import { Effect, Schema } from "effect";
5
+ //#region src/web-search/WebSearchTool.ts
6
+ var WebSearchTool_exports = /* @__PURE__ */ __exportAll({ webSearchTool: () => webSearchTool });
7
+ /**
8
+ * Model-facing argument schema. Deliberately narrow: `query` plus the one
9
+ * filter that is genuinely the model's call - `recency` (it knows whether a
10
+ * question is about current events or evergreen). App-policy scoping
11
+ * (`includeDomains` / `excludeDomains`) and the `maxResults` cost ceiling
12
+ * are pinned on the constructor instead, so they are guaranteed rather than
13
+ * left to the model to remember each call.
14
+ */
15
+ const WebSearchToolArgs = Schema.Struct({
16
+ query: Schema.String,
17
+ recency: Schema.optional(SearchRecency)
18
+ });
19
+ /** Numbered `title / url / snippet` list - what a model reads best. */
20
+ const defaultRender = (results) => results.length === 0 ? "No results found." : results.map((r, i) => {
21
+ const head = `${i + 1}. ${r.title ?? r.url}\n ${r.url}`;
22
+ return r.snippet === void 0 ? head : `${head}\n ${r.snippet}`;
23
+ }).join("\n\n");
24
+ /**
25
+ * The canonical web-search tool. Its `R` is just `WebSearch`, so providing
26
+ * any search-provider Layer satisfies it and the model-facing contract
27
+ * (name, description, schema) is identical no matter which backend answers
28
+ * - swap `PerplexitySearch.layer` for `ExaSearch.layer` and the tool the
29
+ * model sees does not change. Drops straight into a `Toolkit` and the
30
+ * `LanguageModel` tool-calling loop.
31
+ *
32
+ * The model controls only `query` and `recency`; domain scoping and the
33
+ * result cap are app policy, fixed here on the constructor. `Output` is
34
+ * rendered text, not raw `SearchResult[]`: the model reads the list, while
35
+ * the app still gets the structured results through the normal tool-result
36
+ * channel. Pass `render` to change the format.
37
+ */
38
+ const webSearchTool = (options) => {
39
+ const name = options?.name ?? "web_search";
40
+ const render = options?.render ?? defaultRender;
41
+ const maxResults = options?.maxResults ?? 5;
42
+ const includeDomains = options?.includeDomains;
43
+ const excludeDomains = options?.excludeDomains;
44
+ return make({
45
+ name,
46
+ description: "Search the web for current information. Returns ranked results with titles, URLs, and snippets.",
47
+ inputSchema: fromEffectSchema(WebSearchToolArgs),
48
+ run: (args) => search({
49
+ query: args.query,
50
+ maxResults,
51
+ ...args.recency !== void 0 && { recency: args.recency },
52
+ ...includeDomains !== void 0 && { includeDomains },
53
+ ...excludeDomains !== void 0 && { excludeDomains }
54
+ }).pipe(Effect.tap((r) => Effect.annotateCurrentSpan("web_search.result_count", r.results.length)), Effect.map((r) => render(r.results)), Effect.withSpan(name, {
55
+ kind: "client",
56
+ attributes: {
57
+ "web_search.query": args.query,
58
+ "web_search.max_results": maxResults,
59
+ ...args.recency !== void 0 && { "web_search.recency": args.recency },
60
+ ...includeDomains !== void 0 && { "web_search.include_domains": includeDomains },
61
+ ...excludeDomains !== void 0 && { "web_search.exclude_domains": excludeDomains }
62
+ }
63
+ }))
64
+ });
65
+ };
66
+ //#endregion
67
+ export { WebSearchTool_exports as t, webSearchTool };
68
+
69
+ //# sourceMappingURL=WebSearchTool.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSearchTool.mjs","names":["Tool.make","Tool.fromEffectSchema"],"sources":["../../src/web-search/WebSearchTool.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\"\nimport * as Tool from \"../tool/Tool.js\"\nimport { search, SearchRecency, type SearchResult, WebSearch } from \"./WebSearch.js\"\n\n/**\n * Model-facing argument schema. Deliberately narrow: `query` plus the one\n * filter that is genuinely the model's call - `recency` (it knows whether a\n * question is about current events or evergreen). App-policy scoping\n * (`includeDomains` / `excludeDomains`) and the `maxResults` cost ceiling\n * are pinned on the constructor instead, so they are guaranteed rather than\n * left to the model to remember each call.\n */\nconst WebSearchToolArgs = Schema.Struct({\n query: Schema.String,\n recency: Schema.optional(SearchRecency),\n})\n\nexport type WebSearchToolArgs = typeof WebSearchToolArgs.Type\n\n/** Numbered `title / url / snippet` list - what a model reads best. */\nconst defaultRender = (results: ReadonlyArray<SearchResult>): string =>\n results.length === 0\n ? \"No results found.\"\n : results\n .map((r, i) => {\n const head = `${i + 1}. ${r.title ?? r.url}\\n ${r.url}`\n return r.snippet === undefined ? head : `${head}\\n ${r.snippet}`\n })\n .join(\"\\n\\n\")\n\nexport type WebSearchToolOptions = {\n /** Tool name the model sees. Default `\"web_search\"`. */\n readonly name?: string\n /**\n * App-fixed ceiling on results per call - a cost guard, not exposed to\n * the model. Default `5`.\n */\n readonly maxResults?: number\n /**\n * App-fixed allowlist applied to every search. A policy scope (\"only\n * search our docs\"), not a model knob - so it is enforced, not requested.\n */\n readonly includeDomains?: ReadonlyArray<string>\n /** App-fixed denylist applied to every search (\"never return X\"). */\n readonly excludeDomains?: ReadonlyArray<string>\n /**\n * Override how results are rendered into the model-facing string.\n * Default: a numbered `title / url / snippet` list.\n */\n readonly render?: (results: ReadonlyArray<SearchResult>) => string\n}\n\n/**\n * The canonical web-search tool. Its `R` is just `WebSearch`, so providing\n * any search-provider Layer satisfies it and the model-facing contract\n * (name, description, schema) is identical no matter which backend answers\n * - swap `PerplexitySearch.layer` for `ExaSearch.layer` and the tool the\n * model sees does not change. Drops straight into a `Toolkit` and the\n * `LanguageModel` tool-calling loop.\n *\n * The model controls only `query` and `recency`; domain scoping and the\n * result cap are app policy, fixed here on the constructor. `Output` is\n * rendered text, not raw `SearchResult[]`: the model reads the list, while\n * the app still gets the structured results through the normal tool-result\n * channel. Pass `render` to change the format.\n */\nexport const webSearchTool = (\n options?: WebSearchToolOptions,\n): Tool.Tool<string, WebSearchToolArgs, string, WebSearch> => {\n const name = options?.name ?? \"web_search\"\n const render = options?.render ?? defaultRender\n const maxResults = options?.maxResults ?? 5\n const includeDomains = options?.includeDomains\n const excludeDomains = options?.excludeDomains\n return Tool.make({\n name,\n description:\n \"Search the web for current information. Returns ranked results with titles, URLs, and snippets.\",\n inputSchema: Tool.fromEffectSchema(WebSearchToolArgs),\n // The call is wrapped in a tracing span so agent traces show the tool\n // invocation (query, filters, result count) nested under the model turn.\n // `withSpan` is a no-op until a Tracer is installed, so this is free by\n // default and adds nothing to the requirements.\n run: (args) =>\n search({\n query: args.query,\n maxResults,\n ...(args.recency !== undefined && { recency: args.recency }),\n ...(includeDomains !== undefined && { includeDomains }),\n ...(excludeDomains !== undefined && { excludeDomains }),\n }).pipe(\n Effect.tap((r) => Effect.annotateCurrentSpan(\"web_search.result_count\", r.results.length)),\n Effect.map((r) => render(r.results)),\n Effect.withSpan(name, {\n kind: \"client\",\n attributes: {\n \"web_search.query\": args.query,\n \"web_search.max_results\": maxResults,\n ...(args.recency !== undefined && { \"web_search.recency\": args.recency }),\n ...(includeDomains !== undefined && { \"web_search.include_domains\": includeDomains }),\n ...(excludeDomains !== undefined && { \"web_search.exclude_domains\": excludeDomains }),\n },\n }),\n ),\n })\n}\n"],"mappings":";;;;;;;;;;;;;;AAYA,MAAM,oBAAoB,OAAO,OAAO;CACtC,OAAO,OAAO;CACd,SAAS,OAAO,SAAS,cAAc;CACxC,CAAC;;AAKF,MAAM,iBAAiB,YACrB,QAAQ,WAAW,IACf,sBACA,QACG,KAAK,GAAG,MAAM;CACb,MAAM,OAAO,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,OAAO,EAAE;AACpD,QAAO,EAAE,YAAY,KAAA,IAAY,OAAO,GAAG,KAAK,OAAO,EAAE;EACzD,CACD,KAAK,OAAO;;;;;;;;;;;;;;;AAsCrB,MAAa,iBACX,YAC4D;CAC5D,MAAM,OAAO,SAAS,QAAQ;CAC9B,MAAM,SAAS,SAAS,UAAU;CAClC,MAAM,aAAa,SAAS,cAAc;CAC1C,MAAM,iBAAiB,SAAS;CAChC,MAAM,iBAAiB,SAAS;AAChC,QAAOA,KAAU;EACf;EACA,aACE;EACF,aAAaC,iBAAsB,kBAAkB;EAKrD,MAAM,SACJ,OAAO;GACL,OAAO,KAAK;GACZ;GACA,GAAI,KAAK,YAAY,KAAA,KAAa,EAAE,SAAS,KAAK,SAAS;GAC3D,GAAI,mBAAmB,KAAA,KAAa,EAAE,gBAAgB;GACtD,GAAI,mBAAmB,KAAA,KAAa,EAAE,gBAAgB;GACvD,CAAC,CAAC,KACD,OAAO,KAAK,MAAM,OAAO,oBAAoB,2BAA2B,EAAE,QAAQ,OAAO,CAAC,EAC1F,OAAO,KAAK,MAAM,OAAO,EAAE,QAAQ,CAAC,EACpC,OAAO,SAAS,MAAM;GACpB,MAAM;GACN,YAAY;IACV,oBAAoB,KAAK;IACzB,0BAA0B;IAC1B,GAAI,KAAK,YAAY,KAAA,KAAa,EAAE,sBAAsB,KAAK,SAAS;IACxE,GAAI,mBAAmB,KAAA,KAAa,EAAE,8BAA8B,gBAAgB;IACpF,GAAI,mBAAmB,KAAA,KAAa,EAAE,8BAA8B,gBAAgB;IACrF;GACF,CAAC,CACH;EACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-uai/core",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Low-level primitives (loop, conversation, items, tools, streaming codecs) for building AI agents with Effect.",
5
5
  "keywords": [
6
6
  "agents",
@@ -110,6 +110,14 @@
110
110
  "types": "./dist/transcriber/Transcriber.d.mts",
111
111
  "import": "./dist/transcriber/Transcriber.mjs"
112
112
  },
113
+ "./WebSearch": {
114
+ "types": "./dist/web-search/WebSearch.d.mts",
115
+ "import": "./dist/web-search/WebSearch.mjs"
116
+ },
117
+ "./WebSearchTool": {
118
+ "types": "./dist/web-search/WebSearchTool.d.mts",
119
+ "import": "./dist/web-search/WebSearchTool.mjs"
120
+ },
113
121
  "./Loop": {
114
122
  "types": "./dist/loop/Loop.d.mts",
115
123
  "import": "./dist/loop/Loop.mjs"
package/src/index.ts CHANGED
@@ -18,6 +18,8 @@ export * as SandboxImage from "./sandbox/SandboxImage.js"
18
18
  export * as SandboxNetwork from "./sandbox/SandboxNetwork.js"
19
19
  export * as SpeechSynthesizer from "./speech-synthesizer/SpeechSynthesizer.js"
20
20
  export * as Transcriber from "./transcriber/Transcriber.js"
21
+ export * as WebSearch from "./web-search/WebSearch.js"
22
+ export * as WebSearchTool from "./web-search/WebSearchTool.js"
21
23
  export * as Vector from "./math/Vector.js"
22
24
  export * as Loop from "./loop/Loop.js"
23
25
  export * as Retry from "./retry/Retry.js"
@@ -0,0 +1,150 @@
1
+ import { Context, type DateTime, Effect, Schema } from "effect"
2
+ import type * as AiError from "../domain/AiError.js"
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Recency
6
+ // ---------------------------------------------------------------------------
7
+
8
+ /**
9
+ * Convenience freshness enum shared by every provider. A coarse "published
10
+ * within the last …" filter that maps onto each provider's native recency
11
+ * knob (Perplexity `search_recency_filter`, Brave `freshness`, Tavily
12
+ * `time_range`, You.com `freshness`), or onto a computed published-date
13
+ * range where a provider has no enum (Exa).
14
+ *
15
+ * For a precise window use {@link CommonSearchRequest.startDate} /
16
+ * {@link CommonSearchRequest.endDate} instead; `recency` is the sugar for
17
+ * the common "past week / past month" case.
18
+ *
19
+ * Exposed as a `Schema` so {@link "../web-search/WebSearchTool".webSearchTool}
20
+ * can hand it straight to a model as a tool parameter; the
21
+ * {@link SearchRecency} type is derived from it.
22
+ */
23
+ export const SearchRecency = Schema.Literals(["hour", "day", "week", "month", "year"])
24
+
25
+ export type SearchRecency = typeof SearchRecency.Type
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Request
29
+ // ---------------------------------------------------------------------------
30
+
31
+ /**
32
+ * Cross-provider web-search request. A field earns a place here only if
33
+ * most of the supported providers honor it and a developer would expect it
34
+ * from a generic search interface; everything provider-specific (Exa
35
+ * `type`, Tavily `searchDepth`, Brave `goggles`, pagination `offset`,
36
+ * `safeSearch`, `topic`, …) lives on that provider's typed request.
37
+ *
38
+ * Note the one structural difference from `EmbeddingModel` /
39
+ * `Transcriber`: there is no `model`. None of the pure-`/search` endpoints
40
+ * take one - what looks model-shaped on a provider (Exa `type`, Tavily
41
+ * `searchDepth`) is a mode knob, so it stays on the provider-typed request.
42
+ */
43
+ export type CommonSearchRequest = {
44
+ /** The search query. The one field every provider requires. */
45
+ readonly query: string
46
+ /**
47
+ * Upper bound on the number of results to return in this one call.
48
+ * Providers cap differently (Perplexity / Tavily / Brave at ~20, Exa /
49
+ * You.com at ~100); a value above a provider's cap is clamped by that
50
+ * provider. There is no common pagination - only two providers paginate
51
+ * and only shallowly, so `offset` is provider-typed.
52
+ */
53
+ readonly maxResults?: number
54
+ /** Restrict results to these domains (e.g. `["docs.foo.com"]`). */
55
+ readonly includeDomains?: ReadonlyArray<string>
56
+ /** Drop results from these domains. */
57
+ readonly excludeDomains?: ReadonlyArray<string>
58
+ /**
59
+ * Coarse freshness filter - see {@link SearchRecency}. Sugar over an
60
+ * explicit `startDate`; ignored where {@link startDate} is also set and
61
+ * the provider takes only one.
62
+ */
63
+ readonly recency?: SearchRecency
64
+ /** Published-after bound. The precise alternative to {@link recency}. */
65
+ readonly startDate?: DateTime.DateTime
66
+ /** Published-before bound. */
67
+ readonly endDate?: DateTime.DateTime
68
+ /** ISO 3166-1 alpha-2 country code to localize results (e.g. `"us"`). */
69
+ readonly country?: string
70
+ /** ISO 639-1 language code to bias results toward (e.g. `"en"`). */
71
+ readonly language?: string
72
+ }
73
+
74
+ // ---------------------------------------------------------------------------
75
+ // Response
76
+ // ---------------------------------------------------------------------------
77
+
78
+ /**
79
+ * One normalized web-search hit. A flat record with optionals rather than a
80
+ * tagged union: the providers differ by *which fields are present*, not by
81
+ * *kind*. The provider's untouched result object is always on `raw`, so a
82
+ * caller holding a typed provider tag can recover anything not promoted
83
+ * here (`author`, `favicon`, multi-chunk `snippets[]`, …).
84
+ */
85
+ export type SearchResult = {
86
+ /** Canonical result URL. Always present. */
87
+ readonly url: string
88
+ /** Result title / headline, when the provider returns one. */
89
+ readonly title?: string
90
+ /**
91
+ * Primary short excerpt - the one text field all providers return (under
92
+ * various wire names: `snippet`, `content`, `description`). The richer
93
+ * extract fields (`text`, `highlights`, `summary`) belong to the
94
+ * out-of-scope extract feature and stay on the provider-typed result.
95
+ */
96
+ readonly snippet?: string
97
+ /** Publication date, when the provider reports one. */
98
+ readonly publishedDate?: DateTime.DateTime
99
+ /**
100
+ * Relevance score, only from providers that rank (Exa, Tavily);
101
+ * `undefined` for providers that return an unscored list. Kept despite
102
+ * being non-universal because ranking is core to what a "search result"
103
+ * means - and `undefined` cleanly says "this backend doesn't score."
104
+ */
105
+ readonly score?: number
106
+ /** The provider-native result object, never lossy. */
107
+ readonly raw: unknown
108
+ }
109
+
110
+ export type SearchResponse = {
111
+ readonly results: ReadonlyArray<SearchResult>
112
+ /**
113
+ * The provider-native top-level response object. Cost / usage reporting
114
+ * is deliberately not modeled on this surface yet: providers disagree on
115
+ * both what (Exa returns USD, Tavily credits, Brave nothing in-body) and
116
+ * where (Brave reports cost in response headers), so it is deferred to the
117
+ * unified usage design (see plans/usage-tracking.md). Anything a provider
118
+ * reports survives here on `raw`.
119
+ */
120
+ readonly raw: unknown
121
+ }
122
+
123
+ // ---------------------------------------------------------------------------
124
+ // Service + helper
125
+ // ---------------------------------------------------------------------------
126
+
127
+ /**
128
+ * The portable web-search surface: one operation, `search`. Pure search is
129
+ * the one thing every provider does, so - unlike `SpeechSynthesizer` /
130
+ * `Transcriber` - this capability needs no marker tags; every provider
131
+ * Layer can answer.
132
+ */
133
+ export type WebSearchService = {
134
+ readonly search: (request: CommonSearchRequest) => Effect.Effect<SearchResponse, AiError.AiError>
135
+ }
136
+
137
+ /**
138
+ * Generic web-search service tag. Yield this for provider-portable code;
139
+ * yield a provider tag (`PerplexitySearch`, `ExaSearch`, …) when you need
140
+ * that provider's own knobs. A provider's `layer` registers both.
141
+ */
142
+ export class WebSearch extends Context.Service<WebSearch, WebSearchService>()(
143
+ "@betalyra/effect-uai/WebSearch",
144
+ ) {}
145
+
146
+ /** Run one web search against whichever provider Layer is in scope. */
147
+ export const search = (
148
+ request: CommonSearchRequest,
149
+ ): Effect.Effect<SearchResponse, AiError.AiError, WebSearch> =>
150
+ Effect.flatMap(WebSearch.asEffect(), (s) => s.search(request))
@@ -0,0 +1,106 @@
1
+ import { Effect, Schema } from "effect"
2
+ import * as Tool from "../tool/Tool.js"
3
+ import { search, SearchRecency, type SearchResult, WebSearch } from "./WebSearch.js"
4
+
5
+ /**
6
+ * Model-facing argument schema. Deliberately narrow: `query` plus the one
7
+ * filter that is genuinely the model's call - `recency` (it knows whether a
8
+ * question is about current events or evergreen). App-policy scoping
9
+ * (`includeDomains` / `excludeDomains`) and the `maxResults` cost ceiling
10
+ * are pinned on the constructor instead, so they are guaranteed rather than
11
+ * left to the model to remember each call.
12
+ */
13
+ const WebSearchToolArgs = Schema.Struct({
14
+ query: Schema.String,
15
+ recency: Schema.optional(SearchRecency),
16
+ })
17
+
18
+ export type WebSearchToolArgs = typeof WebSearchToolArgs.Type
19
+
20
+ /** Numbered `title / url / snippet` list - what a model reads best. */
21
+ const defaultRender = (results: ReadonlyArray<SearchResult>): string =>
22
+ results.length === 0
23
+ ? "No results found."
24
+ : results
25
+ .map((r, i) => {
26
+ const head = `${i + 1}. ${r.title ?? r.url}\n ${r.url}`
27
+ return r.snippet === undefined ? head : `${head}\n ${r.snippet}`
28
+ })
29
+ .join("\n\n")
30
+
31
+ export type WebSearchToolOptions = {
32
+ /** Tool name the model sees. Default `"web_search"`. */
33
+ readonly name?: string
34
+ /**
35
+ * App-fixed ceiling on results per call - a cost guard, not exposed to
36
+ * the model. Default `5`.
37
+ */
38
+ readonly maxResults?: number
39
+ /**
40
+ * App-fixed allowlist applied to every search. A policy scope ("only
41
+ * search our docs"), not a model knob - so it is enforced, not requested.
42
+ */
43
+ readonly includeDomains?: ReadonlyArray<string>
44
+ /** App-fixed denylist applied to every search ("never return X"). */
45
+ readonly excludeDomains?: ReadonlyArray<string>
46
+ /**
47
+ * Override how results are rendered into the model-facing string.
48
+ * Default: a numbered `title / url / snippet` list.
49
+ */
50
+ readonly render?: (results: ReadonlyArray<SearchResult>) => string
51
+ }
52
+
53
+ /**
54
+ * The canonical web-search tool. Its `R` is just `WebSearch`, so providing
55
+ * any search-provider Layer satisfies it and the model-facing contract
56
+ * (name, description, schema) is identical no matter which backend answers
57
+ * - swap `PerplexitySearch.layer` for `ExaSearch.layer` and the tool the
58
+ * model sees does not change. Drops straight into a `Toolkit` and the
59
+ * `LanguageModel` tool-calling loop.
60
+ *
61
+ * The model controls only `query` and `recency`; domain scoping and the
62
+ * result cap are app policy, fixed here on the constructor. `Output` is
63
+ * rendered text, not raw `SearchResult[]`: the model reads the list, while
64
+ * the app still gets the structured results through the normal tool-result
65
+ * channel. Pass `render` to change the format.
66
+ */
67
+ export const webSearchTool = (
68
+ options?: WebSearchToolOptions,
69
+ ): Tool.Tool<string, WebSearchToolArgs, string, WebSearch> => {
70
+ const name = options?.name ?? "web_search"
71
+ const render = options?.render ?? defaultRender
72
+ const maxResults = options?.maxResults ?? 5
73
+ const includeDomains = options?.includeDomains
74
+ const excludeDomains = options?.excludeDomains
75
+ return Tool.make({
76
+ name,
77
+ description:
78
+ "Search the web for current information. Returns ranked results with titles, URLs, and snippets.",
79
+ inputSchema: Tool.fromEffectSchema(WebSearchToolArgs),
80
+ // The call is wrapped in a tracing span so agent traces show the tool
81
+ // invocation (query, filters, result count) nested under the model turn.
82
+ // `withSpan` is a no-op until a Tracer is installed, so this is free by
83
+ // default and adds nothing to the requirements.
84
+ run: (args) =>
85
+ search({
86
+ query: args.query,
87
+ maxResults,
88
+ ...(args.recency !== undefined && { recency: args.recency }),
89
+ ...(includeDomains !== undefined && { includeDomains }),
90
+ ...(excludeDomains !== undefined && { excludeDomains }),
91
+ }).pipe(
92
+ Effect.tap((r) => Effect.annotateCurrentSpan("web_search.result_count", r.results.length)),
93
+ Effect.map((r) => render(r.results)),
94
+ Effect.withSpan(name, {
95
+ kind: "client",
96
+ attributes: {
97
+ "web_search.query": args.query,
98
+ "web_search.max_results": maxResults,
99
+ ...(args.recency !== undefined && { "web_search.recency": args.recency }),
100
+ ...(includeDomains !== undefined && { "web_search.include_domains": includeDomains }),
101
+ ...(excludeDomains !== undefined && { "web_search.exclude_domains": excludeDomains }),
102
+ },
103
+ }),
104
+ ),
105
+ })
106
+ }