跳到正文

适用版本:Cowork 0.1.41 · 适用于所有 Cowork 用户

查看 Markdown

浏览器 ​

dozin.capabilities 里有 browser 时,Connector 或任务会得到 ctx.browser,用来读取和操作 Cowork 标签页里的网页。只能使用用户交出的标签页;写了 dozin.origins 时,还只能使用这些网站上的页面。

ctx.browser.adoptTab(tabId) ​

接管一个标签页。用户要求 Extension 接管某个页面时,Cowork 把 tabId 交给 Extension;Extension 不能自己挑选标签页。

名称类型必填说明
tabIdstring是Cowork 交过来的标签页

返回 Promise<{ tabId, url, documentId }>。页面每次加载新文档时 documentId 都会变。同一时间最多 8 个标签页。

js
const tab = await ctx.browser.adoptTab(tabId);
ctx.log(`watching ${tab.url}`);

ctx.browser.releaseTab(tabId) ​

交还标签页。它注入的脚本和音频会停止。

名称类型必填说明
tabIdstring是这个 Extension 接管的某个标签页

返回 Promise<void>。

js
await ctx.browser.releaseTab(tabId);

ctx.browser.evaluate(tabId, script) ​

在页面里运行一次脚本,并返回结果。

名称类型必填说明
tabIdstring是已接管的标签页
script.sourcestring是一个函数的源码,最多 64 KB;它接收 args
script.argsunknown否以 JSON 传入,不会拼接进源码

返回 Promise<unknown>:结果,以 JSON 形式,最多 64 KB。

js
const title = await ctx.browser.evaluate(tabId, { source: '(args) => document.title' });

ctx.browser.inject(tabId, script) ​

安装一个留在页面里、可以回传消息的脚本。

名称类型必填说明
tabIdstring是已接管的标签页
script.idstring是1–80 个字母、数字、_ 或 -;在这个标签页内唯一
script.sourcestring是一个函数 (args, { emit, onDispose }) => cleanup?,最多 64 KB;emit(data) 以 message 事件送达
script.argsunknown否以 JSON 传入

返回 Promise<void>。每个标签页最多 16 个脚本。

js
await ctx.browser.inject(tabId, {
  id: 'chat-watch',
  source: `(args, { emit }) => {
    const observer = new MutationObserver(() => emit({ count: document.querySelectorAll(args.selector).length }));
    observer.observe(document.body, { childList: true, subtree: true });
    return () => observer.disconnect();
  }`,
  args: { selector: '.message' }
});

ctx.browser.uninject(tabId, injectionId) ​

移除一个注入的脚本,并运行它的清理函数。

名称类型必填说明
tabIdstring是已接管的标签页
injectionIdstring是传给 inject 的 id

返回 Promise<void>。

js
await ctx.browser.uninject(tabId, 'chat-watch');

ctx.browser.captureAudio(tabId) ​

还需要 audio。开始采集标签页的声音。

名称类型必填说明
tabIdstring是已接管且已加载完成的标签页

返回 Promise<AudioStream>:

字段类型说明
tabId · url · documentId这个标签页,与 adoptTab 相同
streamIdstring这次采集
framesAsyncIterable<{ streamId, sequence, timestamp, sampleRate, channels, pcm: Float32Array }>声音,一块一块地送达
endedPromise采集结束时 settle
stop()() => Promise<void>停止采集

每个标签页同一时间只能有一个采集。

js
const stream = await ctx.browser.captureAudio(tabId);
for await (const chunk of stream.frames) handle(chunk.pcm, chunk.sampleRate);

ctx.browser.stopAudio(tabId) ​

停止这个标签页的采集。

名称类型必填说明
tabIdstring是正在采集的标签页

返回 Promise<void>。

js
await ctx.browser.stopAudio(tabId);

ctx.browser.onEvent(listener) ​

名称类型必填说明
listener(event) => void是Extension 的标签页每发生一个事件都会调用

返回 () => void,调用即停止监听。每个事件都带 tabId、url 和 documentId,以及一个 type:

type附加字段何时
url-changed · navigation-start · ready—页面跳转或加载完成
closed · crashed—标签页没了
injectedinjectionId安装了一个脚本
messageinjectionId、data注入的脚本调用了 emit(data)
errorcode标签页里有操作失败
audio-endedstreamId、lastSequence一次采集结束
js
const off = ctx.browser.onEvent((event) => {
  if (event.type === 'message') ctx.emit({ text: String(event.data.count) });
  if (event.type === 'closed') off();
});

错误 ​

这些函数以下列代码之一 reject:

代码含义
capability_denied没有声明 browser(或 audio)
invalid_tab · tab_not_granted · tab_not_owned标签页 id 无效、Cowork 没有交出这个标签页,或它已被交还
origin_not_allowed页面所在网站不在 dozin.origins 里
tab_limit · injection_limit超过 8 个标签页或 16 个脚本
tab_unavailable · document_not_ready · stale_document标签页已关闭、还在加载,或已加载了另一个页面
invalid_script · invalid_injection_id · injection_exists · invalid_json · result_too_large输入或输出无效
audio_already_started · audio_transport_unavailable · invalid_audio_request无法开始音频采集
session_closed · browser_operation_failedExtension 正在停止,或 Cowork 无法完成这次调用

相关 ​

适用于 Micromeet Cowork 0.1.41 · build 261111110020