Skip to content

Commit e25b70f

Browse files
committed
refactor(core): model adaptor
1 parent 3fbfc37 commit e25b70f

139 files changed

Lines changed: 6825 additions & 3631 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/chrome-extension/src/extension/recorder/generators/playwrightGenerator.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import type {
66
StreamingCodeGenerationOptions,
77
} from '@midscene/core';
88
// Note: Streaming support will be added once the core package exports are updated
9-
import { generatePlaywrightTestStream as coreGeneratePlaywrightTestStream } from '@midscene/core/ai-model';
9+
import {
10+
generatePlaywrightTestStream as coreGeneratePlaywrightTestStream,
11+
getModelRuntime,
12+
} from '@midscene/core/ai-model';
1013
import type { IModelConfig } from '@midscene/shared/env';
1114
import { recordLogger } from '../logger';
1215
import { handleTestGenerationError } from './shared/testGenerationUtils';
@@ -98,7 +101,7 @@ export const generatePlaywrightTestStream = async (
98101
const result = await coreGeneratePlaywrightTestStream(
99102
events,
100103
enhancedOptions,
101-
modelConfig,
104+
getModelRuntime(modelConfig),
102105
);
103106

104107
recordLogger.success('Streaming Playwright test generated successfully', {

‎apps/chrome-extension/src/extension/recorder/generators/yamlGenerator.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
import {
66
generateYamlTest as generateYamlTestCore,
77
generateYamlTestStream as generateYamlTestStreamCore,
8+
getModelRuntime,
89
} from '@midscene/core/ai-model';
910
import type { ChromeRecordedEvent } from '@midscene/recorder';
1011
import type { IModelConfig } from '@midscene/shared/env';
@@ -39,7 +40,7 @@ export const generateYamlTest = async (
3940
const yamlContent = await generateYamlTestCore(
4041
events,
4142
enhancedOptions,
42-
modelConfig,
43+
getModelRuntime(modelConfig),
4344
);
4445

4546
recordLogger.success('AI-powered YAML test generated successfully', {
@@ -125,7 +126,7 @@ export const generateYamlTestStream = async (
125126
const result = await generateYamlTestStreamCore(
126127
events,
127128
enhancedOptions,
128-
modelConfig,
129+
getModelRuntime(modelConfig),
129130
);
130131

131132
recordLogger.success(

‎apps/chrome-extension/src/extension/recorder/utils.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
type AIArgs,
33
callAIWithObjectResponse,
44
callAIWithStringResponse,
5+
getModelRuntime,
56
} from '@midscene/core/ai-model';
67
import type { ChromeRecordedEvent } from '@midscene/recorder';
78
import type { IModelConfig } from '@midscene/shared/env';
@@ -623,7 +624,10 @@ const generateAIMindmap = async (
623624
},
624625
];
625626

626-
const response = await callAIWithStringResponse(prompt, modelConfig);
627+
const response = await callAIWithStringResponse(
628+
prompt,
629+
getModelRuntime(modelConfig),
630+
);
627631

628632
if (response?.content && typeof response.content === 'string') {
629633
return response.content as string;

‎apps/chrome-extension/src/utils/eventOptimizer.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Service from '@midscene/core';
22
import type { Rect, UIContext } from '@midscene/core';
33
import { ScreenshotItem } from '@midscene/core';
4+
import { getModelRuntime } from '@midscene/core/ai-model';
45
import type { RecordedEvent } from '@midscene/recorder';
56
import { globalModelConfigManager } from '@midscene/shared/env';
67
import { compositeElementInfoImg } from '@midscene/shared/img';
@@ -121,7 +122,7 @@ export const generateAIDescription = async (
121122
for (let attempt = 1; attempt <= maxRetries; attempt++) {
122123
try {
123124
const modelConfig = globalModelConfigManager.getModelConfig('default');
124-
return await service.describe(rect, modelConfig);
125+
return await service.describe(rect, getModelRuntime(modelConfig));
125126
} catch (err) {
126127
lastError = err;
127128
if (attempt < maxRetries) {

‎apps/site/docs/en/model-strategy.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Some model providers enable model-native thinking by default. In Midscene UI aut
152152

153153
If you need model-native thinking, set `MIDSCENE_MODEL_REASONING_ENABLED="true"` explicitly. Some model families also support extra controls such as `MIDSCENE_MODEL_REASONING_BUDGET` or `MIDSCENE_MODEL_REASONING_EFFORT`; see [Common Model Configuration](./model-common-config) for model-specific examples and [Advanced settings](./model-config#advanced-settings-optional) for the full environment variable reference.
154154

155-
Explicit reasoning configuration requires a supported `MIDSCENE_MODEL_FAMILY`. If the model family is missing or unsupported, Midscene will throw an error instead of guessing provider-specific reasoning parameters.
155+
Reasoning controls are model-family specific. If the configured model family does not support a reasoning option, Midscene ignores that option instead of guessing provider-specific reasoning parameters.
156156

157157
### API style for model service provider
158158

‎apps/site/docs/zh/model-strategy.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ Midscene 提供了基于页面理解的数据处理接口,如 AI 断言(`aiA
151151

152152
如果你需要模型原生思考,请显式设置 `MIDSCENE_MODEL_REASONING_ENABLED="true"`。部分模型系列还支持 `MIDSCENE_MODEL_REASONING_BUDGET` 或 `MIDSCENE_MODEL_REASONING_EFFORT` 等额外控制项,具体示例请参考[常用模型配置](./model-common-config),完整环境变量说明请参考[高阶配置](./model-config#高阶配置可选)。
153153

154-
显式配置 reasoning 时必须使用已支持的 `MIDSCENE_MODEL_FAMILY`。如果没有配置模型系列,或者模型系列不支持 reasoning 配置,Midscene 会直接抛出错误,而不会猜测服务商的私有参数。
154+
reasoning 控制项与模型系列相关。如果当前模型系列不支持某个 reasoning 配置,Midscene 会忽略该配置,而不会猜测服务商的私有参数。
155155

156156
### 模型接口风格
157157

‎apps/studio/src/main/playground/connectivity-test.ts‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
type ChatCompletionMessageParam,
33
callAIWithStringResponse,
4+
getModelRuntime,
45
} from '@midscene/core/ai-model';
56
import type {
67
ConnectivityTestRequest,
@@ -40,15 +41,16 @@ export async function runConnectivityTest(
4041
);
4142

4243
try {
44+
const modelRuntime = getModelRuntime({
45+
...resolvedWithConfig.modelConfig,
46+
timeout: Math.min(
47+
resolvedWithConfig.modelConfig.timeout ?? CONNECTIVITY_TIMEOUT_MS,
48+
CONNECTIVITY_TIMEOUT_MS,
49+
),
50+
});
4351
const { content } = await callAIWithStringResponse(
4452
CONNECTIVITY_PROMPT,
45-
{
46-
...resolvedWithConfig.modelConfig,
47-
timeout: Math.min(
48-
resolvedWithConfig.modelConfig.timeout ?? CONNECTIVITY_TIMEOUT_MS,
49-
CONNECTIVITY_TIMEOUT_MS,
50-
),
51-
},
53+
modelRuntime,
5254
{
5355
abortSignal: controller.signal,
5456
},

‎apps/studio/tests/connectivity-test.test.ts‎

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
22

33
vi.mock('@midscene/core/ai-model', () => ({
44
callAIWithStringResponse: vi.fn(),
5+
getModelRuntime: vi.fn((config) => ({
6+
config,
7+
adapter: {},
8+
})),
59
}));
610

7-
import { callAIWithStringResponse } from '@midscene/core/ai-model';
11+
import {
12+
callAIWithStringResponse,
13+
getModelRuntime,
14+
} from '@midscene/core/ai-model';
815
import { runConnectivityTest } from '../src/main/playground/connectivity-test';
916

1017
describe('runConnectivityTest', () => {
@@ -27,6 +34,16 @@ describe('runConnectivityTest', () => {
2734
ok: true,
2835
sample: 'CONNECTIVITY_OK',
2936
});
37+
expect(getModelRuntime).toHaveBeenCalledWith(
38+
expect.objectContaining({
39+
openaiApiKey: 'sk-test',
40+
openaiBaseURL: 'https://api.example.com/v1',
41+
modelName: 'gpt-4o',
42+
intent: 'default',
43+
slot: 'default',
44+
timeout: 30_000,
45+
}),
46+
);
3047
expect(callAIWithStringResponse).toHaveBeenCalledWith(
3148
[
3249
{
@@ -39,12 +56,14 @@ describe('runConnectivityTest', () => {
3956
},
4057
],
4158
expect.objectContaining({
42-
openaiApiKey: 'sk-test',
43-
openaiBaseURL: 'https://api.example.com/v1',
44-
modelName: 'gpt-4o',
45-
intent: 'default',
46-
slot: 'default',
47-
timeout: 30_000,
59+
config: expect.objectContaining({
60+
openaiApiKey: 'sk-test',
61+
openaiBaseURL: 'https://api.example.com/v1',
62+
modelName: 'gpt-4o',
63+
intent: 'default',
64+
slot: 'default',
65+
timeout: 30_000,
66+
}),
4867
}),
4968
expect.objectContaining({
5069
abortSignal: expect.any(AbortSignal),

0 commit comments

Comments
 (0)