agents 0.26.0 → 0.28.0
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 +8 -9
- package/dist/abortable-C1SpfVoi.js +21 -0
- package/dist/abortable-C1SpfVoi.js.map +1 -0
- package/dist/{agent-routing-0DR0Tk2v.d.ts → agent-routing-QDcchcQP.d.ts} +16 -16
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-YrATZJu2.d.ts → agent-tools-DHL2XI7u.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/ai-ahruGw7e.d.ts +239 -0
- package/dist/ai-sdk-Bdsf6mSA.js +2444 -0
- package/dist/ai-sdk-Bdsf6mSA.js.map +1 -0
- package/dist/apply-chunks-1FheRb9W.js +99 -0
- package/dist/apply-chunks-1FheRb9W.js.map +1 -0
- package/dist/broadcast-state-CEyI4uAK.js +69 -0
- package/dist/broadcast-state-CEyI4uAK.js.map +1 -0
- package/dist/browser/ai.d.ts +8 -227
- package/dist/browser/ai.js +259 -1
- package/dist/browser/ai.js.map +1 -0
- package/dist/browser/index.d.ts +56 -46
- package/dist/browser/index.js +4 -361
- package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
- package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +6 -5
- package/dist/browser/tools/ai-sdk.js.map +1 -0
- package/dist/browser/tools/pi.d.ts +111 -0
- package/dist/browser/tools/pi.js +119 -0
- package/dist/browser/tools/pi.js.map +1 -0
- package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
- package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
- package/dist/browser/tools/tanstack-ai.js.map +1 -0
- package/dist/browser-CEdNlsaD.js +481 -0
- package/dist/browser-CEdNlsaD.js.map +1 -0
- package/dist/{browser-DE3d-RLk.d.ts → browser-D30VlpcA.d.ts} +63 -37
- package/dist/{browser-tool-CQ10e6Kj.js → browser-tool-4iomavs_.js} +198 -62
- package/dist/browser-tool-4iomavs_.js.map +1 -0
- package/dist/{browser-tool-DuNdlwZ9.d.ts → browser-tool-vtrPOV8e.d.ts} +25 -6
- package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
- package/dist/capability-DBAKc6UZ.js.map +1 -0
- package/dist/{capability-runner-DBAnGr6L.d.ts → capability-runner-BiVUtjqC.d.ts} +9 -7
- package/dist/channel-Bak_6zDP.d.ts +333 -0
- package/dist/chat/index.d.ts +11 -9
- package/dist/chat/index.js +5 -194
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +2 -4
- package/dist/chat/react.js +3 -1
- package/dist/chat/react.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/chat-sdk/index.js +1 -1
- package/dist/cli.js +144 -0
- package/dist/{client-je3koD9Z.d.ts → client-BGIQKJhX.d.ts} +2 -2
- package/dist/{client-fyQrLGkD.js → client-BnYbNT3z.js} +29 -5
- package/dist/client-BnYbNT3z.js.map +1 -0
- package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
- package/dist/client.d.ts +1 -1
- package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
- package/dist/connector-CtZylXdk.js.map +1 -0
- package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
- package/dist/conversations-FjHDRZyD.d.ts +192 -0
- package/dist/{current-agent-vAk_5JMt.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/daemon-core-Buubj-y1.js +481 -0
- package/dist/daemon-core-Buubj-y1.js.map +1 -0
- package/dist/daemon-core-CbohVPAu.d.ts +132 -0
- package/dist/{do-oauth-client-provider-Tmf1vgKz.d.ts → do-oauth-client-provider-DfsUcpc3.d.ts} +7 -1
- package/dist/{durable-object-lifecycle-HhgOMWq9.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
- package/dist/{channels/email.d.ts → experimental/channels/email/index.d.ts} +25 -12
- package/dist/{channels/email.js → experimental/channels/email/index.js} +13 -35
- package/dist/experimental/channels/email/index.js.map +1 -0
- package/dist/experimental/channels/index.d.ts +270 -0
- package/dist/experimental/channels/index.js +1186 -0
- package/dist/experimental/channels/index.js.map +1 -0
- package/dist/{channels/slack.d.ts → experimental/channels/slack/index.d.ts} +19 -9
- package/dist/experimental/channels/slack/index.js +267 -0
- package/dist/experimental/channels/slack/index.js.map +1 -0
- package/dist/{channels/telegram.d.ts → experimental/channels/telegram/index.d.ts} +19 -9
- package/dist/experimental/channels/telegram/index.js +198 -0
- package/dist/experimental/channels/telegram/index.js.map +1 -0
- package/dist/experimental/channels/web/ai-sdk.d.ts +55 -0
- package/dist/experimental/channels/web/ai-sdk.js +266 -0
- package/dist/experimental/channels/web/ai-sdk.js.map +1 -0
- package/dist/experimental/channels/web/client.d.ts +97 -0
- package/dist/experimental/channels/web/client.js +349 -0
- package/dist/experimental/channels/web/client.js.map +1 -0
- package/dist/experimental/channels/web/index.d.ts +189 -0
- package/dist/experimental/channels/web/index.js +332 -0
- package/dist/experimental/channels/web/index.js.map +1 -0
- package/dist/gateway-BFO6vRDn.d.ts +100 -0
- package/dist/handle-zAzh0UW2.d.ts +460 -0
- package/dist/harness/ai-sdk/index.d.ts +175 -0
- package/dist/harness/ai-sdk/index.js +605 -0
- package/dist/harness/ai-sdk/index.js.map +1 -0
- package/dist/harness/container/daemon/index.d.ts +76 -0
- package/dist/harness/container/daemon/index.js +3 -0
- package/dist/harness/container/index.d.ts +740 -0
- package/dist/harness/container/index.js +2152 -0
- package/dist/harness/container/index.js.map +1 -0
- package/dist/harness/container/runtime/index.d.ts +144 -0
- package/dist/harness/container/runtime/index.js +1082 -0
- package/dist/harness/container/runtime/index.js.map +1 -0
- package/dist/harness/opencode/index.d.ts +369 -0
- package/dist/harness/opencode/index.js +1072 -0
- package/dist/harness/opencode/index.js.map +1 -0
- package/dist/harness/pi/index.d.ts +3 -2
- package/dist/harness/pi/index.js +3 -3
- package/dist/harness/store/index.d.ts +24 -0
- package/dist/harness/store/index.js +2 -0
- package/dist/harness/think/index.d.ts +821 -0
- package/dist/harness/think/index.js +2721 -0
- package/dist/harness/think/index.js.map +1 -0
- package/dist/harness-B6B9S3rb.d.ts +203 -0
- package/dist/{images-iiTDSyRu.js → images-Ce9SCu3X.js} +2 -248
- package/dist/images-Ce9SCu3X.js.map +1 -0
- package/dist/{index-BreL0YrQ.d.ts → index-BEL3ZV-s.d.ts} +2 -6
- package/dist/index-CBt8oRJt.d.ts +198 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/ingress-EFbrS547.js +9 -0
- package/dist/ingress-EFbrS547.js.map +1 -0
- package/dist/input-schema-BQykTEp_.js +20 -0
- package/dist/input-schema-BQykTEp_.js.map +1 -0
- package/dist/input-schema-D2QAtHZH.js +23 -0
- package/dist/input-schema-D2QAtHZH.js.map +1 -0
- package/dist/internal-kmw70xwR.js +46 -0
- package/dist/internal-kmw70xwR.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +3 -3
- package/dist/lifecycle/index.js +2 -2
- package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
- package/dist/lifecycle-DGorpAmA.js.map +1 -0
- package/dist/mcp/client/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/client/do-oauth-client-provider.js +9 -0
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/client/index.d.ts +1 -1
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/client/x402.d.ts +35 -4
- package/dist/mcp/client/x402.js +24 -3
- package/dist/mcp/client/x402.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/models/ai-sdk/index.d.ts +16 -14
- package/dist/models/ai-sdk/index.js +1 -2442
- package/dist/models/opencode/index.d.ts +65 -0
- package/dist/models/opencode/index.js +285 -0
- package/dist/models/opencode/index.js.map +1 -0
- package/dist/models/pi-ai/index.d.ts +9 -7
- package/dist/models/pi-ai/index.js +2 -1
- package/dist/models/pi-ai/index.js.map +1 -1
- package/dist/options-CiIsJHXR.d.ts +130 -0
- package/dist/protocol-BEgrJYC5.d.ts +331 -0
- package/dist/protocol-CukuI73M.d.ts +386 -0
- package/dist/protocol-cOklVBBD.js +227 -0
- package/dist/protocol-cOklVBBD.js.map +1 -0
- package/dist/{protocol-kHsr-f0X.js → protocol-eXeJxhgu.js} +2 -67
- package/dist/protocol-eXeJxhgu.js.map +1 -0
- package/dist/protocol-y2sSY584.js +148 -0
- package/dist/protocol-y2sSY584.js.map +1 -0
- package/dist/queue/index.d.ts +1 -1
- package/dist/queue/index.js +1 -1
- package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
- package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/routing/index.d.ts +2 -2
- package/dist/routing/index.js +1 -1
- package/dist/{scheduler-RdACNXDP.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
- package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
- package/dist/scheduler-FIHv2-kJ.js.map +1 -0
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/session-store-Do4xkDcf.js +606 -0
- package/dist/session-store-Do4xkDcf.js.map +1 -0
- package/dist/session-store-DoPY12xM.d.ts +383 -0
- package/dist/sessions/index.d.ts +11 -434
- package/dist/sessions/index.js +1 -2271
- package/dist/sessions-_vN5BEZX.js +2272 -0
- package/dist/sessions-_vN5BEZX.js.map +1 -0
- package/dist/settings-C45hDliX.js +253 -0
- package/dist/settings-C45hDliX.js.map +1 -0
- package/dist/{transport-PfFnt-Ld.d.ts → settings-NgGwF7Qt.d.ts} +14 -208
- package/dist/{src-BZeu-SCD.js → src-CQxJFv4l.js} +8 -8
- package/dist/src-CQxJFv4l.js.map +1 -0
- package/dist/stall-watchdog-BpRF2uwG.js +195 -0
- package/dist/stall-watchdog-BpRF2uwG.js.map +1 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -3
- package/dist/state/index.js.map +1 -1
- package/dist/store-BKM4Xm9M.d.ts +332 -0
- package/dist/store-CslVzfN7.js +458 -0
- package/dist/store-CslVzfN7.js.map +1 -0
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/{streams-DW-UCOUc.js → streams-lsHMJhRW.js} +17 -4
- package/dist/streams-lsHMJhRW.js.map +1 -0
- package/dist/{streams-Cmkj9QfW.d.ts → streams-vrCtbUIn.d.ts} +2 -2
- package/dist/sub-routing.d.ts +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/{tasks-68DESxf0.js → tasks-BN_5AWqI.js} +3 -2
- package/dist/tasks-BN_5AWqI.js.map +1 -0
- package/dist/{tasks-9YxYtByh.d.ts → tasks-E89KdwkS.d.ts} +2 -2
- package/dist/tool-CTp72Jb_.d.ts +278 -0
- package/dist/tool-CxKsvxjm.js +1126 -0
- package/dist/tool-CxKsvxjm.js.map +1 -0
- package/dist/tool-DoVberpN.d.ts +301 -0
- package/dist/tool-cQRkwSZZ.js +410 -0
- package/dist/tool-cQRkwSZZ.js.map +1 -0
- package/dist/tool-helpers-O5BDVEAY.js +58 -0
- package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
- package/dist/transport-k2mFrtL8.d.ts +200 -0
- package/dist/turns-DCV3ycDl.js +317 -0
- package/dist/turns-DCV3ycDl.js.map +1 -0
- package/dist/voice/client.js +1 -1
- package/dist/voice/index.d.ts +2 -2
- package/dist/voice/index.js +1 -1
- package/dist/web/fetch/index.d.ts +89 -0
- package/dist/web/fetch/index.js +20 -0
- package/dist/web/fetch/index.js.map +1 -0
- package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
- package/dist/web/fetch/tools/ai-sdk.js +47 -0
- package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
- package/dist/web/fetch/tools/pi.d.ts +84 -0
- package/dist/web/fetch/tools/pi.js +88 -0
- package/dist/web/fetch/tools/pi.js.map +1 -0
- package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
- package/dist/web/fetch/tools/tanstack-ai.js +45 -0
- package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
- package/dist/web/search/index.d.ts +58 -0
- package/dist/web/search/index.js +2 -0
- package/dist/web/search/tools/ai-sdk.d.ts +77 -0
- package/dist/web/search/tools/ai-sdk.js +46 -0
- package/dist/web/search/tools/ai-sdk.js.map +1 -0
- package/dist/web/search/tools/pi.d.ts +82 -0
- package/dist/web/search/tools/pi.js +89 -0
- package/dist/web/search/tools/pi.js.map +1 -0
- package/dist/web/search/tools/tanstack-ai.d.ts +71 -0
- package/dist/web/search/tools/tanstack-ai.js +46 -0
- package/dist/web/search/tools/tanstack-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +12 -296
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-Ci-LZFHH.js → websockets-C3zy8YR0.js} +20 -8
- package/dist/websockets-C3zy8YR0.js.map +1 -0
- package/dist/{wire-types-CrjKvDyi.d.ts → wire-types-Cv0iwjk5.d.ts} +3 -51
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.js +1 -1
- package/docs/browse-the-web.md +29 -1
- package/docs/fetch-the-web.md +276 -0
- package/docs/harnesses/pi.md +25 -0
- package/docs/harnesses/think.md +215 -0
- package/docs/index.md +99 -75
- package/docs/lifecycle.md +42 -3
- package/docs/queue.md +2 -3
- package/docs/scheduling.md +2 -6
- package/docs/search-the-web.md +135 -0
- package/package.json +148 -44
- package/dist/ai-fm7xx1BK.js +0 -312
- package/dist/ai-fm7xx1BK.js.map +0 -1
- package/dist/browser/ai-sdk.js.map +0 -1
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/tanstack-ai.js.map +0 -1
- package/dist/browser-tool-CQ10e6Kj.js.map +0 -1
- package/dist/capability-B4WbF81e.js.map +0 -1
- package/dist/channel-Bnm4S7T2.d.ts +0 -491
- package/dist/channels/ai-sdk.d.ts +0 -46
- package/dist/channels/ai-sdk.js +0 -120
- package/dist/channels/ai-sdk.js.map +0 -1
- package/dist/channels/email.js.map +0 -1
- package/dist/channels/index.d.ts +0 -233
- package/dist/channels/index.js +0 -608
- package/dist/channels/index.js.map +0 -1
- package/dist/channels/slack.js +0 -614
- package/dist/channels/slack.js.map +0 -1
- package/dist/channels/tanstack-ai.d.ts +0 -39
- package/dist/channels/tanstack-ai.js +0 -17
- package/dist/channels/tanstack-ai.js.map +0 -1
- package/dist/channels/telegram.js +0 -427
- package/dist/channels/telegram.js.map +0 -1
- package/dist/channels/voice.d.ts +0 -45
- package/dist/channels/voice.js +0 -122
- package/dist/channels/voice.js.map +0 -1
- package/dist/client-fyQrLGkD.js.map +0 -1
- package/dist/connector-58XDGvc3.js.map +0 -1
- package/dist/images-iiTDSyRu.js.map +0 -1
- package/dist/index-BB0kqhIz.d.ts +0 -101
- package/dist/ingress-BfetZbMO.js +0 -83
- package/dist/ingress-BfetZbMO.js.map +0 -1
- package/dist/internal-CYlgHl1l.js +0 -59
- package/dist/internal-CYlgHl1l.js.map +0 -1
- package/dist/lifecycle-CFu6OV03.js.map +0 -1
- package/dist/models/ai-sdk/index.js.map +0 -1
- package/dist/protocol-kHsr-f0X.js.map +0 -1
- package/dist/scheduler-DZ3xQfeK.js.map +0 -1
- package/dist/sessions/index.js.map +0 -1
- package/dist/src-BZeu-SCD.js.map +0 -1
- package/dist/streams-DW-UCOUc.js.map +0 -1
- package/dist/surface-bZZJqBka.js +0 -17
- package/dist/surface-bZZJqBka.js.map +0 -1
- package/dist/tasks-68DESxf0.js.map +0 -1
- package/dist/tool-schema-CBjGPrsQ.js +0 -31
- package/dist/tool-schema-CBjGPrsQ.js.map +0 -1
- package/dist/websockets-Ci-LZFHH.js.map +0 -1
- package/docs/channels.md +0 -323
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
a as BrowserSource,
|
|
3
|
+
i as BrowserNewTab,
|
|
4
|
+
n as BrowserToolOptions,
|
|
5
|
+
r as BrowserToolOutput,
|
|
6
|
+
t as BrowserToolInput
|
|
7
|
+
} from "../../browser-tool-vtrPOV8e.js";
|
|
8
|
+
import { Type } from "@earendil-works/pi-ai";
|
|
9
|
+
import { ToolExecutionApi, ToolRegistration } from "@earendil-works/pi-durable";
|
|
10
|
+
|
|
11
|
+
//#region src/browser/tools/pi.d.ts
|
|
12
|
+
interface PiBrowserToolOptions<TName extends string = "browser"> extends Omit<
|
|
13
|
+
BrowserToolOptions,
|
|
14
|
+
"scope"
|
|
15
|
+
> {
|
|
16
|
+
/** The tool's name. Default `"browser"`. */
|
|
17
|
+
name?: TName;
|
|
18
|
+
/**
|
|
19
|
+
* Which calls share an active tab: a string for every call, or a function
|
|
20
|
+
* of the call. Defaults to `conversation:<id>` for the calling
|
|
21
|
+
* conversation, so each
|
|
22
|
+
* conversation (and each fork or subagent) on the Durable Object keeps its
|
|
23
|
+
* own tab, while cookies and logins stay shared.
|
|
24
|
+
*/
|
|
25
|
+
scope?: string | ((api: ToolExecutionApi) => string);
|
|
26
|
+
}
|
|
27
|
+
declare const browserToolParameters: Type.TObject<{
|
|
28
|
+
code: Type.TString;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* What a UI can show about a run without reading the content: the run's
|
|
32
|
+
* outcome and what happened to the browser.
|
|
33
|
+
*/
|
|
34
|
+
type PiBrowserToolDetails = {
|
|
35
|
+
executionId: string;
|
|
36
|
+
status: BrowserToolOutput["status"];
|
|
37
|
+
restarted?: true;
|
|
38
|
+
newTabs?: {
|
|
39
|
+
targetId: string;
|
|
40
|
+
url?: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
}[];
|
|
43
|
+
};
|
|
44
|
+
type PiBrowserTool<TName extends string = "browser"> = ToolRegistration<
|
|
45
|
+
typeof browserToolParameters,
|
|
46
|
+
PiBrowserToolDetails
|
|
47
|
+
> & {
|
|
48
|
+
readonly name: TName;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Create a pi-durable tool that lets the model drive a persistent browser
|
|
52
|
+
* with JavaScript and the Chrome DevTools Protocol.
|
|
53
|
+
*
|
|
54
|
+
* Works like `browserTool` in `agents/browser/ai-sdk`: tabs, cookies, and
|
|
55
|
+
* logins carry over between runs, `sessionId: "active"` addresses the tab the
|
|
56
|
+
* model last worked in, and a replaced browser is reported as
|
|
57
|
+
* `restarted: true`. A returned screenshot comes back as an image part that
|
|
58
|
+
* the model sees, when its model accepts images.
|
|
59
|
+
*
|
|
60
|
+
* Each conversation gets its own active tab (see
|
|
61
|
+
* {@link PiBrowserToolOptions.scope}). A conversation's calls run one at a
|
|
62
|
+
* time, since they share its tab, and the tool doesn't rerun after an
|
|
63
|
+
* eviction (its code may have clicked or
|
|
64
|
+
* submitted something): pi gives the model an interrupted result instead.
|
|
65
|
+
* Pass `ctx` unless the tool is built inside an Agent.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* import { Browser, browserRun } from "agents/browser";
|
|
70
|
+
* import { browserTool } from "agents/browser/pi";
|
|
71
|
+
*
|
|
72
|
+
* export class MyAgent extends DurableObject<Env> {
|
|
73
|
+
* readonly browser = new Browser({ provider: browserRun(this.env.BROWSER) });
|
|
74
|
+
* readonly registry = createRegistry();
|
|
75
|
+
* readonly harness = new PiHarness({
|
|
76
|
+
* harness: ({ storage, context }) => {
|
|
77
|
+
* this.registry.install({
|
|
78
|
+
* name: "browser",
|
|
79
|
+
* tools: [
|
|
80
|
+
* browserTool({
|
|
81
|
+
* ctx: this.ctx,
|
|
82
|
+
* browser: this.browser,
|
|
83
|
+
* loader: this.env.LOADER
|
|
84
|
+
* })
|
|
85
|
+
* ]
|
|
86
|
+
* });
|
|
87
|
+
* return Harness.open(storage, { models, registry: this.registry }, context);
|
|
88
|
+
* }
|
|
89
|
+
* });
|
|
90
|
+
* readonly lifecycle = Lifecycle.install(this)
|
|
91
|
+
* .use(this.browser)
|
|
92
|
+
* .use(this.harness);
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function browserTool<TName extends string = "browser">(
|
|
97
|
+
options: PiBrowserToolOptions<TName>
|
|
98
|
+
): PiBrowserTool<TName>;
|
|
99
|
+
//#endregion
|
|
100
|
+
export {
|
|
101
|
+
type BrowserNewTab,
|
|
102
|
+
type BrowserSource,
|
|
103
|
+
type BrowserToolInput,
|
|
104
|
+
type BrowserToolOptions,
|
|
105
|
+
type BrowserToolOutput,
|
|
106
|
+
PiBrowserTool,
|
|
107
|
+
PiBrowserToolDetails,
|
|
108
|
+
PiBrowserToolOptions,
|
|
109
|
+
browserTool
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=pi.d.ts.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { n as browserScreenshotOutput, t as browserExecuteModelOutput } from "../../tool-helpers-O5BDVEAY.js";
|
|
2
|
+
import { n as createBrowserToolCore } from "../../browser-tool-4iomavs_.js";
|
|
3
|
+
import { Type } from "@earendil-works/pi-ai";
|
|
4
|
+
//#region src/browser/tools/pi.ts
|
|
5
|
+
const browserToolParameters = Type.Object({ code: Type.String({ description: "An async arrow function that drives the browser with `cdp`" }) });
|
|
6
|
+
function details(output) {
|
|
7
|
+
return {
|
|
8
|
+
executionId: output.executionId,
|
|
9
|
+
status: output.status,
|
|
10
|
+
...output.restarted ? { restarted: true } : {},
|
|
11
|
+
...output.newTabs ? { newTabs: output.newTabs.map((tab) => ({
|
|
12
|
+
targetId: tab.targetId,
|
|
13
|
+
...tab.url === void 0 ? {} : { url: tab.url },
|
|
14
|
+
...tab.title === void 0 ? {} : { title: tab.title }
|
|
15
|
+
})) } : {}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function text(value) {
|
|
19
|
+
return {
|
|
20
|
+
type: "text",
|
|
21
|
+
text: typeof value === "string" ? value : JSON.stringify(value)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The tool result pi stores and sends: the model projection of the run as
|
|
26
|
+
* JSON (no `calls` log, bounded `logs`), and a screenshot as an image part
|
|
27
|
+
* after it. pi-ai only sends the image to models that accept images.
|
|
28
|
+
*/
|
|
29
|
+
function browserToolResult(output) {
|
|
30
|
+
const isError = output.status === "error";
|
|
31
|
+
const screenshot = browserScreenshotOutput(output);
|
|
32
|
+
if (!screenshot) return {
|
|
33
|
+
content: [text(browserExecuteModelOutput(output).value)],
|
|
34
|
+
details: details(output),
|
|
35
|
+
...isError ? { isError } : {}
|
|
36
|
+
};
|
|
37
|
+
const bytes = Math.floor(screenshot.data.length * 3 / 4).toLocaleString();
|
|
38
|
+
const summary = browserExecuteModelOutput({
|
|
39
|
+
...output,
|
|
40
|
+
result: `Screenshot attached as an image (${screenshot.mediaType}, approximately ${bytes} bytes). If you can't see it, read the page with Runtime.evaluate instead.`
|
|
41
|
+
}).value;
|
|
42
|
+
const image = {
|
|
43
|
+
type: "image",
|
|
44
|
+
data: screenshot.data,
|
|
45
|
+
mimeType: screenshot.mediaType
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
content: [text(summary), image],
|
|
49
|
+
details: details(output)
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function conversationScope(api) {
|
|
53
|
+
return `conversation:${api.conversationId}`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a pi-durable tool that lets the model drive a persistent browser
|
|
57
|
+
* with JavaScript and the Chrome DevTools Protocol.
|
|
58
|
+
*
|
|
59
|
+
* Works like `browserTool` in `agents/browser/ai-sdk`: tabs, cookies, and
|
|
60
|
+
* logins carry over between runs, `sessionId: "active"` addresses the tab the
|
|
61
|
+
* model last worked in, and a replaced browser is reported as
|
|
62
|
+
* `restarted: true`. A returned screenshot comes back as an image part that
|
|
63
|
+
* the model sees, when its model accepts images.
|
|
64
|
+
*
|
|
65
|
+
* Each conversation gets its own active tab (see
|
|
66
|
+
* {@link PiBrowserToolOptions.scope}). A conversation's calls run one at a
|
|
67
|
+
* time, since they share its tab, and the tool doesn't rerun after an
|
|
68
|
+
* eviction (its code may have clicked or
|
|
69
|
+
* submitted something): pi gives the model an interrupted result instead.
|
|
70
|
+
* Pass `ctx` unless the tool is built inside an Agent.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { Browser, browserRun } from "agents/browser";
|
|
75
|
+
* import { browserTool } from "agents/browser/pi";
|
|
76
|
+
*
|
|
77
|
+
* export class MyAgent extends DurableObject<Env> {
|
|
78
|
+
* readonly browser = new Browser({ provider: browserRun(this.env.BROWSER) });
|
|
79
|
+
* readonly registry = createRegistry();
|
|
80
|
+
* readonly harness = new PiHarness({
|
|
81
|
+
* harness: ({ storage, context }) => {
|
|
82
|
+
* this.registry.install({
|
|
83
|
+
* name: "browser",
|
|
84
|
+
* tools: [
|
|
85
|
+
* browserTool({
|
|
86
|
+
* ctx: this.ctx,
|
|
87
|
+
* browser: this.browser,
|
|
88
|
+
* loader: this.env.LOADER
|
|
89
|
+
* })
|
|
90
|
+
* ]
|
|
91
|
+
* });
|
|
92
|
+
* return Harness.open(storage, { models, registry: this.registry }, context);
|
|
93
|
+
* }
|
|
94
|
+
* });
|
|
95
|
+
* readonly lifecycle = Lifecycle.install(this)
|
|
96
|
+
* .use(this.browser)
|
|
97
|
+
* .use(this.harness);
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
function browserTool(options) {
|
|
102
|
+
const { scope = conversationScope, ...coreOptions } = options;
|
|
103
|
+
const core = createBrowserToolCore(coreOptions, { screenshotHint: "To see a screenshot, return { type: 'browser_screenshot', mediaType, data } with data from Page.captureScreenshot and mediaType 'image/png', or 'image/jpeg' if you captured with format: 'jpeg'. The image is attached to the result." });
|
|
104
|
+
return {
|
|
105
|
+
name: options.name ?? "browser",
|
|
106
|
+
description: core.description,
|
|
107
|
+
parameters: browserToolParameters,
|
|
108
|
+
executionMode: "sequential",
|
|
109
|
+
replay: "unsafe",
|
|
110
|
+
async execute(args, api) {
|
|
111
|
+
const callScope = typeof scope === "string" ? scope : scope(api);
|
|
112
|
+
return browserToolResult(await core.execute({ code: args.code }, callScope));
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
export { browserTool };
|
|
118
|
+
|
|
119
|
+
//# sourceMappingURL=pi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.js","names":[],"sources":["../../../src/browser/tools/pi.ts"],"sourcesContent":["import {\n Type,\n type ImageContent,\n type TextContent\n} from \"@earendil-works/pi-ai\";\nimport type {\n ToolExecutionApi,\n ToolExecutionResult,\n ToolRegistration\n} from \"@earendil-works/pi-durable\";\nimport {\n createBrowserToolCore,\n type BrowserToolOptions,\n type BrowserToolOutput\n} from \"../browser-tool\";\nimport type { BrowserNewTab } from \"../session-connector\";\nimport {\n browserExecuteModelOutput,\n browserScreenshotOutput\n} from \"../tool-helpers\";\n\nexport type {\n BrowserToolInput,\n BrowserToolOptions,\n BrowserToolOutput\n} from \"../browser-tool\";\nexport type { BrowserNewTab, BrowserSource } from \"../session-connector\";\n\nexport interface PiBrowserToolOptions<\n TName extends string = \"browser\"\n> extends Omit<BrowserToolOptions, \"scope\"> {\n /** The tool's name. Default `\"browser\"`. */\n name?: TName;\n /**\n * Which calls share an active tab: a string for every call, or a function\n * of the call. Defaults to `conversation:<id>` for the calling\n * conversation, so each\n * conversation (and each fork or subagent) on the Durable Object keeps its\n * own tab, while cookies and logins stay shared.\n */\n scope?: string | ((api: ToolExecutionApi) => string);\n}\n\nconst browserToolParameters = Type.Object({\n code: Type.String({\n description: \"An async arrow function that drives the browser with `cdp`\"\n })\n});\n\n/**\n * What a UI can show about a run without reading the content: the run's\n * outcome and what happened to the browser.\n */\nexport type PiBrowserToolDetails = {\n executionId: string;\n status: BrowserToolOutput[\"status\"];\n restarted?: true;\n newTabs?: { targetId: string; url?: string; title?: string }[];\n};\n\nexport type PiBrowserTool<TName extends string = \"browser\"> = ToolRegistration<\n typeof browserToolParameters,\n PiBrowserToolDetails\n> & {\n readonly name: TName;\n};\n\nfunction details(output: BrowserToolOutput): PiBrowserToolDetails {\n return {\n executionId: output.executionId,\n status: output.status,\n ...(output.restarted ? { restarted: true as const } : {}),\n ...(output.newTabs\n ? {\n newTabs: output.newTabs.map((tab: BrowserNewTab) => ({\n targetId: tab.targetId,\n ...(tab.url === undefined ? {} : { url: tab.url }),\n ...(tab.title === undefined ? {} : { title: tab.title })\n }))\n }\n : {})\n };\n}\n\nfunction text(value: unknown): TextContent {\n return {\n type: \"text\",\n text: typeof value === \"string\" ? value : JSON.stringify(value)\n };\n}\n\n/**\n * The tool result pi stores and sends: the model projection of the run as\n * JSON (no `calls` log, bounded `logs`), and a screenshot as an image part\n * after it. pi-ai only sends the image to models that accept images.\n */\nfunction browserToolResult(\n output: BrowserToolOutput\n): ToolExecutionResult<PiBrowserToolDetails> {\n const isError = output.status === \"error\";\n const screenshot = browserScreenshotOutput(output);\n if (!screenshot) {\n return {\n content: [text(browserExecuteModelOutput(output).value)],\n details: details(output),\n ...(isError ? { isError } : {})\n };\n }\n\n // No size check: a screenshot comes from one cdp.send result, which\n // codemode caps at 1 MB, well under what model providers accept.\n const bytes = Math.floor((screenshot.data.length * 3) / 4).toLocaleString();\n // Keep the rest of the result (status, restarted, notice, newTabs) around\n // the sentence that replaces the screenshot.\n const summary = browserExecuteModelOutput({\n ...output,\n result: `Screenshot attached as an image (${screenshot.mediaType}, approximately ${bytes} bytes). If you can't see it, read the page with Runtime.evaluate instead.`\n }).value;\n const image: ImageContent = {\n type: \"image\",\n data: screenshot.data,\n mimeType: screenshot.mediaType\n };\n return {\n content: [text(summary), image],\n details: details(output)\n };\n}\n\nfunction conversationScope(api: ToolExecutionApi): string {\n return `conversation:${api.conversationId}`;\n}\n\n/**\n * Create a pi-durable tool that lets the model drive a persistent browser\n * with JavaScript and the Chrome DevTools Protocol.\n *\n * Works like `browserTool` in `agents/browser/ai-sdk`: tabs, cookies, and\n * logins carry over between runs, `sessionId: \"active\"` addresses the tab the\n * model last worked in, and a replaced browser is reported as\n * `restarted: true`. A returned screenshot comes back as an image part that\n * the model sees, when its model accepts images.\n *\n * Each conversation gets its own active tab (see\n * {@link PiBrowserToolOptions.scope}). A conversation's calls run one at a\n * time, since they share its tab, and the tool doesn't rerun after an\n * eviction (its code may have clicked or\n * submitted something): pi gives the model an interrupted result instead.\n * Pass `ctx` unless the tool is built inside an Agent.\n *\n * @example\n * ```ts\n * import { Browser, browserRun } from \"agents/browser\";\n * import { browserTool } from \"agents/browser/pi\";\n *\n * export class MyAgent extends DurableObject<Env> {\n * readonly browser = new Browser({ provider: browserRun(this.env.BROWSER) });\n * readonly registry = createRegistry();\n * readonly harness = new PiHarness({\n * harness: ({ storage, context }) => {\n * this.registry.install({\n * name: \"browser\",\n * tools: [\n * browserTool({\n * ctx: this.ctx,\n * browser: this.browser,\n * loader: this.env.LOADER\n * })\n * ]\n * });\n * return Harness.open(storage, { models, registry: this.registry }, context);\n * }\n * });\n * readonly lifecycle = Lifecycle.install(this)\n * .use(this.browser)\n * .use(this.harness);\n * }\n * ```\n */\nexport function browserTool<TName extends string = \"browser\">(\n options: PiBrowserToolOptions<TName>\n): PiBrowserTool<TName> {\n const { scope = conversationScope, ...coreOptions } = options;\n const core = createBrowserToolCore(coreOptions, {\n screenshotHint:\n \"To see a screenshot, return { type: 'browser_screenshot', mediaType, data } with data from Page.captureScreenshot and mediaType 'image/png', or 'image/jpeg' if you captured with format: 'jpeg'. The image is attached to the result.\"\n });\n return {\n name: options.name ?? (\"browser\" as TName),\n description: core.description,\n parameters: browserToolParameters,\n // A conversation's calls share its tab, so they must not interleave.\n executionMode: \"sequential\",\n // The code may have clicked or submitted something; don't run it twice.\n replay: \"unsafe\",\n async execute(args, api) {\n const callScope = typeof scope === \"string\" ? scope : scope(api);\n return browserToolResult(\n await core.execute({ code: args.code }, callScope)\n );\n }\n };\n}\n"],"mappings":";;;;AA2CA,MAAM,wBAAwB,KAAK,OAAO,EACxC,MAAM,KAAK,OAAO,EAChB,aAAa,6DACf,CAAC,EACH,CAAC;AAoBD,SAAS,QAAQ,QAAiD;CAChE,OAAO;EACL,aAAa,OAAO;EACpB,QAAQ,OAAO;EACf,GAAI,OAAO,YAAY,EAAE,WAAW,KAAc,IAAI,CAAC;EACvD,GAAI,OAAO,UACP,EACE,SAAS,OAAO,QAAQ,KAAK,SAAwB;GACnD,UAAU,IAAI;GACd,GAAI,IAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI;GAChD,GAAI,IAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,IAAI,MAAM;EACxD,EAAE,EACJ,IACA,CAAC;CACP;AACF;AAEA,SAAS,KAAK,OAA6B;CACzC,OAAO;EACL,MAAM;EACN,MAAM,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;CAChE;AACF;;;;;;AAOA,SAAS,kBACP,QAC2C;CAC3C,MAAM,UAAU,OAAO,WAAW;CAClC,MAAM,aAAa,wBAAwB,MAAM;CACjD,IAAI,CAAC,YACH,OAAO;EACL,SAAS,CAAC,KAAK,0BAA0B,MAAM,CAAC,CAAC,KAAK,CAAC;EACvD,SAAS,QAAQ,MAAM;EACvB,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;CAC/B;CAKF,MAAM,QAAQ,KAAK,MAAO,WAAW,KAAK,SAAS,IAAK,CAAC,CAAC,CAAC,eAAe;CAG1E,MAAM,UAAU,0BAA0B;EACxC,GAAG;EACH,QAAQ,oCAAoC,WAAW,UAAU,kBAAkB,MAAM;CAC3F,CAAC,CAAC,CAAC;CACH,MAAM,QAAsB;EAC1B,MAAM;EACN,MAAM,WAAW;EACjB,UAAU,WAAW;CACvB;CACA,OAAO;EACL,SAAS,CAAC,KAAK,OAAO,GAAG,KAAK;EAC9B,SAAS,QAAQ,MAAM;CACzB;AACF;AAEA,SAAS,kBAAkB,KAA+B;CACxD,OAAO,gBAAgB,IAAI;AAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,YACd,SACsB;CACtB,MAAM,EAAE,QAAQ,mBAAmB,GAAG,gBAAgB;CACtD,MAAM,OAAO,sBAAsB,aAAa,EAC9C,gBACE,yOACJ,CAAC;CACD,OAAO;EACL,MAAM,QAAQ,QAAS;EACvB,aAAa,KAAK;EAClB,YAAY;EAEZ,eAAe;EAEf,QAAQ;EACR,MAAM,QAAQ,MAAM,KAAK;GACvB,MAAM,YAAY,OAAO,UAAU,WAAW,QAAQ,MAAM,GAAG;GAC/D,OAAO,kBACL,MAAM,KAAK,QAAQ,EAAE,MAAM,KAAK,KAAK,GAAG,SAAS,CACnD;EACF;CACF;AACF"}
|
|
@@ -1,14 +1,50 @@
|
|
|
1
|
+
import { n as CreateBrowserToolsOptions } from "../../ai-ahruGw7e.js";
|
|
1
2
|
import {
|
|
2
3
|
a as BrowserSource,
|
|
3
4
|
i as BrowserNewTab,
|
|
4
5
|
n as BrowserToolOptions,
|
|
5
6
|
r as BrowserToolOutput,
|
|
6
7
|
t as BrowserToolInput
|
|
7
|
-
} from "
|
|
8
|
-
import { CreateBrowserToolsOptions } from "./ai.js";
|
|
8
|
+
} from "../../browser-tool-vtrPOV8e.js";
|
|
9
9
|
import { ServerTool } from "@tanstack/ai";
|
|
10
10
|
|
|
11
11
|
//#region src/browser/tanstack-ai.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* Create TanStack AI tools for browser automation via CDP code mode.
|
|
14
|
+
*
|
|
15
|
+
* Returns an array with a single durable `browser_execute` `ServerTool`
|
|
16
|
+
* backed by the same codemode runtime as `agents/browser/ai` — the model
|
|
17
|
+
* writes TypeScript against the `cdp` connector and browser sessions
|
|
18
|
+
* survive pauses.
|
|
19
|
+
*
|
|
20
|
+
* The stateless Quick Action tools are not surfaced through this TanStack
|
|
21
|
+
* wrapper (it exposes only `browser_execute`); use `createQuickActionTools`
|
|
22
|
+
* from `agents/browser/ai` if you want them.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { createBrowserTools } from "agents/browser/tanstack-ai";
|
|
27
|
+
* import { chat } from "@tanstack/ai";
|
|
28
|
+
*
|
|
29
|
+
* // inside a Durable Object / Agent:
|
|
30
|
+
* const browserTools = createBrowserTools({
|
|
31
|
+
* ctx: this.ctx,
|
|
32
|
+
* browser: this.env.BROWSER,
|
|
33
|
+
* loader: this.env.LOADER,
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* const stream = chat({
|
|
37
|
+
* adapter: openaiText("gpt-4o"),
|
|
38
|
+
* tools: [...browserTools, ...otherTools],
|
|
39
|
+
* messages,
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function createBrowserTools(
|
|
44
|
+
options: CreateBrowserToolsOptions
|
|
45
|
+
): ServerTool[];
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/browser/tools/tanstack-ai.d.ts
|
|
12
48
|
interface TanStackBrowserToolOptions<
|
|
13
49
|
TName extends string = "browser"
|
|
14
50
|
> extends BrowserToolOptions {
|
|
@@ -54,7 +90,7 @@ interface TanStackBrowserToolOptions<
|
|
|
54
90
|
*/
|
|
55
91
|
declare function browserTool<TName extends string = "browser">(
|
|
56
92
|
options: TanStackBrowserToolOptions<TName>
|
|
57
|
-
): ServerTool<
|
|
93
|
+
): import("@tanstack/ai").ServerTool<
|
|
58
94
|
{
|
|
59
95
|
readonly "~standard": {
|
|
60
96
|
readonly version: 1;
|
|
@@ -87,40 +123,6 @@ declare function browserTool<TName extends string = "browser">(
|
|
|
87
123
|
TName,
|
|
88
124
|
unknown
|
|
89
125
|
>;
|
|
90
|
-
/**
|
|
91
|
-
* Create TanStack AI tools for browser automation via CDP code mode.
|
|
92
|
-
*
|
|
93
|
-
* Returns an array with a single durable `browser_execute` `ServerTool`
|
|
94
|
-
* backed by the same codemode runtime as `agents/browser/ai` — the model
|
|
95
|
-
* writes TypeScript against the `cdp` connector and browser sessions
|
|
96
|
-
* survive pauses.
|
|
97
|
-
*
|
|
98
|
-
* The stateless Quick Action tools are not surfaced through this TanStack
|
|
99
|
-
* wrapper (it exposes only `browser_execute`); use `createQuickActionTools`
|
|
100
|
-
* from `agents/browser/ai` if you want them.
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```ts
|
|
104
|
-
* import { createBrowserTools } from "agents/browser/tanstack-ai";
|
|
105
|
-
* import { chat } from "@tanstack/ai";
|
|
106
|
-
*
|
|
107
|
-
* // inside a Durable Object / Agent:
|
|
108
|
-
* const browserTools = createBrowserTools({
|
|
109
|
-
* ctx: this.ctx,
|
|
110
|
-
* browser: this.env.BROWSER,
|
|
111
|
-
* loader: this.env.LOADER,
|
|
112
|
-
* });
|
|
113
|
-
*
|
|
114
|
-
* const stream = chat({
|
|
115
|
-
* adapter: openaiText("gpt-4o"),
|
|
116
|
-
* tools: [...browserTools, ...otherTools],
|
|
117
|
-
* messages,
|
|
118
|
-
* });
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
declare function createBrowserTools(
|
|
122
|
-
options: CreateBrowserToolsOptions
|
|
123
|
-
): ServerTool[];
|
|
124
126
|
//#endregion
|
|
125
127
|
export {
|
|
126
128
|
type BrowserNewTab,
|
|
@@ -1,67 +1,13 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import {
|
|
1
|
+
import { n as browserScreenshotOutput, t as browserExecuteModelOutput } from "../../tool-helpers-O5BDVEAY.js";
|
|
2
|
+
import { createBrowserRuntime } from "../ai.js";
|
|
3
|
+
import { n as createBrowserToolCore } from "../../browser-tool-4iomavs_.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { toolDefinition } from "@tanstack/ai";
|
|
5
6
|
//#region src/browser/tanstack-ai.ts
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* replaced by a sentence saying it was left out.
|
|
10
|
-
*/
|
|
11
|
-
function browserToolModelResult(output) {
|
|
12
|
-
const screenshot = browserScreenshotOutput(output);
|
|
13
|
-
if (!screenshot) return browserExecuteModelOutput(output).value;
|
|
14
|
-
const bytes = Math.floor(screenshot.data.length * 3 / 4);
|
|
15
|
-
return browserExecuteModelOutput({
|
|
16
|
-
...output,
|
|
17
|
-
result: `Screenshot captured (${screenshot.mediaType}, approximately ${bytes.toLocaleString()} bytes), but this tool can't return images, so neither you nor the user can see it. Read the page with Runtime.evaluate instead.`
|
|
18
|
-
}).value;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Create a TanStack AI tool that lets the model drive a persistent browser
|
|
22
|
-
* with JavaScript and the Chrome DevTools Protocol.
|
|
23
|
-
*
|
|
24
|
-
* Works like `browserTool` in `agents/browser/ai-sdk`: tabs, cookies, and
|
|
25
|
-
* logins carry over between runs, `sessionId: "active"` addresses the tab the
|
|
26
|
-
* model last worked in, and a replaced browser is reported as
|
|
27
|
-
* `restarted: true`. The tool is named `browser` unless you pass `name`.
|
|
28
|
-
*
|
|
29
|
-
* Unlike the AI SDK tool, the host gets the same output as the model, and
|
|
30
|
-
* screenshots aren't supported: a returned screenshot is replaced by a
|
|
31
|
-
* sentence saying it was left out.
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* import { Browser, browserRun } from "agents/browser";
|
|
36
|
-
* import { browserTool } from "agents/browser/tanstack-ai";
|
|
37
|
-
* import { chat } from "@tanstack/ai";
|
|
38
|
-
*
|
|
39
|
-
* export class MyAgent extends Agent<Env> {
|
|
40
|
-
* browser = new Browser({ provider: browserRun(this.env.BROWSER) });
|
|
41
|
-
*
|
|
42
|
-
* constructor(ctx: AgentContext, env: Env) {
|
|
43
|
-
* super(ctx, env);
|
|
44
|
-
* this.lifecycle.use(this.browser);
|
|
45
|
-
* }
|
|
46
|
-
*
|
|
47
|
-
* async onChatMessage() {
|
|
48
|
-
* const stream = chat({
|
|
49
|
-
* adapter,
|
|
50
|
-
* tools: [browserTool({ browser: this.browser, loader: this.env.LOADER })],
|
|
51
|
-
* messages
|
|
52
|
-
* });
|
|
53
|
-
* }
|
|
54
|
-
* }
|
|
55
|
-
* ```
|
|
8
|
+
* The legacy TanStack AI `createBrowserTools`. `agents/browser/tanstack-ai`
|
|
9
|
+
* (`tools/tanstack-ai.ts`) re-exports it until it's retired.
|
|
56
10
|
*/
|
|
57
|
-
function browserTool(options) {
|
|
58
|
-
const core = createBrowserToolCore(options, { screenshotHint: "This tool can't return images, so don't take screenshots; read the page with Runtime.evaluate (for example document.body.innerText) instead." });
|
|
59
|
-
return toolDefinition({
|
|
60
|
-
name: options.name ?? "browser",
|
|
61
|
-
description: core.description,
|
|
62
|
-
inputSchema: core.inputSchema
|
|
63
|
-
}).server(async (input) => browserToolModelResult(await core.execute(input)));
|
|
64
|
-
}
|
|
65
11
|
/**
|
|
66
12
|
* Create TanStack AI tools for browser automation via CDP code mode.
|
|
67
13
|
*
|
|
@@ -125,6 +71,74 @@ function createBrowserTools(options) {
|
|
|
125
71
|
})];
|
|
126
72
|
}
|
|
127
73
|
//#endregion
|
|
74
|
+
//#region src/browser/tools/tanstack-ai.ts
|
|
75
|
+
/**
|
|
76
|
+
* `agents/browser/tanstack-ai` — the TanStack AI tool for a persistent
|
|
77
|
+
* `Browser`.
|
|
78
|
+
*
|
|
79
|
+
* The older `createBrowserTools` lives in `../tanstack-ai.ts` and is
|
|
80
|
+
* re-exported here until it's retired.
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
83
|
+
* What the model sees from one run. TanStack AI has one return channel, so
|
|
84
|
+
* the host gets this too: no `calls` log, bounded `logs`, and a screenshot
|
|
85
|
+
* replaced by a sentence saying it was left out.
|
|
86
|
+
*/
|
|
87
|
+
function browserToolModelResult(output) {
|
|
88
|
+
const screenshot = browserScreenshotOutput(output);
|
|
89
|
+
if (!screenshot) return browserExecuteModelOutput(output).value;
|
|
90
|
+
const bytes = Math.floor(screenshot.data.length * 3 / 4);
|
|
91
|
+
return browserExecuteModelOutput({
|
|
92
|
+
...output,
|
|
93
|
+
result: `Screenshot captured (${screenshot.mediaType}, approximately ${bytes.toLocaleString()} bytes), but this tool can't return images, so neither you nor the user can see it. Read the page with Runtime.evaluate instead.`
|
|
94
|
+
}).value;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create a TanStack AI tool that lets the model drive a persistent browser
|
|
98
|
+
* with JavaScript and the Chrome DevTools Protocol.
|
|
99
|
+
*
|
|
100
|
+
* Works like `browserTool` in `agents/browser/ai-sdk`: tabs, cookies, and
|
|
101
|
+
* logins carry over between runs, `sessionId: "active"` addresses the tab the
|
|
102
|
+
* model last worked in, and a replaced browser is reported as
|
|
103
|
+
* `restarted: true`. The tool is named `browser` unless you pass `name`.
|
|
104
|
+
*
|
|
105
|
+
* Unlike the AI SDK tool, the host gets the same output as the model, and
|
|
106
|
+
* screenshots aren't supported: a returned screenshot is replaced by a
|
|
107
|
+
* sentence saying it was left out.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { Browser, browserRun } from "agents/browser";
|
|
112
|
+
* import { browserTool } from "agents/browser/tanstack-ai";
|
|
113
|
+
* import { chat } from "@tanstack/ai";
|
|
114
|
+
*
|
|
115
|
+
* export class MyAgent extends Agent<Env> {
|
|
116
|
+
* browser = new Browser({ provider: browserRun(this.env.BROWSER) });
|
|
117
|
+
*
|
|
118
|
+
* constructor(ctx: AgentContext, env: Env) {
|
|
119
|
+
* super(ctx, env);
|
|
120
|
+
* this.lifecycle.use(this.browser);
|
|
121
|
+
* }
|
|
122
|
+
*
|
|
123
|
+
* async onChatMessage() {
|
|
124
|
+
* const stream = chat({
|
|
125
|
+
* adapter,
|
|
126
|
+
* tools: [browserTool({ browser: this.browser, loader: this.env.LOADER })],
|
|
127
|
+
* messages
|
|
128
|
+
* });
|
|
129
|
+
* }
|
|
130
|
+
* }
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
function browserTool(options) {
|
|
134
|
+
const core = createBrowserToolCore(options, { screenshotHint: "This tool can't return images, so don't take screenshots; read the page with Runtime.evaluate (for example document.body.innerText) instead." });
|
|
135
|
+
return toolDefinition({
|
|
136
|
+
name: options.name ?? "browser",
|
|
137
|
+
description: core.description,
|
|
138
|
+
inputSchema: core.inputSchema
|
|
139
|
+
}).server(async (input) => browserToolModelResult(await core.execute(input)));
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
128
142
|
export { browserTool, createBrowserTools };
|
|
129
143
|
|
|
130
144
|
//# sourceMappingURL=tanstack-ai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanstack-ai.js","names":[],"sources":["../../../src/browser/tanstack-ai.ts","../../../src/browser/tools/tanstack-ai.ts"],"sourcesContent":["/**\n * The legacy TanStack AI `createBrowserTools`. `agents/browser/tanstack-ai`\n * (`tools/tanstack-ai.ts`) re-exports it until it's retired.\n */\nimport { toolDefinition } from \"@tanstack/ai\";\nimport type { ServerTool } from \"@tanstack/ai\";\nimport type { ProxyToolOutput } from \"@cloudflare/codemode\";\nimport { z } from \"zod\";\nimport { createBrowserRuntime, type CreateBrowserToolsOptions } from \"./ai\";\n\nexport type { CreateBrowserToolsOptions } from \"./ai\";\n\n/**\n * Create TanStack AI tools for browser automation via CDP code mode.\n *\n * Returns an array with a single durable `browser_execute` `ServerTool`\n * backed by the same codemode runtime as `agents/browser/ai` — the model\n * writes TypeScript against the `cdp` connector and browser sessions\n * survive pauses.\n *\n * The stateless Quick Action tools are not surfaced through this TanStack\n * wrapper (it exposes only `browser_execute`); use `createQuickActionTools`\n * from `agents/browser/ai` if you want them.\n *\n * @example\n * ```ts\n * import { createBrowserTools } from \"agents/browser/tanstack-ai\";\n * import { chat } from \"@tanstack/ai\";\n *\n * // inside a Durable Object / Agent:\n * const browserTools = createBrowserTools({\n * ctx: this.ctx,\n * browser: this.env.BROWSER,\n * loader: this.env.LOADER,\n * });\n *\n * const stream = chat({\n * adapter: openaiText(\"gpt-4o\"),\n * tools: [...browserTools, ...otherTools],\n * messages,\n * });\n * ```\n */\nexport function createBrowserTools(\n options: CreateBrowserToolsOptions\n): ServerTool[] {\n // This wrapper only surfaces `browser_execute`, so don't build the default-on\n // Quick Action tools just to discard them.\n const { tools } = createBrowserRuntime({ ...options, quickActions: false });\n const executeTool = tools.browser_execute;\n\n const execute = toolDefinition({\n name: \"browser_execute\" as const,\n description:\n typeof executeTool.description === \"function\"\n ? \"\"\n : (executeTool.description ?? \"\"),\n inputSchema: z.object({\n code: z.string().meta({\n description:\n \"TypeScript async arrow function that uses the cdp connector\"\n })\n })\n }).server(async ({ code }) => {\n if (!executeTool.execute) {\n throw new Error(\"browser_execute tool is not executable\");\n }\n const result = (await executeTool.execute({ code }, {\n toolCallId: crypto.randomUUID(),\n messages: [],\n context: {}\n } as never)) as ProxyToolOutput;\n // TanStack has a single return channel, so what the host sees is what the\n // model sees: apply the AI SDK path's `toModelOutput` projection so a\n // screenshot's base64 cannot reach the model and the durable `calls` log\n // stays out of its context. The execution envelope (status, executionId)\n // is preserved either way.\n const modelOutput = await executeTool.toModelOutput?.({\n toolCallId: crypto.randomUUID(),\n input: { code },\n output: result\n });\n if (modelOutput?.type === \"error-text\") {\n throw new Error(modelOutput.value);\n }\n if (modelOutput?.type === \"text\") {\n return { ...result, result: modelOutput.value };\n }\n if (modelOutput?.type === \"json\") {\n return modelOutput.value;\n }\n return result;\n });\n\n return [execute];\n}\n","/**\n * `agents/browser/tanstack-ai` — the TanStack AI tool for a persistent\n * `Browser`.\n *\n * The older `createBrowserTools` lives in `../tanstack-ai.ts` and is\n * re-exported here until it's retired.\n */\nimport { toolDefinition } from \"@tanstack/ai\";\nimport {\n createBrowserToolCore,\n type BrowserToolOptions,\n type BrowserToolOutput\n} from \"../browser-tool\";\nimport {\n browserExecuteModelOutput,\n browserScreenshotOutput\n} from \"../tool-helpers\";\n\nexport type {\n BrowserToolInput,\n BrowserToolOptions,\n BrowserToolOutput\n} from \"../browser-tool\";\nexport type { BrowserNewTab, BrowserSource } from \"../session-connector\";\n\nexport interface TanStackBrowserToolOptions<\n TName extends string = \"browser\"\n> extends BrowserToolOptions {\n /** The tool's name. TanStack AI tools carry it in the definition. */\n name?: TName;\n}\n\n/**\n * What the model sees from one run. TanStack AI has one return channel, so\n * the host gets this too: no `calls` log, bounded `logs`, and a screenshot\n * replaced by a sentence saying it was left out.\n */\nfunction browserToolModelResult(output: BrowserToolOutput): unknown {\n const screenshot = browserScreenshotOutput(output);\n if (!screenshot) return browserExecuteModelOutput(output).value;\n const bytes = Math.floor((screenshot.data.length * 3) / 4);\n // Keep the rest of the result (status, restarted, notice, newTabs).\n return browserExecuteModelOutput({\n ...output,\n result: `Screenshot captured (${screenshot.mediaType}, approximately ${bytes.toLocaleString()} bytes), but this tool can't return images, so neither you nor the user can see it. Read the page with Runtime.evaluate instead.`\n }).value;\n}\n\n/**\n * Create a TanStack AI tool that lets the model drive a persistent browser\n * with JavaScript and the Chrome DevTools Protocol.\n *\n * Works like `browserTool` in `agents/browser/ai-sdk`: tabs, cookies, and\n * logins carry over between runs, `sessionId: \"active\"` addresses the tab the\n * model last worked in, and a replaced browser is reported as\n * `restarted: true`. The tool is named `browser` unless you pass `name`.\n *\n * Unlike the AI SDK tool, the host gets the same output as the model, and\n * screenshots aren't supported: a returned screenshot is replaced by a\n * sentence saying it was left out.\n *\n * @example\n * ```ts\n * import { Browser, browserRun } from \"agents/browser\";\n * import { browserTool } from \"agents/browser/tanstack-ai\";\n * import { chat } from \"@tanstack/ai\";\n *\n * export class MyAgent extends Agent<Env> {\n * browser = new Browser({ provider: browserRun(this.env.BROWSER) });\n *\n * constructor(ctx: AgentContext, env: Env) {\n * super(ctx, env);\n * this.lifecycle.use(this.browser);\n * }\n *\n * async onChatMessage() {\n * const stream = chat({\n * adapter,\n * tools: [browserTool({ browser: this.browser, loader: this.env.LOADER })],\n * messages\n * });\n * }\n * }\n * ```\n */\nexport function browserTool<TName extends string = \"browser\">(\n options: TanStackBrowserToolOptions<TName>\n) {\n const core = createBrowserToolCore(options, {\n screenshotHint:\n \"This tool can't return images, so don't take screenshots; read the page with Runtime.evaluate (for example document.body.innerText) instead.\"\n });\n return toolDefinition({\n name: options.name ?? (\"browser\" as TName),\n description: core.description,\n inputSchema: core.inputSchema\n }).server(async (input) => browserToolModelResult(await core.execute(input)));\n}\n\nexport {\n createBrowserTools,\n type CreateBrowserToolsOptions\n} from \"../tanstack-ai\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,SAAgB,mBACd,SACc;CAGd,MAAM,EAAE,UAAU,qBAAqB;EAAE,GAAG;EAAS,cAAc;CAAM,CAAC;CAC1E,MAAM,cAAc,MAAM;CA6C1B,OAAO,CA3CS,eAAe;EAC7B,MAAM;EACN,aACE,OAAO,YAAY,gBAAgB,aAC/B,KACC,YAAY,eAAe;EAClC,aAAa,EAAE,OAAO,EACpB,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,EACpB,aACE,8DACJ,CAAC,EACH,CAAC;CACH,CAAC,CAAC,CAAC,OAAO,OAAO,EAAE,WAAW;EAC5B,IAAI,CAAC,YAAY,SACf,MAAM,IAAI,MAAM,wCAAwC;EAE1D,MAAM,SAAU,MAAM,YAAY,QAAQ,EAAE,KAAK,GAAG;GAClD,YAAY,OAAO,WAAW;GAC9B,UAAU,CAAC;GACX,SAAS,CAAC;EACZ,CAAU;EAMV,MAAM,cAAc,MAAM,YAAY,gBAAgB;GACpD,YAAY,OAAO,WAAW;GAC9B,OAAO,EAAE,KAAK;GACd,QAAQ;EACV,CAAC;EACD,IAAI,aAAa,SAAS,cACxB,MAAM,IAAI,MAAM,YAAY,KAAK;EAEnC,IAAI,aAAa,SAAS,QACxB,OAAO;GAAE,GAAG;GAAQ,QAAQ,YAAY;EAAM;EAEhD,IAAI,aAAa,SAAS,QACxB,OAAO,YAAY;EAErB,OAAO;CACT,CAEc,CAAC;AACjB;;;;;;;;;;;;;;;AC1DA,SAAS,uBAAuB,QAAoC;CAClE,MAAM,aAAa,wBAAwB,MAAM;CACjD,IAAI,CAAC,YAAY,OAAO,0BAA0B,MAAM,CAAC,CAAC;CAC1D,MAAM,QAAQ,KAAK,MAAO,WAAW,KAAK,SAAS,IAAK,CAAC;CAEzD,OAAO,0BAA0B;EAC/B,GAAG;EACH,QAAQ,wBAAwB,WAAW,UAAU,kBAAkB,MAAM,eAAe,EAAE;CAChG,CAAC,CAAC,CAAC;AACL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,SAAgB,YACd,SACA;CACA,MAAM,OAAO,sBAAsB,SAAS,EAC1C,gBACE,+IACJ,CAAC;CACD,OAAO,eAAe;EACpB,MAAM,QAAQ,QAAS;EACvB,aAAa,KAAK;EAClB,aAAa,KAAK;CACpB,CAAC,CAAC,CAAC,OAAO,OAAO,UAAU,uBAAuB,MAAM,KAAK,QAAQ,KAAK,CAAC,CAAC;AAC9E"}
|