Skip to content

Commit b8cc35a

Browse files
committed
chore: merge main branch
2 parents c17f870 + 032b505 commit b8cc35a

Some content is hidden

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

48 files changed

+32956
-5178
lines changed

apps/site/docs/en/docs/more/prompting-tips.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,19 @@ Bad ❌: "[number, number], the [x, y] coords of the main button"
3434

3535
Use the visualization tool to debug and understand each step of Midscene. Just upload the log, and view the AI's parse results. You can find [the tool](/visualization/) on the navigation bar on this site.
3636

37-
### Remember to cross-check the result by assertion
37+
### Infer or assert from the interface, not the DOM properties or browser status
38+
39+
All the data sent to the LLM is in the form of screenshots and element coordinates. The DOM and the browser instance are almost invisible to the LLM. Therefore, ensure everything you expect is visible in the on the screen.
40+
41+
Good ✅: The title is blue
42+
43+
Bad ❌: The title has a `test-id-size` property
44+
45+
Bad ❌: The browser has two active tabs
46+
47+
Bad ❌: The request has finished.
48+
49+
### Cross-check the result using assertion
3850

3951
LLM could behave incorrectly. A better practice is to check its result after running.
4052

@@ -49,13 +61,7 @@ expect(taskList.length).toBe(1);
4961
expect(taskList[0]).toBe('Learning AI the day after tomorrow');
5062
```
5163

52-
### Infer from the UI, not the DOM properties
53-
54-
All the data sent to the LLM are the screenshots and element coordinates. The DOM is almost invisible to the LLM. So do not expect the LLM infer any information from the DOM (such as `test-id-*` properties).
55-
56-
Ensure everything you expect from the LLM is visible in the screenshot.
57-
58-
### non-English prompting is acceptable
64+
### Non-English prompting is acceptable
5965

6066
Since most AI models can understand many languages, feel free to write the prompt in any language you prefer. It usually works even if the prompt is in a language different from the page's language.
6167

apps/site/docs/en/docs/usage/cache.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Cache
22

3-
Midscene.js provides AI caching capabilities to improve the stability and speed of the entire AI execution process. The cache here mainly refers to caching AI's recognition of page elements. When the page elements have not changed, the AI query results will be cached.
3+
Midscene.js provides AI caching features to improve the stability and speed of the entire AI execution process. The cache mainly refers to caching how AI recognizes page elements. Cached AI query results are used if page elements haven't changed.
44

55
## Instructions
66

@@ -15,6 +15,8 @@ Currently, the caching capability is supported in all scenarios, and Midscene ca
1515

1616
**Effect**
1717

18+
After enabling the cache, the execution time is significantly reduced, for example, from 1m16s to 23s.
19+
1820
* **before**
1921

2022
![](/cache/no-cache-time.png)

apps/site/docs/zh/docs/more/prompting-tips.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@
3333

3434
使用可视化工具调试和理解 Midscene 的每个步骤。只需上传日志,就可以查看 AI 的解析结果。你可以在本站导航栏上找到 [可视化工具](/visualization/)
3535

36+
### 从界面做推断,而不是 DOM 属性或者浏览器状态
37+
38+
所有传递给 LLM 的数据都是截图和元素坐标。DOM和浏览器 对 LLM 来说几乎是不可见的。因此,务必确保你想提取的信息都在截图中有所体现且能被 LLM “看到”。
39+
40+
正确示例 ✅:标题是蓝色的
41+
42+
错误实例 ❌:标题有个 `test-id-size` 属性
43+
44+
错误实例 ❌:浏览器有两个 tab 开着
45+
46+
错误实例 ❌:异步请求已经结束了
47+
3648
### 通过断言交叉检查结果
3749

3850
LLM 可能会表现出错误的行为。更好的做法是运行操作后检查其结果。
@@ -48,12 +60,6 @@ expect(taskList.length).toBe(1);
4860
expect(taskList[0]).toBe('后天学习 AI');
4961
```
5062

