From 64cac4d655c17dab7913613630e8aa79b6206b7a Mon Sep 17 00:00:00 2001 From: HairlessVillager Date: Thu, 23 Jan 2025 15:15:56 +0800 Subject: [PATCH 1/4] feat: `web_search` always reuse current window --- src/extension/tools/web_search.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/extension/tools/web_search.ts b/src/extension/tools/web_search.ts index 7fae487..a3c4ca1 100644 --- a/src/extension/tools/web_search.ts +++ b/src/extension/tools/web_search.ts @@ -47,7 +47,8 @@ export class WebSearch implements Tool { } let taskId = new Date().getTime() + ''; let searchs = [{ url: url as string, keyword: query as string }]; - let searchInfo = await deepSearch(taskId, searchs, maxResults || 5); + let window = await chrome.windows.getCurrent(); + let searchInfo = await deepSearch(taskId, searchs, maxResults || 5, window); let links = searchInfo.result[0]?.links || []; return links.filter((s: any) => s.content) as WebSearchResult[]; } From 905aa69249a59388a000f495d77a1953977e06e8 Mon Sep 17 00:00:00 2001 From: HairlessVillager Date: Thu, 23 Jan 2025 18:26:27 +0800 Subject: [PATCH 2/4] refactor the EkoConfig, add `alwaysOpenNewWindow` option --- src/core/eko.ts | 29 ++++++++++++++++----------- src/extension/tools/export_file.ts | 32 +++++++++++++++++++----------- src/extension/tools/web_search.ts | 10 ++++++++-- src/types/action.types.ts | 5 +++++ src/types/eko.types.ts | 2 +- 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/core/eko.ts b/src/core/eko.ts index c476bff..c020ead 100644 --- a/src/core/eko.ts +++ b/src/core/eko.ts @@ -2,7 +2,7 @@ import { WorkflowGenerator } from '../services/workflow/generator'; import { ClaudeProvider } from '../services/llm/claude-provider'; import { OpenaiProvider } from '../services/llm/openai-provider'; import { - EkoConfig, + LLMConfig, EkoInvokeParam, LLMProvider, Tool, @@ -11,6 +11,8 @@ import { OpenaiConfig, WorkflowCallback, NodeOutput, + ExecutionContext, + EkoConfig, } from '../types'; import { ToolRegistry } from './tool-registry'; @@ -23,30 +25,32 @@ export class Eko { private llmProvider: LLMProvider; private toolRegistry = new ToolRegistry(); private workflowGeneratorMap = new Map(); + private ekoConfig: EkoConfig; - constructor(config: EkoConfig) { - if (typeof config == 'string') { - this.llmProvider = new ClaudeProvider(config); - } else if ('llm' in config) { - if (config.llm == 'claude') { - let claudeConfig = config as ClaudeConfig; + constructor(llmConfig: LLMConfig, ekoConfig: EkoConfig) { + this.ekoConfig = ekoConfig; + if (typeof llmConfig == 'string') { + this.llmProvider = new ClaudeProvider(llmConfig); + } else if ('llm' in llmConfig) { + if (llmConfig.llm == 'claude') { + let claudeConfig = llmConfig as ClaudeConfig; this.llmProvider = new ClaudeProvider( claudeConfig.apiKey, claudeConfig.modelName, claudeConfig.options ); - } else if (config.llm == 'openai') { - let openaiConfig = config as OpenaiConfig; + } else if (llmConfig.llm == 'openai') { + let openaiConfig = llmConfig as OpenaiConfig; this.llmProvider = new OpenaiProvider( openaiConfig.apiKey, openaiConfig.modelName, openaiConfig.options ); } else { - throw new Error('Unknown parameter: llm > ' + config['llm']); + throw new Error('Unknown parameter: llm > ' + llmConfig['llm']); } } else { - this.llmProvider = config as LLMProvider; + this.llmProvider = llmConfig as LLMProvider; } Eko.tools.forEach((tool) => this.toolRegistry.registerTool(tool)); } @@ -108,8 +112,9 @@ export class Eko { if (typeof tool === 'string') { tool = this.getTool(tool); } - let context = { + let context: ExecutionContext = { llmProvider: this.llmProvider, + ekoConfig: this.ekoConfig, variables: new Map(), tools: new Map>(), callback, diff --git a/src/extension/tools/export_file.ts b/src/extension/tools/export_file.ts index b339a29..6c28c0f 100644 --- a/src/extension/tools/export_file.ts +++ b/src/extension/tools/export_file.ts @@ -75,22 +75,30 @@ export class ExportFile implements Tool { filename = params.filename; } let tabId = await getTabId(context); - try { + + const url = 'https://www.google.com'; + const exportClosure = async (tabId: number) => { await chrome.scripting.executeScript({ - target: { tabId: tabId as number }, - func: exportFile, - args: [filename, type, params.content], - }); - } catch (e) { - let tab = await open_new_tab('https://www.google.com', true); + target: { tabId: tabId}, + func: exportFile, + args: [filename, type, params.content], + });} + const openNewTabAndProcess = async (url: string, tabId: number) => { + let tab = await open_new_tab(url, true); tabId = tab.id as number; - await chrome.scripting.executeScript({ - target: { tabId: tabId as number }, - func: exportFile, - args: [filename, type, params.content], - }); + await exportClosure(tabId); await sleep(1000); await chrome.tabs.remove(tabId); + }; + console.log("context.ekoConfig: "+context.ekoConfig); + if (context.ekoConfig.alwaysOpenNewWindow) { + await openNewTabAndProcess(url, tabId); + } else { + try { + await exportClosure(tabId as number); + } catch (e) { + await openNewTabAndProcess(url, tabId); + } } return { success: true }; } diff --git a/src/extension/tools/web_search.ts b/src/extension/tools/web_search.ts index a3c4ca1..d50eeb4 100644 --- a/src/extension/tools/web_search.ts +++ b/src/extension/tools/web_search.ts @@ -47,8 +47,14 @@ export class WebSearch implements Tool { } let taskId = new Date().getTime() + ''; let searchs = [{ url: url as string, keyword: query as string }]; - let window = await chrome.windows.getCurrent(); - let searchInfo = await deepSearch(taskId, searchs, maxResults || 5, window); + let searchInfo: any; + console.log("context.ekoConfig: "+context.ekoConfig); + if (context.ekoConfig.alwaysOpenNewWindow) { + searchInfo = await deepSearch(taskId, searchs, maxResults || 5); + } else { + let window = await chrome.windows.getCurrent(); + searchInfo = await deepSearch(taskId, searchs, maxResults || 5, window); + } let links = searchInfo.result[0]?.links || []; return links.filter((s: any) => s.content) as WebSearchResult[]; } diff --git a/src/types/action.types.ts b/src/types/action.types.ts index 0dff75a..81047f3 100644 --- a/src/types/action.types.ts +++ b/src/types/action.types.ts @@ -29,8 +29,13 @@ export interface Property { properties?: Properties; } +export interface EkoConfig { + alwaysOpenNewWindow: boolean; +} + export interface ExecutionContext { llmProvider: LLMProvider; + ekoConfig: EkoConfig; variables: Map; workflow?: Workflow; tools?: Map>; diff --git a/src/types/eko.types.ts b/src/types/eko.types.ts index 37fea53..b4a2eb7 100644 --- a/src/types/eko.types.ts +++ b/src/types/eko.types.ts @@ -19,7 +19,7 @@ export interface OpenaiConfig { export type ClaudeApiKey = string; -export type EkoConfig = ClaudeApiKey | ClaudeConfig | OpenaiConfig | LLMProvider; +export type LLMConfig = ClaudeApiKey | ClaudeConfig | OpenaiConfig | LLMProvider; export interface EkoInvokeParam { tools?: Array | Array>; From 5f6dbd1e5075c194e6ccda3bde90a3227ab36b44 Mon Sep 17 00:00:00 2001 From: HairlessVillager Date: Thu, 23 Jan 2025 18:53:10 +0800 Subject: [PATCH 3/4] make the `ekoConfig` as optional --- src/core/eko.ts | 6 ++++-- src/models/workflow.ts | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/eko.ts b/src/core/eko.ts index c020ead..796e318 100644 --- a/src/core/eko.ts +++ b/src/core/eko.ts @@ -27,8 +27,10 @@ export class Eko { private workflowGeneratorMap = new Map(); private ekoConfig: EkoConfig; - constructor(llmConfig: LLMConfig, ekoConfig: EkoConfig) { - this.ekoConfig = ekoConfig; + constructor(llmConfig: LLMConfig, ekoConfig?: EkoConfig) { + this.ekoConfig = ekoConfig ? ekoConfig : { + alwaysOpenNewWindow: false, + } if (typeof llmConfig == 'string') { this.llmProvider = new ClaudeProvider(llmConfig); } else if ('llm' in llmConfig) { diff --git a/src/models/workflow.ts b/src/models/workflow.ts index 602aebd..0c946fb 100644 --- a/src/models/workflow.ts +++ b/src/models/workflow.ts @@ -38,10 +38,11 @@ export class WorkflowImpl implements Workflow { const node = this.getNode(nodeId); // Execute the node's action - const context = { + const context: ExecutionContext = { __skip: false, __abort: false, workflow: this, + ekoConfig: {alwaysOpenNewWindow: false}, variables: this.variables, llmProvider: this.llmProvider as LLMProvider, tools: new Map(node.action.tools.map(tool => [tool.name, tool])), From 33938b4f276a6f2f4fa62459179b1741ad99e8d3 Mon Sep 17 00:00:00 2001 From: HairlessVillager Date: Thu, 23 Jan 2025 19:01:07 +0800 Subject: [PATCH 4/4] add log for checking `ekoConfig` --- src/core/eko.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/eko.ts b/src/core/eko.ts index 796e318..dec2b04 100644 --- a/src/core/eko.ts +++ b/src/core/eko.ts @@ -28,9 +28,10 @@ export class Eko { private ekoConfig: EkoConfig; constructor(llmConfig: LLMConfig, ekoConfig?: EkoConfig) { + console.log("ekoConfig: " + ekoConfig); this.ekoConfig = ekoConfig ? ekoConfig : { alwaysOpenNewWindow: false, - } + }; if (typeof llmConfig == 'string') { this.llmProvider = new ClaudeProvider(llmConfig); } else if ('llm' in llmConfig) {