@omnivoice/page-agent 0.5.0 → 0.6.1

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.
@@ -0,0 +1,45 @@
1
+ const debugWindow = () => window;
2
+ const MAX_STEPS = 200;
3
+ const MAX_PAGES = 5;
4
+ const HEAD_LENGTH = 4e3;
5
+ function createDebugExtension() {
6
+ const store = () => debugWindow().__pageAgentDebug ??= { task: "", steps: [], pages: [] };
7
+ let pageCount = 0;
8
+ return {
9
+ name: "debug",
10
+ hooks: {
11
+ onBeforeTask(agent) {
12
+ debugWindow().__pageAgentDebug = { task: agent.task, steps: [], pages: [] };
13
+ pageCount = 0;
14
+ console.debug("[page-agent debug] tarefa:", agent.task);
15
+ },
16
+ transformPageContent(content) {
17
+ const debug = store();
18
+ pageCount += 1;
19
+ debug.pages.push({ step: pageCount, length: content.length, head: content.slice(0, HEAD_LENGTH) });
20
+ if (debug.pages.length > MAX_PAGES) debug.pages.shift();
21
+ return content;
22
+ },
23
+ onAfterStep(_agent, history) {
24
+ const last = [...history].reverse().find((event) => event.type === "step");
25
+ if (!last || last.type !== "step") return;
26
+ const entry = {
27
+ step: last.stepIndex,
28
+ goal: last.reflection.next_goal ?? "",
29
+ evaluation: last.reflection.evaluation_previous_goal ?? "",
30
+ tool: last.action.name,
31
+ input: last.action.input,
32
+ output: last.action.output.slice(0, 300)
33
+ };
34
+ const debug = store();
35
+ debug.steps.push(entry);
36
+ if (debug.steps.length > MAX_STEPS) debug.steps.shift();
37
+ console.debug(`[page-agent debug] passo ${entry.step}: ${entry.goal} → ${entry.tool}`, entry.input, "⇒", entry.output);
38
+ }
39
+ }
40
+ };
41
+ }
42
+ export {
43
+ createDebugExtension
44
+ };
45
+ //# sourceMappingURL=debug-extension-D0P_sNkc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-extension-D0P_sNkc.js","sources":["../../src/package/debug-extension.ts"],"sourcesContent":["/**\n * Diagnóstico do agente: por passo, o que ele PENSOU (objetivo), FEZ (ferramenta e entrada) e VIU (o conteúdo\n * indexado que foi ao modelo). Serve para responder \"por que o agente não achou X?\" sem adivinhar.\n *\n * ATENÇÃO: o conteúdo da página pode ter dados de clientes. Os registros ficam só no navegador (console e\n * `window.__pageAgentDebug`), nunca são enviados a lugar nenhum, e só existem com `debug: true`. Use em diagnóstico.\n */\n\nimport type { WidgetExtension } from \"../../vendor/page-agent/packages/page-agent/src/widget\";\n\nexport interface DebugStep {\n step: number;\n goal: string;\n evaluation: string;\n tool: string;\n input: unknown;\n output: string;\n}\n\nexport interface DebugPage {\n step: number;\n length: number;\n /** Primeiros caracteres do conteúdo que o modelo recebeu naquele passo. */\n head: string;\n}\n\nexport interface PageAgentDebug {\n task: string;\n steps: DebugStep[];\n pages: DebugPage[];\n}\n\n/** `window` com o registro de diagnóstico. Local de propósito: não polui o escopo global de quem consome o pacote. */\ntype DebugWindow = Window & { __pageAgentDebug?: PageAgentDebug };\nconst debugWindow = (): DebugWindow => window;\n\nconst MAX_STEPS = 200;\nconst MAX_PAGES = 5;\nconst HEAD_LENGTH = 4000;\n\nexport function createDebugExtension(): WidgetExtension {\n const store = (): PageAgentDebug => (debugWindow().__pageAgentDebug ??= { task: \"\", steps: [], pages: [] });\n let pageCount = 0;\n\n return {\n name: \"debug\",\n hooks: {\n onBeforeTask(agent) {\n debugWindow().__pageAgentDebug = { task: agent.task, steps: [], pages: [] };\n pageCount = 0;\n console.debug(\"[page-agent debug] tarefa:\", agent.task);\n },\n\n transformPageContent(content) {\n const debug = store();\n pageCount += 1;\n debug.pages.push({ step: pageCount, length: content.length, head: content.slice(0, HEAD_LENGTH) });\n if (debug.pages.length > MAX_PAGES) debug.pages.shift();\n return content;\n },\n\n onAfterStep(_agent, history) {\n const last = [...history].reverse().find((event) => event.type === \"step\");\n if (!last || last.type !== \"step\") return;\n const entry: DebugStep = {\n step: last.stepIndex,\n goal: last.reflection.next_goal ?? \"\",\n evaluation: last.reflection.evaluation_previous_goal ?? \"\",\n tool: last.action.name,\n input: last.action.input,\n output: last.action.output.slice(0, 300),\n };\n const debug = store();\n debug.steps.push(entry);\n if (debug.steps.length > MAX_STEPS) debug.steps.shift();\n console.debug(`[page-agent debug] passo ${entry.step}: ${entry.goal} → ${entry.tool}`, entry.input, \"⇒\", entry.output);\n },\n },\n };\n}\n"],"names":[],"mappings":"AAkCA,MAAM,cAAc,MAAmB;AAEvC,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,cAAc;AAEb,SAAS,uBAAwC;AACtD,QAAM,QAAQ,MAAuB,YAAA,EAAc,qBAAqB,EAAE,MAAM,IAAI,OAAO,IAAI,OAAO,CAAA,EAAC;AACvG,MAAI,YAAY;AAEhB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,MACL,aAAa,OAAO;AAClB,oBAAA,EAAc,mBAAmB,EAAE,MAAM,MAAM,MAAM,OAAO,CAAA,GAAI,OAAO,GAAC;AACxE,oBAAY;AACZ,gBAAQ,MAAM,8BAA8B,MAAM,IAAI;AAAA,MACxD;AAAA,MAEA,qBAAqB,SAAS;AAC5B,cAAM,QAAQ,MAAA;AACd,qBAAa;AACb,cAAM,MAAM,KAAK,EAAE,MAAM,WAAW,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,MAAM,GAAG,WAAW,GAAG;AACjG,YAAI,MAAM,MAAM,SAAS,UAAW,OAAM,MAAM,MAAA;AAChD,eAAO;AAAA,MACT;AAAA,MAEA,YAAY,QAAQ,SAAS;AAC3B,cAAM,OAAO,CAAC,GAAG,OAAO,EAAE,QAAA,EAAU,KAAK,CAAC,UAAU,MAAM,SAAS,MAAM;AACzE,YAAI,CAAC,QAAQ,KAAK,SAAS,OAAQ;AACnC,cAAM,QAAmB;AAAA,UACvB,MAAM,KAAK;AAAA,UACX,MAAM,KAAK,WAAW,aAAa;AAAA,UACnC,YAAY,KAAK,WAAW,4BAA4B;AAAA,UACxD,MAAM,KAAK,OAAO;AAAA,UAClB,OAAO,KAAK,OAAO;AAAA,UACnB,QAAQ,KAAK,OAAO,OAAO,MAAM,GAAG,GAAG;AAAA,QAAA;AAEzC,cAAM,QAAQ,MAAA;AACd,cAAM,MAAM,KAAK,KAAK;AACtB,YAAI,MAAM,MAAM,SAAS,UAAW,OAAM,MAAM,MAAA;AAChD,gBAAQ,MAAM,4BAA4B,MAAM,IAAI,KAAK,MAAM,IAAI,MAAM,MAAM,IAAI,IAAI,MAAM,OAAO,KAAK,MAAM,MAAM;AAAA,MACvH;AAAA,IAAA;AAAA,EACF;AAEJ;"}
@@ -224,6 +224,21 @@ export declare interface AgentStepEvent {
224
224
  rawRequest?: unknown;
225
225
  }
