misoai-web 1.0.4 → 1.0.6
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/LICENSE +21 -21
- package/README.md +353 -9
- package/bin/midscene-playground +2 -2
- package/dist/es/agent.js +378 -92
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +3 -3
- package/dist/es/bridge-mode-browser.js.map +1 -1
- package/dist/es/bridge-mode.js +380 -94
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +379 -93
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +378 -92
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +378 -92
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/midscene-server.js.map +1 -1
- package/dist/es/playground.js +378 -92
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright-report.js.map +1 -1
- package/dist/es/playwright.js +378 -92
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +378 -92
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +378 -92
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/es/ui-utils.js.map +1 -1
- package/dist/es/utils.js.map +1 -1
- package/dist/es/yaml.js.map +1 -1
- package/dist/lib/agent.js +378 -92
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +3 -3
- package/dist/lib/bridge-mode-browser.js.map +1 -1
- package/dist/lib/bridge-mode.js +380 -94
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +379 -93
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +378 -92
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +378 -92
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/midscene-server.js.map +1 -1
- package/dist/lib/playground.js +378 -92
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright-report.js.map +1 -1
- package/dist/lib/playwright.js +378 -92
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +378 -92
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +378 -92
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/lib/ui-utils.js.map +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent.d.ts +45 -4
- package/dist/types/bridge-mode-browser.d.ts +2 -2
- package/dist/types/bridge-mode.d.ts +2 -2
- package/dist/types/{browser-a1877d18.d.ts → browser-aec1055d.d.ts} +1 -1
- package/dist/types/chrome-extension.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/midscene-server.d.ts +1 -1
- package/dist/types/{page-663ece08.d.ts → page-86ab0fe1.d.ts} +34 -34
- package/dist/types/playground.d.ts +2 -2
- package/dist/types/playwright.d.ts +1 -1
- package/dist/types/puppeteer-agent-launcher.d.ts +1 -1
- package/dist/types/puppeteer.d.ts +1 -1
- package/dist/types/utils.d.ts +1 -1
- package/dist/types/yaml.d.ts +1 -1
- package/package.json +3 -3
@@ -1707,7 +1707,7 @@ import yaml3 from "js-yaml";
|
|
1707
1707
|
import semver from "semver";
|
1708
1708
|
|
1709
1709
|
// package.json
|
1710
|
-
var version = "1.0.
|
1710
|
+
var version = "1.0.5";
|
1711
1711
|
|
1712
1712
|
// src/common/task-cache.ts
|
1713
1713
|
var debug3 = getDebug3("cache");
|
@@ -1735,44 +1735,70 @@ var TaskCache = class {
|
|
1735
1735
|
this.cache = cacheContent;
|
1736
1736
|
this.cacheOriginalLength = this.cache.caches.length;
|
1737
1737
|
}
|
1738
|
-
matchCache(prompt, type) {
|
1738
|
+
matchCache(prompt, type, contextData) {
|
1739
|
+
const contextHash = contextData ? this.generateContextHash(contextData) : void 0;
|
1739
1740
|
for (let i = 0; i < this.cacheOriginalLength; i++) {
|
1740
1741
|
const item = this.cache.caches[i];
|
1741
1742
|
const key = `${type}:${prompt}:${i}`;
|
1742
|
-
if (item.type
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
cacheContent: item,
|
1752
|
-
updateFn: (cb) => {
|
1753
|
-
debug3(
|
1754
|
-
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1755
|
-
type,
|
1756
|
-
prompt,
|
1757
|
-
i
|
1758
|
-
);
|
1759
|
-
cb(item);
|
1760
|
-
debug3(
|
1761
|
-
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1762
|
-
type,
|
1763
|
-
prompt,
|
1764
|
-
i
|
1765
|
-
);
|
1766
|
-
this.flushCacheToFile();
|
1743
|
+
if (item.type !== type || item.prompt !== prompt || this.matchedCacheIndices.has(key)) {
|
1744
|
+
continue;
|
1745
|
+
}
|
1746
|
+
if (type === "plan" && item.type === "plan") {
|
1747
|
+
const planItem = item;
|
1748
|
+
if (contextHash && planItem.contextHash) {
|
1749
|
+
if (contextHash !== planItem.contextHash) {
|
1750
|
+
debug3("cache context mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
|
1751
|
+
continue;
|
1767
1752
|
}
|
1768
|
-
}
|
1753
|
+
} else if (contextHash || planItem.contextHash) {
|
1754
|
+
debug3("cache context availability mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
|
1755
|
+
continue;
|
1756
|
+
}
|
1769
1757
|
}
|
1758
|
+
this.matchedCacheIndices.add(key);
|
1759
|
+
debug3(
|
1760
|
+
"cache found and marked as used, type: %s, prompt: %s, index: %d, contextMatch: %s",
|
1761
|
+
type,
|
1762
|
+
prompt,
|
1763
|
+
i,
|
1764
|
+
contextHash ? "yes" : "no-context"
|
1765
|
+
);
|
1766
|
+
return {
|
1767
|
+
cacheContent: item,
|
1768
|
+
updateFn: (cb) => {
|
1769
|
+
debug3(
|
1770
|
+
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1771
|
+
type,
|
1772
|
+
prompt,
|
1773
|
+
i
|
1774
|
+
);
|
1775
|
+
cb(item);
|
1776
|
+
debug3(
|
1777
|
+
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1778
|
+
type,
|
1779
|
+
prompt,
|
1780
|
+
i
|
1781
|
+
);
|
1782
|
+
this.flushCacheToFile();
|
1783
|
+
}
|
1784
|
+
};
|
1770
1785
|
}
|
1771
|
-
debug3("no unused cache found, type: %s, prompt: %s", type, prompt);
|
1786
|
+
debug3("no unused cache found, type: %s, prompt: %s, contextHash: %s", type, prompt, contextHash);
|
1772
1787
|
return void 0;
|
1773
1788
|
}
|
1774
|
-
|
1775
|
-
|
1789
|
+
generateContextHash(contextData) {
|
1790
|
+
const sortedKeys = Object.keys(contextData).sort();
|
1791
|
+
const stableString = sortedKeys.map((key) => `${key}:${JSON.stringify(contextData[key])}`).join("|");
|
1792
|
+
let hash = 0;
|
1793
|
+
for (let i = 0; i < stableString.length; i++) {
|
1794
|
+
const char = stableString.charCodeAt(i);
|
1795
|
+
hash = (hash << 5) - hash + char;
|
1796
|
+
hash = hash & hash;
|
1797
|
+
}
|
1798
|
+
return hash.toString(36);
|
1799
|
+
}
|
1800
|
+
matchPlanCache(prompt, contextData) {
|
1801
|
+
return this.matchCache(prompt, "plan", contextData);
|
1776
1802
|
}
|
1777
1803
|
matchLocateCache(prompt) {
|
1778
1804
|
return this.matchCache(prompt, "locate");
|
@@ -1848,11 +1874,16 @@ cache file: ${cacheFile}`
|
|
1848
1874
|
);
|
1849
1875
|
}
|
1850
1876
|
}
|
1851
|
-
updateOrAppendCacheRecord(newRecord, cachedRecord) {
|
1877
|
+
updateOrAppendCacheRecord(newRecord, cachedRecord, contextData) {
|
1852
1878
|
if (cachedRecord) {
|
1853
1879
|
if (newRecord.type === "plan") {
|
1854
1880
|
cachedRecord.updateFn((cache) => {
|
1855
|
-
|
1881
|
+
const planCache = cache;
|
1882
|
+
planCache.yamlWorkflow = newRecord.yamlWorkflow;
|
1883
|
+
if (contextData) {
|
1884
|
+
planCache.contextHash = this.generateContextHash(contextData);
|
1885
|
+
planCache.contextData = { ...contextData };
|
1886
|
+
}
|
1856
1887
|
});
|
1857
1888
|
} else {
|
1858
1889
|
cachedRecord.updateFn((cache) => {
|
@@ -1860,6 +1891,11 @@ cache file: ${cacheFile}`
|
|
1860
1891
|
});
|
1861
1892
|
}
|
1862
1893
|
} else {
|
1894
|
+
if (newRecord.type === "plan" && contextData) {
|
1895
|
+
const planRecord = newRecord;
|
1896
|
+
planRecord.contextHash = this.generateContextHash(contextData);
|
1897
|
+
planRecord.contextData = { ...contextData };
|
1898
|
+
}
|
1863
1899
|
this.appendCache(newRecord);
|
1864
1900
|
}
|
1865
1901
|
}
|
@@ -1889,10 +1925,13 @@ var PageAgent = class {
|
|
1889
1925
|
generateReport: true,
|
1890
1926
|
autoPrintReportMsg: true,
|
1891
1927
|
groupName: "Midscene Report",
|
1892
|
-
groupDescription: ""
|
1928
|
+
groupDescription: "",
|
1929
|
+
enableCumulativeContext: true,
|
1930
|
+
autoClearContext: false
|
1893
1931
|
},
|
1894
1932
|
opts || {}
|
1895
1933
|
);
|
1934
|
+
this.initializeContextStore();
|
1896
1935
|
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1897
1936
|
this.page.waitForNavigationTimeout = this.opts.waitForNavigationTimeout || DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
1898
1937
|
this.page.waitForNetworkIdleTimeout = this.opts.waitForNetworkIdleTimeout || DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
|
@@ -1919,6 +1958,69 @@ var PageAgent = class {
|
|
1919
1958
|
opts?.testId || this.page.pageType || "web"
|
1920
1959
|
);
|
1921
1960
|
}
|
1961
|
+
/**
|
1962
|
+
* Initialize context store for cumulative context functionality
|
1963
|
+
*/
|
1964
|
+
async initializeContextStore() {
|
1965
|
+
if (!this.opts.enableCumulativeContext) {
|
1966
|
+
debug4("Cumulative context disabled via options");
|
1967
|
+
return;
|
1968
|
+
}
|
1969
|
+
try {
|
1970
|
+
const aiModel = await import("misoai-core/ai-model");
|
1971
|
+
this.contextStore = aiModel.getContextStore();
|
1972
|
+
debug4("Context store initialized successfully", {
|
1973
|
+
autoClearContext: this.opts.autoClearContext,
|
1974
|
+
testId: this.opts.testId
|
1975
|
+
});
|
1976
|
+
if (this.opts.autoClearContext) {
|
1977
|
+
this.contextStore.clear();
|
1978
|
+
debug4("Context store cleared due to autoClearContext option");
|
1979
|
+
} else {
|
1980
|
+
const existingData = this.contextStore.getAllData();
|
1981
|
+
const existingSteps = this.contextStore.getRecentSteps(100).length;
|
1982
|
+
debug4("Context store preserving existing data", {
|
1983
|
+
existingDataKeys: Object.keys(existingData),
|
1984
|
+
existingStepsCount: existingSteps
|
1985
|
+
});
|
1986
|
+
}
|
1987
|
+
} catch (error) {
|
1988
|
+
debug4("Failed to initialize context store:", error);
|
1989
|
+
console.warn("⚠️ Could not initialize context store:", error);
|
1990
|
+
}
|
1991
|
+
}
|
1992
|
+
/**
|
1993
|
+
* Get the context store instance
|
1994
|
+
*/
|
1995
|
+
getContextStore() {
|
1996
|
+
return this.contextStore;
|
1997
|
+
}
|
1998
|
+
/**
|
1999
|
+
* Clear the context store
|
2000
|
+
*/
|
2001
|
+
clearContext() {
|
2002
|
+
if (this.contextStore) {
|
2003
|
+
this.contextStore.clear();
|
2004
|
+
}
|
2005
|
+
}
|
2006
|
+
/**
|
2007
|
+
* Get all stored data from context store
|
2008
|
+
*/
|
2009
|
+
getStoredData() {
|
2010
|
+
if (this.contextStore) {
|
2011
|
+
return this.contextStore.getAllData();
|
2012
|
+
}
|
2013
|
+
return {};
|
2014
|
+
}
|
2015
|
+
/**
|
2016
|
+
* Get step summary from context store
|
2017
|
+
*/
|
2018
|
+
getStepSummary() {
|
2019
|
+
if (this.contextStore) {
|
2020
|
+
return this.contextStore.getStepSummary();
|
2021
|
+
}
|
2022
|
+
return "";
|
2023
|
+
}
|
1922
2024
|
async getUIContext(action) {
|
1923
2025
|
if (action && (action === "extract" || action === "assert" || action === "captcha")) {
|
1924
2026
|
return await parseContextFromWebPage(this.page, {
|
@@ -2154,22 +2256,35 @@ var PageAgent = class {
|
|
2154
2256
|
};
|
2155
2257
|
}
|
2156
2258
|
async aiAction(taskPrompt, opt) {
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2259
|
+
const originalPrompt = taskPrompt;
|
2260
|
+
let processedPrompt = taskPrompt;
|
2261
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2262
|
+
try {
|
2263
|
+
const storedData = this.contextStore.getAllData();
|
2264
|
+
if (Object.keys(storedData).length > 0) {
|
2265
|
+
debug4("Available data for aiAction:", {
|
2266
|
+
prompt: taskPrompt,
|
2267
|
+
availableData: storedData
|
2268
|
+
});
|
2269
|
+
}
|
2270
|
+
} catch (error) {
|
2271
|
+
debug4("Context store operation failed:", error);
|
2272
|
+
}
|
2169
2273
|
}
|
2170
2274
|
const cacheable = opt?.cacheable;
|
2171
2275
|
const isVlmUiTars = vlLocateMode() === "vlm-ui-tars";
|
2172
|
-
|
2276
|
+
let contextData;
|
2277
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2278
|
+
try {
|
2279
|
+
contextData = this.contextStore.getAllData();
|
2280
|
+
if (contextData && Object.keys(contextData).length === 0) {
|
2281
|
+
contextData = void 0;
|
2282
|
+
}
|
2283
|
+
} catch (error) {
|
2284
|
+
debug4("Failed to get context data for cache:", error);
|
2285
|
+
}
|
2286
|
+
}
|
2287
|
+
const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt, contextData);
|
2173
2288
|
if (matchedCache && this.taskCache?.isCacheResultUsed) {
|
2174
2289
|
const { executor: executor2 } = await this.taskExecutor.loadYamlFlowAsPlanning(
|
2175
2290
|
taskPrompt,
|
@@ -2179,6 +2294,28 @@ var PageAgent = class {
|
|
2179
2294
|
debug4("matched cache, will call .runYaml to run the action");
|
2180
2295
|
const yaml5 = matchedCache.cacheContent?.yamlWorkflow;
|
2181
2296
|
const result = await this.runYaml(yaml5);
|
2297
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2298
|
+
try {
|
2299
|
+
const executionResult = {
|
2300
|
+
success: true,
|
2301
|
+
actionType: "cached",
|
2302
|
+
description: `Executed cached action: ${processedPrompt}`,
|
2303
|
+
timing: result.metadata?.totalTime
|
2304
|
+
};
|
2305
|
+
this.contextStore.addStep({
|
2306
|
+
type: "action",
|
2307
|
+
summary: `Action: ${processedPrompt} (cached)`,
|
2308
|
+
prompt: processedPrompt,
|
2309
|
+
executionResult
|
2310
|
+
});
|
2311
|
+
debug4("Added cached action step to context store:", {
|
2312
|
+
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2313
|
+
totalSteps: this.contextStore.getRecentSteps(100).length
|
2314
|
+
});
|
2315
|
+
} catch (error) {
|
2316
|
+
debug4("Failed to add cached action step:", error);
|
2317
|
+
}
|
2318
|
+
}
|
2182
2319
|
return {
|
2183
2320
|
result: result.result,
|
2184
2321
|
metadata: metadata2
|
@@ -2203,10 +2340,39 @@ var PageAgent = class {
|
|
2203
2340
|
prompt: taskPrompt,
|
2204
2341
|
yamlWorkflow: yamlFlowStr
|
2205
2342
|
},
|
2206
|
-
matchedCache
|
2343
|
+
matchedCache,
|
2344
|
+
contextData
|
2345
|
+
// Pass context data for cache creation
|
2207
2346
|
);
|
2208
2347
|
}
|
2209
2348
|
const metadata = this.afterTaskRunning(executor);
|
2349
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2350
|
+
try {
|
2351
|
+
const executionResult = this.analyzeExecutionResults(executor, originalPrompt);
|
2352
|
+
this.contextStore.addStep({
|
2353
|
+
type: "action",
|
2354
|
+
summary: `Action: ${processedPrompt}`,
|
2355
|
+
prompt: processedPrompt,
|
2356
|
+
executionResult
|
2357
|
+
});
|
2358
|
+
debug4("Added action step with execution result to context store:", {
|
2359
|
+
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2360
|
+
totalSteps: this.contextStore.getRecentSteps(100).length,
|
2361
|
+
executionResult
|
2362
|
+
});
|
2363
|
+
} catch (error) {
|
2364
|
+
debug4("Failed to analyze execution results, adding step without execution result:", error);
|
2365
|
+
try {
|
2366
|
+
this.contextStore.addStep({
|
2367
|
+
type: "action",
|
2368
|
+
summary: `Action: ${processedPrompt}`,
|
2369
|
+
prompt: processedPrompt
|
2370
|
+
});
|
2371
|
+
} catch (stepError) {
|
2372
|
+
debug4("Failed to add action step:", stepError);
|
2373
|
+
}
|
2374
|
+
}
|
2375
|
+
}
|
2210
2376
|
return {
|
2211
2377
|
result: output,
|
2212
2378
|
metadata
|
@@ -2236,38 +2402,50 @@ var PageAgent = class {
|
|
2236
2402
|
debug4("Context store not available:", error);
|
2237
2403
|
}
|
2238
2404
|
const { output, executor } = await this.taskExecutor.query(processedDemand);
|
2239
|
-
if (
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2405
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2406
|
+
if (storageKey && output) {
|
2407
|
+
try {
|
2408
|
+
const pendingAliases = this.contextStore._pendingAliases;
|
2409
|
+
if (pendingAliases) {
|
2410
|
+
this.contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
|
2411
|
+
delete this.contextStore._pendingAliases;
|
2412
|
+
debug4("Stored query result with aliases:", {
|
2413
|
+
key: storageKey,
|
2414
|
+
value: output,
|
2415
|
+
aliases: pendingAliases
|
2416
|
+
});
|
2417
|
+
} else {
|
2418
|
+
this.contextStore.storeData(storageKey, output);
|
2419
|
+
debug4("Stored query result:", {
|
2420
|
+
key: storageKey,
|
2421
|
+
value: output
|
2422
|
+
});
|
2423
|
+
}
|
2424
|
+
this.contextStore.addStep({
|
2425
|
+
type: "query",
|
2426
|
+
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
|
2427
|
+
data: output,
|
2428
|
+
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2429
|
+
});
|
2430
|
+
debug4("Added query step to context store:", {
|
2431
|
+
storageKey,
|
2432
|
+
totalStoredItems: Object.keys(this.contextStore.getAllData()).length,
|
2433
|
+
totalSteps: this.contextStore.getRecentSteps(100).length
|
2434
|
+
});
|
2435
|
+
} catch (error) {
|
2436
|
+
debug4("Failed to store query result:", error);
|
2437
|
+
}
|
2438
|
+
} else {
|
2439
|
+
try {
|
2440
|
+
this.contextStore.addStep({
|
2441
|
+
type: "query",
|
2442
|
+
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
|
2443
|
+
data: output,
|
2444
|
+
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2445
|
+
});
|
2446
|
+
} catch (error) {
|
2447
|
+
debug4("Failed to add query step:", error);
|
2249
2448
|
}
|
2250
|
-
contextStore.addStep({
|
2251
|
-
type: "query",
|
2252
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
|
2253
|
-
data: output,
|
2254
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2255
|
-
});
|
2256
|
-
} catch (error) {
|
2257
|
-
debug4("Failed to store query result:", error);
|
2258
|
-
}
|
2259
|
-
} else {
|
2260
|
-
try {
|
2261
|
-
const aiModel = await import("misoai-core/ai-model");
|
2262
|
-
const contextStore = aiModel.getContextStore();
|
2263
|
-
contextStore.addStep({
|
2264
|
-
type: "query",
|
2265
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
|
2266
|
-
data: output,
|
2267
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2268
|
-
});
|
2269
|
-
} catch (error) {
|
2270
|
-
debug4("Failed to add query step:", error);
|
2271
2449
|
}
|
2272
2450
|
}
|
2273
2451
|
const metadata = this.afterTaskRunning(executor);
|
@@ -2379,18 +2557,47 @@ var PageAgent = class {
|
|
2379
2557
|
};
|
2380
2558
|
}
|
2381
2559
|
async aiAssert(assertion, msg, opt) {
|
2382
|
-
let
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2387
|
-
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2560
|
+
let executionContext = "";
|
2561
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2562
|
+
try {
|
2563
|
+
const recentSteps = this.contextStore.getRecentSteps(3);
|
2564
|
+
const stepsWithExecutionResults = recentSteps.filter((step) => step.executionResult);
|
2565
|
+
const storedData = this.contextStore.getAllData();
|
2566
|
+
if (stepsWithExecutionResults.length > 0) {
|
2567
|
+
const recentActions = stepsWithExecutionResults.map((step) => {
|
2568
|
+
const result = step.executionResult;
|
2569
|
+
return `- ${result.description}${result.success ? "" : " (FAILED)"}`;
|
2570
|
+
}).join("\n");
|
2571
|
+
executionContext = `
|
2572
|
+
|
2573
|
+
Recent actions performed:
|
2574
|
+
${recentActions}
|
2575
|
+
|
2576
|
+
This context may help verify the assertion.`;
|
2577
|
+
}
|
2578
|
+
if (storedData && Object.keys(storedData).length > 0) {
|
2579
|
+
executionContext += `
|
2580
|
+
|
2581
|
+
Available data for reference:
|
2582
|
+
${JSON.stringify(storedData, null, 2)}
|
2583
|
+
|
2584
|
+
Note: If the assertion references any data keys or natural language equivalents, consider the stored values when verifying.`;
|
2585
|
+
debug4("Available data for aiAssert:", {
|
2586
|
+
assertion,
|
2587
|
+
availableData: storedData
|
2588
|
+
});
|
2589
|
+
}
|
2590
|
+
this.contextStore.addStep({
|
2591
|
+
type: "assertion",
|
2592
|
+
summary: `Assertion: ${assertion}`,
|
2593
|
+
prompt: assertion
|
2594
|
+
});
|
2595
|
+
debug4("Added assertion step to context store:", {
|
2596
|
+
totalSteps: this.contextStore.getRecentSteps(100).length
|
2597
|
+
});
|
2598
|
+
} catch (error) {
|
2599
|
+
debug4("Context store operation failed:", error);
|
2600
|
+
}
|
2394
2601
|
}
|
2395
2602
|
let currentUrl = "";
|
2396
2603
|
if (this.page.url) {
|
@@ -2399,7 +2606,13 @@ var PageAgent = class {
|
|
2399
2606
|
} catch (e) {
|
2400
2607
|
}
|
2401
2608
|
}
|
2402
|
-
|
2609
|
+
let assertionWithContext = assertion;
|
2610
|
+
if (currentUrl) {
|
2611
|
+
assertionWithContext = `For the page at URL "${currentUrl}", ${assertion}`;
|
2612
|
+
}
|
2613
|
+
if (executionContext) {
|
2614
|
+
assertionWithContext += executionContext;
|
2615
|
+
}
|
2403
2616
|
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2404
2617
|
const metadata = this.afterTaskRunning(executor, true);
|
2405
2618
|
if (output && opt?.keepRawResponse) {
|
@@ -2613,6 +2826,79 @@ ${errors}`);
|
|
2613
2826
|
async destroy() {
|
2614
2827
|
await this.page.destroy();
|
2615
2828
|
}
|
2829
|
+
/**
|
2830
|
+
* Analyze execution results from executor to generate meaningful descriptions
|
2831
|
+
*/
|
2832
|
+
analyzeExecutionResults(executor, originalPrompt) {
|
2833
|
+
const tasks = executor.tasks;
|
2834
|
+
const success = !executor.isInErrorState();
|
2835
|
+
if (!success) {
|
2836
|
+
const errorTask = executor.latestErrorTask();
|
2837
|
+
return {
|
2838
|
+
success: false,
|
2839
|
+
actionType: "error",
|
2840
|
+
description: `Failed to execute: ${originalPrompt}`,
|
2841
|
+
error: errorTask?.error
|
2842
|
+
};
|
2843
|
+
}
|
2844
|
+
const actionTasks = tasks.filter((t) => t.type === "Action" && t.status === "finished");
|
2845
|
+
const locateTasks = tasks.filter((t) => t.type === "Insight" && t.subType === "Locate");
|
2846
|
+
const lastAction = actionTasks[actionTasks.length - 1];
|
2847
|
+
const lastLocate = locateTasks[locateTasks.length - 1];
|
2848
|
+
if (!lastAction) {
|
2849
|
+
return {
|
2850
|
+
success: true,
|
2851
|
+
actionType: "unknown",
|
2852
|
+
description: `Completed: ${originalPrompt}`
|
2853
|
+
};
|
2854
|
+
}
|
2855
|
+
const actionType = lastAction.subType || "unknown";
|
2856
|
+
const elementInfo = this.extractElementInfo(lastLocate, lastAction);
|
2857
|
+
const description = this.generateActionDescription(actionType, lastAction.param, elementInfo);
|
2858
|
+
return {
|
2859
|
+
success: true,
|
2860
|
+
actionType,
|
2861
|
+
description,
|
2862
|
+
elementInfo,
|
2863
|
+
timing: lastAction.timing?.cost
|
2864
|
+
};
|
2865
|
+
}
|
2866
|
+
/**
|
2867
|
+
* Extract element information from locate task
|
2868
|
+
*/
|
2869
|
+
extractElementInfo(locateTask, _actionTask) {
|
2870
|
+
if (!locateTask?.output?.element)
|
2871
|
+
return void 0;
|
2872
|
+
const element = locateTask.output.element;
|
2873
|
+
return {
|
2874
|
+
type: element.attributes?.nodeType || "unknown",
|
2875
|
+
text: element.content || element.attributes?.placeholder || element.attributes?.title || "",
|
2876
|
+
location: `(${element.center[0]}, ${element.center[1]})`
|
2877
|
+
};
|
2878
|
+
}
|
2879
|
+
/**
|
2880
|
+
* Generate natural language description for actions
|
2881
|
+
*/
|
2882
|
+
generateActionDescription(actionType, param, elementInfo) {
|
2883
|
+
const elementDesc = elementInfo ? `'${elementInfo.text || elementInfo.type}' element` : "element";
|
2884
|
+
switch (actionType) {
|
2885
|
+
case "Tap":
|
2886
|
+
return `Clicked on ${elementDesc}`;
|
2887
|
+
case "Input":
|
2888
|
+
const inputValue = param?.value || "";
|
2889
|
+
return `Entered "${inputValue}" into ${elementDesc}`;
|
2890
|
+
case "KeyboardPress":
|
2891
|
+
return `Pressed ${param?.value || "key"}`;
|
2892
|
+
case "Scroll":
|
2893
|
+
return `Scrolled ${param?.direction || "on page"}`;
|
2894
|
+
case "Hover":
|
2895
|
+
return `Hovered over ${elementDesc}`;
|
2896
|
+
case "Drag":
|
2897
|
+
return `Dragged ${elementDesc}`;
|
2898
|
+
default:
|
2899
|
+
return `Performed ${actionType} action on ${elementDesc}`;
|
2900
|
+
}
|
2901
|
+
}
|
2616
2902
|
};
|
2617
2903
|
|
2618
2904
|
// src/chrome-extension/agent.ts
|
@@ -2832,7 +3118,7 @@ function sleep2(ms) {
|
|
2832
3118
|
var ChromeExtensionProxyPage = class {
|
2833
3119
|
constructor(forceSameTabNavigation) {
|
2834
3120
|
this.pageType = "chrome-extension-proxy";
|
2835
|
-
this.version = "1.0.
|
3121
|
+
this.version = "1.0.5";
|
2836
3122
|
this.activeTabId = null;
|
2837
3123
|
this.tabIdOfDebuggerAttached = null;
|
2838
3124
|
this.attachingDebugger = null;
|