misoai-web 1.0.6 → 1.5.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/README.md +5 -349
- package/dist/es/agent.js +43 -409
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +3 -3
- package/dist/es/bridge-mode.js +45 -411
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +44 -410
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +47 -413
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +43 -409
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/playground.js +43 -409
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright.js +44 -410
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +47 -413
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +47 -413
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/es/yaml.js +5 -3
- package/dist/es/yaml.js.map +1 -1
- package/dist/lib/agent.js +43 -409
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +3 -3
- package/dist/lib/bridge-mode.js +45 -411
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +44 -410
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +47 -413
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +43 -409
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/playground.js +43 -409
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright.js +44 -410
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +47 -413
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +47 -413
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/lib/yaml.js +5 -3
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent.d.ts +3 -44
- package/iife-script/htmlElement.js +2 -2
- package/iife-script/htmlElementDebug.js +2 -2
- package/package.json +4 -4
@@ -156,10 +156,11 @@ var ScriptPlayer = class {
|
|
156
156
|
this.unnamedResultIndex = 0;
|
157
157
|
this.pageAgent = null;
|
158
158
|
this.result = {};
|
159
|
+
const target = script.target || script.web || script.android;
|
159
160
|
if (import_utils3.ifInBrowser) {
|
160
161
|
this.output = void 0;
|
161
|
-
} else if (
|
162
|
-
this.output = (0, import_node_path.resolve)(process.cwd(),
|
162
|
+
} else if (target?.output) {
|
163
|
+
this.output = (0, import_node_path.resolve)(process.cwd(), target.output);
|
163
164
|
} else {
|
164
165
|
this.output = (0, import_node_path.join)((0, import_common.getMidsceneRunSubDir)("output"), `${process.pid}.json`);
|
165
166
|
}
|
@@ -233,12 +234,13 @@ var ScriptPlayer = class {
|
|
233
234
|
} else if ("aiAssert" in flowItem) {
|
234
235
|
const assertTask = flowItem;
|
235
236
|
const prompt = assertTask.aiAssert;
|
237
|
+
const msg = assertTask.errorMessage;
|
236
238
|
(0, import_utils3.assert)(prompt, "missing prompt for aiAssert");
|
237
239
|
(0, import_utils3.assert)(
|
238
240
|
typeof prompt === "string",
|
239
241
|
"prompt for aiAssert must be a string"
|
240
242
|
);
|
241
|
-
await agent.aiAssert(prompt);
|
243
|
+
await agent.aiAssert(prompt, msg);
|
242
244
|
} else if ("aiQuery" in flowItem) {
|
243
245
|
const queryTask = flowItem;
|
244
246
|
const prompt = queryTask.aiQuery;
|
@@ -1665,7 +1667,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
|
|
1665
1667
|
var import_semver = __toESM(require("semver"));
|
1666
1668
|
|
1667
1669
|
// package.json
|
1668
|
-
var version = "1.
|
1670
|
+
var version = "1.5.6";
|
1669
1671
|
|
1670
1672
|
// src/common/task-cache.ts
|
1671
1673
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -1693,70 +1695,44 @@ var TaskCache = class {
|
|
1693
1695
|
this.cache = cacheContent;
|
1694
1696
|
this.cacheOriginalLength = this.cache.caches.length;
|
1695
1697
|
}
|
1696
|
-
matchCache(prompt, type
|
1697
|
-
const contextHash = contextData ? this.generateContextHash(contextData) : void 0;
|
1698
|
+
matchCache(prompt, type) {
|
1698
1699
|
for (let i = 0; i < this.cacheOriginalLength; i++) {
|
1699
1700
|
const item = this.cache.caches[i];
|
1700
1701
|
const key = `${type}:${prompt}:${i}`;
|
1701
|
-
if (item.type
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1702
|
+
if (item.type === type && item.prompt === prompt && !this.matchedCacheIndices.has(key)) {
|
1703
|
+
this.matchedCacheIndices.add(key);
|
1704
|
+
debug3(
|
1705
|
+
"cache found and marked as used, type: %s, prompt: %s, index: %d",
|
1706
|
+
type,
|
1707
|
+
prompt,
|
1708
|
+
i
|
1709
|
+
);
|
1710
|
+
return {
|
1711
|
+
cacheContent: item,
|
1712
|
+
updateFn: (cb) => {
|
1713
|
+
debug3(
|
1714
|
+
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1715
|
+
type,
|
1716
|
+
prompt,
|
1717
|
+
i
|
1718
|
+
);
|
1719
|
+
cb(item);
|
1720
|
+
debug3(
|
1721
|
+
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1722
|
+
type,
|
1723
|
+
prompt,
|
1724
|
+
i
|
1725
|
+
);
|
1726
|
+
this.flushCacheToFile();
|
1710
1727
|
}
|
1711
|
-
}
|
1712
|
-
debug3("cache context availability mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
|
1713
|
-
continue;
|
1714
|
-
}
|
1728
|
+
};
|
1715
1729
|
}
|
1716
|
-
this.matchedCacheIndices.add(key);
|
1717
|
-
debug3(
|
1718
|
-
"cache found and marked as used, type: %s, prompt: %s, index: %d, contextMatch: %s",
|
1719
|
-
type,
|
1720
|
-
prompt,
|
1721
|
-
i,
|
1722
|
-
contextHash ? "yes" : "no-context"
|
1723
|
-
);
|
1724
|
-
return {
|
1725
|
-
cacheContent: item,
|
1726
|
-
updateFn: (cb) => {
|
1727
|
-
debug3(
|
1728
|
-
"will call updateFn to update cache, type: %s, prompt: %s, index: %d",
|
1729
|
-
type,
|
1730
|
-
prompt,
|
1731
|
-
i
|
1732
|
-
);
|
1733
|
-
cb(item);
|
1734
|
-
debug3(
|
1735
|
-
"cache updated, will flush to file, type: %s, prompt: %s, index: %d",
|
1736
|
-
type,
|
1737
|
-
prompt,
|
1738
|
-
i
|
1739
|
-
);
|
1740
|
-
this.flushCacheToFile();
|
1741
|
-
}
|
1742
|
-
};
|
1743
1730
|
}
|
1744
|
-
debug3("no unused cache found, type: %s, prompt: %s
|
1731
|
+
debug3("no unused cache found, type: %s, prompt: %s", type, prompt);
|
1745
1732
|
return void 0;
|
1746
1733
|
}
|
1747
|
-
|
1748
|
-
|
1749
|
-
const stableString = sortedKeys.map((key) => `${key}:${JSON.stringify(contextData[key])}`).join("|");
|
1750
|
-
let hash = 0;
|
1751
|
-
for (let i = 0; i < stableString.length; i++) {
|
1752
|
-
const char = stableString.charCodeAt(i);
|
1753
|
-
hash = (hash << 5) - hash + char;
|
1754
|
-
hash = hash & hash;
|
1755
|
-
}
|
1756
|
-
return hash.toString(36);
|
1757
|
-
}
|
1758
|
-
matchPlanCache(prompt, contextData) {
|
1759
|
-
return this.matchCache(prompt, "plan", contextData);
|
1734
|
+
matchPlanCache(prompt) {
|
1735
|
+
return this.matchCache(prompt, "plan");
|
1760
1736
|
}
|
1761
1737
|
matchLocateCache(prompt) {
|
1762
1738
|
return this.matchCache(prompt, "locate");
|
@@ -1832,16 +1808,11 @@ cache file: ${cacheFile}`
|
|
1832
1808
|
);
|
1833
1809
|
}
|
1834
1810
|
}
|
1835
|
-
updateOrAppendCacheRecord(newRecord, cachedRecord
|
1811
|
+
updateOrAppendCacheRecord(newRecord, cachedRecord) {
|
1836
1812
|
if (cachedRecord) {
|
1837
1813
|
if (newRecord.type === "plan") {
|
1838
1814
|
cachedRecord.updateFn((cache) => {
|
1839
|
-
|
1840
|
-
planCache.yamlWorkflow = newRecord.yamlWorkflow;
|
1841
|
-
if (contextData) {
|
1842
|
-
planCache.contextHash = this.generateContextHash(contextData);
|
1843
|
-
planCache.contextData = { ...contextData };
|
1844
|
-
}
|
1815
|
+
cache.yamlWorkflow = newRecord.yamlWorkflow;
|
1845
1816
|
});
|
1846
1817
|
} else {
|
1847
1818
|
cachedRecord.updateFn((cache) => {
|
@@ -1849,11 +1820,6 @@ cache file: ${cacheFile}`
|
|
1849
1820
|
});
|
1850
1821
|
}
|
1851
1822
|
} else {
|
1852
|
-
if (newRecord.type === "plan" && contextData) {
|
1853
|
-
const planRecord = newRecord;
|
1854
|
-
planRecord.contextHash = this.generateContextHash(contextData);
|
1855
|
-
planRecord.contextData = { ...contextData };
|
1856
|
-
}
|
1857
1823
|
this.appendCache(newRecord);
|
1858
1824
|
}
|
1859
1825
|
}
|
@@ -1883,13 +1849,10 @@ var PageAgent = class {
|
|
1883
1849
|
generateReport: true,
|
1884
1850
|
autoPrintReportMsg: true,
|
1885
1851
|
groupName: "Midscene Report",
|
1886
|
-
groupDescription: ""
|
1887
|
-
enableCumulativeContext: true,
|
1888
|
-
autoClearContext: false
|
1852
|
+
groupDescription: ""
|
1889
1853
|
},
|
1890
1854
|
opts || {}
|
1891
1855
|
);
|
1892
|
-
this.initializeContextStore();
|
1893
1856
|
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1894
1857
|
this.page.waitForNavigationTimeout = this.opts.waitForNavigationTimeout || import_constants2.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
1895
1858
|
this.page.waitForNetworkIdleTimeout = this.opts.waitForNetworkIdleTimeout || import_constants2.DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
|
@@ -1916,69 +1879,6 @@ var PageAgent = class {
|
|
1916
1879
|
opts?.testId || this.page.pageType || "web"
|
1917
1880
|
);
|
1918
1881
|
}
|
1919
|
-
/**
|
1920
|
-
* Initialize context store for cumulative context functionality
|
1921
|
-
*/
|
1922
|
-
async initializeContextStore() {
|
1923
|
-
if (!this.opts.enableCumulativeContext) {
|
1924
|
-
debug4("Cumulative context disabled via options");
|
1925
|
-
return;
|
1926
|
-
}
|
1927
|
-
try {
|
1928
|
-
const aiModel = await import("misoai-core/ai-model");
|
1929
|
-
this.contextStore = aiModel.getContextStore();
|
1930
|
-
debug4("Context store initialized successfully", {
|
1931
|
-
autoClearContext: this.opts.autoClearContext,
|
1932
|
-
testId: this.opts.testId
|
1933
|
-
});
|
1934
|
-
if (this.opts.autoClearContext) {
|
1935
|
-
this.contextStore.clear();
|
1936
|
-
debug4("Context store cleared due to autoClearContext option");
|
1937
|
-
} else {
|
1938
|
-
const existingData = this.contextStore.getAllData();
|
1939
|
-
const existingSteps = this.contextStore.getRecentSteps(100).length;
|
1940
|
-
debug4("Context store preserving existing data", {
|
1941
|
-
existingDataKeys: Object.keys(existingData),
|
1942
|
-
existingStepsCount: existingSteps
|
1943
|
-
});
|
1944
|
-
}
|
1945
|
-
} catch (error) {
|
1946
|
-
debug4("Failed to initialize context store:", error);
|
1947
|
-
console.warn("⚠️ Could not initialize context store:", error);
|
1948
|
-
}
|
1949
|
-
}
|
1950
|
-
/**
|
1951
|
-
* Get the context store instance
|
1952
|
-
*/
|
1953
|
-
getContextStore() {
|
1954
|
-
return this.contextStore;
|
1955
|
-
}
|
1956
|
-
/**
|
1957
|
-
* Clear the context store
|
1958
|
-
*/
|
1959
|
-
clearContext() {
|
1960
|
-
if (this.contextStore) {
|
1961
|
-
this.contextStore.clear();
|
1962
|
-
}
|
1963
|
-
}
|
1964
|
-
/**
|
1965
|
-
* Get all stored data from context store
|
1966
|
-
*/
|
1967
|
-
getStoredData() {
|
1968
|
-
if (this.contextStore) {
|
1969
|
-
return this.contextStore.getAllData();
|
1970
|
-
}
|
1971
|
-
return {};
|
1972
|
-
}
|
1973
|
-
/**
|
1974
|
-
* Get step summary from context store
|
1975
|
-
*/
|
1976
|
-
getStepSummary() {
|
1977
|
-
if (this.contextStore) {
|
1978
|
-
return this.contextStore.getStepSummary();
|
1979
|
-
}
|
1980
|
-
return "";
|
1981
|
-
}
|
1982
1882
|
async getUIContext(action) {
|
1983
1883
|
if (action && (action === "extract" || action === "assert" || action === "captcha")) {
|
1984
1884
|
return await parseContextFromWebPage(this.page, {
|
@@ -2214,35 +2114,9 @@ var PageAgent = class {
|
|
2214
2114
|
};
|
2215
2115
|
}
|
2216
2116
|
async aiAction(taskPrompt, opt) {
|
2217
|
-
const originalPrompt = taskPrompt;
|
2218
|
-
let processedPrompt = taskPrompt;
|
2219
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2220
|
-
try {
|
2221
|
-
const storedData = this.contextStore.getAllData();
|
2222
|
-
if (Object.keys(storedData).length > 0) {
|
2223
|
-
debug4("Available data for aiAction:", {
|
2224
|
-
prompt: taskPrompt,
|
2225
|
-
availableData: storedData
|
2226
|
-
});
|
2227
|
-
}
|
2228
|
-
} catch (error) {
|
2229
|
-
debug4("Context store operation failed:", error);
|
2230
|
-
}
|
2231
|
-
}
|
2232
2117
|
const cacheable = opt?.cacheable;
|
2233
2118
|
const isVlmUiTars = (0, import_env2.vlLocateMode)() === "vlm-ui-tars";
|
2234
|
-
|
2235
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2236
|
-
try {
|
2237
|
-
contextData = this.contextStore.getAllData();
|
2238
|
-
if (contextData && Object.keys(contextData).length === 0) {
|
2239
|
-
contextData = void 0;
|
2240
|
-
}
|
2241
|
-
} catch (error) {
|
2242
|
-
debug4("Failed to get context data for cache:", error);
|
2243
|
-
}
|
2244
|
-
}
|
2245
|
-
const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt, contextData);
|
2119
|
+
const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
|
2246
2120
|
if (matchedCache && this.taskCache?.isCacheResultUsed) {
|
2247
2121
|
const { executor: executor2 } = await this.taskExecutor.loadYamlFlowAsPlanning(
|
2248
2122
|
taskPrompt,
|
@@ -2252,28 +2126,6 @@ var PageAgent = class {
|
|
2252
2126
|
debug4("matched cache, will call .runYaml to run the action");
|
2253
2127
|
const yaml5 = matchedCache.cacheContent?.yamlWorkflow;
|
2254
2128
|
const result = await this.runYaml(yaml5);
|
2255
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2256
|
-
try {
|
2257
|
-
const executionResult = {
|
2258
|
-
success: true,
|
2259
|
-
actionType: "cached",
|
2260
|
-
description: `Executed cached action: ${processedPrompt}`,
|
2261
|
-
timing: result.metadata?.totalTime
|
2262
|
-
};
|
2263
|
-
this.contextStore.addStep({
|
2264
|
-
type: "action",
|
2265
|
-
summary: `Action: ${processedPrompt} (cached)`,
|
2266
|
-
prompt: processedPrompt,
|
2267
|
-
executionResult
|
2268
|
-
});
|
2269
|
-
debug4("Added cached action step to context store:", {
|
2270
|
-
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2271
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2272
|
-
});
|
2273
|
-
} catch (error) {
|
2274
|
-
debug4("Failed to add cached action step:", error);
|
2275
|
-
}
|
2276
|
-
}
|
2277
2129
|
return {
|
2278
2130
|
result: result.result,
|
2279
2131
|
metadata: metadata2
|
@@ -2298,114 +2150,17 @@ var PageAgent = class {
|
|
2298
2150
|
prompt: taskPrompt,
|
2299
2151
|
yamlWorkflow: yamlFlowStr
|
2300
2152
|
},
|
2301
|
-
matchedCache
|
2302
|
-
contextData
|
2303
|
-
// Pass context data for cache creation
|
2153
|
+
matchedCache
|
2304
2154
|
);
|
2305
2155
|
}
|
2306
2156
|
const metadata = this.afterTaskRunning(executor);
|
2307
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2308
|
-
try {
|
2309
|
-
const executionResult = this.analyzeExecutionResults(executor, originalPrompt);
|
2310
|
-
this.contextStore.addStep({
|
2311
|
-
type: "action",
|
2312
|
-
summary: `Action: ${processedPrompt}`,
|
2313
|
-
prompt: processedPrompt,
|
2314
|
-
executionResult
|
2315
|
-
});
|
2316
|
-
debug4("Added action step with execution result to context store:", {
|
2317
|
-
stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
|
2318
|
-
totalSteps: this.contextStore.getRecentSteps(100).length,
|
2319
|
-
executionResult
|
2320
|
-
});
|
2321
|
-
} catch (error) {
|
2322
|
-
debug4("Failed to analyze execution results, adding step without execution result:", error);
|
2323
|
-
try {
|
2324
|
-
this.contextStore.addStep({
|
2325
|
-
type: "action",
|
2326
|
-
summary: `Action: ${processedPrompt}`,
|
2327
|
-
prompt: processedPrompt
|
2328
|
-
});
|
2329
|
-
} catch (stepError) {
|
2330
|
-
debug4("Failed to add action step:", stepError);
|
2331
|
-
}
|
2332
|
-
}
|
2333
|
-
}
|
2334
2157
|
return {
|
2335
2158
|
result: output,
|
2336
2159
|
metadata
|
2337
2160
|
};
|
2338
2161
|
}
|
2339
2162
|
async aiQuery(demand) {
|
2340
|
-
|
2341
|
-
let storageKey;
|
2342
|
-
try {
|
2343
|
-
const aiModel = await import("misoai-core/ai-model");
|
2344
|
-
const contextStore = aiModel.getContextStore();
|
2345
|
-
if (typeof demand === "string") {
|
2346
|
-
const storageInstruction = contextStore.parseStorageInstruction(demand);
|
2347
|
-
if (storageInstruction) {
|
2348
|
-
storageKey = storageInstruction.key;
|
2349
|
-
processedDemand = storageInstruction.cleanText;
|
2350
|
-
contextStore._pendingAliases = storageInstruction.aliases;
|
2351
|
-
} else {
|
2352
|
-
const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
|
2353
|
-
if (storageMatch) {
|
2354
|
-
storageKey = storageMatch[1];
|
2355
|
-
processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
|
2356
|
-
}
|
2357
|
-
}
|
2358
|
-
}
|
2359
|
-
} catch (error) {
|
2360
|
-
debug4("Context store not available:", error);
|
2361
|
-
}
|
2362
|
-
const { output, executor } = await this.taskExecutor.query(processedDemand);
|
2363
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2364
|
-
if (storageKey && output) {
|
2365
|
-
try {
|
2366
|
-
const pendingAliases = this.contextStore._pendingAliases;
|
2367
|
-
if (pendingAliases) {
|
2368
|
-
this.contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
|
2369
|
-
delete this.contextStore._pendingAliases;
|
2370
|
-
debug4("Stored query result with aliases:", {
|
2371
|
-
key: storageKey,
|
2372
|
-
value: output,
|
2373
|
-
aliases: pendingAliases
|
2374
|
-
});
|
2375
|
-
} else {
|
2376
|
-
this.contextStore.storeData(storageKey, output);
|
2377
|
-
debug4("Stored query result:", {
|
2378
|
-
key: storageKey,
|
2379
|
-
value: output
|
2380
|
-
});
|
2381
|
-
}
|
2382
|
-
this.contextStore.addStep({
|
2383
|
-
type: "query",
|
2384
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
|
2385
|
-
data: output,
|
2386
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2387
|
-
});
|
2388
|
-
debug4("Added query step to context store:", {
|
2389
|
-
storageKey,
|
2390
|
-
totalStoredItems: Object.keys(this.contextStore.getAllData()).length,
|
2391
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2392
|
-
});
|
2393
|
-
} catch (error) {
|
2394
|
-
debug4("Failed to store query result:", error);
|
2395
|
-
}
|
2396
|
-
} else {
|
2397
|
-
try {
|
2398
|
-
this.contextStore.addStep({
|
2399
|
-
type: "query",
|
2400
|
-
summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
|
2401
|
-
data: output,
|
2402
|
-
prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
|
2403
|
-
});
|
2404
|
-
} catch (error) {
|
2405
|
-
debug4("Failed to add query step:", error);
|
2406
|
-
}
|
2407
|
-
}
|
2408
|
-
}
|
2163
|
+
const { output, executor } = await this.taskExecutor.query(demand);
|
2409
2164
|
const metadata = this.afterTaskRunning(executor);
|
2410
2165
|
return {
|
2411
2166
|
result: output,
|
@@ -2515,48 +2270,6 @@ var PageAgent = class {
|
|
2515
2270
|
};
|
2516
2271
|
}
|
2517
2272
|
async aiAssert(assertion, msg, opt) {
|
2518
|
-
let executionContext = "";
|
2519
|
-
if (this.opts.enableCumulativeContext && this.contextStore) {
|
2520
|
-
try {
|
2521
|
-
const recentSteps = this.contextStore.getRecentSteps(3);
|
2522
|
-
const stepsWithExecutionResults = recentSteps.filter((step) => step.executionResult);
|
2523
|
-
const storedData = this.contextStore.getAllData();
|
2524
|
-
if (stepsWithExecutionResults.length > 0) {
|
2525
|
-
const recentActions = stepsWithExecutionResults.map((step) => {
|
2526
|
-
const result = step.executionResult;
|
2527
|
-
return `- ${result.description}${result.success ? "" : " (FAILED)"}`;
|
2528
|
-
}).join("\n");
|
2529
|
-
executionContext = `
|
2530
|
-
|
2531
|
-
Recent actions performed:
|
2532
|
-
${recentActions}
|
2533
|
-
|
2534
|
-
This context may help verify the assertion.`;
|
2535
|
-
}
|
2536
|
-
if (storedData && Object.keys(storedData).length > 0) {
|
2537
|
-
executionContext += `
|
2538
|
-
|
2539
|
-
Available data for reference:
|
2540
|
-
${JSON.stringify(storedData, null, 2)}
|
2541
|
-
|
2542
|
-
Note: If the assertion references any data keys or natural language equivalents, consider the stored values when verifying.`;
|
2543
|
-
debug4("Available data for aiAssert:", {
|
2544
|
-
assertion,
|
2545
|
-
availableData: storedData
|
2546
|
-
});
|
2547
|
-
}
|
2548
|
-
this.contextStore.addStep({
|
2549
|
-
type: "assertion",
|
2550
|
-
summary: `Assertion: ${assertion}`,
|
2551
|
-
prompt: assertion
|
2552
|
-
});
|
2553
|
-
debug4("Added assertion step to context store:", {
|
2554
|
-
totalSteps: this.contextStore.getRecentSteps(100).length
|
2555
|
-
});
|
2556
|
-
} catch (error) {
|
2557
|
-
debug4("Context store operation failed:", error);
|
2558
|
-
}
|
2559
|
-
}
|
2560
2273
|
let currentUrl = "";
|
2561
2274
|
if (this.page.url) {
|
2562
2275
|
try {
|
@@ -2564,13 +2277,7 @@ Note: If the assertion references any data keys or natural language equivalents,
|
|
2564
2277
|
} catch (e) {
|
2565
2278
|
}
|
2566
2279
|
}
|
2567
|
-
|
2568
|
-
if (currentUrl) {
|
2569
|
-
assertionWithContext = `For the page at URL "${currentUrl}", ${assertion}`;
|
2570
|
-
}
|
2571
|
-
if (executionContext) {
|
2572
|
-
assertionWithContext += executionContext;
|
2573
|
-
}
|
2280
|
+
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2574
2281
|
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2575
2282
|
const metadata = this.afterTaskRunning(executor, true);
|
2576
2283
|
if (output && opt?.keepRawResponse) {
|
@@ -2784,79 +2491,6 @@ ${errors}`);
|
|
2784
2491
|
async destroy() {
|
2785
2492
|
await this.page.destroy();
|
2786
2493
|
}
|
2787
|
-
/**
|
2788
|
-
* Analyze execution results from executor to generate meaningful descriptions
|
2789
|
-
*/
|
2790
|
-
analyzeExecutionResults(executor, originalPrompt) {
|
2791
|
-
const tasks = executor.tasks;
|
2792
|
-
const success = !executor.isInErrorState();
|
2793
|
-
if (!success) {
|
2794
|
-
const errorTask = executor.latestErrorTask();
|
2795
|
-
return {
|
2796
|
-
success: false,
|
2797
|
-
actionType: "error",
|
2798
|
-
description: `Failed to execute: ${originalPrompt}`,
|
2799
|
-
error: errorTask?.error
|
2800
|
-
};
|
2801
|
-
}
|
2802
|
-
const actionTasks = tasks.filter((t) => t.type === "Action" && t.status === "finished");
|
2803
|
-
const locateTasks = tasks.filter((t) => t.type === "Insight" && t.subType === "Locate");
|
2804
|
-
const lastAction = actionTasks[actionTasks.length - 1];
|
2805
|
-
const lastLocate = locateTasks[locateTasks.length - 1];
|
2806
|
-
if (!lastAction) {
|
2807
|
-
return {
|
2808
|
-
success: true,
|
2809
|
-
actionType: "unknown",
|
2810
|
-
description: `Completed: ${originalPrompt}`
|
2811
|
-
};
|
2812
|
-
}
|
2813
|
-
const actionType = lastAction.subType || "unknown";
|
2814
|
-
const elementInfo = this.extractElementInfo(lastLocate, lastAction);
|
2815
|
-
const description = this.generateActionDescription(actionType, lastAction.param, elementInfo);
|
2816
|
-
return {
|
2817
|
-
success: true,
|
2818
|
-
actionType,
|
2819
|
-
description,
|
2820
|
-
elementInfo,
|
2821
|
-
timing: lastAction.timing?.cost
|
2822
|
-
};
|
2823
|
-
}
|
2824
|
-
/**
|
2825
|
-
* Extract element information from locate task
|
2826
|
-
*/
|
2827
|
-
extractElementInfo(locateTask, _actionTask) {
|
2828
|
-
if (!locateTask?.output?.element)
|
2829
|
-
return void 0;
|
2830
|
-
const element = locateTask.output.element;
|
2831
|
-
return {
|
2832
|
-
type: element.attributes?.nodeType || "unknown",
|
2833
|
-
text: element.content || element.attributes?.placeholder || element.attributes?.title || "",
|
2834
|
-
location: `(${element.center[0]}, ${element.center[1]})`
|
2835
|
-
};
|
2836
|
-
}
|
2837
|
-
/**
|
2838
|
-
* Generate natural language description for actions
|
2839
|
-
*/
|
2840
|
-
generateActionDescription(actionType, param, elementInfo) {
|
2841
|
-
const elementDesc = elementInfo ? `'${elementInfo.text || elementInfo.type}' element` : "element";
|
2842
|
-
switch (actionType) {
|
2843
|
-
case "Tap":
|
2844
|
-
return `Clicked on ${elementDesc}`;
|
2845
|
-
case "Input":
|
2846
|
-
const inputValue = param?.value || "";
|
2847
|
-
return `Entered "${inputValue}" into ${elementDesc}`;
|
2848
|
-
case "KeyboardPress":
|
2849
|
-
return `Pressed ${param?.value || "key"}`;
|
2850
|
-
case "Scroll":
|
2851
|
-
return `Scrolled ${param?.direction || "on page"}`;
|
2852
|
-
case "Hover":
|
2853
|
-
return `Hovered over ${elementDesc}`;
|
2854
|
-
case "Drag":
|
2855
|
-
return `Dragged ${elementDesc}`;
|
2856
|
-
default:
|
2857
|
-
return `Performed ${actionType} action on ${elementDesc}`;
|
2858
|
-
}
|
2859
|
-
}
|
2860
2494
|
};
|
2861
2495
|
|
2862
2496
|
// src/playground/agent.ts
|