@mind-harness/mh-browser 0.2.1 → 0.2.2
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/extension/manifest.json
CHANGED
package/lib/index.js
CHANGED
|
@@ -2964,7 +2964,12 @@ async function launchBrowser(options) {
|
|
|
2964
2964
|
...options.headless ? {} : {
|
|
2965
2965
|
viewport: null,
|
|
2966
2966
|
ignoreDefaultArgs: ["--disable-extensions"],
|
|
2967
|
-
args: [
|
|
2967
|
+
args: [
|
|
2968
|
+
"--enable-unsafe-extension-debugging",
|
|
2969
|
+
"--keep-alive-for-test",
|
|
2970
|
+
"--disable-blink-features=AutomationControlled",
|
|
2971
|
+
"--test-type"
|
|
2972
|
+
]
|
|
2968
2973
|
},
|
|
2969
2974
|
...options.browser === "chromium" ? {} : { channel: options.browser },
|
|
2970
2975
|
...options.executablePath !== void 0 ? { executablePath: options.executablePath } : {}
|
|
@@ -4107,6 +4112,12 @@ function handoverQuestion(reason) {
|
|
|
4107
4112
|
}
|
|
4108
4113
|
/** The option that hands the browser back. */
|
|
4109
4114
|
const HAND_BACK = "交回";
|
|
4115
|
+
/** The handover card when the browser has no window: the person cannot act in it. */
|
|
4116
|
+
function stepQuestion(reason) {
|
|
4117
|
+
return `需要你来:${reason}(浏览器没有窗口,这里做不了;写下怎么继续)`;
|
|
4118
|
+
}
|
|
4119
|
+
/** The option on that card when the person has nothing to add. */
|
|
4120
|
+
const REPLIED = "继续";
|
|
4110
4121
|
//#endregion
|
|
4111
4122
|
//#region lib/types/service/extension.js
|
|
4112
4123
|
const PACKAGE = "@mind-harness/mh-browser";
|
|
@@ -6723,18 +6734,30 @@ function browserDownloadTool(ctx, reader) {
|
|
|
6723
6734
|
}
|
|
6724
6735
|
//#endregion
|
|
6725
6736
|
//#region lib/types/tools/handover.js
|
|
6726
|
-
const
|
|
6737
|
+
const THEIRS = "a check that they are human, a login form, a Mind Harness login or consent form, or any form that issues credentials. Those steps are theirs: do not click through them, work around them, or fetch the page another way. A human check can clear by itself; if it is still there after one wait, call this.";
|
|
6738
|
+
const HEADED = [
|
|
6727
6739
|
"Hand the browser to the person and wait until they hand it back.",
|
|
6740
|
+
"The browser is a window on the person's screen; they can see it and act in it.",
|
|
6728
6741
|
"The person can take over a tab at any time; that stops the action in progress on that tab, and a tab they have touched stays with them until they hand it back. Other tabs keep working.",
|
|
6729
|
-
|
|
6742
|
+
`Call it when a site asks for the person themselves: ${THEIRS} A handover usually takes the person seconds.`,
|
|
6743
|
+
"Call it too whenever only the person can continue."
|
|
6744
|
+
].join(" ");
|
|
6745
|
+
const HEADLESS = [
|
|
6746
|
+
"Tell the person about a step only they can take, and wait for their reply.",
|
|
6747
|
+
"The browser has no window: the person cannot see it or act in it, so the step cannot be finished in this browser. Their reply says how to go on.",
|
|
6748
|
+
`Call it when a site asks for the person themselves: ${THEIRS}`,
|
|
6749
|
+
"Call it too whenever only the person can continue."
|
|
6730
6750
|
].join(" ");
|
|
6731
6751
|
const REASON = "The sentence the person sees on the handover card, unchanged.";
|
|
6732
|
-
const TAB =
|
|
6752
|
+
const TAB = {
|
|
6753
|
+
headed: "Tab id of the human page to show the person, copied from a page element's tab attribute. Omit it to hand over without naming a tab; that does not pick the latest result. A page with an Agent View has no tab until you open it with snapshot.",
|
|
6754
|
+
headless: "Tab id of the page the step is on, copied from a page element's tab attribute; the result carries that page as it is after the reply. Omit it to name no tab; that does not pick the latest result. A page with an Agent View has no tab until you open it with snapshot."
|
|
6755
|
+
};
|
|
6733
6756
|
const ABORT = Symbol("abort");
|
|
6734
|
-
function browserHandoverTool(ctx, reader) {
|
|
6757
|
+
function browserHandoverTool(ctx, reader, headed = true) {
|
|
6735
6758
|
return defineTool({
|
|
6736
6759
|
name: "browser_handover",
|
|
6737
|
-
description:
|
|
6760
|
+
description: headed ? HEADED : HEADLESS,
|
|
6738
6761
|
parameters: {
|
|
6739
6762
|
reason: {
|
|
6740
6763
|
type: "string",
|
|
@@ -6743,7 +6766,7 @@ function browserHandoverTool(ctx, reader) {
|
|
|
6743
6766
|
},
|
|
6744
6767
|
tab: {
|
|
6745
6768
|
type: "string",
|
|
6746
|
-
description: TAB
|
|
6769
|
+
description: TAB[headed ? "headed" : "headless"]
|
|
6747
6770
|
}
|
|
6748
6771
|
},
|
|
6749
6772
|
output: {
|
|
@@ -6785,7 +6808,7 @@ function browserHandoverTool(ctx, reader) {
|
|
|
6785
6808
|
reason: args.reason,
|
|
6786
6809
|
...args.tab === void 0 ? {} : { tab: args.tab }
|
|
6787
6810
|
}, exec.signal);
|
|
6788
|
-
const answer = await askUntilAnswered(ctx, args.reason, exec);
|
|
6811
|
+
const answer = await askUntilAnswered(ctx, args.reason, exec, headed);
|
|
6789
6812
|
if (answer === ABORT || exec.signal.aborted) return quiet();
|
|
6790
6813
|
const note = answer.answers[0]?.custom;
|
|
6791
6814
|
const back = await ctx.mhBrowser.handBack(session.id, note);
|
|
@@ -6793,11 +6816,7 @@ function browserHandoverTool(ctx, reader) {
|
|
|
6793
6816
|
const pages = page === void 0 ? [] : [page];
|
|
6794
6817
|
const block = tabBlock(ctx, reader, session);
|
|
6795
6818
|
return {
|
|
6796
|
-
text: `${[
|
|
6797
|
-
...note === void 0 || note === "" ? [] : [note],
|
|
6798
|
-
`${String(back.operations)} operations`,
|
|
6799
|
-
takeoverText(back)
|
|
6800
|
-
].join("\n")}\n${renderOutcome(pages)}${block.suffix}`,
|
|
6819
|
+
text: `${[...note === void 0 || note === "" ? [] : [note], ...headed ? [`${String(back.operations)} operations`, takeoverText(back)] : []].join("\n")}\n${renderOutcome(pages)}${block.suffix}`,
|
|
6801
6820
|
meta: JSON.parse(JSON.stringify({
|
|
6802
6821
|
...readingsOf(pages, "handover"),
|
|
6803
6822
|
closed: block.closed,
|
|
@@ -6816,14 +6835,14 @@ function browserHandoverTool(ctx, reader) {
|
|
|
6816
6835
|
});
|
|
6817
6836
|
}
|
|
6818
6837
|
/** Closing the card is not an answer. Ask the same question again. */
|
|
6819
|
-
async function askUntilAnswered(ctx, reason, exec) {
|
|
6838
|
+
async function askUntilAnswered(ctx, reason, exec, headed) {
|
|
6820
6839
|
const stopped = aborted(exec.signal);
|
|
6821
6840
|
for (;;) try {
|
|
6822
6841
|
return await Promise.race([ctx.userQuestions.ask({
|
|
6823
6842
|
questions: [{
|
|
6824
6843
|
id: "handback",
|
|
6825
|
-
question: handoverQuestion(reason),
|
|
6826
|
-
options: [{ label: HAND_BACK }]
|
|
6844
|
+
question: headed ? handoverQuestion(reason) : stepQuestion(reason),
|
|
6845
|
+
options: [{ label: headed ? HAND_BACK : REPLIED }]
|
|
6827
6846
|
}],
|
|
6828
6847
|
...exec.agent !== void 0 ? { agent: exec.agent } : {},
|
|
6829
6848
|
signal: exec.signal
|
|
@@ -7187,14 +7206,14 @@ function line(receipt) {
|
|
|
7187
7206
|
}
|
|
7188
7207
|
//#endregion
|
|
7189
7208
|
//#region lib/types/tools/register.js
|
|
7190
|
-
function registerBrowserTools(ctx, reader) {
|
|
7209
|
+
function registerBrowserTools(ctx, reader, headed) {
|
|
7191
7210
|
followSessionTitles(ctx);
|
|
7192
7211
|
ctx.tools.register(browserOpenTool(ctx, reader));
|
|
7193
7212
|
for (const tool of pageOperationTools(ctx, reader)) ctx.tools.register(tool);
|
|
7194
7213
|
ctx.tools.register(browserInvokeTool(ctx, reader));
|
|
7195
7214
|
ctx.tools.register(browserDownloadTool(ctx, reader));
|
|
7196
7215
|
ctx.tools.register(browserPresenceTool(ctx, reader));
|
|
7197
|
-
ctx.tools.register(browserHandoverTool(ctx, reader));
|
|
7216
|
+
ctx.tools.register(browserHandoverTool(ctx, reader, headed));
|
|
7198
7217
|
}
|
|
7199
7218
|
//#endregion
|
|
7200
7219
|
//#region lib/types/index.js
|
|
@@ -7221,7 +7240,7 @@ async function apply(ctx, config) {
|
|
|
7221
7240
|
inject: ["mhBrowser", ...inject],
|
|
7222
7241
|
async apply(inner) {
|
|
7223
7242
|
const reader = await registerProjections(inner);
|
|
7224
|
-
registerBrowserTools(inner, reader);
|
|
7243
|
+
registerBrowserTools(inner, reader, !config.headless);
|
|
7225
7244
|
registerPresence(inner, reader);
|
|
7226
7245
|
}
|
|
7227
7246
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
2
|
import { type ToolDefinition } from '@deepseek-ai/dsh-tools';
|
|
3
3
|
import type { LogReader } from '../projections.ts';
|
|
4
|
-
export declare function browserHandoverTool(ctx: Context, reader: LogReader): ToolDefinition;
|
|
4
|
+
export declare function browserHandoverTool(ctx: Context, reader: LogReader, headed?: boolean): ToolDefinition;
|
|
5
5
|
//# sourceMappingURL=handover.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
2
|
import type { LogReader } from '../projections.ts';
|
|
3
|
-
export declare function registerBrowserTools(ctx: Context, reader: LogReader): void;
|
|
3
|
+
export declare function registerBrowserTools(ctx: Context, reader: LogReader, headed: boolean): void;
|
|
4
4
|
//# sourceMappingURL=register.d.ts.map
|
package/lib/types/words.d.ts
CHANGED
|
@@ -4,4 +4,8 @@ export declare const WAITING_TITLE = "\u7B49\u4F60\uFF1A";
|
|
|
4
4
|
export declare function handoverQuestion(reason: string): string;
|
|
5
5
|
/** The option that hands the browser back. */
|
|
6
6
|
export declare const HAND_BACK = "\u4EA4\u56DE";
|
|
7
|
+
/** The handover card when the browser has no window: the person cannot act in it. */
|
|
8
|
+
export declare function stepQuestion(reason: string): string;
|
|
9
|
+
/** The option on that card when the person has nothing to add. */
|
|
10
|
+
export declare const REPLIED = "\u7EE7\u7EED";
|
|
7
11
|
//# sourceMappingURL=words.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mind-harness/mh-browser",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Opens pages in a real browser for the agent, keeps chosen Agent Views in context, and hands the browser to you when a person is needed.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"files": [
|