226
226
 
227
+ export declare type BrainExtension = WidgetExtension & {
228
+ name: "brain";
229
+ };
230
+
231
+ export declare interface BrainOptions {
232
+ /** `task-intent` (padrão): escrever só se a tarefa pedir. `allow` desliga; `deny` torna somente-leitura. */
233
+ writePolicy?: WritePolicyMode;
234
+ /** Quantas repetições consecutivas da mesma ação sem efeito encerram a tarefa. @default 3 */
235
+ repeatLimit?: number;
236
+ /** Quantos passos recentes o histórico mantém por inteiro. @default 6 */
237
+ historyWindow?: number;
238
+ /** Quantas escritas recusadas encerram a tarefa (o agente insiste em algo que a política nega). @default 3 */
239
+ refusalLimit?: number;
240
+ }
241
+
227
242
  /**
228
243
  * Structured browser state for LLM consumption
229
244
  */
@@ -242,6 +257,22 @@ declare function cleanUpHighlights(): void;
242
257
 
243
258
  export declare function createVoice(options?: VoiceOptions): Voice;
244
259
 
260
+ declare interface DebugPage {
261
+ step: number;
262
+ length: number;
263
+ /** Primeiros caracteres do conteúdo que o modelo recebeu naquele passo. */
264
+ head: string;
265
+ }
266
+
267
+ export declare interface DebugStep {
268
+ step: number;
269
+ goal: string;
270
+ evaluation: string;
271
+ tool: string;
272
+ input: unknown;
273
+ output: string;
274
+ }
275
+
245
276
  declare namespace dom {
246
277
  export {
247
278
  resolveViewportExpansion,
@@ -622,6 +653,12 @@ export declare type PageAgentCoreConfig = AgentConfig & {
622
653
  pageController: PageController;
623
654
  };
624
655
 
656
+ export declare interface PageAgentDebug {
657
+ task: string;
658
+ steps: DebugStep[];
659
+ pages: DebugPage[];
660
+ }
661
+
625
662
  /** `window.PageAgent` na build IIFE (CDN): a classe com `mountWidget` e `createVoice` anexados. */
626
663
  export declare type PageAgentGlobal = typeof PageAgent & {
627
664
  mountWidget: typeof mountWidget;
@@ -891,6 +928,11 @@ export declare interface RetryEvent {
891
928
  maxAttempts: number;
892
929
  }
893
930
 
931
+ /** Resultado da tarefa, com a verificação que o supervisor anexa. */
932
+ export declare type SupervisedResult = {
933
+ verification?: Verification;
934
+ };
935
+
894
936
  /** Supported UI languages */
895
937
  export declare type SupportedLanguage = 'en-US' | 'zh-CN' | 'pt-BR';
896
938
 
@@ -944,6 +986,29 @@ export declare interface UserTakeoverEvent {
944
986
  type: 'user_takeover';
945
987
  }
946
988
 
989
+ export declare interface Verification {
990
+ status: VerificationStatus;
991
+ reasons: string[];
992
+ evidence: {
993
+ effects: number;
994
+ navigations: number;
995
+ refusedWrites: number;
996
+ };
997
+ }
998
+
999
+ /**
1000
+ * Veredito do supervisor sobre uma tarefa que o agente deu por encerrada. Lógica pura (sem DOM): recebe o que foi
1001
+ * observado e devolve o resultado final com a verificação anexada.
1002
+ *
1003
+ * Princípios:
1004
+ * - Quem manda parar (não-progresso, escritas recusadas em excesso) torna o resultado FALHA, com o motivo.
1005
+ * - "Sucesso" declarado pelo modelo só vira VERIFICADO quando requisitos explícitos da tarefa foram confirmados no DOM
1006
+ * por um verificador independente. Tarefas abertas (resumir, navegar, responder) não têm esse verificador: ficam
1007
+ * NÃO VERIFICADAS, com a contagem de efeitos observados. Isso não as reprova — uma resposta legítima pode não mexer
1008
+ * na página — mas deixa de apresentar a palavra do modelo como fato.
1009
+ */
1010
+ export declare type VerificationStatus = "verified" | "unverified" | "failed";
1011
+
947
1012
  export declare interface Voice {
948
1013
  /** O que o navegador realmente oferece. A UI usa isto para mostrar/ocultar controles. */
949
1014
  readonly supported: {
@@ -1017,12 +1082,39 @@ export declare interface Widget {
1017
1082
  hide(): void;
1018
1083
  toggle(): void;
1019
1084
  /** Atualiza config em runtime (recria o agente quando muda algo de LLM/agente). */
1020
- setConfig(patch: Partial<WidgetOptions>): void;
1085
+ setConfig(patch: Partial<WidgetOptions_2>): void;
1021
1086
  /** Remove launcher, painel e voz da página. */
1022
1087
  unmount(): void;
1023
1088
  }
1024
1089
 
1025
- export declare interface WidgetOptions {
1090
+ /**
1091
+ * Extensão do agente: um pacote de ferramentas, instruções e ganchos que se acopla ao agente do widget
1092
+ * sem o widget conhecê-la (o segundo cérebro é uma extensão). Fusão com o que o host já passou:
1093
+ * - `customTools`: mescladas; a extensão que vem depois vence um nome repetido;
1094
+ * - `instructions.system`: concatenado; `getPageInstructions`: resultados concatenados;
1095
+ * - `hooks`: encadeados em ordem (primeiro os do host, depois os de cada extensão); o erro de um gancho
1096
+ * é registrado e NÃO derruba a tarefa; `transformPageContent` forma um pipeline.
1097
+ */
1098
+ export declare interface WidgetExtension {
1099
+ /** Nome, só para diagnóstico. */
1100
+ name?: string;
1101
+ customTools?: PageAgentConfig['customTools'];
1102
+ instructions?: {
1103
+ system?: string;
1104
+ getPageInstructions?: (url: string) => string | undefined | null;
1105
+ };
1106
+ hooks?: WidgetHooks;
1107
+ }
1108
+
1109
+ /** Ganchos do ciclo do agente (os mesmos do núcleo). Vários ganchos são encadeados em ordem. */
1110
+ export declare type WidgetHooks = Pick<PageAgentConfig, 'onBeforeStep' | 'onAfterStep' | 'onBeforeTask' | 'onAfterTask' | 'onDispose' | 'transformPageContent'>;
1111
+
1112
+ export declare type WidgetOptions = Omit<WidgetOptions_2, 'brain'> & {
1113
+ /** Liga o segundo cérebro (opt-in). Aceita as opções dele; o gateway só consegue enviar `true`/`false`. */
1114
+ brain?: boolean | BrainOptions;
1115
+ };
1116
+
1117
+ declare interface WidgetOptions_2 {
1026
1118
  /** Modelo. Ex.: "gpt-4o-mini". */
1027
1119
  model?: string;
1028
1120
  /** Endpoint OpenAI-compatible. */
@@ -1057,6 +1149,20 @@ export declare interface WidgetOptions {
1057
1149
  viewportExpansion?: number;
1058
1150
  /** Pergunta pela próxima tarefa ao concluir. @default true */
1059
1151
  promptForNextTask?: boolean;
1152
+ /** Ganchos do host (rodam antes dos das extensões). */
1153
+ hooks?: WidgetHooks;
1154
+ /** Extensões já prontas (síncronas). */
1155
+ extensions?: WidgetExtension[];
1156
+ /**
1157
+ * Chamada a cada vez que um agente é criado, DEPOIS de a config do gateway ter sido aplicada a `options`.
1158
+ * Serve para decidir extensões a partir de flags declarativas (`brain`, `debug`), que o gateway pode enviar
1159
+ * em JSON — o que não comporta funções.
1160
+ */
1161
+ resolveExtensions?: (options: WidgetOptions_2) => WidgetExtension[] | Promise<WidgetExtension[]>;
1162
+ /** Flag declarativa (o gateway pode enviá-la). Quem a interpreta é `resolveExtensions`; o widget só a repassa. */
1163
+ brain?: boolean;
1164
+ /** Flag declarativa de diagnóstico (idem). */
1165
+ debug?: boolean;
1060
1166
  /** Posição do botão-lançador. @default 'bottom-right' */
1061
1167
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
1062
1168
  /** Rótulo acessível do botão-lançador. @default 'Abrir assistente da página' */
@@ -1073,4 +1179,22 @@ export declare interface WidgetVoiceOptions extends VoiceOptions {
1073
1179
  speakSteps?: boolean;
1074
1180
  }
1075
1181
 
1182
+ /**
1183
+ * Política de escrita do segundo cérebro: o agente só altera dados quando a TAREFA pede.
1184
+ *
1185
+ * Por que existe: numa execução real o agente recebeu uma tarefa de localizar um registro e, por conta própria,
1186
+ * digitou texto inventado em formulários, clicou em "Salvar" e em "Criar", e disparou uma sincronização no
1187
+ * servidor. Ler e navegar são seguros; escrever num sistema em produção não é, e o modelo não distingue.
1188
+ *
1189
+ * O que é "escrita", sem inferência de modelo:
1190
+ * - digitar ou selecionar um valor num campo (`input_text`, `select_dropdown_option`);
1191
+ * - clicar num controle cujo NOME de acesso é um verbo de alteração (Salvar, Criar, Excluir, Atualizar, ...).
1192
+ * Clicar em menus, abas, links e botões comuns nunca é bloqueado.
1193
+ *
1194
+ * Quando é permitida: a tarefa contém um verbo de alteração (salvar, criar, excluir, ...); para digitar/selecionar também
1195
+ * basta um verbo de preenchimento (preencher, digitar, selecionar, ...) ou conter o próprio valor a escrever. Os verbos são uma lista fixa e pública (abaixo): a decisão é reproduzível e
1196
+ * não muda com a página. Modo `allow` desliga a política; `deny` torna o agente somente-leitura.
1197
+ */
1198
+ export declare type WritePolicyMode = "task-intent" | "allow" | "deny";
1199
+
1076
1200
  export { }
@@ -4558,7 +4558,66 @@ function positionCss(position) {
4558
4558
  return { bottom: "20px", right: "20px", top: "auto", left: "auto" };
4559
4559
  }
4560
4560
  }
4561
- function mountWidget(options = {}) {
4561
+ function logHookError(name, error2) {
4562
+ console.error(`[page-agent-widget] gancho ${name} falhou (a tarefa segue):`, error2);
4563
+ }
4564
+ function mergeExtensions(host, extensions) {
4565
+ const customTools = { ...host.customTools };
4566
+ for (const extension of extensions) Object.assign(customTools, extension.customTools);
4567
+ const system = [host.instructions?.system, ...extensions.map((e) => e.instructions?.system)].map((text) => text?.trim()).filter((text) => Boolean(text)).join("\n\n");
4568
+ const pageProviders = [host.instructions?.getPageInstructions, ...extensions.map((e) => e.instructions?.getPageInstructions)].filter(
4569
+ (fn) => typeof fn === "function"
4570
+ );
4571
+ const getPageInstructions = pageProviders.length ? (url) => {
4572
+ const parts = [];
4573
+ for (const provide of pageProviders) {
4574
+ try {
4575
+ const text = provide(url)?.trim();
4576
+ if (text) parts.push(text);
4577
+ } catch (error2) {
4578
+ logHookError("getPageInstructions", error2);
4579
+ }
4580
+ }
4581
+ return parts.join("\n\n") || void 0;
4582
+ } : void 0;
4583
+ const sources = [host.hooks, ...extensions.map((e) => e.hooks)].filter((h) => Boolean(h));
4584
+ const chain = (name) => {
4585
+ const fns = sources.map((source) => source[name]).filter((fn) => typeof fn === "function");
4586
+ if (!fns.length) return void 0;
4587
+ return (async (...args) => {
4588
+ for (const fn of fns) {
4589
+ try {
4590
+ await fn(...args);
4591
+ } catch (error2) {
4592
+ logHookError(String(name), error2);
4593
+ }
4594
+ }
4595
+ });
4596
+ };
4597
+ const transforms = sources.map((source) => source.transformPageContent).filter((fn) => typeof fn === "function");
4598
+ const transformPageContent = transforms.length ? async (content) => {
4599
+ let current = content;
4600
+ for (const transform of transforms) {
4601
+ try {
4602
+ current = await transform(current);
4603
+ } catch (error2) {
4604
+ logHookError("transformPageContent", error2);
4605
+ }
4606
+ }
4607
+ return current;
4608
+ } : void 0;
4609
+ return {
4610
+ customTools,
4611
+ instructions: system || getPageInstructions ? { ...system ? { system } : {}, ...getPageInstructions ? { getPageInstructions } : {} } : void 0,
4612
+ onBeforeStep: chain("onBeforeStep"),
4613
+ onAfterStep: chain("onAfterStep"),
4614
+ onBeforeTask: chain("onBeforeTask"),
4615
+ onAfterTask: chain("onAfterTask"),
4616
+ onDispose: chain("onDispose"),
4617
+ transformPageContent
4618
+ };
4619
+ }
4620
+ function mountWidget$1(options = {}) {
4562
4621
  const position = options.position ?? DEFAULTS.position;
4563
4622
  const launcherLabel = options.launcherLabel ?? DEFAULTS.launcherLabel;
4564
4623
  const open = options.open ?? DEFAULTS.open;
@@ -4574,7 +4633,7 @@ function mountWidget(options = {}) {
4574
4633
  const res = await fetch(options.configUrl, { headers: { accept: "application/json" } });
4575
4634
  if (!res.ok) throw new Error(`mountWidget: configUrl respondeu ${res.status} — o gateway está no ar?`);
4576
4635
  const server = await res.json();
4577
- for (const key of ["model", "language", "maxSteps", "promptForNextTask", "instructions", "voice"]) {
4636
+ for (const key of ["model", "language", "maxSteps", "promptForNextTask", "instructions", "voice", "brain", "debug"]) {
4578
4637
  const value = server[key];
4579
4638
  if (value !== void 0 && value !== null) {
4580
4639
  options[key] = value;
@@ -4598,6 +4657,8 @@ function mountWidget(options = {}) {
4598
4657
  options.configUrl ? "mountWidget: o gateway não enviou `model` e/ou falta `baseURL` no front. Confira AGENT_MODEL no gateway e a baseURL do widget." : "mountWidget: configure `model` e `baseURL` (config central do LLM) antes de abrir o agente."
4599
4658
  );
4600
4659
  }
4660
+ const resolved = options.resolveExtensions ? await options.resolveExtensions(options) : [];
4661
+ const merged = mergeExtensions(options, [...options.extensions ?? [], ...resolved]);
4601
4662
  agent = new PageAgent({
4602
4663
  model,
4603
4664
  baseURL,
@@ -4609,8 +4670,14 @@ function mountWidget(options = {}) {
4609
4670
  maxSteps: options.maxSteps ?? DEFAULTS.maxSteps,
4610
4671
  enableMask: options.enableMask ?? DEFAULTS.enableMask,
4611
4672
  viewportExpansion: options.viewportExpansion ?? DEFAULTS.viewportExpansion,
4612
- instructions: options.instructions,
4613
- customTools: options.customTools,
4673
+ instructions: merged.instructions,
4674
+ customTools: merged.customTools,
4675
+ onBeforeStep: merged.onBeforeStep,
4676
+ onAfterStep: merged.onAfterStep,
4677
+ onBeforeTask: merged.onBeforeTask,
4678
+ onAfterTask: merged.onAfterTask,
4679
+ onDispose: merged.onDispose,
4680
+ transformPageContent: merged.transformPageContent,
4614
4681
  promptForNextTask: options.promptForNextTask ?? DEFAULTS.promptForNextTask
4615
4682
  });
4616
4683
  wireVoiceOutput(agent, v);
@@ -4773,6 +4840,26 @@ function mountWidget(options = {}) {
4773
4840
  };
4774
4841
  return widget;
4775
4842
  }
4843
+ function mountWidget(options = {}) {
4844
+ const { brain: brainOption, ...rest } = options;
4845
+ const previous = rest.resolveExtensions;
4846
+ return mountWidget$1({
4847
+ ...rest,
4848
+ brain: Boolean(brainOption),
4849
+ resolveExtensions: async (resolved) => {
4850
+ const extensions = previous ? [...await previous(resolved)] : [];
4851
+ if (resolved.brain) {
4852
+ const { createBrainExtension } = await import("./brain-extension-DDuKTYrJ.js").then((n) => n.d);
4853
+ extensions.push(createBrainExtension(typeof brainOption === "object" ? brainOption : {}));
4854
+ }
4855
+ if (resolved.debug) {
4856
+ const { createDebugExtension } = await import("./debug-extension-D0P_sNkc.js");
4857
+ extensions.push(createDebugExtension());
4858
+ }
4859
+ return extensions;
4860
+ }
4861
+ });
4862
+ }
4776
4863
  export {
4777
4864
  PageAgent,
4778
4865
  PageAgentCore,