@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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Mind Harness",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "permissions": ["tabGroups"],
6
6
  "background": { "service_worker": "sw.js" }
7
7
  }
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: ["--enable-unsafe-extension-debugging", "--keep-alive-for-test"]
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 HANDOVER = [
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
- "Call it instead of filling or submitting a login form, a Mind Harness login or consent form, or any form that issues credentials, and whenever only the person can continue."
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 = "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.";
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: HANDOVER,
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
@@ -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.1",
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": [