51-
### 从界面而不是 DOM 属性推断信息
52-
53-
所有传递给 LLM 的数据都是截图和元素坐标。DOM 对 LLM 来说几乎是不可见的。因此,不要指望 LLM 能从 DOM 中推断任何信息(比如 `test-id-*` 属性)。
54-
55-
务必确保你想提取的信息都在截图中有所体现且能被 LLM “看到”。
56-
5763
### 中、英文提示词都是可行的
5864

5965
由于大多数 AI 模型可以理解多种语言,所以请随意用你喜欢的语言撰写提示指令。即使提示语言与页面语言不同,通常也是可行的。

apps/site/docs/zh/docs/usage/cache.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Midscene.js 提供了 AI 缓存能力,用于提升整个 AI 执行过程的稳
1515

1616
**使用效果**
1717

18+
通过引入缓存后,用例的执行时间大幅降低了,例如从1分16秒降低到了23秒。
19+
1820
* **before**
1921

2022
![](/cache/no-cache-time.png)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "midscene",
33
"private": true,
4-
"version": "0.4.0",
4+
"version": "0.5.1",
55
"scripts": {
66
"build:pkg": "nx run-many --target=build --projects=@midscene/core,@midscene/shared,@midscene/visualizer,@midscene/web,@midscene/cli --verbose",
77
"test": "nx run-many --target=test --projects=@midscene/core,--projects=@midscene/shared,@midscene/visualizer,@midscene/web,@midscene/cli --verbose",

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@midscene/cli",
33
"description": "Cli for Midscene.js",
4-
"version": "0.4.0",
4+
"version": "0.5.1",
55
"jsnext:source": "./src/index.ts",
66
"main": "./dist/lib/index.js",
77
"bin": {

packages/midscene/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@midscene/core",
33
"description": "Hello, It's Midscene",
4-
"version": "0.4.0",
4+
"version": "0.5.1",
55
"jsnext:source": "./src/index.ts",
66
"main": "./dist/lib/index.js",
77
"module": "./dist/es/index.js",

packages/midscene/src/ai-model/common.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ export async function callAiFn<T>(options: {
6565
return parseResult;
6666
}
6767

68-
throw Error('Does not contain coze and openai environment variables');
68+
throw Error(
69+
'Cannot find Coze or OpenAI config. You should set at least one of them.',
70+
);
6971
}
7072

7173
export function transformUserMessages(msgs: ChatCompletionContentPart[]) {

packages/midscene/src/utils.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,6 @@ export async function sleep(ms: number) {
145145
return new Promise((resolve) => setTimeout(resolve, ms));
146146
}
147147

148-
export const commonScreenshotParam = { type: 'jpeg', quality: 75 } as any;
149-
150148
export function replacerForPageObject(key: string, value: any) {
151149
if (value && value.constructor?.name === 'Page') {
152150
return '[Page object]';

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@midscene/shared",
3-
"version": "0.4.0",
3+
"version": "0.5.1",
44
"types": "./src/index.ts",
55
"main": "./dist/lib/index.js",
66
"module": "./dist/es/index.js",

packages/visualizer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@midscene/visualizer",
3-
"version": "0.4.0",
3+
"version": "0.5.1",
44
"types": "./dist/types/index.d.ts",
55
"main": "./dist/lib/index.js",
66
"module": "./dist/es/index.js",

packages/visualizer/scripts/build-html.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ const htmlPath = join(__dirname, '../html/tpl.html');
2222
const cssPath = join(__dirname, '../dist/report/index.css');
2323
const jsPath = join(__dirname, '../dist/report/index.js');
2424
const demoPath = join(__dirname, './fixture/demo-dump.json');
25+
const demoMobilePath = join(__dirname, './fixture/demo-mobile-dump.json');
2526
const multiEntrySegment = join(__dirname, './fixture/multi-entries.html');
2627
const outputHTML = join(__dirname, '../dist/report/index.html');
2728
const outputDemoHTML = join(__dirname, '../dist/report/demo.html');
29+
const outputDemoMobileHTML = join(__dirname, '../dist/report/demo-mobile.html');
2830
const outputMultiEntriesHTML = join(__dirname, '../dist/report/multi.html');
2931
const outputEmptyDumpHTML = join(__dirname, '../dist/report/empty-error.html');
3032

@@ -75,6 +77,15 @@ function build() {
7577
writeFileSync(outputDemoHTML, resultWithDemo);
7678
console.log(`HTML file generated successfully: ${outputDemoHTML}`);
7779

80+
const demoMobileData = readFileSync(demoMobilePath, 'utf-8');
81+
const resultWithDemoMobile = tplReplacer(html, {
82+
css: `<style>\n${css}\n</style>\n`,
83+
js: `<script>\n${js}\n</script>`,
84+
dump: `<script type="midscene_web_dump" type="application/json">${demoMobileData}</script>`,
85+
});
86+
writeFileSync(outputDemoMobileHTML, resultWithDemoMobile);
87+
console.log(`HTML file generated successfully: ${outputDemoMobileHTML}`);
88+
7889
const multiEntriesData = readFileSync(multiEntrySegment, 'utf-8');
7990
const resultWithMultiEntries = tplReplacer(html, {
8091
css: `<style>\n${css}\n</style>\n`,

packages/visualizer/scripts/fixture/demo-dump.json

Lines changed: 4932 additions & 4932 deletions
Large diffs are not rendered by default.

packages/visualizer/scripts/fixture/demo-mobile-dump.json

Lines changed: 26749 additions & 0 deletions
Large diffs are not rendered by default.

packages/visualizer/src/component/blackboard.tsx

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,53 @@ import { colorForName, highlightColorForType } from './color';
88
import './blackboard.less';
99
import { useBlackboardPreference, useInsightDump } from './store';
1010

11-
const itemFillAlpha = 0.3;
11+
const itemFillAlpha = 0.4;
12+
const highlightAlpha = 0.7;
1213
const bgOnAlpha = 0.8;
1314
const bgOffAlpha = 0.3;
1415
const noop = () => {
1516
// noop
1617
};
1718

19+
export const rectMarkForItem = (
20+
rect: Rect,
21+
name: string,
22+
ifHighlight: boolean,
23+
onPointOver?: () => void,
24+
onPointerOut?: () => void,
25+
) => {
26+
const { left, top, width, height } = rect;
27+
const themeColor = ifHighlight
28+
? highlightColorForType('element')
29+
: colorForName(name);
30+
const alpha = ifHighlight ? highlightAlpha : itemFillAlpha;
31+
const graphics = new PIXI.Graphics();
32+
graphics.beginFill(themeColor, alpha);
33+
graphics.lineStyle(1, themeColor, 1);
34+
graphics.drawRect(left, top, width, height);
35+
graphics.endFill();
36+
if (onPointOver && onPointerOut) {
37+
graphics.interactive = true;
38+
graphics.on('pointerover', onPointOver);
39+
graphics.on('pointerout', onPointerOut);
40+
}
41+
42+
const nameFontSize = 18;
43+
const texts = new PIXI.Text(name, {
44+
fontSize: nameFontSize,
45+
fill: 0x0,
46+
});
47+
texts.x = left;
48+
texts.y = Math.max(top - (nameFontSize + 4), 0);
49+
return [graphics, texts];
50+
};
51+
1852
const BlackBoard = (): JSX.Element => {
1953
const dump = useInsightDump((store) => store.data);
2054
const setHighlightElements = useInsightDump(
2155
(store) => store.setHighlightElements,
2256
);
23-
const highlightSectionNames = useInsightDump(
24-
(store) => store.highlightSectionNames,
25-
);
57+
2658
const highlightElements = useInsightDump((store) => store.highlightElements);
2759
const highlightIds = highlightElements.map((e) => e.id);
2860

@@ -107,34 +139,6 @@ const BlackBoard = (): JSX.Element => {
107139
};
108140
}, [app.stage, appInitialed]);
109141

110-
const rectMarkForItem = (
111-
rect: Rect,
112-
name: string,
113-
themeColor: string,
114-
alpha: number,
115-
onPointOver: () => void,
116-
onPointerOut: () => void,
117-
) => {
118-
const { left, top, width, height } = rect;
119-
const graphics = new PIXI.Graphics();
120-
graphics.beginFill(themeColor, alpha);
121-
graphics.lineStyle(1, themeColor, 1);
122-
graphics.drawRect(left, top, width, height);
123-
graphics.endFill();
124-
graphics.interactive = true;
125-
graphics.on('pointerover', onPointOver);
126-
graphics.on('pointerout', onPointerOut);
127-
128-
const nameFontSize = 18;
129-
const texts = new PIXI.Text(name, {
130-
fontSize: nameFontSize,
131-
fill: 0x0,
132-
});
133-
texts.x = left;
134-
texts.y = Math.max(top - (nameFontSize + 4), 0);
135-
return [graphics, texts];
136-
};
137-
138142
const { highlightElementRects } = useMemo(() => {
139143
const highlightElementRects: Rect[] = [];
140144

@@ -149,10 +153,7 @@ const BlackBoard = (): JSX.Element => {
149153
const [graphics] = rectMarkForItem(
150154
rect,
151155
content,
152-
ifHighlight
153-
? highlightColorForType('element')
154-
: colorForName('element', content),
155-
ifHighlight ? 1 : itemFillAlpha,
156+
ifHighlight,
156157
noop,
157158
noop,
158159
);
@@ -162,10 +163,7 @@ const BlackBoard = (): JSX.Element => {
162163
const [graphics] = rectMarkForItem(
163164
rect,
164165
content,
165-
ifHighlight
166-
? highlightColorForType('element')
167-
: colorForName('element', content),
168-
ifHighlight ? 1 : itemFillAlpha,
166+
ifHighlight,
169167
() => {
170168
setHighlightElements([element]);
171169
},
Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// https://coolors.co/palettes/popular/#01204e
22
const sectionColor = ['#028391'];
3-
const elementColor = ['#fb6107'];
3+
// const elementColor = ['#fb6107'];
4+
const elementColor = ['#01204E'];
45
const highlightColorForSection = '#01204E';
56
const highlightColorForElement = '#F56824'; // @main-orange
67

78
function djb2Hash(str?: string): number {
89
if (!str) {
9-
console.warn('djb2Hash: empty string');
10+
// console.warn('djb2Hash: empty string');
1011
str = 'unnamed';
1112
}
1213
let hash = 5381;
@@ -16,20 +17,12 @@ function djb2Hash(str?: string): number {
1617
return hash >>> 0; // Convert to unsigned 32
1718
}
1819

19-
export function colorForName(
20-
type: 'section' | 'element',
21-
name: string,
22-
): string {
20+
export function colorForName(name: string): string {
2321
const hashNumber = djb2Hash(name);
24-
if (type === 'section') {
25-
return sectionColor[hashNumber % sectionColor.length];
26-
}
2722
return elementColor[hashNumber % elementColor.length];
2823
}
2924

3025
export function highlightColorForType(type: 'section' | 'element'): string {
31-
if (type === 'section') {
32-
return highlightColorForSection;
33-
}
26+
// return highlightColorForSection;
3427
return highlightColorForElement;
3528
}

packages/visualizer/src/component/detail-panel.less

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66
display: flex;
77
flex-direction: column;
88
height: 100%;
9+
box-sizing: border-box;
910
padding: @layout-space;
1011
background: #FFF;
1112

13+
.scrollable {
14+
height: 100%;
15+
overflow: auto;
16+
}
17+
1218
.ant-segmented{
1319
padding: 0;
1420
}
@@ -24,6 +30,8 @@
2430
flex-direction: column;
2531
display: flex;
2632
flex-grow: 1;
33+
height: 100%;
34+
overflow: hidden;
2735
}
2836

2937
.blackboard {
@@ -48,6 +56,8 @@
4856
img {
4957
border: 1px solid @heavy-border-color;
5058
max-width: 100%;
59+
max-height: 720px;
60+
box-sizing: border-box;
5161
}
5262
}
5363

0 commit comments

Comments
 (0)