Skip to content

Commit 9894171

Browse files
yuyutaotaoquanruclaude
authored
feat(core): update signature of warp-openai (#1383)
* feat(core): update signature of warp-openai * docs(site): update createOpenAIClient API documentation Update the documentation for createOpenAIClient to reflect the new signature: - Changed from factory function to wrapper function - Now receives base OpenAI instance and options - Returns Promise<OpenAI | undefined> - Updated examples to show async wrapper pattern - Removed unnecessary OpenAI import from examples 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: quanruzhuoxiu <[email protected]> Co-authored-by: Claude <[email protected]>
1 parent 57cd24a commit 9894171

File tree

10 files changed

+178
-155
lines changed

10 files changed

+178
-155
lines changed

apps/site/docs/en/api.mdx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,41 +41,39 @@ These Agents also support the following advanced configuration parameters:
4141
});
4242
```
4343

44-
- `createOpenAIClient: (config) => OpenAI`: Optional. Custom OpenAI client factory function. Allows you to create custom OpenAI client instances for integrating observability tools (such as LangSmith, LangFuse) or using custom OpenAI-compatible clients.
44+
- `createOpenAIClient: (openai, options) => Promise<OpenAI | undefined>`: Optional. Custom OpenAI client wrapper function. Allows you to wrap the OpenAI client instance for integrating observability tools (such as LangSmith, LangFuse) or applying custom middleware.
4545

4646
**Parameter Description:**
47-
- `config.modelName: string` - Model name
48-
- `config.openaiApiKey?: string` - API key
49-
- `config.openaiBaseURL?: string` - API endpoint URL
50-
- `config.intent: string` - AI task type ('VQA' | 'planning' | 'grounding' | 'default')
51-
- `config.vlMode?: string` - Visual language model mode
52-
- Other configuration parameters...
47+
- `openai: OpenAI` - The base OpenAI client instance created by Midscene with all necessary configurations (API key, base URL, proxy, etc.)
48+
- `options: Record<string, unknown>` - OpenAI initialization options, including:
49+
- `baseURL?: string` - API endpoint URL
50+
- `apiKey?: string` - API key
51+
- `dangerouslyAllowBrowser: boolean` - Always true in Midscene
52+
- Other OpenAI configuration options
53+
54+
**Return Value:**
55+
- Return the wrapped OpenAI client instance, or `undefined` to use the original instance
5356

5457
**Example (LangSmith Integration):**
5558
```typescript
56-
import OpenAI from 'openai';
5759
import { wrapOpenAI } from 'langsmith/wrappers';
5860

