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
@@ -1725,7 +1725,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
|
|
1725
1725
|
var import_semver = __toESM(require("semver"));
|
1726
1726
|
|
1727
1727
|
// package.json
|
1728
|
-
var version = "1.0.
|
1728
|
+
var version = "1.0.5";
|
1729
1729
|
|
1730
1730
|
// src/common/task-cache.ts
|
1731
1731
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -1753,44 +1753,70 @@ var TaskCache = class {
|
|
1753
1753
|
this.cache = cacheContent;
|
1754
1754
|
this.cacheOriginalLength = this.cache.caches.length;
|
1755
1755
|
}
|
1756
|
-
matchCache(prompt, type) {
|
1756
|
+
matchCache(prompt, type, contextData) {
|
1757
|
+
const contextHash = contextData ? this.generateContextHash(contextData) : void 0;
|
1757
1758
|
for (let i = 0; i < this.cacheOriginalLength; i++) {
|
1758
1759
|
const item = this.cache.caches[i];
|
1759
1760
|
const key = `${type}:${prompt}:${i}`;
|
1760
|
-
if (item.type
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
cacheContent: item,
|
1770
|
-
updateFn: (cb) => {
|
1771
|
-
debug3(
|
1772
|
-
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1773
|
-
type,
|
1774
|
-
prompt,
|
1775
|
-
i
|
1776
|
-
);
|
1777
|
-
cb(item);
|
1778
|
-
debug3(
|
1779
|
-
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1780
|
-
type,
|
1781
|
-
prompt,
|
1782
|
-
i
|
1783
|
-
);
|
1784
|
-
this.flushCacheToFile();
|
1761
|
+
if (item.type !== type || item.prompt !== prompt || this.matchedCacheIndices.has(key)) {
|
1762
|
+
continue;
|
1763
|
+
}
|
1764
|
+
if (type === "plan" && item.type === "plan") {
|
1765
|
+
const planItem = item;
|
1766
|
+
if (contextHash && planItem.contextHash) {
|
1767
|
+
if (contextHash !== planItem.contextHash) {
|
1768
|
+
debug3("cache context mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
|
1769
|
+
continue;
|
1785
1770
|
}
|
1786
|
-
}
|
1771
|
+
} else if (contextHash || planItem.contextHash) {
|
1772
|
+
debug3("cache context availability mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
|
1773
|
+
continue;
|
1774
|
+
}
|
1787
1775
|
}
|
1776
|
+
this.matchedCacheIndices.add(key);
|
1777
|
+
debug3(
|
1778
|
+
"cache found and marked as used, type: %s, prompt: %s, index: %d, contextMatch: %s",
|
1779
|
+
type,
|
1780
|
+
prompt,
|
1781
|
+
i,
|
1782
|
+
contextHash ? "yes" : "no-context"
|
1783
|
+
);
|
1784
|
+
return {
|
1785
|
+
cacheContent: item,
|
1786
|
+
updateFn: (cb) => {
|
1787
|
+
debug3(
|
1788
|
+
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1789
|
+
type,
|
1790
|
+
prompt,
|
1791
|
+
i
|
1792
|
+
);
|
1793
|
+
cb(item);
|
1794
|
+
debug3(
|
1795
|
+
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1796
|
+
type,
|
1797
|
+
prompt,
|
1798
|
+
i
|
1799
|
+
);
|
1800
|
+
this.flushCacheToFile();
|
1801
|
+
}
|
1802
|
+
};
|
1788
1803
|
}
|
1789
|
-
debug3("no unused cache found, type: %s, prompt: %s", type, prompt);
|
1804
|
+
debug3("no unused cache found, type: %s, prompt: %s, contextHash: %s", type, prompt, contextHash);
|
1790
1805
|
return void 0;
|
1791
1806
|
}
|
1792
|
-
|
1793
|
-
|
1807
|
+
generateContextHash(contextData) {
|
1808
|
+
const sortedKeys = Object.keys(contextData).sort();
|
1809
|
+
const stableString = sortedKeys.map((key) => `${key}:${JSON.stringify(contextData[key])}`).join("|");
|
1810
|
+
let hash = 0;
|
1811
|
+
for (let i = 0; i < stableString.length; i++) {
|
1812
|
+
const char = stableString.charCodeAt(i);
|
1813
|
+
hash = (hash << 5) - hash + char;
|
1814
|
+
hash = hash & hash;
|
1815
|
+
}
|
1816
|
+
return hash.toString(36);
|
1817
|
+
}
|
1818
|
+
matchPlanCache(prompt, contextData) {
|
1819
|
+
return this.matchCache(prompt, "plan", contextData);
|
1794
1820
|
}
|
1795
1821
|
matchLocateCache(prompt) {
|
1796
1822
|
return this.matchCache(prompt, "locate");
|
@@ -1866,11 +1892,16 @@ cache file: ${cacheFile}`
|
|
1866
1892
|
);
|
1867
1893
|
}
|
1868
1894
|
}
|
1869
|
-
updateOrAppendCacheRecord(newRecord, cachedRecord) {
|
1895
|
+
updateOrAppendCacheRecord(newRecord, cachedRecord, contextData) {
|
1870
1896
|
if (cachedRecord) {
|
1871
1897
|
if (newRecord.type === "plan") {
|
1872
1898
|
cachedRecord.updateFn((cache) => {
|
1873
|
-
|
1899
|
+
const planCache = cache;
|
1900
|
+
planCache.yamlWorkflow = newRecord.yamlWorkflow;
|
1901
|
+
if (contextData) {
|
1902
|
+
planCache.contextHash = this.generateContextHash(contextData);
|
1903
|
+
planCache.contextData = { ...contextData };
|
1904
|
+
}
|
1874
1905
|
});
|
1875
1906
|
} else {
|
1876
1907
|
cachedRecord.updateFn((cache) => {
|
@@ -1878,6 +1909,11 @@ cache file: ${cacheFile}`
|
|
1878
1909
|
});
|
1879
1910
|
}
|
1880
1911
|
} else {
|
1912
|
+
if (newRecord.type === "plan" && contextData) {
|
1913
|
+
const planRecord = newRecord;
|
1914
|
+
planRecord.contextHash = this.generateContextHash(contextData);
|
1915
|
+
planRecord.contextData = { ...contextData };
|
1916
|
+
}
|
1881
1917
|
this.appendCache(newRecord);
|
1882
1918
|
}
|
1883
1919
|
}
|
@@ -1907,10 +1943,13 @@ var PageAgent = class {
|
|
1907
1943
|
generateReport: true,
|
1908
1944
|
autoPrintReportMsg: true,
|
1909
1945
|
groupName: "Midscene Report",
|
1910
|
-
groupDescription: ""
|
1946
|
+
groupDescription: "",
|
1947
|
+
enableCumulativeContext: true,
|
1948
|
+
autoClearContext: false
|
1911
1949
|
},
|
1912
1950
|
opts || {}
|
1913
1951
|
);
|
1952
|
+
this.initializeContextStore();
|
1914
1953
|
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1915
1954
|
this.page.waitForNavigationTimeout = this.opts.waitForNavigationTimeout || import_constants2.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
1916
1955
|
this.page.waitForNetworkIdleTimeout = this.opts.waitForNetworkIdleTimeout || import_constants2.DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
|
@@ -1937,6 +1976,69 @@ var PageAgent = class {
|
|
1937
1976
|
opts?.testId || this.page.pageType || "web"
|
1938
1977
|
);
|
1939
1978
|
}
|
1979
|
+
/**
|
1980
|
+
* Initialize context store for cumulative context functionality
|
1981
|
+
*/
|
1982
|
+
async initializeContextStore() {
|
1983
|
+
if (!this.opts.enableCumulativeContext) {
|
1984
|
+
debug4("Cumulative context disabled via options");
|
1985
|
+
return;
|
1986
|
+
}
|
1987
|
+
try {
|
1988
|
+
const aiModel = await import("misoai-core/ai-model");
|
1989
|
+
this.contextStore = aiModel.getContextStore();
|
1990
|
+
debug4("Context store initialized successfully", {
|
1991
|
+
autoClearContext: this.opts.autoClearContext,
|
1992
|
+
testId: this.opts.testId
|
1993
|
+
});
|
1994
|
+
if (this.opts.autoClearContext) {
|
1995
|
+
this.contextStore.clear();
|
1996
|
+
debug4("Context store cleared due to autoClearContext option");
|
1997
|
+
} else {
|
1998
|
+
const existingData = this.contextStore.getAllData();
|
1999
|
+
const existingSteps = this.contextStore.getRecentSteps(100).length;
|
2000
|
+
debug4("Context store preserving existing data", {
|
2001
|
+
existingDataKeys: Object.keys(existingData),
|
2002
|
+
existingStepsCount: existingSteps
|
2003
|
+
});
|
2004
|
+
}
|
2005
|
+
} catch (error) {
|
2006
|
+
debug4("Failed to initialize context store:", error);
|
2007
|
+
console.warn("⚠️ Could not initialize context store:", error);
|
2008
|
+
}
|
2009
|
+
}
|
2010
|
+
/**
|
2011
|
+
* Get the context store instance
|
2012
|
+
*/
|
2013
|
+
getContextStore() {
|
2014
|
+
return this.contextStore;
|
2015
|
+
}
|
2016
|
+
/**
|
2017
|
+
* Clear the context store
|
2018
|
+
*/
|
2019
|
+
clearContext() {
|
2020
|
+
if (this.contextStore) {
|
2021
|
+
this.contextStore.clear();
|
2022
|
+
}
|
2023
|
+
}
|
2024
|
+
/**
|
2025
|
+
* Get all stored data from context store
|
2026
|
+
*/
|
2027
|
+
getStoredData() {
|
2028
|
+
if (this.contextStore) {
|
2029
|
+
return this.contextStore.getAllData();
|
2030
|
+
}
|
2031
|
+
return {};
|
2032
|
+
}
|
2033
|
+
/**
|
2034
|
+
* Get step summary from context store
|
2035
|
+
*/
|
2036
|
+
getStepSummary() {
|
2037
|
+
if (this.contextStore) {
|
2038
|
+
return this.contextStore.getStepSummary();
|
2039
|
+
}
|
2040
|
+
return "";
|
2041
|
+
}
|
1940
2042
|
async getUIContext(action) {
|
1941
2043
|
if (action && (action === "extract" || action === "assert" || action === "captcha")) {
|
1942
2044
|
return await parseContextFromWebPage(this.page, {
|
@@ -2172,22 +2274,35 @@ var PageAgent = class {
|
|
2172
2274
|
};
|
2173
2275
|
}
|
2174
2276
|
async aiAction(taskPrompt, opt) {
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2277
|
+
const originalPrompt = taskPrompt;
|
2278
|
+
let processedPrompt = taskPrompt;
|
2279
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2280
|
+
try {
|
2281
|
+
const storedData = this.contextStore.getAllData();
|
2282
|
+
if (Object.keys(storedData).length > 0) {
|
2283
|
+
debug4("Available data for aiAction:", {
|
2284
|
+
prompt: taskPrompt,
|
2285
|
+
availableData: storedData
|
2286
|
+
});
|
2287
|
+
}
|
2288
|
+
} catch (error) {
|
2289
|
+
debug4("Context store operation failed:", error);
|
2290
|
+
}
|
2187
2291
|
}
|
2188
2292
|
const cacheable = opt?.cacheable;
|
2189
2293
|
const isVlmUiTars = (0, import_env2.vlLocateMode)() === "vlm-ui-tars";
|
2190
|
-
|
2294
|
+
let contextData;
|
2295
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2296
|
+
try {
|
2297
|
+
contextData = this.contextStore.getAllData();
|
2298
|
+
if (contextData && Object.keys(contextData).length === 0) {
|
2299
|
+
contextData = void 0;
|
2300
|
+
}
|
2301
|
+
} catch (error) {
|
2302
|
+
debug4("Failed to get context data for cache:", error);
|
2303
|
+
}
|
2304
|
+
}
|
2305
|
+
const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt, contextData);
|
2191
2306
|
if (matchedCache && this.taskCache?.isCacheResultUsed) {
|
2192
2307
|
const { executor: executor2 } = await this.taskExecutor.loadYamlFlowAsPlanning(
|
2193
2308
|
taskPrompt,
|
@@ -2197,6 +2312,28 @@ var PageAgent = class {
|
|
2197
2312
|
debug4("matched cache, will call .runYaml to run the action");
|
2198
2313
|
const yaml5 = matchedCache.cacheContent?.yamlWorkflow;
|
2199
2314
|
const result = await this.runYaml(yaml5);
|
2315
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2316
|
+
try {
|
2317
|
+
const executionResult = {
|
2318
|
+
success: true,
|
2319
|
+
actionType: "cached",
|
2320
|
+
description: `Executed cached action: ${processedPrompt}`,
|
2321
|
+
timing: result.metadata?.totalTime
|
2322
|
+
};
|
2323
|
+
this.contextStore.addStep({
|
2324
|
+
type: "action",
|
2325
|
+
summary: `Action: ${processedPrompt} (cached)`,
|
2326
|
+
prompt: processedPrompt,
|
2327
|
+
executionResult
|
2328
|
+
});
|
2329
|
+
debug4("Added cached action step to context store:", {
|
2330
|
+
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2331
|
+
totalSteps: this.contextStore.getRecentSteps(100).length
|
2332
|
+
});
|
2333
|
+
} catch (error) {
|
2334
|
+
debug4("Failed to add cached action step:", error);
|
2335
|
+
}
|
2336
|
+
}
|
2200
2337
|
return {
|
2201
2338
|
result: result.result,
|
2202
2339
|
metadata: metadata2
|
@@ -2221,10 +2358,39 @@ var PageAgent = class {
|
|
2221
2358
|
prompt: taskPrompt,
|
2222
2359
|
yamlWorkflow: yamlFlowStr
|
2223
2360
|
},
|
2224
|
-
matchedCache
|
2361
|
+
matchedCache,
|
2362
|
+
contextData
|
2363
|
+
// Pass context data for cache creation
|
2225
2364
|
);
|
2226
2365
|
}
|
2227
2366
|
const metadata = this.afterTaskRunning(executor);
|
2367
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2368
|
+
try {
|
2369
|
+
const executionResult = this.analyzeExecutionResults(executor, originalPrompt);
|
2370
|
+
this.contextStore.addStep({
|
2371
|
+
type: "action",
|
2372
|
+
summary: `Action: ${processedPrompt}`,
|
2373
|
+
prompt: processedPrompt,
|
2374
|
+
executionResult
|
2375
|
+
});
|
2376
|
+
debug4("Added action step with execution result to context store:", {
|
2377
|
+
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2378
|
+
totalSteps: this.contextStore.getRecentSteps(100).length,
|
2379
|
+
executionResult
|
2380
|
+
});
|
2381
|
+
} catch (error) {
|
2382
|
+
debug4("Failed to analyze execution results, adding step without execution result:", error);
|
2383
|
+
try {
|
2384
|
+
this.contextStore.addStep({
|
2385
|
+
type: "action",
|
2386
|
+
summary: `Action: ${processedPrompt}`,
|
2387
|
+
prompt: processedPrompt
|
2388
|
+
});
|
2389
|
+
} catch (stepError) {
|
2390
|
+
debug4("Failed to add action step:", stepError);
|
2391
|
+
}
|
2392
|
+
}
|
2393
|
+
}
|
2228
2394
|
return {
|
2229
2395
|
result: output,
|
2230
2396
|
metadata
|
@@ -2254,38 +2420,50 @@ var PageAgent = class {
|
|
2254
2420
|
debug4("Context store not available:", error);
|
2255
2421
|
}
|
2256
2422
|
const { output, executor } = await this.taskExecutor.query(processedDemand);
|
2257
|
-
if (
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2423
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2424
|
+
if (storageKey && output) {
|
2425
|
+
try {
|
2426
|
+
const pendingAliases = this.contextStore._pendingAliases;
|
2427
|
+
if (pendingAliases) {
|
2428
|
+
this.contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
|
2429
|
+
delete this.contextStore._pendingAliases;
|
2430
|
+
debug4("Stored query result with aliases:", {
|
2431
|
+
key: storageKey,
|
2432
|
+
value: output,
|
2433
|
+
aliases: pendingAliases
|
2434
|
+
});
|
2435
|
+
} else {
|
2436
|
+
this.contextStore.storeData(storageKey, output);
|
2437
|
+
debug4("Stored query result:", {
|
2438
|
+
key: storageKey,
|
2439
|
+
value: output
|
2440
|
+
});
|
2441
|
+
}
|
2442
|
+
this.contextStore.addStep({
|
2443
|
+
type: "query",
|
2444
|
+
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
|
2445
|
+
data: output,
|
2446
|
+
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2447
|
+
});
|
2448
|
+
debug4("Added query step to context store:", {
|
2449
|
+
storageKey,
|
2450
|
+
totalStoredItems: Object.keys(this.contextStore.getAllData()).length,
|
2451
|
+
totalSteps: this.contextStore.getRecentSteps(100).length
|
2452
|
+
});
|
2453
|
+
} catch (error) {
|
2454
|
+
debug4("Failed to store query result:", error);
|
2455
|
+
}
|
2456
|
+
} else {
|
2457
|
+
try {
|
2458
|
+
this.contextStore.addStep({
|
2459
|
+
type: "query",
|
2460
|
+
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
|
2461
|
+
data: output,
|
2462
|
+
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2463
|
+
});
|
2464
|
+
} catch (error) {
|
2465
|
+
debug4("Failed to add query step:", error);
|
2267
2466
|
}
|
2268
|
-
contextStore.addStep({
|
2269
|
-
type: "query",
|
2270
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
|
2271
|
-
data: output,
|
2272
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2273
|
-
});
|
2274
|
-
} catch (error) {
|
2275
|
-
debug4("Failed to store query result:", error);
|
2276
|
-
}
|
2277
|
-
} else {
|
2278
|
-
try {
|
2279
|
-
const aiModel = await import("misoai-core/ai-model");
|
2280
|
-
const contextStore = aiModel.getContextStore();
|
2281
|
-
contextStore.addStep({
|
2282
|
-
type: "query",
|
2283
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
|
2284
|
-
data: output,
|
2285
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2286
|
-
});
|
2287
|
-
} catch (error) {
|
2288
|
-
debug4("Failed to add query step:", error);
|
2289
2467
|
}
|
2290
2468
|
}
|
2291
2469
|
const metadata = this.afterTaskRunning(executor);
|
@@ -2397,18 +2575,47 @@ var PageAgent = class {
|
|
2397
2575
|
};
|
2398
2576
|
}
|
2399
2577
|
async aiAssert(assertion, msg, opt) {
|
2400
|
-
let
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
2409
|
-
|
2410
|
-
|
2411
|
-
|
2578
|
+
let executionContext = "";
|
2579
|
+
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2580
|
+
try {
|
2581
|
+
const recentSteps = this.contextStore.getRecentSteps(3);
|
2582
|
+
const stepsWithExecutionResults = recentSteps.filter((step) => step.executionResult);
|
2583
|
+
const storedData = this.contextStore.getAllData();
|
2584
|
+
if (stepsWithExecutionResults.length > 0) {
|
2585
|
+
const recentActions = stepsWithExecutionResults.map((step) => {
|
2586
|
+
const result = step.executionResult;
|
2587
|
+
return `- ${result.description}${result.success ? "" : " (FAILED)"}`;
|
2588
|
+
}).join("\n");
|
2589
|
+
executionContext = `
|
2590
|
+
|
2591
|
+
Recent actions performed:
|
2592
|
+
${recentActions}
|
2593
|
+
|
2594
|
+
This context may help verify the assertion.`;
|
2595
|
+
}
|
2596
|
+
if (storedData && Object.keys(storedData).length > 0) {
|
2597
|
+
executionContext += `
|
2598
|
+
|
2599
|
+
Available data for reference:
|
2600
|
+
${JSON.stringify(storedData, null, 2)}
|
2601
|
+
|
2602
|
+
Note: If the assertion references any data keys or natural language equivalents, consider the stored values when verifying.`;
|
2603
|
+
debug4("Available data for aiAssert:", {
|
2604
|
+
assertion,
|
2605
|
+
availableData: storedData
|
2606
|
+
});
|
2607
|
+
}
|
2608
|
+
this.contextStore.addStep({
|
2609
|
+
type: "assertion",
|
2610
|
+
summary: `Assertion: ${assertion}`,
|
2611
|
+
prompt: assertion
|
2612
|
+
});
|
2613
|
+
debug4("Added assertion step to context store:", {
|
2614
|
+
totalSteps: this.contextStore.getRecentSteps(100).length
|
2615
|
+
});
|
2616
|
+
} catch (error) {
|
2617
|
+
debug4("Context store operation failed:", error);
|
2618
|
+
}
|
2412
2619
|
}
|
2413
2620
|
let currentUrl = "";
|
2414
2621
|
if (this.page.url) {
|
@@ -2417,7 +2624,13 @@ var PageAgent = class {
|
|
2417
2624
|
} catch (e) {
|
2418
2625
|
}
|
2419
2626
|
}
|
2420
|
-
|
2627
|
+
let assertionWithContext = assertion;
|
2628
|
+
if (currentUrl) {
|
2629
|
+
assertionWithContext = `For the page at URL "${currentUrl}", ${assertion}`;
|
2630
|
+
}
|
2631
|
+
if (executionContext) {
|
2632
|
+
assertionWithContext += executionContext;
|
2633
|
+
}
|
2421
2634
|
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2422
2635
|
const metadata = this.afterTaskRunning(executor, true);
|
2423
2636
|
if (output && opt?.keepRawResponse) {
|
@@ -2631,6 +2844,79 @@ ${errors}`);
|
|
2631
2844
|
async destroy() {
|
2632
2845
|
await this.page.destroy();
|
2633
2846
|
}
|
2847
|
+
/**
|
2848
|
+
* Analyze execution results from executor to generate meaningful descriptions
|
2849
|
+
*/
|
2850
|
+
analyzeExecutionResults(executor, originalPrompt) {
|
2851
|
+
const tasks = executor.tasks;
|
2852
|
+
const success = !executor.isInErrorState();
|
2853
|
+
if (!success) {
|
2854
|
+
const errorTask = executor.latestErrorTask();
|
2855
|
+
return {
|
2856
|
+
success: false,
|
2857
|
+
actionType: "error",
|
2858
|
+
description: `Failed to execute: ${originalPrompt}`,
|
2859
|
+
error: errorTask?.error
|
2860
|
+
};
|
2861
|
+
}
|
2862
|
+
const actionTasks = tasks.filter((t) => t.type === "Action" && t.status === "finished");
|
2863
|
+
const locateTasks = tasks.filter((t) => t.type === "Insight" && t.subType === "Locate");
|
2864
|
+
const lastAction = actionTasks[actionTasks.length - 1];
|
2865
|
+
const lastLocate = locateTasks[locateTasks.length - 1];
|
2866
|
+
if (!lastAction) {
|
2867
|
+
return {
|
2868
|
+
success: true,
|
2869
|
+
actionType: "unknown",
|
2870
|
+
description: `Completed: ${originalPrompt}`
|
2871
|
+
};
|
2872
|
+
}
|
2873
|
+
const actionType = lastAction.subType || "unknown";
|
2874
|
+
const elementInfo = this.extractElementInfo(lastLocate, lastAction);
|
2875
|
+
const description = this.generateActionDescription(actionType, lastAction.param, elementInfo);
|
2876
|
+
return {
|
2877
|
+
success: true,
|
2878
|
+
actionType,
|
2879
|
+
description,
|
2880
|
+
elementInfo,
|
2881
|
+
timing: lastAction.timing?.cost
|
2882
|
+
};
|
2883
|
+
}
|
2884
|
+
/**
|
2885
|
+
* Extract element information from locate task
|
2886
|
+
*/
|
2887
|
+
extractElementInfo(locateTask, _actionTask) {
|
2888
|
+
if (!locateTask?.output?.element)
|
2889
|
+
return void 0;
|
2890
|
+
const element = locateTask.output.element;
|
2891
|
+
return {
|
2892
|
+
type: element.attributes?.nodeType || "unknown",
|
2893
|
+
text: element.content || element.attributes?.placeholder || element.attributes?.title || "",
|
2894
|
+
location: `(${element.center[0]}, ${element.center[1]})`
|
2895
|
+
};
|
2896
|
+
}
|
2897
|
+
/**
|
2898
|
+
* Generate natural language description for actions
|
2899
|
+
*/
|
2900
|
+
generateActionDescription(actionType, param, elementInfo) {
|
2901
|
+
const elementDesc = elementInfo ? `'${elementInfo.text || elementInfo.type}' element` : "element";
|
2902
|
+
switch (actionType) {
|
2903
|
+
case "Tap":
|
2904
|
+
return `Clicked on ${elementDesc}`;
|
2905
|
+
case "Input":
|
2906
|
+
const inputValue = param?.value || "";
|
2907
|
+
return `Entered "${inputValue}" into ${elementDesc}`;
|
2908
|
+
case "KeyboardPress":
|
2909
|
+
return `Pressed ${param?.value || "key"}`;
|
2910
|
+
case "Scroll":
|
2911
|
+
return `Scrolled ${param?.direction || "on page"}`;
|
2912
|
+
case "Hover":
|
2913
|
+
return `Hovered over ${elementDesc}`;
|
2914
|
+
case "Drag":
|
2915
|
+
return `Dragged ${elementDesc}`;
|
2916
|
+
default:
|
2917
|
+
return `Performed ${actionType} action on ${elementDesc}`;
|
2918
|
+
}
|
2919
|
+
}
|
2634
2920
|
};
|
2635
2921
|
|
2636
2922
|
// src/chrome-extension/agent.ts
|
@@ -2848,7 +3134,7 @@ function sleep2(ms) {
|
|
2848
3134
|
var ChromeExtensionProxyPage = class {
|
2849
3135
|
constructor(forceSameTabNavigation) {
|
2850
3136
|
this.pageType = "chrome-extension-proxy";
|
2851
|
-
this.version = "1.0.
|
3137
|
+
this.version = "1.0.5";
|
2852
3138
|
this.activeTabId = null;
|
2853
3139
|
this.tabIdOfDebuggerAttached = null;
|
2854
3140
|
this.attachingDebugger = null;
|