managed-deepagents 0.10.0-dev.9 → 0.10.1-dev.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.
- package/README.md +864 -143
- package/dist/browser.d.ts +37 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +31 -0
- package/dist/browser.js.map +1 -0
- package/dist/channels/actor.d.ts +57 -0
- package/dist/channels/actor.d.ts.map +1 -0
- package/dist/channels/actor.js +24 -0
- package/dist/channels/actor.js.map +1 -0
- package/dist/channels/assistant-text.d.ts +29 -0
- package/dist/channels/assistant-text.d.ts.map +1 -1
- package/dist/channels/assistant-text.js +81 -4
- package/dist/channels/assistant-text.js.map +1 -1
- package/dist/channels/binding.d.ts +20 -1
- package/dist/channels/binding.d.ts.map +1 -1
- package/dist/channels/binding.js +44 -11
- package/dist/channels/binding.js.map +1 -1
- package/dist/channels/delivery.d.ts +51 -0
- package/dist/channels/delivery.d.ts.map +1 -0
- package/dist/channels/delivery.js +424 -0
- package/dist/channels/delivery.js.map +1 -0
- package/dist/channels/github/app-setup.d.ts +32 -0
- package/dist/channels/github/app-setup.d.ts.map +1 -0
- package/dist/channels/github/app-setup.js +146 -0
- package/dist/channels/github/app-setup.js.map +1 -0
- package/dist/channels/github/index.d.ts +5 -1
- package/dist/channels/github/index.d.ts.map +1 -1
- package/dist/channels/github/index.js +38 -46
- package/dist/channels/github/index.js.map +1 -1
- package/dist/channels/github/mentions.d.ts +12 -0
- package/dist/channels/github/mentions.d.ts.map +1 -0
- package/dist/channels/github/mentions.js +185 -0
- package/dist/channels/github/mentions.js.map +1 -0
- package/dist/channels/github/schema.d.ts +271 -0
- package/dist/channels/github/schema.d.ts.map +1 -1
- package/dist/channels/github/schema.js +33 -0
- package/dist/channels/github/schema.js.map +1 -1
- package/dist/channels/github/types.d.ts +50 -26
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/http/endpoint.d.ts +137 -0
- package/dist/channels/http/endpoint.d.ts.map +1 -0
- package/dist/channels/http/endpoint.js +286 -0
- package/dist/channels/http/endpoint.js.map +1 -0
- package/dist/channels/http/http.d.ts.map +1 -1
- package/dist/channels/http/http.js +209 -89
- package/dist/channels/http/http.js.map +1 -1
- package/dist/channels/http/index.d.ts +7 -1
- package/dist/channels/http/index.d.ts.map +1 -1
- package/dist/channels/http/index.js +32 -23
- package/dist/channels/http/index.js.map +1 -1
- package/dist/channels/http/ingress.d.ts +30 -24
- package/dist/channels/http/ingress.d.ts.map +1 -1
- package/dist/channels/http/ingress.js +61 -57
- package/dist/channels/http/ingress.js.map +1 -1
- package/dist/channels/http/provider.d.ts +38 -15
- package/dist/channels/http/provider.d.ts.map +1 -1
- package/dist/channels/http/provider.js +54 -24
- package/dist/channels/http/provider.js.map +1 -1
- package/dist/channels/http/studio.d.ts +8 -1
- package/dist/channels/http/studio.d.ts.map +1 -1
- package/dist/channels/http/studio.js +13 -0
- package/dist/channels/http/studio.js.map +1 -1
- package/dist/channels/http/types.d.ts +95 -69
- package/dist/channels/http/types.d.ts.map +1 -1
- package/dist/channels/linear/app-setup.d.ts +29 -0
- package/dist/channels/linear/app-setup.d.ts.map +1 -0
- package/dist/channels/linear/app-setup.js +102 -0
- package/dist/channels/linear/app-setup.js.map +1 -0
- package/dist/channels/linear/index.d.ts +5 -1
- package/dist/channels/linear/index.d.ts.map +1 -1
- package/dist/channels/linear/index.js +65 -94
- package/dist/channels/linear/index.js.map +1 -1
- package/dist/channels/linear/schema.d.ts +11 -25
- package/dist/channels/linear/schema.d.ts.map +1 -1
- package/dist/channels/linear/schema.js +6 -0
- package/dist/channels/linear/schema.js.map +1 -1
- package/dist/channels/linear/types.d.ts +37 -31
- package/dist/channels/linear/types.d.ts.map +1 -1
- package/dist/channels/messaging-registry.d.ts +16 -0
- package/dist/channels/messaging-registry.d.ts.map +1 -1
- package/dist/channels/messaging-registry.js +29 -0
- package/dist/channels/messaging-registry.js.map +1 -1
- package/dist/channels/reserved-connections.d.ts.map +1 -1
- package/dist/channels/reserved-connections.js +10 -0
- package/dist/channels/reserved-connections.js.map +1 -1
- package/dist/channels/resolve-user-endpoint.d.ts +34 -0
- package/dist/channels/resolve-user-endpoint.d.ts.map +1 -0
- package/dist/channels/resolve-user-endpoint.js +51 -0
- package/dist/channels/resolve-user-endpoint.js.map +1 -0
- package/dist/channels/resolve-user.d.ts +95 -0
- package/dist/channels/resolve-user.d.ts.map +1 -0
- package/dist/channels/resolve-user.js +143 -0
- package/dist/channels/resolve-user.js.map +1 -0
- package/dist/channels/run-input.d.ts +46 -4
- package/dist/channels/run-input.d.ts.map +1 -1
- package/dist/channels/run-input.js +94 -30
- package/dist/channels/run-input.js.map +1 -1
- package/dist/channels/runtime.d.ts +5 -2
- package/dist/channels/runtime.d.ts.map +1 -1
- package/dist/channels/runtime.js +19 -10
- package/dist/channels/runtime.js.map +1 -1
- package/dist/channels/schedule-delivery.d.ts +2 -13
- package/dist/channels/schedule-delivery.d.ts.map +1 -1
- package/dist/channels/schedule-delivery.js +9 -76
- package/dist/channels/schedule-delivery.js.map +1 -1
- package/dist/channels/slack/api.d.ts +2 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +6 -0
- package/dist/channels/slack/api.js.map +1 -1
- package/dist/channels/slack/connections.d.ts +6 -0
- package/dist/channels/slack/connections.d.ts.map +1 -0
- package/dist/channels/slack/connections.js +6 -0
- package/dist/channels/slack/connections.js.map +1 -0
- package/dist/channels/slack/events.d.ts +278 -0
- package/dist/channels/slack/events.d.ts.map +1 -0
- package/dist/channels/slack/events.js +235 -0
- package/dist/channels/slack/events.js.map +1 -0
- package/dist/channels/slack/files.d.ts.map +1 -1
- package/dist/channels/slack/files.js +2 -3
- package/dist/channels/slack/files.js.map +1 -1
- package/dist/channels/slack/index.d.ts +90 -2
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +188 -6
- package/dist/channels/slack/index.js.map +1 -1
- package/dist/channels/slack/message-content.d.ts.map +1 -1
- package/dist/channels/slack/message-content.js +23 -28
- package/dist/channels/slack/message-content.js.map +1 -1
- package/dist/channels/slack/status.d.ts +76 -0
- package/dist/channels/slack/status.d.ts.map +1 -0
- package/dist/channels/slack/status.js +427 -0
- package/dist/channels/slack/status.js.map +1 -0
- package/dist/channels/trigger/client.d.ts.map +1 -1
- package/dist/channels/trigger/client.js +9 -11
- package/dist/channels/trigger/client.js.map +1 -1
- package/dist/channels/trigger/conversation.d.ts +11 -0
- package/dist/channels/trigger/conversation.d.ts.map +1 -0
- package/dist/channels/trigger/conversation.js +72 -0
- package/dist/channels/trigger/conversation.js.map +1 -0
- package/dist/channels/trigger/http.d.ts +130 -4
- package/dist/channels/trigger/http.d.ts.map +1 -1
- package/dist/channels/trigger/http.js +419 -82
- package/dist/channels/trigger/http.js.map +1 -1
- package/dist/channels/trigger/identity-context.d.ts +1 -1
- package/dist/channels/trigger/identity-context.d.ts.map +1 -1
- package/dist/channels/trigger/identity-context.js +3 -5
- package/dist/channels/trigger/identity-context.js.map +1 -1
- package/dist/channels/trigger/ingress.d.ts +70 -1
- package/dist/channels/trigger/ingress.d.ts.map +1 -1
- package/dist/channels/trigger/ingress.js +141 -9
- package/dist/channels/trigger/ingress.js.map +1 -1
- package/dist/channels/trigger/transport.d.ts +10 -0
- package/dist/channels/trigger/transport.d.ts.map +1 -1
- package/dist/channels/trigger/transport.js +25 -9
- package/dist/channels/trigger/transport.js.map +1 -1
- package/dist/channels/trigger/types.d.ts +92 -3
- package/dist/channels/trigger/types.d.ts.map +1 -1
- package/dist/channels/trigger/types.js +37 -0
- package/dist/channels/trigger/types.js.map +1 -1
- package/dist/channels/types.d.ts +53 -4
- package/dist/channels/types.d.ts.map +1 -1
- package/dist/channels/types.js +2 -0
- package/dist/channels/types.js.map +1 -1
- package/dist/concurrency/batch-processor.d.ts +51 -0
- package/dist/concurrency/batch-processor.d.ts.map +1 -0
- package/dist/concurrency/batch-processor.js +99 -0
- package/dist/concurrency/batch-processor.js.map +1 -0
- package/dist/connections.d.ts +5 -12
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +28 -30
- package/dist/connections.js.map +1 -1
- package/dist/connectors/mcp/langsmith-url.d.ts.map +1 -1
- package/dist/connectors/mcp/langsmith-url.js +0 -1
- package/dist/connectors/mcp/langsmith-url.js.map +1 -1
- package/dist/credential-gate.js +3 -3
- package/dist/credential-gate.js.map +1 -1
- package/dist/define-deep-agent.d.ts +2 -2
- package/dist/define-deep-agent.d.ts.map +1 -1
- package/dist/define-deep-agent.js +53 -2
- package/dist/define-deep-agent.js.map +1 -1
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +3 -1
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/loopback.d.ts +7 -2
- package/dist/identity/loopback.d.ts.map +1 -1
- package/dist/identity/loopback.js +15 -4
- package/dist/identity/loopback.js.map +1 -1
- package/dist/identity/options.d.ts +9 -0
- package/dist/identity/options.d.ts.map +1 -1
- package/dist/identity/options.js +1 -1
- package/dist/identity/options.js.map +1 -1
- package/dist/identity/slack/links.js +3 -2
- package/dist/identity/slack/links.js.map +1 -1
- package/dist/identity/types.d.ts +3 -0
- package/dist/identity/types.d.ts.map +1 -1
- package/dist/index.d.ts +15 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/ingress/index.d.ts +8 -0
- package/dist/ingress/index.d.ts.map +1 -1
- package/dist/ingress/index.js +32 -2
- package/dist/ingress/index.js.map +1 -1
- package/dist/ingress/loopback.d.ts +1 -0
- package/dist/ingress/loopback.d.ts.map +1 -1
- package/dist/ingress/loopback.js +7 -3
- package/dist/ingress/loopback.js.map +1 -1
- package/dist/ingress/runs.d.ts +27 -1
- package/dist/ingress/runs.d.ts.map +1 -1
- package/dist/ingress/runs.js +69 -6
- package/dist/ingress/runs.js.map +1 -1
- package/dist/managed-composition.d.ts +3 -0
- package/dist/managed-composition.d.ts.map +1 -1
- package/dist/managed-composition.js +29 -13
- package/dist/managed-composition.js.map +1 -1
- package/dist/memory/instructions-middleware.d.ts.map +1 -1
- package/dist/memory/instructions-middleware.js +6 -5
- package/dist/memory/instructions-middleware.js.map +1 -1
- package/dist/namespaces.d.ts +4 -21
- package/dist/namespaces.d.ts.map +1 -1
- package/dist/namespaces.js +0 -29
- package/dist/namespaces.js.map +1 -1
- package/dist/resilience/retry.d.ts +21 -0
- package/dist/resilience/retry.d.ts.map +1 -0
- package/dist/resilience/retry.js +40 -0
- package/dist/resilience/retry.js.map +1 -0
- package/dist/runtime/async-subagents.d.ts +27 -0
- package/dist/runtime/async-subagents.d.ts.map +1 -0
- package/dist/runtime/async-subagents.js +139 -0
- package/dist/runtime/async-subagents.js.map +1 -0
- package/dist/runtime/auth.d.ts +1 -2
- package/dist/runtime/auth.d.ts.map +1 -1
- package/dist/runtime/auth.js +138 -72
- package/dist/runtime/auth.js.map +1 -1
- package/dist/runtime/backend.d.ts +9 -1
- package/dist/runtime/backend.d.ts.map +1 -1
- package/dist/runtime/backend.js +36 -11
- package/dist/runtime/backend.js.map +1 -1
- package/dist/runtime/browser-facade.d.ts +10 -0
- package/dist/runtime/browser-facade.d.ts.map +1 -0
- package/dist/runtime/browser-facade.js +23 -0
- package/dist/runtime/browser-facade.js.map +1 -0
- package/dist/runtime/browser-langsmith.d.ts +143 -0
- package/dist/runtime/browser-langsmith.d.ts.map +1 -0
- package/dist/runtime/browser-langsmith.js +507 -0
- package/dist/runtime/browser-langsmith.js.map +1 -0
- package/dist/runtime/browser-recorder.py +831 -0
- package/dist/runtime/browser-selection.d.ts +10 -0
- package/dist/runtime/browser-selection.d.ts.map +1 -0
- package/dist/runtime/browser-selection.js +21 -0
- package/dist/runtime/browser-selection.js.map +1 -0
- package/dist/runtime/browser.d.ts +138 -0
- package/dist/runtime/browser.d.ts.map +1 -0
- package/dist/runtime/browser.js +802 -0
- package/dist/runtime/browser.js.map +1 -0
- package/dist/runtime/channel-icon.d.ts.map +1 -1
- package/dist/runtime/channel-icon.js +18 -7
- package/dist/runtime/channel-icon.js.map +1 -1
- package/dist/runtime/channel.d.ts +5 -0
- package/dist/runtime/channel.d.ts.map +1 -1
- package/dist/runtime/channel.js.map +1 -1
- package/dist/runtime/graph-build-timing.d.ts +30 -0
- package/dist/runtime/graph-build-timing.d.ts.map +1 -0
- package/dist/runtime/graph-build-timing.js +50 -0
- package/dist/runtime/graph-build-timing.js.map +1 -0
- package/dist/runtime/http.d.ts +15 -0
- package/dist/runtime/http.d.ts.map +1 -1
- package/dist/runtime/http.js +37 -0
- package/dist/runtime/http.js.map +1 -1
- package/dist/runtime/identity-http.d.ts.map +1 -1
- package/dist/runtime/identity-http.js +19 -7
- package/dist/runtime/identity-http.js.map +1 -1
- package/dist/runtime/identity-runtime.d.ts +4 -9
- package/dist/runtime/identity-runtime.d.ts.map +1 -1
- package/dist/runtime/identity-runtime.js +12 -25
- package/dist/runtime/identity-runtime.js.map +1 -1
- package/dist/runtime/index.d.ts +38 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +104 -52
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/langsmith-env.d.ts +19 -0
- package/dist/runtime/langsmith-env.d.ts.map +1 -0
- package/dist/runtime/langsmith-env.js +38 -0
- package/dist/runtime/langsmith-env.js.map +1 -0
- package/dist/runtime/log.d.ts +8 -14
- package/dist/runtime/log.d.ts.map +1 -1
- package/dist/runtime/log.js +16 -7
- package/dist/runtime/log.js.map +1 -1
- package/dist/runtime/managed-middleware.d.ts.map +1 -1
- package/dist/runtime/managed-middleware.js +1 -14
- package/dist/runtime/managed-middleware.js.map +1 -1
- package/dist/runtime/managed-thread.d.ts +61 -0
- package/dist/runtime/managed-thread.d.ts.map +1 -0
- package/dist/runtime/managed-thread.js +76 -0
- package/dist/runtime/managed-thread.js.map +1 -0
- package/dist/runtime/managed-tools.d.ts +18 -2
- package/dist/runtime/managed-tools.d.ts.map +1 -1
- package/dist/runtime/managed-tools.js +26 -22
- package/dist/runtime/managed-tools.js.map +1 -1
- package/dist/runtime/memory/mounts.d.ts +82 -11
- package/dist/runtime/memory/mounts.d.ts.map +1 -1
- package/dist/runtime/memory/mounts.js +173 -34
- package/dist/runtime/memory/mounts.js.map +1 -1
- package/dist/runtime/memory/policy.d.ts.map +1 -1
- package/dist/runtime/memory/policy.js +1 -3
- package/dist/runtime/memory/policy.js.map +1 -1
- package/dist/runtime/parent-run.d.ts +33 -0
- package/dist/runtime/parent-run.d.ts.map +1 -0
- package/dist/runtime/parent-run.js +114 -0
- package/dist/runtime/parent-run.js.map +1 -0
- package/dist/runtime/run-input.d.ts +14 -1
- package/dist/runtime/run-input.d.ts.map +1 -1
- package/dist/runtime/run-input.js +118 -7
- package/dist/runtime/run-input.js.map +1 -1
- package/dist/runtime/sandbox-manager.d.ts +31 -17
- package/dist/runtime/sandbox-manager.d.ts.map +1 -1
- package/dist/runtime/sandbox-manager.js +112 -70
- package/dist/runtime/sandbox-manager.js.map +1 -1
- package/dist/runtime/schedule-auth.d.ts +79 -0
- package/dist/runtime/schedule-auth.d.ts.map +1 -1
- package/dist/runtime/schedule-auth.js +165 -7
- package/dist/runtime/schedule-auth.js.map +1 -1
- package/dist/runtime/selected-skills-backend.d.ts +3 -3
- package/dist/runtime/selected-skills-backend.d.ts.map +1 -1
- package/dist/runtime/selected-skills-backend.js +5 -5
- package/dist/runtime/selected-skills-backend.js.map +1 -1
- package/dist/runtime/static-entry.d.ts.map +1 -1
- package/dist/runtime/static-entry.js +1 -0
- package/dist/runtime/static-entry.js.map +1 -1
- package/dist/runtime/thread-record.d.ts +88 -0
- package/dist/runtime/thread-record.d.ts.map +1 -0
- package/dist/runtime/thread-record.js +213 -0
- package/dist/runtime/thread-record.js.map +1 -0
- package/dist/runtime/types.d.ts +12 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime-schedules.d.ts +15 -0
- package/dist/runtime-schedules.d.ts.map +1 -1
- package/dist/runtime-schedules.js +85 -23
- package/dist/runtime-schedules.js.map +1 -1
- package/dist/sandbox.d.ts +0 -6
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +3 -7
- package/dist/sandbox.js.map +1 -1
- package/dist/schedule-channel.d.ts +5 -2
- package/dist/schedule-channel.d.ts.map +1 -1
- package/dist/schedule-channel.js +13 -12
- package/dist/schedule-channel.js.map +1 -1
- package/dist/telemetry/lifecycle.d.ts +26 -0
- package/dist/telemetry/lifecycle.d.ts.map +1 -0
- package/dist/telemetry/lifecycle.js +49 -0
- package/dist/telemetry/lifecycle.js.map +1 -0
- package/dist/telemetry/metadata.d.ts.map +1 -1
- package/dist/telemetry/metadata.js +4 -4
- package/dist/telemetry/metadata.js.map +1 -1
- package/dist/telemetry/otel/context.d.ts +57 -0
- package/dist/telemetry/otel/context.d.ts.map +1 -0
- package/dist/telemetry/otel/context.js +122 -0
- package/dist/telemetry/otel/context.js.map +1 -0
- package/dist/telemetry/otel/exporter.d.ts +53 -0
- package/dist/telemetry/otel/exporter.d.ts.map +1 -0
- package/dist/telemetry/otel/exporter.js +190 -0
- package/dist/telemetry/otel/exporter.js.map +1 -0
- package/dist/telemetry/otel/index.d.ts +6 -0
- package/dist/telemetry/otel/index.d.ts.map +1 -0
- package/dist/telemetry/otel/index.js +3 -0
- package/dist/telemetry/otel/index.js.map +1 -0
- package/dist/telemetry/otel/otlp.d.ts +44 -0
- package/dist/telemetry/otel/otlp.d.ts.map +1 -0
- package/dist/telemetry/otel/otlp.js +7 -0
- package/dist/telemetry/otel/otlp.js.map +1 -0
- package/dist/telemetry/otel/truncate.d.ts +10 -0
- package/dist/telemetry/otel/truncate.d.ts.map +1 -0
- package/dist/telemetry/otel/truncate.js +39 -0
- package/dist/telemetry/otel/truncate.js.map +1 -0
- package/dist/telemetry/run-listener.d.ts +1 -1
- package/dist/telemetry/run-listener.d.ts.map +1 -1
- package/dist/telemetry/run-listener.js +32 -2
- package/dist/telemetry/run-listener.js.map +1 -1
- package/dist/telemetry/transport/posthog.d.ts +13 -1
- package/dist/telemetry/transport/posthog.d.ts.map +1 -1
- package/dist/telemetry/transport/posthog.js +68 -30
- package/dist/telemetry/transport/posthog.js.map +1 -1
- package/dist/types.d.ts +19 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/values.d.ts +15 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +31 -0
- package/dist/values.js.map +1 -0
- package/package.json +26 -12
- package/dist/channels/http/forward.d.ts +0 -13
- package/dist/channels/http/forward.d.ts.map +0 -1
- package/dist/channels/http/forward.js +0 -128
- package/dist/channels/http/forward.js.map +0 -1
- package/dist/channels/http/reply.d.ts +0 -20
- package/dist/channels/http/reply.d.ts.map +0 -1
- package/dist/channels/http/reply.js +0 -116
- package/dist/channels/http/reply.js.map +0 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser use, the LangSmith side: create a key's browser, put Stagehand's
|
|
3
|
+
* extension on it, connect Stagehand to one of its windows, and run the
|
|
4
|
+
* recorder beside Chrome.
|
|
5
|
+
*
|
|
6
|
+
* The LangSmith half of Python's `browser.py`, kept apart from the middleware
|
|
7
|
+
* (`browser.ts`) so its tests can stand in for it, as Python's do for `_open`
|
|
8
|
+
* and `_share_localhost`.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
11
|
+
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
|
12
|
+
import { tmpdir } from "node:os";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
15
|
+
import { getExtensionArchive, localBrowser, Stagehand, } from "@browserbasehq/stagehand";
|
|
16
|
+
import { SandboxClient } from "langsmith/sandbox";
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
import { StagehandFacadeTools } from "./browser-facade.js";
|
|
19
|
+
import { managedDeploymentName, managedSandboxName, } from "./sandbox-manager.js";
|
|
20
|
+
/** The client and the browser's extension must match; `mda` pins this in deployments. */
|
|
21
|
+
export const STAGEHAND_VERSION = "4.3.0";
|
|
22
|
+
const BROWSER_GENERATIONS = 5;
|
|
23
|
+
const UNUSABLE = new Set(["deleting", "deleted", "failed", "error"]); // browser states to move past
|
|
24
|
+
const EXTENSION_DIR = `/var/lib/browserd/extensions/stagehand-${STAGEHAND_VERSION}`;
|
|
25
|
+
const EXTENSION_ZIP = "/tmp/mda-stagehand.zip"; // in the browser sandbox
|
|
26
|
+
const WINDOWS_FILE = "/var/lib/browserd/attachments.json"; // browserd's windows and their ports
|
|
27
|
+
const LOCALHOST_WINDOW = "mda-localhost"; // shares a sandbox's localhost with every window
|
|
28
|
+
export const HANDOFF_LINK_TTL_S = 900; // how long the link a user gets for a handoff works
|
|
29
|
+
// The recorder is Python's program, which both runtimes run in the browser's sandbox:
|
|
30
|
+
// `npm run compile` copies it beside this module.
|
|
31
|
+
const RECORDER = new URL("./browser-recorder.py", import.meta.url);
|
|
32
|
+
// Installed beside it, as Python installs them: the versions Python's tests run it with.
|
|
33
|
+
const RECORDER_PACKAGES = [
|
|
34
|
+
"av==19.0.2",
|
|
35
|
+
"pillow==13.0.0",
|
|
36
|
+
"websockets==16.1.1",
|
|
37
|
+
];
|
|
38
|
+
const RECORDER_HOME = "/var/lib/mda-recorder"; // in the browser sandbox: its packages
|
|
39
|
+
const RECORDER_PACKAGES_DIR = `${RECORDER_HOME}/packages-${createHash("sha256")
|
|
40
|
+
.update(RECORDER_PACKAGES.join(" "))
|
|
41
|
+
.digest("hex")
|
|
42
|
+
.slice(0, 16)}`;
|
|
43
|
+
// In the browser sandbox: a take's folder, `<prefix>-<id>`, which holds the take and
|
|
44
|
+
// its own copy of the recorder. Python looks for modules beside the program first,
|
|
45
|
+
// so the folder holds no other.
|
|
46
|
+
const RECORDER_TAKES = "/tmp/mda-recording";
|
|
47
|
+
const RECORDER_STOP_TIMEOUT_S = 660; // the recorder's own 600 s to encode, and some
|
|
48
|
+
// The recorder's replies, as it prints them: to `start`, to `stop`, and when either fails.
|
|
49
|
+
const StartReply = z.object({ recording: z.literal(true) });
|
|
50
|
+
const StopReply = z.object({
|
|
51
|
+
seconds: z.number(),
|
|
52
|
+
early: z.string(), // why it ended before it was stopped, as the recorder words it, or ""
|
|
53
|
+
summary: z.string(), // a line per event, as the recorder writes it
|
|
54
|
+
});
|
|
55
|
+
const ErrorReply = z.object({ error: z.string() });
|
|
56
|
+
/** The recorder's own failure, in the browser's sandbox: the client is fine. */
|
|
57
|
+
export class RecorderError extends Error {
|
|
58
|
+
}
|
|
59
|
+
/** A handoff that waits on the user, in the thread's state. */
|
|
60
|
+
export const PendingBrowserHandoffSchema = z.object({
|
|
61
|
+
/** The LangSmith browser's name. */
|
|
62
|
+
browser: z.string(),
|
|
63
|
+
/** The window the user has. */
|
|
64
|
+
window_id: z.string(),
|
|
65
|
+
/** When the user's link runs out, in epoch seconds. */
|
|
66
|
+
until: z.number(),
|
|
67
|
+
});
|
|
68
|
+
export async function closeSession(session) {
|
|
69
|
+
// Not `browser.close()`, which closes the browser. Closing Stagehand frees the
|
|
70
|
+
// extension; dropping the CDP connection lets the browser idle out.
|
|
71
|
+
await Promise.race([
|
|
72
|
+
session.stagehand.close(),
|
|
73
|
+
sleep(3_000, undefined, { ref: false }),
|
|
74
|
+
]).catch(() => undefined);
|
|
75
|
+
try {
|
|
76
|
+
session.transport?.close();
|
|
77
|
+
}
|
|
78
|
+
catch { }
|
|
79
|
+
// As Python's rmtree(ignore_errors=True): closing never fails.
|
|
80
|
+
await rm(session.artifacts, { recursive: true, force: true }).catch(() => undefined);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* `key`'s browser, under the deployment's prefix like its sandboxes.
|
|
84
|
+
*
|
|
85
|
+
* A later `generation` replaces a browser that is being deleted or broke.
|
|
86
|
+
*/
|
|
87
|
+
export function browserName(key, generation = 0) {
|
|
88
|
+
const scope = generation === 0 ? `browser:${key}` : `browser:${key}:${generation}`;
|
|
89
|
+
const deployment = managedDeploymentName();
|
|
90
|
+
if (deployment)
|
|
91
|
+
return managedSandboxName(deployment, scope);
|
|
92
|
+
return `mda-${createHash("sha256").update(scope).digest("hex").slice(0, 16)}`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* `key`'s browser, created or started as needed, and its sandbox.
|
|
96
|
+
*
|
|
97
|
+
* A browser that is being deleted, or broke, can't be used or recreated under
|
|
98
|
+
* its name, so `key` moves on to its next generation.
|
|
99
|
+
*/
|
|
100
|
+
export async function usableBrowser(api, boxes, key, idleTtlSeconds) {
|
|
101
|
+
for (let generation = 0; generation < BROWSER_GENERATIONS; generation++) {
|
|
102
|
+
const name = browserName(key, generation);
|
|
103
|
+
try {
|
|
104
|
+
// HiDPI renders at twice the resolution, so a person watching or driving
|
|
105
|
+
// the window sees it sharp; it can only be chosen at creation.
|
|
106
|
+
const create = { name, idle_ttl_seconds: idleTtlSeconds, hidpi: true };
|
|
107
|
+
await request(api, "POST", `${api.url}/browsers`, create);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (err.status !== 409)
|
|
111
|
+
throw err; // conflict: it exists
|
|
112
|
+
}
|
|
113
|
+
let box = await boxes.getSandbox(name);
|
|
114
|
+
if (UNUSABLE.has(box.status ?? ""))
|
|
115
|
+
continue;
|
|
116
|
+
if (box.status === "stopped") {
|
|
117
|
+
box = await boxes.startSandbox(name, { timeout: 300 });
|
|
118
|
+
}
|
|
119
|
+
return { name, box };
|
|
120
|
+
}
|
|
121
|
+
throw new Error("could not find or create a usable browser");
|
|
122
|
+
}
|
|
123
|
+
/** LangSmith's sandboxes API, and its headers: the key, and the workspace if set. */
|
|
124
|
+
export function browsersApi() {
|
|
125
|
+
const workspace = process.env.LANGSMITH_WORKSPACE_ID;
|
|
126
|
+
const key = process.env.LANGSMITH_API_KEY || process.env.LANGCHAIN_API_KEY || "";
|
|
127
|
+
return {
|
|
128
|
+
url: `${endpoint()}/v2/sandboxes`,
|
|
129
|
+
headers: {
|
|
130
|
+
"X-Api-Key": key,
|
|
131
|
+
...(workspace ? { "X-Tenant-Id": workspace } : {}),
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/** LangSmith's API. */
|
|
136
|
+
export function endpoint() {
|
|
137
|
+
const url = process.env.LANGSMITH_ENDPOINT ||
|
|
138
|
+
process.env.LANGCHAIN_ENDPOINT ||
|
|
139
|
+
"https://api.smith.langchain.com";
|
|
140
|
+
return url.replace(/\/+$/, "");
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Attach Stagehand to a window of `key`'s browser, creating either as needed.
|
|
144
|
+
*
|
|
145
|
+
* The client reaches Chrome through the API's CDP proxy; the extension, inside
|
|
146
|
+
* the browser sandbox, dials the window's local port. A window the user still
|
|
147
|
+
* holds from an ended handoff is taken back.
|
|
148
|
+
*/
|
|
149
|
+
export async function openSession(key, windowName, idleTtlSeconds, onCloseRequested) {
|
|
150
|
+
const api = browsersApi();
|
|
151
|
+
const { headers } = api;
|
|
152
|
+
const browsers = `${api.url}/browsers`;
|
|
153
|
+
const boxes = new SandboxClient({ apiKey: headers["X-Api-Key"], headers });
|
|
154
|
+
const { name, box } = await usableBrowser(api, boxes, key, idleTtlSeconds);
|
|
155
|
+
await installExtension(box);
|
|
156
|
+
await request(api, "POST", `${browsers}/${name}/extensions/load`); // a no-op once loaded
|
|
157
|
+
const window = await findWindow(api, `${browsers}/${name}`, windowName);
|
|
158
|
+
if (window.controller === "user") {
|
|
159
|
+
const controller = `${browsers}/${name}/attachments/${window.id}/controller`;
|
|
160
|
+
await request(api, "POST", controller, { controller: "agent" });
|
|
161
|
+
}
|
|
162
|
+
const debugging = `${window.api_cdp_url}/json/version`;
|
|
163
|
+
const cdpUrl = (await request(api, "GET", debugging)).webSocketDebuggerUrl;
|
|
164
|
+
const port = await windowPort(box, window.id);
|
|
165
|
+
const localUrl = `ws://127.0.0.1:${port}/devtools/browser/${window.id}`;
|
|
166
|
+
const attach = () => connect(windowName, name, cdpUrl, localUrl, headers, onCloseRequested);
|
|
167
|
+
try {
|
|
168
|
+
return await attach();
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
if (!String(err).includes("already initialized"))
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
// A client that never closed (a crash, another replica) left its claim in the
|
|
175
|
+
// extension; reloading it clears the claim without restarting Chrome.
|
|
176
|
+
await reloadExtension(cdpUrl, headers);
|
|
177
|
+
return attach();
|
|
178
|
+
}
|
|
179
|
+
/** The browser's window `name`, created for the agent if it has none. */
|
|
180
|
+
async function findWindow(api, browser, name) {
|
|
181
|
+
const info = await request(api, "GET", browser);
|
|
182
|
+
const window = info.attachments?.find((w) => w.name === name);
|
|
183
|
+
if (window)
|
|
184
|
+
return window;
|
|
185
|
+
const body = { name, controller: "agent" };
|
|
186
|
+
return request(api, "POST", `${browser}/attachments`, body);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Give the user `key`'s window, creating either as needed.
|
|
190
|
+
*
|
|
191
|
+
* Returns the browser's name, the window's id, and a short-lived link the user
|
|
192
|
+
* drives it with.
|
|
193
|
+
*/
|
|
194
|
+
export async function handOver(key, windowName, idleTtlSeconds) {
|
|
195
|
+
const api = browsersApi();
|
|
196
|
+
const { headers } = api;
|
|
197
|
+
const browsers = `${api.url}/browsers`;
|
|
198
|
+
const boxes = new SandboxClient({ apiKey: headers["X-Api-Key"], headers });
|
|
199
|
+
const { name } = await usableBrowser(api, boxes, key, idleTtlSeconds);
|
|
200
|
+
const window = await findWindow(api, `${browsers}/${name}`, windowName);
|
|
201
|
+
const windowApi = `${browsers}/${name}/attachments/${window.id}`;
|
|
202
|
+
await request(api, "POST", `${windowApi}/controller`, { controller: "user" });
|
|
203
|
+
const body = {
|
|
204
|
+
ttl_seconds: HANDOFF_LINK_TTL_S,
|
|
205
|
+
embed_origins: await embedOrigins(api),
|
|
206
|
+
};
|
|
207
|
+
const link = await request(api, "POST", `${windowApi}/links`, body);
|
|
208
|
+
return { browser: name, windowId: window.id, url: link.act_url };
|
|
209
|
+
}
|
|
210
|
+
/** How the handoff ended, or `undefined` while the user still has the window. */
|
|
211
|
+
export async function handoffStatus(pending) {
|
|
212
|
+
const api = browsersApi();
|
|
213
|
+
try {
|
|
214
|
+
const browser = `${api.url}/browsers/${pending.browser}`;
|
|
215
|
+
const info = await request(api, "GET", browser, undefined, 10_000);
|
|
216
|
+
const window = info.attachments?.find((w) => w.id === pending.window_id);
|
|
217
|
+
if (window === undefined)
|
|
218
|
+
return "ended";
|
|
219
|
+
if (window.controller === "agent")
|
|
220
|
+
return "handed_back";
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
if (err.status === 404)
|
|
224
|
+
return "ended";
|
|
225
|
+
// Asked again later.
|
|
226
|
+
}
|
|
227
|
+
return Date.now() / 1000 >= pending.until ? "ended" : undefined;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Origins whose pages may frame a handoff's window: the LangSmith UI, plus any
|
|
231
|
+
* in `MDA_BROWSER_EMBED_ORIGINS` (comma-separated), such as a UI preview build.
|
|
232
|
+
*/
|
|
233
|
+
export async function embedOrigins(api) {
|
|
234
|
+
const extra = (process.env.MDA_BROWSER_EMBED_ORIGINS ?? "").split(",");
|
|
235
|
+
const ui = await langsmithUiOrigin(api);
|
|
236
|
+
const origins = [ui, ...extra.map((o) => o.trim()).filter(Boolean)];
|
|
237
|
+
return [...new Set(origins)];
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* The LangSmith UI's origin, where Studio may embed a handoff's window: the
|
|
241
|
+
* workspace's `dashboard_url`.
|
|
242
|
+
*/
|
|
243
|
+
async function langsmithUiOrigin(api) {
|
|
244
|
+
const workspace = `${endpoint()}/v1/platform/workspaces/current/info`;
|
|
245
|
+
const info = await request(api, "GET", workspace);
|
|
246
|
+
return new URL(info.dashboard_url).origin;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Let browser `name` open `sandbox`'s servers at `http://localhost:<port>`.
|
|
250
|
+
*
|
|
251
|
+
* One window attached with `share_localhost` serves the whole browser. A
|
|
252
|
+
* sandbox MDA replaced under the same name keeps the window's `sandbox` but not
|
|
253
|
+
* its id, so the window is checked by the id its `localhost_alias` names.
|
|
254
|
+
*/
|
|
255
|
+
export async function shareLocalhost(name, sandbox) {
|
|
256
|
+
const api = browsersApi();
|
|
257
|
+
const browser = `${api.url}/browsers/${name}`;
|
|
258
|
+
const info = await request(api, "GET", browser);
|
|
259
|
+
const window = info.attachments?.find((w) => w.name === LOCALHOST_WINDOW);
|
|
260
|
+
if (window) {
|
|
261
|
+
const box = `${api.url}/boxes/${sandbox}`;
|
|
262
|
+
const { id } = await request(api, "GET", box);
|
|
263
|
+
if (window.localhost_alias === localhostAlias(id))
|
|
264
|
+
return;
|
|
265
|
+
await request(api, "DELETE", `${browser}/attachments/${window.id}`); // an old sandbox's
|
|
266
|
+
}
|
|
267
|
+
const body = { name: LOCALHOST_WINDOW, sandbox, share_localhost: true };
|
|
268
|
+
await request(api, "POST", `${browser}/attachments`, body);
|
|
269
|
+
}
|
|
270
|
+
/** The browser's host for a sandbox's localhost: `sb-` and its id in base32. */
|
|
271
|
+
export function localhostAlias(sandboxId) {
|
|
272
|
+
const hex = sandboxId.replaceAll("-", "");
|
|
273
|
+
if (!/^[\da-f]{32}$/i.test(hex)) {
|
|
274
|
+
throw new Error("badly formed hexadecimal UUID string"); // as uuid.UUID
|
|
275
|
+
}
|
|
276
|
+
// RFC 4648 base32 of the UUID's 16 bytes, lowercase and unpadded: 26 digits.
|
|
277
|
+
const alphabet = "abcdefghijklmnopqrstuvwxyz234567";
|
|
278
|
+
const digits = (BigInt(`0x${hex}`) << 2n).toString(32).padStart(26, "0");
|
|
279
|
+
const label = [...digits].map((d) => alphabet[parseInt(d, 32)]).join("");
|
|
280
|
+
return `sb-${label}.localhost`;
|
|
281
|
+
}
|
|
282
|
+
/** A browsers API call's JSON, if any; an unsuccessful status throws, as Python's `_raise` does. */
|
|
283
|
+
async function request(api, method, url, body, timeoutMs = 90_000) {
|
|
284
|
+
const response = await fetch(url, {
|
|
285
|
+
method,
|
|
286
|
+
headers: body
|
|
287
|
+
? { ...api.headers, "Content-Type": "application/json" }
|
|
288
|
+
: api.headers,
|
|
289
|
+
body: body && JSON.stringify(body),
|
|
290
|
+
redirect: "manual", // as httpx: a redirect is an error, and the key never follows one
|
|
291
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
292
|
+
});
|
|
293
|
+
const text = await response.text(); // read even when unused, freeing the connection
|
|
294
|
+
if (!response.ok) {
|
|
295
|
+
const msg = `LangSmith browsers API: HTTP ${response.status} ${text.slice(0, 300)}`;
|
|
296
|
+
throw Object.assign(new Error(msg), { status: response.status });
|
|
297
|
+
}
|
|
298
|
+
return (text ? JSON.parse(text) : undefined);
|
|
299
|
+
}
|
|
300
|
+
export async function connect(window, browser, cdpUrl, localUrl, headers, onCloseRequested) {
|
|
301
|
+
const handle = await localBrowser.connect({
|
|
302
|
+
cdpUrl,
|
|
303
|
+
extensionCdpUrl: localUrl,
|
|
304
|
+
headers,
|
|
305
|
+
});
|
|
306
|
+
// When this fails, 4.3.0 has no public way to drop `handle`: a known leak.
|
|
307
|
+
const stagehand = await Stagehand.create({ browser: handle });
|
|
308
|
+
const artifacts = await mkdtemp(join(tmpdir(), "mda-browser-"));
|
|
309
|
+
// Run code's `browser.close()` releases only our client, not the browser.
|
|
310
|
+
const tools = new StagehandFacadeTools(stagehand, {
|
|
311
|
+
artifactRoot: artifacts,
|
|
312
|
+
onCloseRequested,
|
|
313
|
+
quietWait: true,
|
|
314
|
+
keeperPage: false,
|
|
315
|
+
});
|
|
316
|
+
// The facade acts on Chrome's focused tab, which is often in a window this client
|
|
317
|
+
// cannot see (another thread's, or the shared localhost one), and `setActivePage`
|
|
318
|
+
// does not move headless Chrome's focus. It has no hook for the page, so name ours.
|
|
319
|
+
Object.assign(tools, { activePage: () => newestTab(handle.context) });
|
|
320
|
+
return {
|
|
321
|
+
window,
|
|
322
|
+
browser,
|
|
323
|
+
stagehand,
|
|
324
|
+
tools,
|
|
325
|
+
artifacts,
|
|
326
|
+
transport: stagehand.rpcClient?.cdp, // `stagehand.close()` clears `rpcClient`
|
|
327
|
+
closing: false,
|
|
328
|
+
shared: undefined,
|
|
329
|
+
localUrl,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/** The window's newest tab, as it was: the client's CDP lists only its window's. */
|
|
333
|
+
export async function newestTab(context) {
|
|
334
|
+
const pages = await context.pages();
|
|
335
|
+
return pages.at(-1) ?? (await context.newPage());
|
|
336
|
+
}
|
|
337
|
+
/** Browser `name`'s sandbox, where the recorder runs. */
|
|
338
|
+
export async function browserBox(name) {
|
|
339
|
+
const { headers } = browsersApi();
|
|
340
|
+
const boxes = new SandboxClient({ apiKey: headers["X-Api-Key"], headers });
|
|
341
|
+
return boxes.getSandbox(name);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Start recording `tab` of the window at `localUrl`, beside Chrome in `box`.
|
|
345
|
+
*
|
|
346
|
+
* Returns the take's folder there. The recorder follows newer tabs itself, and
|
|
347
|
+
* records until it is stopped or reaches its limit, whatever happens to this
|
|
348
|
+
* process's client.
|
|
349
|
+
*/
|
|
350
|
+
export async function startTake(box, localUrl, tab) {
|
|
351
|
+
const folder = `${RECORDER_TAKES}-${randomUUID()}`;
|
|
352
|
+
const start = recorderCommand(folder, "start", localUrl, tab);
|
|
353
|
+
try {
|
|
354
|
+
await box.run(`mkdir -p -- ${shellQuote(folder)}`, { timeout: 60 });
|
|
355
|
+
await box.write(`${folder}/recorder.py`, await readFile(RECORDER), 60);
|
|
356
|
+
await recorder(box, `${installRecorder()} && ${start}`, 300, StartReply);
|
|
357
|
+
}
|
|
358
|
+
catch (err) {
|
|
359
|
+
if (err instanceof RecorderError)
|
|
360
|
+
await removeTake(box, folder);
|
|
361
|
+
throw err;
|
|
362
|
+
}
|
|
363
|
+
return folder;
|
|
364
|
+
}
|
|
365
|
+
/** Stop the take in `folder`, wait while the recorder encodes it, and download it. */
|
|
366
|
+
export async function stopTake(box, folder) {
|
|
367
|
+
const stop = recorderCommand(folder, "stop");
|
|
368
|
+
try {
|
|
369
|
+
const reply = await recorder(box, stop, RECORDER_STOP_TIMEOUT_S, StopReply);
|
|
370
|
+
const read = (name) => box.read(`${folder}/${name}`, 300);
|
|
371
|
+
const [video, timeline, first, last] = await Promise.all([
|
|
372
|
+
read("take.mp4"),
|
|
373
|
+
read("take.json"),
|
|
374
|
+
read("first.jpg"),
|
|
375
|
+
read("last.jpg"),
|
|
376
|
+
]);
|
|
377
|
+
return { video, timeline, first, last, ...reply };
|
|
378
|
+
}
|
|
379
|
+
finally {
|
|
380
|
+
await removeTake(box, folder); // the take holds what the tab showed
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/** Remove a take's folder, with its copy of the recorder; it never fails. */
|
|
384
|
+
async function removeTake(box, folder) {
|
|
385
|
+
const remove = `rm -rf -- ${shellQuote(folder)}`;
|
|
386
|
+
await box.run(remove, { timeout: 60 }).catch(() => undefined);
|
|
387
|
+
}
|
|
388
|
+
/** Run a recorder `command`: its `reply`, or `RecorderError` with why it failed. */
|
|
389
|
+
async function recorder(box, command, timeout, reply) {
|
|
390
|
+
const ran = await box.run(command, { timeout });
|
|
391
|
+
let printed;
|
|
392
|
+
try {
|
|
393
|
+
printed = JSON.parse(ran.stdout.trim().split(/\r?\n/).at(-1));
|
|
394
|
+
}
|
|
395
|
+
catch { } // not the recorder's reply
|
|
396
|
+
const parsed = reply.safeParse(printed);
|
|
397
|
+
if (ran.exit_code === 0 && parsed.success)
|
|
398
|
+
return parsed.data;
|
|
399
|
+
const stderr = ran.stderr.trim().slice(-300);
|
|
400
|
+
const why = ErrorReply.safeParse(printed).data?.error ||
|
|
401
|
+
stderr ||
|
|
402
|
+
`exit ${ran.exit_code}`;
|
|
403
|
+
throw new RecorderError(`the recorder failed: ${why}`);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* A command that installs the recorder's packages, unless they are there.
|
|
407
|
+
*
|
|
408
|
+
* Installed aside, so a partial install never passes the check.
|
|
409
|
+
*/
|
|
410
|
+
function installRecorder() {
|
|
411
|
+
const [target, home] = [RECORDER_PACKAGES_DIR, RECORDER_HOME].map(shellQuote);
|
|
412
|
+
const pins = RECORDER_PACKAGES.map(shellQuote).join(" ");
|
|
413
|
+
const pip = "python3 -m pip install --quiet --disable-pip-version-check --no-cache-dir " +
|
|
414
|
+
`--root-user-action=ignore --only-binary=:all: --target "$tmp" ${pins}`;
|
|
415
|
+
return (`{ test -e ${target}/.installed || { mkdir -p ${home} && ` +
|
|
416
|
+
`tmp=$(mktemp -d ${home}/install.XXXXXX) && ` +
|
|
417
|
+
`{ ${pip} >"$tmp.log" 2>&1 || { tail -c 300 "$tmp.log" >&2; exit 1; }; } && ` +
|
|
418
|
+
`rm -f "$tmp.log" && touch "$tmp/.installed" && ` +
|
|
419
|
+
`{ mv -T "$tmp" ${target} 2>/dev/null || rm -rf "$tmp"; }; }; }`);
|
|
420
|
+
}
|
|
421
|
+
/** Run the take's own copy of the recorder, in `folder`, on `folder`. */
|
|
422
|
+
function recorderCommand(folder, action, ...args) {
|
|
423
|
+
const words = [`${folder}/recorder.py`, action, folder, ...args].map(shellQuote);
|
|
424
|
+
return `PYTHONPATH=${shellQuote(RECORDER_PACKAGES_DIR)} python3 ${words.join(" ")}`;
|
|
425
|
+
}
|
|
426
|
+
/** `text` quoted for a POSIX shell, as Python's `shlex.quote` does. */
|
|
427
|
+
export function shellQuote(text) {
|
|
428
|
+
if (text === "")
|
|
429
|
+
return "''";
|
|
430
|
+
if (/^[\w@%+=:,./-]+$/.test(text))
|
|
431
|
+
return text;
|
|
432
|
+
return `'${text.replaceAll("'", `'"'"'`)}'`;
|
|
433
|
+
}
|
|
434
|
+
/** Unpack the client's own extension into the browser, unless it is there already. */
|
|
435
|
+
export async function installExtension(box) {
|
|
436
|
+
const check = `test -f ${EXTENSION_DIR}/manifest.json`;
|
|
437
|
+
if ((await box.run(check, { timeout: 60 })).exit_code === 0)
|
|
438
|
+
return;
|
|
439
|
+
await box.write(EXTENSION_ZIP, await getExtensionArchive(), 300);
|
|
440
|
+
const tmp = `${EXTENSION_DIR}.tmp`; // unpacked aside, so a partial copy never passes the check
|
|
441
|
+
const unpacked = await box.run(`rm -rf ${tmp} && python3 -m zipfile -e ${EXTENSION_ZIP} ${tmp} && ` +
|
|
442
|
+
`rm -rf ${EXTENSION_DIR} && mv ${tmp} ${EXTENSION_DIR}`, { timeout: 300 });
|
|
443
|
+
if (unpacked.exit_code !== 0) {
|
|
444
|
+
const msg = `could not install Stagehand in the browser: ${unpacked.stderr.slice(-500)}`;
|
|
445
|
+
throw new Error(msg);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Load Stagehand's extension again over CDP, which reloads it in place.
|
|
450
|
+
*
|
|
451
|
+
* Not uninstalled first: Chrome uninstalls over CDP only an extension loaded
|
|
452
|
+
* over CDP, and browserd loads it otherwise when Chrome starts.
|
|
453
|
+
*/
|
|
454
|
+
async function reloadExtension(cdpUrl, headers) {
|
|
455
|
+
const ws = new WebSocket(cdpUrl, { headers });
|
|
456
|
+
let fail = () => undefined;
|
|
457
|
+
const failed = new Promise((_, reject) => {
|
|
458
|
+
fail = reject;
|
|
459
|
+
});
|
|
460
|
+
failed.catch(() => undefined); // raced by each step; it may also settle after the last
|
|
461
|
+
const deadline = AbortSignal.timeout(30_000);
|
|
462
|
+
deadline.addEventListener("abort", () => fail(deadline.reason));
|
|
463
|
+
ws.addEventListener("close", () => fail(new Error("CDP connection closed")));
|
|
464
|
+
const waiting = new Map();
|
|
465
|
+
ws.addEventListener("message", (event) => {
|
|
466
|
+
try {
|
|
467
|
+
const reply = JSON.parse(String(event.data));
|
|
468
|
+
waiting.get(reply.id ?? -1)?.(reply); // events share the socket
|
|
469
|
+
}
|
|
470
|
+
catch (err) {
|
|
471
|
+
fail(err); // a listener that throws would crash the process
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
async function cdp(id, method, params = {}) {
|
|
475
|
+
const reply = new Promise((resolve) => waiting.set(id, resolve));
|
|
476
|
+
ws.send(JSON.stringify({ id, method, params }));
|
|
477
|
+
const { error, result } = await Promise.race([reply, failed]);
|
|
478
|
+
if (error !== undefined) {
|
|
479
|
+
throw new Error(`CDP ${method} failed: ${JSON.stringify(error)}`);
|
|
480
|
+
}
|
|
481
|
+
return result ?? {};
|
|
482
|
+
}
|
|
483
|
+
try {
|
|
484
|
+
const open = new Promise((resolve) => ws.addEventListener("open", resolve));
|
|
485
|
+
await Promise.race([open, failed]);
|
|
486
|
+
await cdp(0, "Extensions.loadUnpacked", { path: EXTENSION_DIR });
|
|
487
|
+
}
|
|
488
|
+
finally {
|
|
489
|
+
ws.close();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/** The port browserd serves a window on inside the browser sandbox, once it is saved. */
|
|
493
|
+
async function windowPort(box, windowId) {
|
|
494
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
495
|
+
const saved = await box.run(`cat ${WINDOWS_FILE}`, { timeout: 60 });
|
|
496
|
+
try {
|
|
497
|
+
const { attachments } = JSON.parse(saved.stdout);
|
|
498
|
+
const port = attachments.find((w) => w.id === windowId)?.port;
|
|
499
|
+
if (port)
|
|
500
|
+
return Number(port);
|
|
501
|
+
}
|
|
502
|
+
catch { } // not saved yet
|
|
503
|
+
await sleep(250);
|
|
504
|
+
}
|
|
505
|
+
throw new Error("could not find the browser window's port");
|
|
506
|
+
}
|
|
507
|
+
//# sourceMappingURL=browser-langsmith.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-langsmith.js","sourceRoot":"","sources":["../../src/runtime/browser-langsmith.ts"],"names":[],"mappings":"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"}
|