@yourgpt/copilot-sdk 2.0.0 → 2.0.2-beta.1
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/README.md +68 -27
- package/dist/{ThreadManager-JT0sqSSD.d.ts → ThreadManager-Dkp_eLty.d.ts} +1 -1
- package/dist/{ThreadManager-CUq5Ocu2.d.cts → ThreadManager-LfFRhr4e.d.cts} +1 -1
- package/dist/anthropic-6F5GRE3B.js +4 -0
- package/dist/anthropic-6F5GRE3B.js.map +1 -0
- package/dist/anthropic-DGalr_Fw.d.cts +17 -0
- package/dist/anthropic-DkCEDYOt.d.ts +17 -0
- package/dist/anthropic-NMTRABEH.cjs +21 -0
- package/dist/anthropic-NMTRABEH.cjs.map +1 -0
- package/dist/brave-DdnWb7Gb.d.cts +17 -0
- package/dist/brave-DsI9n7Wr.d.ts +17 -0
- package/dist/brave-OYKCOZEM.cjs +21 -0
- package/dist/brave-OYKCOZEM.cjs.map +1 -0
- package/dist/brave-XSASGGH2.js +4 -0
- package/dist/brave-XSASGGH2.js.map +1 -0
- package/dist/chunk-2FAWEBZS.cjs +88 -0
- package/dist/chunk-2FAWEBZS.cjs.map +1 -0
- package/dist/{chunk-CJ7UWN2Y.js → chunk-3YKHVLNP.js} +397 -7
- package/dist/chunk-3YKHVLNP.js.map +1 -0
- package/dist/chunk-4WWWMNUA.js +1142 -0
- package/dist/chunk-4WWWMNUA.js.map +1 -0
- package/dist/chunk-53UGJNHN.js +92 -0
- package/dist/chunk-53UGJNHN.js.map +1 -0
- package/dist/chunk-6BXQFCK3.js +79 -0
- package/dist/chunk-6BXQFCK3.js.map +1 -0
- package/dist/chunk-6T5XXJEP.cjs +80 -0
- package/dist/chunk-6T5XXJEP.cjs.map +1 -0
- package/dist/chunk-7W7QLZNC.js +72 -0
- package/dist/chunk-7W7QLZNC.js.map +1 -0
- package/dist/chunk-ASV6JLYG.cjs +99 -0
- package/dist/chunk-ASV6JLYG.cjs.map +1 -0
- package/dist/chunk-CBAHCI4R.cjs +76 -0
- package/dist/chunk-CBAHCI4R.cjs.map +1 -0
- package/dist/chunk-CEOMTQTP.js +85 -0
- package/dist/chunk-CEOMTQTP.js.map +1 -0
- package/dist/chunk-DABZYCVX.js +84 -0
- package/dist/chunk-DABZYCVX.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-4PRWNAXQ.cjs → chunk-DUPNYVBP.cjs} +27 -89
- package/dist/chunk-DUPNYVBP.cjs.map +1 -0
- package/dist/chunk-DVC63PGD.cjs +1160 -0
- package/dist/chunk-DVC63PGD.cjs.map +1 -0
- package/dist/chunk-G4SF2PNQ.js +33 -0
- package/dist/chunk-G4SF2PNQ.js.map +1 -0
- package/dist/chunk-GANCV72Z.cjs +110 -0
- package/dist/chunk-GANCV72Z.cjs.map +1 -0
- package/dist/chunk-J4OMGO5O.js +66 -0
- package/dist/chunk-J4OMGO5O.js.map +1 -0
- package/dist/chunk-JEQ2X3Z6.cjs +12 -0
- package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
- package/dist/chunk-JO4BHPAD.cjs +40 -0
- package/dist/chunk-JO4BHPAD.cjs.map +1 -0
- package/dist/chunk-MEBXW75C.cjs +89 -0
- package/dist/chunk-MEBXW75C.cjs.map +1 -0
- package/dist/chunk-MNDGIW47.js +76 -0
- package/dist/chunk-MNDGIW47.js.map +1 -0
- package/dist/chunk-PPFHA6IL.js +83 -0
- package/dist/chunk-PPFHA6IL.js.map +1 -0
- package/dist/{chunk-BLSI67J6.cjs → chunk-RBZXLBGI.cjs} +425 -30
- package/dist/chunk-RBZXLBGI.cjs.map +1 -0
- package/dist/chunk-RQ74USYU.js +128 -0
- package/dist/chunk-RQ74USYU.js.map +1 -0
- package/dist/chunk-TX7CGITI.cjs +82 -0
- package/dist/chunk-TX7CGITI.cjs.map +1 -0
- package/dist/chunk-TXLIY7GF.cjs +132 -0
- package/dist/chunk-TXLIY7GF.cjs.map +1 -0
- package/dist/chunk-VD74IPKB.js +106 -0
- package/dist/chunk-VD74IPKB.js.map +1 -0
- package/dist/chunk-W73FBYIH.cjs +87 -0
- package/dist/chunk-W73FBYIH.cjs.map +1 -0
- package/dist/chunk-W74OTXXX.cjs +73 -0
- package/dist/chunk-W74OTXXX.cjs.map +1 -0
- package/dist/chunk-XGITAEXU.js +93 -0
- package/dist/chunk-XGITAEXU.js.map +1 -0
- package/dist/chunk-XWOHNY3F.cjs +96 -0
- package/dist/chunk-XWOHNY3F.cjs.map +1 -0
- package/dist/{chunk-JM7PB2LP.js → chunk-Z7PHGSJT.js} +10 -66
- package/dist/chunk-Z7PHGSJT.js.map +1 -0
- package/dist/core/index.cjs +156 -84
- package/dist/core/index.d.cts +16 -4
- package/dist/core/index.d.ts +16 -4
- package/dist/core/index.js +13 -1
- package/dist/exa-72KFY5A7.cjs +21 -0
- package/dist/exa-72KFY5A7.cjs.map +1 -0
- package/dist/exa-Dp9U-WTc.d.ts +17 -0
- package/dist/exa-NNVPBC2M.js +4 -0
- package/dist/exa-NNVPBC2M.js.map +1 -0
- package/dist/exa-jJSPhyUW.d.cts +17 -0
- package/dist/google-CHU2yycE.d.cts +17 -0
- package/dist/google-CTEK6SV2.js +4 -0
- package/dist/google-CTEK6SV2.js.map +1 -0
- package/dist/google-Da8IQxaI.d.ts +17 -0
- package/dist/google-IIUXFFVF.cjs +21 -0
- package/dist/google-IIUXFFVF.cjs.map +1 -0
- package/dist/index-DBNh0jhE.d.ts +206 -0
- package/dist/index-DOlhSb79.d.cts +206 -0
- package/dist/mcp/index.cjs +670 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +779 -0
- package/dist/mcp/index.d.ts +779 -0
- package/dist/mcp/index.js +574 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/openai-6KTCQ7PZ.cjs +21 -0
- package/dist/openai-6KTCQ7PZ.cjs.map +1 -0
- package/dist/openai-7W2PCNW5.js +4 -0
- package/dist/openai-7W2PCNW5.js.map +1 -0
- package/dist/openai-Cam8hF4f.d.ts +17 -0
- package/dist/openai-HVSCuXgO.d.cts +17 -0
- package/dist/react/index.cjs +75 -42
- package/dist/react/index.d.cts +270 -45
- package/dist/react/index.d.ts +270 -45
- package/dist/react/index.js +15 -2
- package/dist/searxng-AXLVGY7Z.js +4 -0
- package/dist/searxng-AXLVGY7Z.js.map +1 -0
- package/dist/searxng-EJKNY236.cjs +21 -0
- package/dist/searxng-EJKNY236.cjs.map +1 -0
- package/dist/searxng-K0qtY9vp.d.ts +17 -0
- package/dist/searxng-QGOte_Gq.d.cts +17 -0
- package/dist/serper-3JYJHJX6.js +4 -0
- package/dist/serper-3JYJHJX6.js.map +1 -0
- package/dist/serper-63FT4AOL.cjs +21 -0
- package/dist/serper-63FT4AOL.cjs.map +1 -0
- package/dist/serper-7Czya3PW.d.ts +17 -0
- package/dist/serper-JzdaSnS9.d.cts +17 -0
- package/dist/styles.css +38 -0
- package/dist/tavily-AWFP4RM7.cjs +21 -0
- package/dist/tavily-AWFP4RM7.cjs.map +1 -0
- package/dist/tavily-C8cXXojE.d.cts +17 -0
- package/dist/tavily-CIWAAZPH.js +4 -0
- package/dist/tavily-CIWAAZPH.js.map +1 -0
- package/dist/tavily-DdSGVgkE.d.ts +17 -0
- package/dist/themes/catppuccin.css +2 -0
- package/dist/themes/claude.css +2 -0
- package/dist/themes/linear.css +2 -0
- package/dist/themes/modern-minimal.css +2 -0
- package/dist/themes/posthog.css +2 -0
- package/dist/themes/supabase.css +2 -0
- package/dist/themes/twitter.css +2 -0
- package/dist/themes/vercel.css +2 -0
- package/dist/tools/anthropic/index.cjs +61 -0
- package/dist/tools/anthropic/index.cjs.map +1 -0
- package/dist/tools/anthropic/index.d.cts +67 -0
- package/dist/tools/anthropic/index.d.ts +67 -0
- package/dist/tools/anthropic/index.js +56 -0
- package/dist/tools/anthropic/index.js.map +1 -0
- package/dist/tools/brave/index.cjs +85 -0
- package/dist/tools/brave/index.cjs.map +1 -0
- package/dist/tools/brave/index.d.cts +91 -0
- package/dist/tools/brave/index.d.ts +91 -0
- package/dist/tools/brave/index.js +80 -0
- package/dist/tools/brave/index.js.map +1 -0
- package/dist/tools/exa/index.cjs +90 -0
- package/dist/tools/exa/index.cjs.map +1 -0
- package/dist/tools/exa/index.d.cts +92 -0
- package/dist/tools/exa/index.d.ts +92 -0
- package/dist/tools/exa/index.js +85 -0
- package/dist/tools/exa/index.js.map +1 -0
- package/dist/tools/google/index.cjs +81 -0
- package/dist/tools/google/index.cjs.map +1 -0
- package/dist/tools/google/index.d.cts +81 -0
- package/dist/tools/google/index.d.ts +81 -0
- package/dist/tools/google/index.js +76 -0
- package/dist/tools/google/index.js.map +1 -0
- package/dist/tools/openai/index.cjs +83 -0
- package/dist/tools/openai/index.cjs.map +1 -0
- package/dist/tools/openai/index.d.cts +84 -0
- package/dist/tools/openai/index.d.ts +84 -0
- package/dist/tools/openai/index.js +78 -0
- package/dist/tools/openai/index.js.map +1 -0
- package/dist/tools/searxng/index.cjs +85 -0
- package/dist/tools/searxng/index.cjs.map +1 -0
- package/dist/tools/searxng/index.d.cts +91 -0
- package/dist/tools/searxng/index.d.ts +91 -0
- package/dist/tools/searxng/index.js +80 -0
- package/dist/tools/searxng/index.js.map +1 -0
- package/dist/tools/serper/index.cjs +85 -0
- package/dist/tools/serper/index.cjs.map +1 -0
- package/dist/tools/serper/index.d.cts +91 -0
- package/dist/tools/serper/index.d.ts +91 -0
- package/dist/tools/serper/index.js +80 -0
- package/dist/tools/serper/index.js.map +1 -0
- package/dist/tools/tavily/index.cjs +91 -0
- package/dist/tools/tavily/index.cjs.map +1 -0
- package/dist/tools/tavily/index.d.cts +95 -0
- package/dist/tools/tavily/index.d.ts +95 -0
- package/dist/tools/tavily/index.js +86 -0
- package/dist/tools/tavily/index.js.map +1 -0
- package/dist/tools/web-search/index.cjs +31 -0
- package/dist/tools/web-search/index.cjs.map +1 -0
- package/dist/tools/web-search/index.d.cts +3 -0
- package/dist/tools/web-search/index.d.ts +3 -0
- package/dist/tools/web-search/index.js +14 -0
- package/dist/tools/web-search/index.js.map +1 -0
- package/dist/{types-BtAaOV07.d.cts → tools-EiPWA9Ay.d.cts} +34 -367
- package/dist/{types-BtAaOV07.d.ts → tools-EiPWA9Ay.d.ts} +34 -367
- package/dist/types-B20VCJXL.d.cts +347 -0
- package/dist/types-B20VCJXL.d.ts +347 -0
- package/dist/types-CKA6U74u.d.cts +441 -0
- package/dist/types-DG2ya08y.d.cts +367 -0
- package/dist/types-DG2ya08y.d.ts +367 -0
- package/dist/types-ZguuKEs_.d.cts +127 -0
- package/dist/types-ZguuKEs_.d.ts +127 -0
- package/dist/types-iBkPICvQ.d.ts +441 -0
- package/dist/ui/index.cjs +1069 -146
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +410 -4
- package/dist/ui/index.d.ts +410 -4
- package/dist/ui/index.js +1001 -94
- package/dist/ui/index.js.map +1 -1
- package/package.json +53 -2
- package/dist/chunk-4PRWNAXQ.cjs.map +0 -1
- package/dist/chunk-BLSI67J6.cjs.map +0 -1
- package/dist/chunk-CJ7UWN2Y.js.map +0 -1
- package/dist/chunk-JM7PB2LP.js.map +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/types/tools.ts
|
|
4
|
+
function tool(config) {
|
|
5
|
+
return {
|
|
6
|
+
description: config.description,
|
|
7
|
+
location: config.location ?? "client",
|
|
8
|
+
// Display configuration
|
|
9
|
+
title: config.title,
|
|
10
|
+
executingTitle: config.executingTitle,
|
|
11
|
+
completedTitle: config.completedTitle,
|
|
12
|
+
// Schema and handlers
|
|
13
|
+
inputSchema: config.inputSchema ?? {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {},
|
|
16
|
+
required: []
|
|
17
|
+
},
|
|
18
|
+
handler: config.handler,
|
|
19
|
+
render: config.render,
|
|
20
|
+
available: config.available,
|
|
21
|
+
needsApproval: config.needsApproval,
|
|
22
|
+
approvalMessage: config.approvalMessage,
|
|
23
|
+
aiResponseMode: config.aiResponseMode,
|
|
24
|
+
aiContext: config.aiContext
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function toolToOpenAIFormat(tool2) {
|
|
28
|
+
return {
|
|
29
|
+
type: "function",
|
|
30
|
+
function: {
|
|
31
|
+
name: tool2.name,
|
|
32
|
+
description: tool2.description,
|
|
33
|
+
parameters: tool2.inputSchema
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function toolToAnthropicFormat(tool2) {
|
|
38
|
+
return {
|
|
39
|
+
name: tool2.name,
|
|
40
|
+
description: tool2.description,
|
|
41
|
+
input_schema: tool2.inputSchema
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function createToolResult(toolCallId, response) {
|
|
45
|
+
return {
|
|
46
|
+
toolCallId,
|
|
47
|
+
content: JSON.stringify(response),
|
|
48
|
+
success: response.success,
|
|
49
|
+
error: response.error
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function success(data, message) {
|
|
53
|
+
return {
|
|
54
|
+
success: true,
|
|
55
|
+
data,
|
|
56
|
+
message
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function failure(error) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
exports.createToolResult = createToolResult;
|
|
67
|
+
exports.failure = failure;
|
|
68
|
+
exports.success = success;
|
|
69
|
+
exports.tool = tool;
|
|
70
|
+
exports.toolToAnthropicFormat = toolToAnthropicFormat;
|
|
71
|
+
exports.toolToOpenAIFormat = toolToOpenAIFormat;
|
|
72
|
+
//# sourceMappingURL=chunk-W74OTXXX.cjs.map
|
|
73
|
+
//# sourceMappingURL=chunk-W74OTXXX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/types/tools.ts"],"names":["tool"],"mappings":";;;AA2uBO,SAAS,KACd,MAAA,EACuC;AACvC,EAAA,OAAO;AAAA,IACL,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,QAAA,EAAU,OAAO,QAAA,IAAY,QAAA;AAAA;AAAA,IAE7B,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,gBAAgB,MAAA,CAAO,cAAA;AAAA,IACvB,gBAAgB,MAAA,CAAO,cAAA;AAAA;AAAA,IAEvB,WAAA,EAAa,OAAO,WAAA,IAAe;AAAA,MACjC,IAAA,EAAM,QAAA;AAAA,MACN,YAAY,EAAC;AAAA,MACb,UAAU;AAAC,KACb;AAAA,IACA,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,WAAW,MAAA,CAAO,SAAA;AAAA,IAClB,eAAe,MAAA,CAAO,aAAA;AAAA,IACtB,iBAAiB,MAAA,CAAO,eAAA;AAAA,IACxB,gBAAgB,MAAA,CAAO,cAAA;AAAA,IACvB,WAAW,MAAA,CAAO;AAAA,GACpB;AACF;AASO,SAAS,mBAAmBA,KAAAA,EAA8B;AAC/D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,MAAMA,KAAAA,CAAK,IAAA;AAAA,MACX,aAAaA,KAAAA,CAAK,WAAA;AAAA,MAClB,YAAYA,KAAAA,CAAK;AAAA;AACnB,GACF;AACF;AAKO,SAAS,sBAAsBA,KAAAA,EAA8B;AAClE,EAAA,OAAO;AAAA,IACL,MAAMA,KAAAA,CAAK,IAAA;AAAA,IACX,aAAaA,KAAAA,CAAK,WAAA;AAAA,IAClB,cAAcA,KAAAA,CAAK;AAAA,GACrB;AACF;AAKO,SAAS,gBAAA,CACd,YACA,QAAA,EACmB;AACnB,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,IAChC,SAAS,QAAA,CAAS,OAAA;AAAA,IAClB,OAAO,QAAA,CAAS;AAAA,GAClB;AACF;AAKO,SAAS,OAAA,CACd,MACA,OAAA,EACiB;AACjB,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,IAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,SAAS,QAAQ,KAAA,EAA6B;AACnD,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT;AAAA,GACF;AACF","file":"chunk-W74OTXXX.cjs","sourcesContent":["/**\n * Tool-related types for the agentic loop\n */\n\nimport type { ActionRenderProps } from \"./actions\";\n\n// ============================================\n// Provider Types\n// ============================================\n\n/**\n * Supported AI providers for tool calling\n */\nexport type AIProvider =\n | \"anthropic\"\n | \"openai\"\n | \"xai\"\n | \"grok\"\n | \"gemini\"\n | \"groq\"\n | \"ollama\";\n\n/**\n * Where the tool executes\n */\nexport type ToolLocation = \"server\" | \"client\";\n\n// ============================================\n// Tool Definition Types\n// ============================================\n\n/**\n * JSON Schema property definition\n */\nexport interface JSONSchemaProperty {\n type:\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"object\"\n | \"array\"\n | \"integer\"\n | \"null\";\n description?: string;\n enum?: (string | number | boolean)[];\n items?: JSONSchemaProperty;\n properties?: Record<string, JSONSchemaProperty>;\n required?: string[];\n default?: unknown;\n minLength?: number;\n maxLength?: number;\n minimum?: number;\n maximum?: number;\n pattern?: string;\n}\n\n/**\n * JSON Schema for tool input\n */\nexport interface ToolInputSchema {\n type: \"object\";\n properties: Record<string, JSONSchemaProperty>;\n required?: string[];\n additionalProperties?: boolean;\n}\n\n/**\n * Tool execution context\n *\n * Provides runtime information to tool handlers including cancellation signals,\n * request metadata, and custom context data.\n */\nexport interface ToolContext {\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Thread ID if using threads */\n threadId?: string;\n /** Custom context data passed from runtime config */\n data?: Record<string, unknown>;\n\n // ============================================\n // Rich Context (Vercel AI SDK pattern)\n // ============================================\n\n /**\n * Unique ID for this specific tool call.\n * Useful for logging, tracing, and correlating tool executions.\n */\n toolCallId?: string;\n\n /**\n * Request headers (for auth in server tools).\n * Contains headers from the original HTTP request.\n *\n * @example\n * ```typescript\n * handler: async (params, context) => {\n * const token = context?.headers?.authorization;\n * if (!token) return failure('Authentication required');\n * // ...\n * }\n * ```\n */\n headers?: Record<string, string>;\n\n /**\n * Full request metadata for server-side tools.\n * Provides access to HTTP method, URL, and headers.\n *\n * @example\n * ```typescript\n * handler: async (params, context) => {\n * console.log(`Tool called from: ${context?.request?.url}`);\n * // Forward auth to internal service\n * const authHeader = context?.request?.headers?.authorization;\n * }\n * ```\n */\n request?: {\n /** HTTP method (GET, POST, etc.) */\n method?: string;\n /** Request URL path */\n url?: string;\n /** Request headers */\n headers?: Record<string, string>;\n };\n\n /**\n * Data passed from user's approval action.\n * Only present when tool has `needsApproval: true` and user approved with extra data.\n *\n * @example\n * ```typescript\n * // In render function:\n * approval.onApprove({ supervisor: selectedSupervisor });\n *\n * // In handler:\n * handler: async (params, context) => {\n * const supervisor = context?.approvalData?.supervisor;\n * await assignToSupervisor(params.ticketId, supervisor);\n * }\n * ```\n */\n approvalData?: Record<string, unknown>;\n}\n\n// ============================================\n// AI Response Control Types\n// ============================================\n\n/**\n * AI response behavior for tool results.\n *\n * Controls what the AI sees after a tool executes and renders UI.\n *\n * - `'none'`: AI generates minimal response, UI component handles display\n * - `'brief'`: AI gets summary context (via aiContext), gives brief acknowledgment\n * - `'full'`: AI receives full data and responds accordingly (default)\n */\nexport type AIResponseMode = \"none\" | \"brief\" | \"full\";\n\n/**\n * Multimodal content for AI to analyze\n */\nexport type AIContent =\n | { type: \"image\"; data: string; mediaType: string }\n | { type: \"text\"; text: string };\n\n/**\n * Tool response format\n */\nexport interface ToolResponse<T = unknown> {\n /** Whether the tool succeeded */\n success: boolean;\n /** Human-readable message */\n message?: string;\n /** Error message if failed */\n error?: string;\n /** Result data */\n data?: T;\n\n // ============================================\n // AI Response Control (result-level overrides)\n // ============================================\n\n /**\n * Override AI context for this specific result.\n * Takes precedence over tool-level aiContext config.\n * If set, this message is sent to AI instead of full result data.\n *\n * @example\n * ```typescript\n * return {\n * success: true,\n * data: sensitiveData,\n * _aiContext: '[Data retrieved - contains sensitive info, displayed to user]'\n * };\n * ```\n */\n _aiContext?: string;\n\n /**\n * Override AI response mode for this specific result.\n * Takes precedence over tool-level aiResponseMode config.\n */\n _aiResponseMode?: AIResponseMode;\n\n /**\n * Content for AI to analyze (images, documents, etc.).\n * When present, these are included as multimodal content for AI analysis.\n *\n * @example\n * ```typescript\n * // Screenshot for AI to analyze\n * return {\n * success: true,\n * message: 'Screenshot captured',\n * _aiContent: [{ type: 'image', data: base64, mediaType: 'image/png' }]\n * };\n * ```\n */\n _aiContent?: AIContent[];\n\n /**\n * MCP-UI resources for rendering interactive UI components.\n * These are extracted from MCP tool results and rendered as iframes.\n * Not sent to the AI - purely for UI rendering.\n *\n * @example\n * ```typescript\n * // MCP tool returning UI\n * return {\n * success: true,\n * message: 'Product displayed',\n * _uiResources: [{\n * uri: 'ui://shop/product/123',\n * mimeType: 'text/html',\n * content: '<div class=\"product\">...</div>',\n * metadata: { height: '300px' }\n * }]\n * };\n * ```\n */\n _uiResources?: Array<{\n uri: string;\n mimeType:\n | \"text/html\"\n | \"text/uri-list\"\n | \"application/vnd.mcp-ui.remote-dom\";\n content?: string;\n blob?: string;\n metadata?: {\n title?: string;\n width?: string;\n height?: string;\n sandbox?: string[];\n className?: string;\n };\n }>;\n}\n\n/**\n * Approval callbacks passed to render when tool requires user action.\n * Only present when status is \"approval-required\".\n */\nexport interface ToolApprovalCallbacks {\n /**\n * Approve execution and optionally pass extra data to the handler.\n * The extraData is available in handler via `context.approvalData`.\n *\n * @example\n * ```tsx\n * // Simple approval\n * approval.onApprove();\n *\n * // Approval with data (e.g., user selection)\n * approval.onApprove({ supervisor: { name: \"John\", role: \"Manager\" } });\n * ```\n */\n onApprove: (extraData?: Record<string, unknown>) => void;\n\n /**\n * Reject the tool execution with optional reason.\n * This stops the tool from executing and returns an error to AI.\n */\n onReject: (reason?: string) => void;\n\n /** Custom message from tool's approvalMessage config */\n message?: string;\n}\n\n/**\n * Props passed to tool render function.\n *\n * The render function is called for every status change, enabling\n * full lifecycle rendering similar to Vercel AI SDK.\n *\n * @example\n * ```tsx\n * render: ({ status, args, approval, result }) => {\n * if (status === \"approval-required\" && approval) {\n * return <ApprovalCard onConfirm={() => approval.onApprove()} />;\n * }\n * if (status === \"executing\") {\n * return <LoadingSkeleton />;\n * }\n * if (status === \"completed\") {\n * return <ResultCard data={result.data} />;\n * }\n * return null;\n * }\n * ```\n */\nexport interface ToolRenderProps<TParams = Record<string, unknown>> {\n /**\n * Current execution status:\n * - `pending`: Tool call received, waiting to start\n * - `approval-required`: Waiting for user approval (when needsApproval is set)\n * - `executing`: Handler is running\n * - `completed`: Handler finished successfully\n * - `error`: Handler failed\n */\n status: \"pending\" | \"approval-required\" | \"executing\" | \"completed\" | \"error\";\n\n /** Arguments passed to the tool */\n args: TParams;\n\n /** Result if completed */\n result?: ToolResponse;\n\n /** Error if failed */\n error?: string;\n\n /** Tool call ID */\n toolCallId: string;\n\n /** Tool name */\n toolName: string;\n\n /**\n * Approval callbacks - only present when status is \"approval-required\".\n * Use these to create custom approval UIs that can pass extra data to the handler.\n */\n approval?: ToolApprovalCallbacks;\n}\n\n/**\n * Tool definition with JSON Schema\n */\nexport interface ToolDefinition<TParams = Record<string, unknown>> {\n /** Unique tool name */\n name: string;\n /** Tool description for LLM */\n description: string;\n /** Where the tool executes (server or client) */\n location: ToolLocation;\n\n // ============================================\n // Display Configuration\n // ============================================\n\n /**\n * Human-readable title for UI display.\n * Can be a static string or a function that generates title from args.\n *\n * @example\n * ```typescript\n * title: \"Get order details\"\n * // or dynamic:\n * title: (args) => `Order #${args.orderId}`\n * ```\n */\n title?: string | ((args: TParams) => string);\n\n /**\n * Title shown while executing (present tense with \"...\").\n * If not provided, uses `title` with \"...\" appended.\n *\n * @example\n * ```typescript\n * executingTitle: (args) => `Fetching order #${args.orderId}...`\n * ```\n */\n executingTitle?: string | ((args: TParams) => string);\n\n /**\n * Title shown after completion.\n * If not provided, defaults to `title`.\n *\n * @example\n * ```typescript\n * completedTitle: (args) => `Retrieved order #${args.orderId}`\n * ```\n */\n completedTitle?: string | ((args: TParams) => string);\n /** JSON Schema for input parameters */\n inputSchema: ToolInputSchema;\n /** Handler function (optional for client tools registered on server) */\n handler?: (\n params: TParams,\n context?: ToolContext,\n ) => Promise<ToolResponse> | ToolResponse;\n /** Optional render function for UI */\n render?: (props: ToolRenderProps<TParams>) => unknown;\n /** Whether the tool is available (for conditional registration) */\n available?: boolean;\n\n /**\n * Require user approval before execution.\n * Can be:\n * - `true`: Always require approval\n * - `false` or `undefined`: No approval needed (default)\n * - `(params) => boolean`: Conditional approval based on input\n *\n * Similar to Vercel AI SDK v6's needsApproval pattern.\n */\n needsApproval?: boolean | ((params: TParams) => boolean | Promise<boolean>);\n\n /**\n * Custom message shown in the approval UI.\n * Can be a string or a function that generates a message from params.\n * If not provided, a default message with the tool name is shown.\n */\n approvalMessage?: string | ((params: TParams) => string);\n\n // ============================================\n // AI Response Control\n // ============================================\n\n /**\n * How the AI should respond when this tool's result is rendered as UI.\n *\n * - `'none'`: AI generates minimal response (\"[Result displayed to user]\").\n * Use for tools where UI component fully handles the display (stats cards, etc.)\n *\n * - `'brief'`: AI receives summary context (from aiContext) and gives brief acknowledgment.\n * Use for charts/visualizations where AI should acknowledge but not repeat data.\n *\n * - `'full'`: AI receives complete data and responds accordingly (default).\n * Use for tools where AI should analyze and elaborate on results.\n *\n * @default 'full'\n *\n * @example\n * ```typescript\n * // Chart tool - AI acknowledges without repeating data\n * const chartTool: ToolDefinition = {\n * name: 'get_chart',\n * aiResponseMode: 'brief',\n * aiContext: (result) => `[Chart displayed: ${result.data.title}]`,\n * handler: async () => ({ success: true, data: chartData })\n * };\n * ```\n */\n aiResponseMode?: AIResponseMode;\n\n /**\n * Context/summary sent to AI instead of (or along with) full result.\n *\n * Used when:\n * - `aiResponseMode: 'brief'` - This becomes the only thing AI sees\n * - `aiResponseMode: 'full'` - This is prepended to full data for context\n *\n * Can be:\n * - `string`: Static message (e.g., \"[Weather data displayed]\")\n * - `function`: Dynamic based on result (e.g., (result) => `[Chart: ${result.data.title}]`)\n *\n * @example\n * ```typescript\n * // Static context\n * aiContext: '[Analytics chart displayed to user]'\n *\n * // Dynamic context based on result\n * aiContext: (result, args) => {\n * const { title, currentValue } = result.data;\n * return `[Chart displayed: ${title}, showing ${currentValue}]`;\n * }\n * ```\n */\n aiContext?:\n | string\n | ((result: ToolResponse, args: Record<string, unknown>) => string);\n}\n\n// ============================================\n// Unified Tool Call Types (Provider-Agnostic)\n// ============================================\n\n/**\n * Unified tool call format (internal representation)\n */\nexport interface UnifiedToolCall {\n /** Unique tool call ID */\n id: string;\n /** Tool name */\n name: string;\n /** Tool input arguments */\n input: Record<string, unknown>;\n}\n\n/**\n * Unified tool result format\n */\nexport interface UnifiedToolResult {\n /** Tool call ID this result is for */\n toolCallId: string;\n /** Serialized result content (JSON string) */\n content: string;\n /** Whether the tool succeeded */\n success: boolean;\n /** Error message if failed */\n error?: string;\n}\n\n// ============================================\n// Tool Execution Types\n// ============================================\n\n/**\n * Tool execution status\n */\nexport type ToolExecutionStatus =\n | \"pending\"\n | \"executing\"\n | \"completed\"\n | \"error\";\n\n/**\n * Tool approval status (for human-in-the-loop)\n *\n * Similar to Vercel AI SDK v6's tool approval pattern.\n */\nexport type ToolApprovalStatus =\n | \"none\" // No approval needed (default)\n | \"required\" // Waiting for user decision\n | \"approved\" // User approved, execution can proceed\n | \"rejected\"; // User rejected, execution skipped\n\n// ============================================\n// Permission Persistence Types\n// ============================================\n\n/**\n * Permission level for tool execution\n *\n * Controls whether approval is needed and how the choice is remembered:\n * - \"ask\" - Always prompt user (default)\n * - \"allow_always\" - Auto-approve, persisted to storage\n * - \"deny_always\" - Auto-reject, persisted to storage\n * - \"session\" - Auto-approve for current session only\n */\nexport type PermissionLevel =\n | \"ask\"\n | \"allow_always\"\n | \"deny_always\"\n | \"session\";\n\n/**\n * Stored tool permission record\n */\nexport interface ToolPermission {\n /** Tool name (unique identifier) */\n toolName: string;\n /** Permission level */\n level: PermissionLevel;\n /** When permission was set */\n createdAt: number;\n /** Last time this permission was used */\n lastUsedAt?: number;\n}\n\n/**\n * Permission storage configuration\n */\nexport interface PermissionStorageConfig {\n /**\n * Storage type:\n * - \"localStorage\" - Persists across browser sessions\n * - \"sessionStorage\" - Clears when tab closes\n * - \"memory\" - In-memory only (for SSR or testing)\n */\n type: \"localStorage\" | \"sessionStorage\" | \"memory\";\n /** Storage key prefix (default: \"yourgpt-permissions\") */\n keyPrefix?: string;\n}\n\n/**\n * Permission storage adapter interface (for custom implementations)\n */\nexport interface PermissionStorageAdapter {\n /** Get permission for a tool */\n get(toolName: string): Promise<ToolPermission | null>;\n /** Set permission for a tool */\n set(permission: ToolPermission): Promise<void>;\n /** Remove permission for a tool */\n remove(toolName: string): Promise<void>;\n /** Get all permissions */\n getAll(): Promise<ToolPermission[]>;\n /** Clear all permissions */\n clear(): Promise<void>;\n}\n\n/**\n * Tool execution record (for UI tracking)\n */\nexport interface ToolExecution {\n /** Tool call ID */\n id: string;\n /** Tool name */\n name: string;\n /** Tool arguments */\n args: Record<string, unknown>;\n /** Execution status */\n status: ToolExecutionStatus;\n /** Result if completed */\n result?: ToolResponse;\n /** Error message if failed */\n error?: string;\n /** Timestamp when execution started */\n timestamp: number;\n /** Duration in ms (set when completed) */\n duration?: number;\n\n // Approval fields (for needsApproval tools)\n\n /** Approval status for this execution */\n approvalStatus: ToolApprovalStatus;\n /** Message shown in approval UI (from tool's approvalMessage) */\n approvalMessage?: string;\n /** Timestamp when user responded to approval request */\n approvalTimestamp?: number;\n}\n\n// ============================================\n// Agent Loop Types\n// ============================================\n\n/**\n * Agentic loop configuration\n */\nexport interface AgentLoopConfig {\n /** Maximum iterations before stopping (default: 20) */\n maxIterations?: number;\n /** Enable debug logging */\n debug?: boolean;\n /** Whether to enable the agentic loop (default: true) */\n enabled?: boolean;\n}\n\n/**\n * Agent loop state (for tracking)\n */\nexport interface AgentLoopState {\n /** Current iteration number */\n iteration: number;\n /** Maximum iterations allowed */\n maxIterations: number;\n /** Whether the loop is currently running */\n running: boolean;\n /** Whether max iterations was reached */\n maxIterationsReached: boolean;\n /** Whether the loop was aborted */\n aborted: boolean;\n}\n\n// ============================================\n// ToolSet Type (Vercel AI SDK pattern)\n// ============================================\n\n/**\n * A set of tools, keyed by tool name\n *\n * @example\n * ```typescript\n * const myTools: ToolSet = {\n * capture_screenshot: screenshotTool,\n * get_weather: weatherTool,\n * };\n * ```\n */\nexport type ToolSet = Record<string, ToolDefinition>;\n\n// ============================================\n// Tool Helper Function (Vercel AI SDK pattern)\n// ============================================\n\n/**\n * Configuration for creating a tool\n */\nexport interface ToolConfig<TParams = Record<string, unknown>> {\n /** Tool description for LLM */\n description: string;\n /** Where the tool executes (default: 'client') */\n location?: ToolLocation;\n\n // Display Configuration\n /** Human-readable title for UI display */\n title?: string | ((args: TParams) => string);\n /** Title shown while executing */\n executingTitle?: string | ((args: TParams) => string);\n /** Title shown after completion */\n completedTitle?: string | ((args: TParams) => string);\n\n /** JSON Schema for input parameters */\n inputSchema?: ToolInputSchema;\n /** Handler function */\n handler?: (\n params: TParams,\n context?: ToolContext,\n ) => Promise<ToolResponse> | ToolResponse;\n /** Optional render function for UI */\n render?: (props: ToolRenderProps<TParams>) => unknown;\n /** Whether the tool is available */\n available?: boolean;\n /** Require user approval before execution */\n needsApproval?: boolean | ((params: TParams) => boolean | Promise<boolean>);\n /** Custom message shown in the approval UI */\n approvalMessage?: string | ((params: TParams) => string);\n /** AI response mode for this tool (default: 'full') */\n aiResponseMode?: AIResponseMode;\n /** Context/summary sent to AI instead of full result */\n aiContext?:\n | string\n | ((result: ToolResponse, args: Record<string, unknown>) => string);\n}\n\n/**\n * Create a tool definition (similar to Vercel AI SDK's tool())\n *\n * @example\n * ```typescript\n * const weatherTool = tool({\n * description: 'Get weather for a location',\n * inputSchema: {\n * type: 'object',\n * properties: {\n * location: { type: 'string', description: 'City name' },\n * },\n * required: ['location'],\n * },\n * handler: async ({ location }) => {\n * const weather = await fetchWeather(location);\n * return success(weather);\n * },\n * });\n * ```\n */\nexport function tool<TParams = Record<string, unknown>>(\n config: ToolConfig<TParams>,\n): Omit<ToolDefinition<TParams>, \"name\"> {\n return {\n description: config.description,\n location: config.location ?? \"client\",\n // Display configuration\n title: config.title,\n executingTitle: config.executingTitle,\n completedTitle: config.completedTitle,\n // Schema and handlers\n inputSchema: config.inputSchema ?? {\n type: \"object\",\n properties: {},\n required: [],\n },\n handler: config.handler,\n render: config.render,\n available: config.available,\n needsApproval: config.needsApproval,\n approvalMessage: config.approvalMessage,\n aiResponseMode: config.aiResponseMode,\n aiContext: config.aiContext,\n };\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Convert ToolDefinition to OpenAI tool format\n */\nexport function toolToOpenAIFormat(tool: ToolDefinition): object {\n return {\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.inputSchema,\n },\n };\n}\n\n/**\n * Convert ToolDefinition to Anthropic tool format\n */\nexport function toolToAnthropicFormat(tool: ToolDefinition): object {\n return {\n name: tool.name,\n description: tool.description,\n input_schema: tool.inputSchema,\n };\n}\n\n/**\n * Create a tool result response\n */\nexport function createToolResult(\n toolCallId: string,\n response: ToolResponse,\n): UnifiedToolResult {\n return {\n toolCallId,\n content: JSON.stringify(response),\n success: response.success,\n error: response.error,\n };\n}\n\n/**\n * Create a successful tool response\n */\nexport function success<T = unknown>(\n data?: T,\n message?: string,\n): ToolResponse<T> {\n return {\n success: true,\n data,\n message,\n };\n}\n\n/**\n * Create a failed tool response\n */\nexport function failure(error: string): ToolResponse {\n return {\n success: false,\n error,\n };\n}\n"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// src/core/tools/webSearch/index.ts
|
|
2
|
+
var providerLoaders = {
|
|
3
|
+
openai: () => import('./openai-7W2PCNW5.js').then((m) => m.openaiProvider),
|
|
4
|
+
google: () => import('./google-CTEK6SV2.js').then((m) => m.googleProvider),
|
|
5
|
+
anthropic: () => import('./anthropic-6F5GRE3B.js').then((m) => m.anthropicProvider),
|
|
6
|
+
tavily: () => import('./tavily-CIWAAZPH.js').then((m) => m.tavilyProvider),
|
|
7
|
+
serper: () => import('./serper-3JYJHJX6.js').then((m) => m.serperProvider),
|
|
8
|
+
brave: () => import('./brave-XSASGGH2.js').then((m) => m.braveProvider),
|
|
9
|
+
searxng: () => import('./searxng-AXLVGY7Z.js').then((m) => m.searxngProvider),
|
|
10
|
+
exa: () => import('./exa-NNVPBC2M.js').then((m) => m.exaProvider)
|
|
11
|
+
};
|
|
12
|
+
var loadedProviders = /* @__PURE__ */ new Map();
|
|
13
|
+
async function getProvider(name) {
|
|
14
|
+
const cached = loadedProviders.get(name);
|
|
15
|
+
if (cached) {
|
|
16
|
+
return cached;
|
|
17
|
+
}
|
|
18
|
+
const loader = providerLoaders[name];
|
|
19
|
+
if (!loader) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Unknown search provider: ${name}. Available providers: ${Object.keys(providerLoaders).join(", ")}`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
const provider = await loader();
|
|
25
|
+
const resolvedProvider = "default" in provider ? provider.default : provider;
|
|
26
|
+
loadedProviders.set(name, resolvedProvider);
|
|
27
|
+
return resolvedProvider;
|
|
28
|
+
}
|
|
29
|
+
function getAvailableProviders() {
|
|
30
|
+
return Object.keys(providerLoaders);
|
|
31
|
+
}
|
|
32
|
+
function isProviderInterface(provider) {
|
|
33
|
+
return typeof provider === "object" && "search" in provider;
|
|
34
|
+
}
|
|
35
|
+
async function executeWebSearch(params, config) {
|
|
36
|
+
const provider = isProviderInterface(config.provider) ? config.provider : await getProvider(config.provider);
|
|
37
|
+
const providerName = isProviderInterface(config.provider) ? "custom" : config.provider;
|
|
38
|
+
const resolvedConfig = {
|
|
39
|
+
...config,
|
|
40
|
+
provider: providerName
|
|
41
|
+
};
|
|
42
|
+
if (provider.validateConfig) {
|
|
43
|
+
provider.validateConfig(resolvedConfig);
|
|
44
|
+
}
|
|
45
|
+
return provider.search(params, resolvedConfig);
|
|
46
|
+
}
|
|
47
|
+
function formatSearchResultsForAI(response, options) {
|
|
48
|
+
const {
|
|
49
|
+
includeUrls = true,
|
|
50
|
+
includeScores = false,
|
|
51
|
+
maxContentLength = 200
|
|
52
|
+
} = options || {};
|
|
53
|
+
const lines = [];
|
|
54
|
+
if (response.answer) {
|
|
55
|
+
lines.push(`Answer: ${response.answer}`);
|
|
56
|
+
lines.push("");
|
|
57
|
+
}
|
|
58
|
+
lines.push(`Search results for "${response.query}":`);
|
|
59
|
+
lines.push("");
|
|
60
|
+
response.results.forEach((result, index) => {
|
|
61
|
+
const num = index + 1;
|
|
62
|
+
let content = result.content;
|
|
63
|
+
if (maxContentLength && content.length > maxContentLength) {
|
|
64
|
+
content = content.slice(0, maxContentLength) + "...";
|
|
65
|
+
}
|
|
66
|
+
lines.push(`${num}. ${result.title}`);
|
|
67
|
+
if (includeUrls) {
|
|
68
|
+
lines.push(` URL: ${result.url}`);
|
|
69
|
+
}
|
|
70
|
+
lines.push(` ${content}`);
|
|
71
|
+
if (includeScores && result.score !== void 0) {
|
|
72
|
+
lines.push(` Relevance: ${(result.score * 100).toFixed(1)}%`);
|
|
73
|
+
}
|
|
74
|
+
lines.push("");
|
|
75
|
+
});
|
|
76
|
+
return lines.join("\n");
|
|
77
|
+
}
|
|
78
|
+
function summarizeSearchResults(response) {
|
|
79
|
+
const count = response.results.length;
|
|
80
|
+
const sources = response.results.slice(0, 3).map((r) => r.domain || new URL(r.url).hostname).join(", ");
|
|
81
|
+
let summary = `Found ${count} result${count !== 1 ? "s" : ""}`;
|
|
82
|
+
if (sources) {
|
|
83
|
+
summary += ` from ${sources}`;
|
|
84
|
+
}
|
|
85
|
+
if (response.searchTime) {
|
|
86
|
+
summary += ` (${response.searchTime}ms)`;
|
|
87
|
+
}
|
|
88
|
+
return summary;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { executeWebSearch, formatSearchResultsForAI, getAvailableProviders, getProvider, summarizeSearchResults };
|
|
92
|
+
//# sourceMappingURL=chunk-XGITAEXU.js.map
|
|
93
|
+
//# sourceMappingURL=chunk-XGITAEXU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/index.ts"],"names":[],"mappings":"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","file":"chunk-XGITAEXU.js","sourcesContent":["/**\n * Web Search Module\n *\n * Multi-provider web search with unified API.\n * Supports tree-shaking - only the provider you use gets bundled.\n *\n * @example\n * ```typescript\n * // Option 1: Lazy loading (provider loaded on first use)\n * import { executeWebSearch } from './webSearch';\n * const results = await executeWebSearch(\n * { query: 'latest AI news' },\n * { provider: 'tavily', apiKey: 'your-api-key' }\n * );\n *\n * // Option 2: Direct import (best for tree-shaking)\n * import { tavilyProvider, executeWebSearch } from './webSearch';\n * const results = await executeWebSearch(\n * { query: 'latest AI news' },\n * { provider: tavilyProvider, apiKey: 'your-api-key' }\n * );\n * ```\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProvider,\n WebSearchProviderInterface,\n} from \"./types\";\n\n// ============================================\n// Lazy Provider Loading (for tree-shaking)\n// ============================================\n\n/**\n * Provider loaders - dynamically import providers only when needed.\n * This ensures unused providers are NOT included in the bundle.\n */\nconst providerLoaders: Record<\n WebSearchProvider,\n () => Promise<\n { default: WebSearchProviderInterface } | WebSearchProviderInterface\n >\n> = {\n openai: () => import(\"./providers/openai\").then((m) => m.openaiProvider),\n google: () => import(\"./providers/google\").then((m) => m.googleProvider),\n anthropic: () =>\n import(\"./providers/anthropic\").then((m) => m.anthropicProvider),\n tavily: () => import(\"./providers/tavily\").then((m) => m.tavilyProvider),\n serper: () => import(\"./providers/serper\").then((m) => m.serperProvider),\n brave: () => import(\"./providers/brave\").then((m) => m.braveProvider),\n searxng: () => import(\"./providers/searxng\").then((m) => m.searxngProvider),\n exa: () => import(\"./providers/exa\").then((m) => m.exaProvider),\n};\n\n// Cache for loaded providers\nconst loadedProviders: Map<WebSearchProvider, WebSearchProviderInterface> =\n new Map();\n\n/**\n * Get a provider by name (lazy loading)\n *\n * @param name - Provider name string\n * @returns Provider interface (loaded dynamically)\n */\nexport async function getProvider(\n name: WebSearchProvider,\n): Promise<WebSearchProviderInterface> {\n // Check cache first\n const cached = loadedProviders.get(name);\n if (cached) {\n return cached;\n }\n\n // Load provider dynamically\n const loader = providerLoaders[name];\n if (!loader) {\n throw new Error(\n `Unknown search provider: ${name}. ` +\n `Available providers: ${Object.keys(providerLoaders).join(\", \")}`,\n );\n }\n\n const provider = await loader();\n const resolvedProvider = \"default\" in provider ? provider.default : provider;\n\n // Cache for future use\n loadedProviders.set(name, resolvedProvider as WebSearchProviderInterface);\n\n return resolvedProvider as WebSearchProviderInterface;\n}\n\n/**\n * Get all available provider names\n */\nexport function getAvailableProviders(): WebSearchProvider[] {\n return Object.keys(providerLoaders) as WebSearchProvider[];\n}\n\n// ============================================\n// Extended Config with Direct Provider Support\n// ============================================\n\n/**\n * Extended config that allows passing provider directly for tree-shaking\n */\nexport interface WebSearchConfigExtended extends Omit<\n WebSearchConfig,\n \"provider\"\n> {\n /**\n * Provider can be either:\n * - A string name (lazy loaded): \"tavily\", \"openai\", \"anthropic\", \"google\", etc.\n * - A provider instance (best for tree-shaking): import { tavilyProvider } from '...'\n */\n provider: WebSearchProvider | WebSearchProviderInterface;\n}\n\n/**\n * Check if a value is a provider interface (not a string)\n */\nfunction isProviderInterface(\n provider: WebSearchProvider | WebSearchProviderInterface,\n): provider is WebSearchProviderInterface {\n return typeof provider === \"object\" && \"search\" in provider;\n}\n\n// ============================================\n// Execute Search\n// ============================================\n\n/**\n * Execute a web search using the configured provider\n *\n * @param params - Search parameters (query, maxResults, searchDepth)\n * @param config - Provider configuration (provider, apiKey, options)\n * @returns Search results with optional AI-generated answer\n *\n * @example\n * ```typescript\n * // Option 1: String provider name (lazy loaded)\n * const results = await executeWebSearch(\n * { query: 'What is the latest news about SpaceX?' },\n * {\n * provider: 'tavily',\n * apiKey: process.env.TAVILY_API_KEY,\n * }\n * );\n *\n * // Option 2: Direct provider import (best for tree-shaking)\n * import { tavilyProvider } from '@yourgpt/copilot-sdk/core';\n * const results = await executeWebSearch(\n * { query: 'What is the latest news about SpaceX?' },\n * {\n * provider: tavilyProvider,\n * apiKey: process.env.TAVILY_API_KEY,\n * }\n * );\n * ```\n */\nexport async function executeWebSearch(\n params: WebSearchParams,\n config: WebSearchConfigExtended,\n): Promise<WebSearchResponse> {\n // Resolve provider (either from string or direct reference)\n const provider = isProviderInterface(config.provider)\n ? config.provider\n : await getProvider(config.provider);\n\n // Build config with string provider name for validation\n const providerName: WebSearchProvider = isProviderInterface(config.provider)\n ? (\"custom\" as WebSearchProvider) // Direct provider\n : config.provider;\n\n const resolvedConfig: WebSearchConfig = {\n ...config,\n provider: providerName,\n };\n\n // Validate configuration if provider supports it\n if (provider.validateConfig) {\n provider.validateConfig(resolvedConfig);\n }\n\n // Execute search\n return provider.search(params, resolvedConfig);\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Format search results for display in AI context\n *\n * @param response - Web search response\n * @param options - Formatting options\n * @returns Formatted string for AI consumption\n */\nexport function formatSearchResultsForAI(\n response: WebSearchResponse,\n options?: {\n includeUrls?: boolean;\n includeScores?: boolean;\n maxContentLength?: number;\n },\n): string {\n const {\n includeUrls = true,\n includeScores = false,\n maxContentLength = 200,\n } = options || {};\n\n const lines: string[] = [];\n\n // Add answer if available\n if (response.answer) {\n lines.push(`Answer: ${response.answer}`);\n lines.push(\"\");\n }\n\n // Add results\n lines.push(`Search results for \"${response.query}\":`);\n lines.push(\"\");\n\n response.results.forEach((result, index) => {\n const num = index + 1;\n let content = result.content;\n\n // Truncate content if needed\n if (maxContentLength && content.length > maxContentLength) {\n content = content.slice(0, maxContentLength) + \"...\";\n }\n\n lines.push(`${num}. ${result.title}`);\n if (includeUrls) {\n lines.push(` URL: ${result.url}`);\n }\n lines.push(` ${content}`);\n if (includeScores && result.score !== undefined) {\n lines.push(` Relevance: ${(result.score * 100).toFixed(1)}%`);\n }\n lines.push(\"\");\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Create a minimal search result summary\n *\n * @param response - Web search response\n * @returns Brief summary string\n */\nexport function summarizeSearchResults(response: WebSearchResponse): string {\n const count = response.results.length;\n const sources = response.results\n .slice(0, 3)\n .map((r) => r.domain || new URL(r.url).hostname)\n .join(\", \");\n\n let summary = `Found ${count} result${count !== 1 ? \"s\" : \"\"}`;\n if (sources) {\n summary += ` from ${sources}`;\n }\n if (response.searchTime) {\n summary += ` (${response.searchTime}ms)`;\n }\n\n return summary;\n}\n\n// ============================================\n// Re-exports\n// ============================================\n\n// Export types\nexport * from \"./types\";\n\n// Export individual providers for direct import (tree-shakeable)\n// Users should import these directly for best bundle size:\n// import { tavilyProvider } from '@yourgpt/copilot-sdk/core';\nexport { openaiProvider } from \"./providers/openai\";\nexport { googleProvider } from \"./providers/google\";\nexport { anthropicProvider } from \"./providers/anthropic\";\nexport { tavilyProvider } from \"./providers/tavily\";\nexport { serperProvider } from \"./providers/serper\";\nexport { braveProvider } from \"./providers/brave\";\nexport { searxngProvider } from \"./providers/searxng\";\nexport { exaProvider } from \"./providers/exa\";\n"]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/tools/webSearch/providers/google.ts
|
|
4
|
+
var GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models";
|
|
5
|
+
function validateGoogleConfig(config) {
|
|
6
|
+
if (!config.apiKey) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"Google API key is required for native web search. Pass apiKey or set GOOGLE_API_KEY/GEMINI_API_KEY environment variable."
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
async function searchGoogle(params, config) {
|
|
13
|
+
validateGoogleConfig(config);
|
|
14
|
+
const startTime = Date.now();
|
|
15
|
+
const apiKey = config.apiKey || process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
|
|
16
|
+
const model = "gemini-2.0-flash";
|
|
17
|
+
const url = `${GEMINI_API_URL}/${model}:generateContent?key=${apiKey}`;
|
|
18
|
+
const requestBody = {
|
|
19
|
+
contents: [
|
|
20
|
+
{
|
|
21
|
+
parts: [
|
|
22
|
+
{
|
|
23
|
+
text: params.query
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
tools: [
|
|
29
|
+
{
|
|
30
|
+
google_search: {}
|
|
31
|
+
// Enable Google Search grounding
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
// Generation config
|
|
35
|
+
generationConfig: {
|
|
36
|
+
temperature: 0.7,
|
|
37
|
+
maxOutputTokens: 1024
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const response = await fetch(url, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
"Content-Type": "application/json"
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify(requestBody),
|
|
46
|
+
signal: config.timeout ? AbortSignal.timeout(config.timeout) : void 0
|
|
47
|
+
});
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Google Gemini API error (${response.status}): ${errorText}`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
const data = await response.json();
|
|
55
|
+
const searchTime = Date.now() - startTime;
|
|
56
|
+
const candidates = data.candidates || [];
|
|
57
|
+
const content = candidates[0]?.content;
|
|
58
|
+
const textParts = content?.parts?.filter((p) => p.text) || [];
|
|
59
|
+
const generatedText = textParts.map((p) => p.text).join("\n");
|
|
60
|
+
const groundingMetadata = candidates[0]?.groundingMetadata;
|
|
61
|
+
const groundingChunks = groundingMetadata?.groundingChunks || [];
|
|
62
|
+
groundingMetadata?.searchEntryPoint;
|
|
63
|
+
const results = groundingChunks.filter((chunk) => chunk.web).slice(0, params.maxResults ?? config.maxResults ?? 5).map((chunk, i) => ({
|
|
64
|
+
title: chunk.web.title || extractDomain(chunk.web.uri),
|
|
65
|
+
url: chunk.web.uri,
|
|
66
|
+
content: "",
|
|
67
|
+
// Google doesn't provide snippets in grounding response
|
|
68
|
+
score: 1 - i * 0.1,
|
|
69
|
+
domain: extractDomain(chunk.web.uri)
|
|
70
|
+
}));
|
|
71
|
+
return {
|
|
72
|
+
query: params.query,
|
|
73
|
+
answer: generatedText,
|
|
74
|
+
results,
|
|
75
|
+
provider: "google",
|
|
76
|
+
totalResults: groundingChunks.length,
|
|
77
|
+
searchTime
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function extractDomain(url) {
|
|
81
|
+
try {
|
|
82
|
+
return new URL(url).hostname.replace("www.", "");
|
|
83
|
+
} catch {
|
|
84
|
+
return url;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
var googleProvider = {
|
|
88
|
+
search: searchGoogle,
|
|
89
|
+
validateConfig: validateGoogleConfig
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
exports.googleProvider = googleProvider;
|
|
93
|
+
exports.searchGoogle = searchGoogle;
|
|
94
|
+
exports.validateGoogleConfig = validateGoogleConfig;
|
|
95
|
+
//# sourceMappingURL=chunk-XWOHNY3F.cjs.map
|
|
96
|
+
//# sourceMappingURL=chunk-XWOHNY3F.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/tools/webSearch/providers/google.ts"],"names":[],"mappings":"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","file":"chunk-XWOHNY3F.cjs","sourcesContent":["/**\n * Google Web Search Provider (Grounding with Google Search)\n *\n * Uses Google's built-in grounding feature via the Gemini API.\n * No third-party API key required - uses your Google/Gemini API key.\n *\n * @see https://ai.google.dev/gemini-api/docs/google-search\n */\n\nimport type {\n WebSearchConfig,\n WebSearchParams,\n WebSearchResponse,\n WebSearchProviderInterface,\n} from \"../types\";\n\nconst GEMINI_API_URL =\n \"https://generativelanguage.googleapis.com/v1beta/models\";\n\n/**\n * Validate Google native search configuration\n */\nexport function validateGoogleConfig(config: WebSearchConfig): void {\n if (!config.apiKey) {\n throw new Error(\n \"Google API key is required for native web search. \" +\n \"Pass apiKey or set GOOGLE_API_KEY/GEMINI_API_KEY environment variable.\",\n );\n }\n}\n\n/**\n * Search using Google's native grounding with Google Search\n */\nexport async function searchGoogle(\n params: WebSearchParams,\n config: WebSearchConfig,\n): Promise<WebSearchResponse> {\n validateGoogleConfig(config);\n\n const startTime = Date.now();\n const apiKey =\n config.apiKey || process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;\n const model = \"gemini-2.0-flash\"; // Use latest model with grounding support\n\n const url = `${GEMINI_API_URL}/${model}:generateContent?key=${apiKey}`;\n\n // Build request with Google Search grounding\n const requestBody = {\n contents: [\n {\n parts: [\n {\n text: params.query,\n },\n ],\n },\n ],\n tools: [\n {\n google_search: {}, // Enable Google Search grounding\n },\n ],\n // Generation config\n generationConfig: {\n temperature: 0.7,\n maxOutputTokens: 1024,\n },\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n signal: config.timeout ? AbortSignal.timeout(config.timeout) : undefined,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n throw new Error(\n `Google Gemini API error (${response.status}): ${errorText}`,\n );\n }\n\n const data = await response.json();\n const searchTime = Date.now() - startTime;\n\n // Extract the generated text\n const candidates = data.candidates || [];\n const content = candidates[0]?.content;\n const textParts =\n content?.parts?.filter((p: { text?: string }) => p.text) || [];\n const generatedText = textParts\n .map((p: { text: string }) => p.text)\n .join(\"\\n\");\n\n // Extract grounding metadata (sources)\n const groundingMetadata = candidates[0]?.groundingMetadata;\n const groundingChunks = groundingMetadata?.groundingChunks || [];\n const searchEntryPoint = groundingMetadata?.searchEntryPoint;\n\n // Build results from grounding chunks\n const results = groundingChunks\n .filter((chunk: { web?: { uri: string; title?: string } }) => chunk.web)\n .slice(0, params.maxResults ?? config.maxResults ?? 5)\n .map((chunk: { web: { uri: string; title?: string } }, i: number) => ({\n title: chunk.web.title || extractDomain(chunk.web.uri),\n url: chunk.web.uri,\n content: \"\", // Google doesn't provide snippets in grounding response\n score: 1 - i * 0.1,\n domain: extractDomain(chunk.web.uri),\n }));\n\n return {\n query: params.query,\n answer: generatedText,\n results,\n provider: \"google\",\n totalResults: groundingChunks.length,\n searchTime,\n };\n}\n\n/**\n * Extract domain from URL\n */\nfunction extractDomain(url: string): string {\n try {\n return new URL(url).hostname.replace(\"www.\", \"\");\n } catch {\n return url;\n }\n}\n\n/**\n * Google native search provider implementation\n */\nexport const googleProvider: WebSearchProviderInterface = {\n search: searchGoogle,\n validateConfig: validateGoogleConfig,\n};\n"]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { webSearchTool } from './chunk-6BXQFCK3.js';
|
|
2
|
+
import { tool, failure, success } from './chunk-J4OMGO5O.js';
|
|
3
|
+
|
|
1
4
|
// src/core/tools/screenshot.ts
|
|
2
5
|
var isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
3
6
|
var DEFAULT_OPTIONS = {
|
|
@@ -1030,69 +1033,6 @@ function createCustomDetector(customKeywords) {
|
|
|
1030
1033
|
};
|
|
1031
1034
|
}
|
|
1032
1035
|
|
|
1033
|
-
// src/core/types/tools.ts
|
|
1034
|
-
function tool(config) {
|
|
1035
|
-
return {
|
|
1036
|
-
description: config.description,
|
|
1037
|
-
location: config.location ?? "client",
|
|
1038
|
-
// Display configuration
|
|
1039
|
-
title: config.title,
|
|
1040
|
-
executingTitle: config.executingTitle,
|
|
1041
|
-
completedTitle: config.completedTitle,
|
|
1042
|
-
// Schema and handlers
|
|
1043
|
-
inputSchema: config.inputSchema ?? {
|
|
1044
|
-
type: "object",
|
|
1045
|
-
properties: {},
|
|
1046
|
-
required: []
|
|
1047
|
-
},
|
|
1048
|
-
handler: config.handler,
|
|
1049
|
-
render: config.render,
|
|
1050
|
-
available: config.available,
|
|
1051
|
-
needsApproval: config.needsApproval,
|
|
1052
|
-
approvalMessage: config.approvalMessage,
|
|
1053
|
-
aiResponseMode: config.aiResponseMode,
|
|
1054
|
-
aiContext: config.aiContext
|
|
1055
|
-
};
|
|
1056
|
-
}
|
|
1057
|
-
function toolToOpenAIFormat(tool2) {
|
|
1058
|
-
return {
|
|
1059
|
-
type: "function",
|
|
1060
|
-
function: {
|
|
1061
|
-
name: tool2.name,
|
|
1062
|
-
description: tool2.description,
|
|
1063
|
-
parameters: tool2.inputSchema
|
|
1064
|
-
}
|
|
1065
|
-
};
|
|
1066
|
-
}
|
|
1067
|
-
function toolToAnthropicFormat(tool2) {
|
|
1068
|
-
return {
|
|
1069
|
-
name: tool2.name,
|
|
1070
|
-
description: tool2.description,
|
|
1071
|
-
input_schema: tool2.inputSchema
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
function createToolResult(toolCallId, response) {
|
|
1075
|
-
return {
|
|
1076
|
-
toolCallId,
|
|
1077
|
-
content: JSON.stringify(response),
|
|
1078
|
-
success: response.success,
|
|
1079
|
-
error: response.error
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
function success(data, message) {
|
|
1083
|
-
return {
|
|
1084
|
-
success: true,
|
|
1085
|
-
data,
|
|
1086
|
-
message
|
|
1087
|
-
};
|
|
1088
|
-
}
|
|
1089
|
-
function failure(error) {
|
|
1090
|
-
return {
|
|
1091
|
-
success: false,
|
|
1092
|
-
error
|
|
1093
|
-
};
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
1036
|
// src/core/tools/builtin/screenshot.ts
|
|
1097
1037
|
var screenshotTool = tool({
|
|
1098
1038
|
description: "Capture a screenshot of the user's current screen/viewport. Use this when the user asks you to look at their screen, see what they're seeing, help with visual issues, or debug UI problems.",
|
|
@@ -1361,6 +1301,10 @@ var builtinTools = {
|
|
|
1361
1301
|
get_network_requests: {
|
|
1362
1302
|
name: "get_network_requests",
|
|
1363
1303
|
...networkRequestsTool
|
|
1304
|
+
},
|
|
1305
|
+
web_search: {
|
|
1306
|
+
name: "web_search",
|
|
1307
|
+
...webSearchTool
|
|
1364
1308
|
}
|
|
1365
1309
|
};
|
|
1366
1310
|
|
|
@@ -2873,6 +2817,6 @@ function createThreadManager(config, callbacks) {
|
|
|
2873
2817
|
return new ThreadManager(config, callbacks);
|
|
2874
2818
|
}
|
|
2875
2819
|
|
|
2876
|
-
export { CLOUD_MAX_FILE_SIZE, DEFAULT_YOURGPT_ENDPOINT, SimpleThreadManagerState, ThreadManager, actionToTool, builtinTools, captureCurrentLogs, captureScreenshot, clearConsoleLogs, clearNetworkRequests, consoleLogsTool, createAssistantMessage, createCloudStorage, createConsoleLogsTool, createCustomDetector, createLocalStorageAdapter, createMemoryAdapter, createMessage, createNetworkRequestsTool, createSSEStream, createScreenshotTool, createServerAdapter, createThreadManager, createToolCall, createToolMessage,
|
|
2877
|
-
//# sourceMappingURL=chunk-
|
|
2878
|
-
//# sourceMappingURL=chunk-
|
|
2820
|
+
export { CLOUD_MAX_FILE_SIZE, DEFAULT_YOURGPT_ENDPOINT, SimpleThreadManagerState, ThreadManager, actionToTool, builtinTools, captureCurrentLogs, captureScreenshot, clearConsoleLogs, clearNetworkRequests, consoleLogsTool, createAssistantMessage, createCloudStorage, createConsoleLogsTool, createCustomDetector, createLocalStorageAdapter, createMemoryAdapter, createMessage, createNetworkRequestsTool, createSSEStream, createScreenshotTool, createServerAdapter, createThreadManager, createToolCall, createToolMessage, createUserMessage, defaultSystemMessage, defineClientTool, defineServerTool, defineTool, detectIntent, formatLogsForAI, formatRequestsForAI, formatSSE, generateId, generateMessageId, generateSuggestionReason, generateThreadId, generateThreadTitle, generateToolCallId, getAttachmentTypeFromMime, getConsoleErrors, getConsoleLogs, getConsoleWarnings, getFailedRequests, getNetworkRequests, getPrimaryTool, hasToolCalls, hasToolSuggestions, isConsoleCaptureActive, isNetworkCaptureActive, isScreenshotSupported, isToolResult, localStorageAdapter, networkRequestsTool, noopAdapter, parseSSELine, parseStreamEvent, parseToolCallArgs, processFileToAttachment, resizeScreenshot, screenshotTool, serializeStreamEvent, startConsoleCapture, startNetworkCapture, stopConsoleCapture, stopNetworkCapture, streamSSE, zodObjectToInputSchema, zodToJsonSchema };
|
|
2821
|
+
//# sourceMappingURL=chunk-Z7PHGSJT.js.map
|
|
2822
|
+
//# sourceMappingURL=chunk-Z7PHGSJT.js.map
|