5961
const agent = new PuppeteerAgent(page, {
60-
createOpenAIClient: (config) => {
61-
const openai = new OpenAI({
62-
apiKey: config.openaiApiKey,
63-
baseURL: config.openaiBaseURL,
64-
});
65-
62+
createOpenAIClient: async (openai, options) => {
6663
// Wrap with LangSmith for planning tasks
67-
if (config.intent === 'planning') {
64+
if (options.baseURL?.includes('planning')) {
6865
return wrapOpenAI(openai, {
6966
metadata: { task: 'planning' }
7067
});
7168
}
7269

70+
// Return the original client for other tasks
7371
return openai;
7472
}
7573
});
7674
```
7775

78-
**Note:** `createOpenAIClient` overrides the behavior of the `MIDSCENE_LANGSMITH_DEBUG` environment variable. If you provide a custom client factory function, you need to handle the integration of LangSmith or other observability tools yourself.
76+
**Note:** `createOpenAIClient` overrides the behavior of the `MIDSCENE_LANGSMITH_DEBUG` environment variable. If you provide a custom client wrapper function, you need to handle the integration of LangSmith or other observability tools yourself.
7977

8078
In Puppeteer, there is also a parameter:
8179

apps/site/docs/zh/api.mdx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,41 +41,39 @@ Midscene 中每个 Agent 都有自己的构造函数。
4141
});
4242
```
4343

44-
- `createOpenAIClient: (config) => OpenAI`: 可选。自定义 OpenAI 客户端工厂函数。允许你创建自定义的 OpenAI 客户端实例,用于集成可观测性工具(如 LangSmith、LangFuse)或使用自定义的 OpenAI 兼容客户端
44+
- `createOpenAIClient: (openai, options) => Promise<OpenAI | undefined>`: 可选。自定义 OpenAI 客户端包装函数。允许你包装 OpenAI 客户端实例,用于集成可观测性工具(如 LangSmith、LangFuse)或应用自定义中间件
4545

4646
**参数说明:**
47-
- `config.modelName: string` - 模型名称
48-
- `config.openaiApiKey?: string` - API 密钥
49-
- `config.openaiBaseURL?: string` - API 接入地址
50-
- `config.intent: string` - AI 任务类型('VQA' | 'planning' | 'grounding' | 'default')
51-
- `config.vlMode?: string` - 视觉语言模型模式
52-
- 其他配置参数...
47+
- `openai: OpenAI` - Midscene 创建的基础 OpenAI 客户端实例,已包含所有必要配置(API 密钥、基础 URL、代理等)
48+
- `options: Record<string, unknown>` - OpenAI 初始化选项,包括:
49+
- `baseURL?: string` - API 接入地址
50+
- `apiKey?: string` - API 密钥
51+
- `dangerouslyAllowBrowser: boolean` - 在 Midscene 中始终为 true
52+
- 其他 OpenAI 配置选项
53+
54+
**返回值:**
55+
- 返回包装后的 OpenAI 客户端实例,或返回 `undefined` 表示使用原始实例
5356

5457
**示例(集成 LangSmith):**
5558
```typescript
56-
import OpenAI from 'openai';
5759
import { wrapOpenAI } from 'langsmith/wrappers';
5860

5961
const agent = new PuppeteerAgent(page, {
60-
createOpenAIClient: (config) => {
61-
const openai = new OpenAI({
62-
apiKey: config.openaiApiKey,
63-
baseURL: config.openaiBaseURL,
64-
});
65-
62+
createOpenAIClient: async (openai, options) => {
6663
// 为规划任务包装 LangSmith
67-
if (config.intent === 'planning') {
64+
if (options.baseURL?.includes('planning')) {
6865
return wrapOpenAI(openai, {
6966
metadata: { task: 'planning' }
7067
});
7168
}
7269

70+
// 其他任务返回原始客户端
7371
return openai;
7472
}
7573
});
7674
```
7775

78-
**注意:** `createOpenAIClient` 会覆盖 `MIDSCENE_LANGSMITH_DEBUG` 环境变量的行为。如果你提供了自定义的客户端工厂函数,需要自行处理 LangSmith 或其他可观测性工具的集成。
76+
**注意:** `createOpenAIClient` 会覆盖 `MIDSCENE_LANGSMITH_DEBUG` 环境变量的行为。如果你提供了自定义的客户端包装函数,需要自行处理 LangSmith 或其他可观测性工具的集成。
7977

8078
在 Puppeteer 中,还有以下参数:
8179

packages/cli/src/create-yaml-player.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ export async function createYamlPlayer(
129129
webTarget,
130130
{
131131
...preference,
132-
cache: processCacheConfig(clonedYamlScript.agent?.cache, fileName),
132+
cache: processCacheConfig(
133+
clonedYamlScript.agent?.cache,
134+
fileName,
135+
),
133136
},
134137
options?.browser,
135138
);

packages/core/src/ai-model/service-caller/index.ts

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,40 +46,34 @@ async function createChatClient({
4646
createOpenAIClient,
4747
} = modelConfig;
4848

49-
let openai: OpenAI;
49+
let proxyAgent = undefined;
50+
const debugProxy = getDebug('ai:call:proxy');
51+
if (httpProxy) {
52+
debugProxy('using http proxy', httpProxy);
53+
proxyAgent = new HttpsProxyAgent(httpProxy);
54+
} else if (socksProxy) {
55+
debugProxy('using socks proxy', socksProxy);
56+
proxyAgent = new SocksProxyAgent(socksProxy);
57+
}
58+
59+
const openAIOptions = {
60+
baseURL: openaiBaseURL,
61+
apiKey: openaiApiKey,
62+
...(proxyAgent ? { httpAgent: proxyAgent as any } : {}),
63+
...openaiExtraConfig,
64+
dangerouslyAllowBrowser: true,
65+
};
66+
67+
const baseOpenAI = new OpenAI(openAIOptions);
68+
69+
let openai: OpenAI = baseOpenAI;
5070

51-
// Use custom client factory if provided
5271
if (createOpenAIClient) {
53-
openai = createOpenAIClient({
54-
modelName,
55-
openaiApiKey,
56-
openaiBaseURL,
57-
socksProxy,
58-
httpProxy,
59-
openaiExtraConfig,
60-
vlMode,
61-
intent: modelConfig.intent,
62-
modelDescription,
63-
});
64-
} else {
65-
// Default OpenAI client creation
66-
let proxyAgent = undefined;
67-
const debugProxy = getDebug('ai:call:proxy');
68-
if (httpProxy) {
69-
debugProxy('using http proxy', httpProxy);
70-
proxyAgent = new HttpsProxyAgent(httpProxy);
71-
} else if (socksProxy) {
72-
debugProxy('using socks proxy', socksProxy);
73-
proxyAgent = new SocksProxyAgent(socksProxy);
74-
}
72+
const wrappedClient = await createOpenAIClient(baseOpenAI, openAIOptions);
7573

76-
openai = new OpenAI({
77-
baseURL: openaiBaseURL,
78-
apiKey: openaiApiKey,
79-
...(proxyAgent ? { httpAgent: proxyAgent as any } : {}),
80-
...openaiExtraConfig,
81-
dangerouslyAllowBrowser: true,
82-
});
74+
if (wrappedClient) {
75+
openai = wrappedClient as OpenAI;
76+
}
8377
}
8478

8579
return {

packages/core/src/types.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -614,14 +614,9 @@ export interface AgentOpt {
614614
*
615615
* @example
616616
* ```typescript
617-
* createOpenAIClient: (config) => {
618-
* const openai = new OpenAI({
619-
* apiKey: config.openaiApiKey,
620-
* baseURL: config.openaiBaseURL,
621-
* });
622-
*
617+
* createOpenAIClient: async (openai, opts) => {
623618
* // Wrap with langsmith for planning tasks
624-
* if (config.intent === 'planning') {
619+
* if (opts.baseURL?.includes('planning')) {
625620
* return wrapOpenAI(openai, { metadata: { task: 'planning' } });
626621
* }
627622
*

0 commit comments

Comments
 (0)