@townco/agent 0.1.55 → 0.1.57
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/dist/acp-server/adapter.d.ts +7 -0
- package/dist/acp-server/adapter.js +96 -18
- package/dist/acp-server/http.js +74 -1
- package/dist/acp-server/session-storage.d.ts +14 -0
- package/dist/acp-server/session-storage.js +47 -0
- package/dist/definition/index.d.ts +16 -0
- package/dist/definition/index.js +16 -0
- package/dist/runner/agent-runner.d.ts +8 -1
- package/dist/runner/agent-runner.js +3 -1
- package/dist/runner/langchain/index.js +139 -7
- package/dist/runner/langchain/model-factory.d.ts +2 -0
- package/dist/runner/langchain/model-factory.js +19 -0
- package/dist/runner/langchain/tools/browser.d.ts +100 -0
- package/dist/runner/langchain/tools/browser.js +412 -0
- package/dist/runner/langchain/tools/subagent-connections.d.ts +28 -0
- package/dist/runner/langchain/tools/subagent-connections.js +58 -0
- package/dist/runner/langchain/tools/subagent.js +5 -1
- package/dist/runner/tools.d.ts +2 -2
- package/dist/runner/tools.js +1 -0
- package/dist/scaffold/index.js +7 -1
- package/dist/scaffold/templates/dot-claude/CLAUDE-append.md +2 -0
- package/dist/telemetry/index.d.ts +5 -0
- package/dist/telemetry/index.js +10 -0
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.js +29 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -6
- package/templates/index.ts +39 -7
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
|
|
2
2
|
import { context, propagation, trace } from "@opentelemetry/api";
|
|
3
|
+
import { loadAuthCredentials } from "@townco/core/auth";
|
|
3
4
|
import { AIMessageChunk, createAgent, ToolMessage, tool, } from "langchain";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
import { SUBAGENT_MODE_KEY } from "../../acp-server/adapter";
|
|
@@ -8,9 +9,11 @@ import { telemetry } from "../../telemetry/index.js";
|
|
|
8
9
|
import { loadCustomToolModule, } from "../tool-loader.js";
|
|
9
10
|
import { createModelFromString, detectProvider } from "./model-factory.js";
|
|
10
11
|
import { makeOtelCallbacks } from "./otel-callbacks.js";
|
|
12
|
+
import { makeBrowserTools } from "./tools/browser";
|
|
11
13
|
import { makeFilesystemTools } from "./tools/filesystem";
|
|
12
14
|
import { makeGenerateImageTool } from "./tools/generate_image";
|
|
13
15
|
import { SUBAGENT_TOOL_NAME } from "./tools/subagent";
|
|
16
|
+
import { hashQuery, queryToToolCallId, subagentEvents, } from "./tools/subagent-connections";
|
|
14
17
|
import { TODO_WRITE_TOOL_NAME, todoWrite } from "./tools/todo";
|
|
15
18
|
import { makeWebSearchTools } from "./tools/web_search";
|
|
16
19
|
const _logger = createLogger("agent-runner");
|
|
@@ -29,6 +32,7 @@ export const TOOL_REGISTRY = {
|
|
|
29
32
|
web_search: () => makeWebSearchTools(),
|
|
30
33
|
filesystem: () => makeFilesystemTools(process.cwd()),
|
|
31
34
|
generate_image: () => makeGenerateImageTool(),
|
|
35
|
+
browser: () => makeBrowserTools(),
|
|
32
36
|
};
|
|
33
37
|
// ============================================================================
|
|
34
38
|
// Custom tool loading
|
|
@@ -78,11 +82,64 @@ export class LangchainAgent {
|
|
|
78
82
|
const countedMessageIds = new Set();
|
|
79
83
|
// Track tool calls for which we've emitted preliminary notifications (from early tool_use blocks)
|
|
80
84
|
const preliminaryToolCallIds = new Set();
|
|
85
|
+
// Set session_id as a base attribute so all spans in this invocation include it
|
|
86
|
+
telemetry.setBaseAttributes({
|
|
87
|
+
"agent.session_id": req.sessionId,
|
|
88
|
+
});
|
|
89
|
+
const subagentUpdateQueue = [];
|
|
90
|
+
let subagentUpdateResolver = null;
|
|
91
|
+
// Listen for subagent connection events - resolve any waiting promise immediately
|
|
92
|
+
const onSubagentConnection = (event) => {
|
|
93
|
+
_logger.info("Received subagent connection event", {
|
|
94
|
+
toolCallId: event.toolCallId,
|
|
95
|
+
port: event.port,
|
|
96
|
+
sessionId: event.sessionId,
|
|
97
|
+
});
|
|
98
|
+
if (subagentUpdateResolver) {
|
|
99
|
+
// If someone is waiting, resolve immediately
|
|
100
|
+
const resolver = subagentUpdateResolver;
|
|
101
|
+
subagentUpdateResolver = null;
|
|
102
|
+
resolver(event);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Otherwise queue for later
|
|
106
|
+
subagentUpdateQueue.push(event);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
subagentEvents.on("connection", onSubagentConnection);
|
|
110
|
+
// Helper to get next subagent update (returns immediately if queued, otherwise waits)
|
|
111
|
+
const waitForSubagentUpdate = () => {
|
|
112
|
+
if (subagentUpdateQueue.length > 0) {
|
|
113
|
+
return Promise.resolve(subagentUpdateQueue.shift());
|
|
114
|
+
}
|
|
115
|
+
return new Promise((resolve) => {
|
|
116
|
+
subagentUpdateResolver = resolve;
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
// Helper to check and yield all pending subagent updates
|
|
120
|
+
async function* yieldPendingSubagentUpdates() {
|
|
121
|
+
while (subagentUpdateQueue.length > 0) {
|
|
122
|
+
const update = subagentUpdateQueue.shift();
|
|
123
|
+
_logger.info("Yielding queued subagent connection update", {
|
|
124
|
+
toolCallId: update.toolCallId,
|
|
125
|
+
subagentPort: update.port,
|
|
126
|
+
subagentSessionId: update.sessionId,
|
|
127
|
+
});
|
|
128
|
+
yield {
|
|
129
|
+
sessionUpdate: "tool_call_update",
|
|
130
|
+
toolCallId: update.toolCallId,
|
|
131
|
+
_meta: {
|
|
132
|
+
messageId: req.messageId,
|
|
133
|
+
subagentPort: update.port,
|
|
134
|
+
subagentSessionId: update.sessionId,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
81
139
|
// Start telemetry span for entire invocation
|
|
82
140
|
const invocationSpan = telemetry.startSpan("agent.invoke", {
|
|
83
141
|
"agent.model": this.definition.model,
|
|
84
142
|
"agent.subagent": meta?.[SUBAGENT_MODE_KEY] === true,
|
|
85
|
-
"agent.session_id": req.sessionId,
|
|
86
143
|
"agent.message_id": req.messageId,
|
|
87
144
|
}, parentContext);
|
|
88
145
|
// Create a context with the invocation span as active
|
|
@@ -294,7 +351,7 @@ export class LangchainAgent {
|
|
|
294
351
|
: wrappedTools;
|
|
295
352
|
// Wrap tools with tracing so each tool executes within its own span context.
|
|
296
353
|
// This ensures subagent spans are children of the Task tool span.
|
|
297
|
-
const finalTools = filteredTools.map((t) => wrapToolWithTracing(t
|
|
354
|
+
const finalTools = filteredTools.map((t) => wrapToolWithTracing(t));
|
|
298
355
|
// Create the model instance using the factory
|
|
299
356
|
// This detects the provider from the model string:
|
|
300
357
|
// - "gemini-2.0-flash" → Google Generative AI
|
|
@@ -419,7 +476,53 @@ export class LangchainAgent {
|
|
|
419
476
|
recursionLimit: 200,
|
|
420
477
|
callbacks: [otelCallbacks],
|
|
421
478
|
}));
|
|
422
|
-
|
|
479
|
+
// Use manual iteration with Promise.race to interleave stream events with subagent updates
|
|
480
|
+
const streamIterator = (await stream)[Symbol.asyncIterator]();
|
|
481
|
+
let streamDone = false;
|
|
482
|
+
let pendingStreamPromise = null;
|
|
483
|
+
while (!streamDone) {
|
|
484
|
+
// Get or create the stream promise (reuse if still pending from last iteration)
|
|
485
|
+
const nextStreamPromise = pendingStreamPromise ?? streamIterator.next();
|
|
486
|
+
pendingStreamPromise = nextStreamPromise; // Track it
|
|
487
|
+
// Create subagent wait promise (only if no queued updates)
|
|
488
|
+
const subagentPromise = waitForSubagentUpdate();
|
|
489
|
+
// Use Promise.race, but we need to handle both outcomes
|
|
490
|
+
const result = await Promise.race([
|
|
491
|
+
nextStreamPromise.then((r) => ({
|
|
492
|
+
type: "stream",
|
|
493
|
+
result: r,
|
|
494
|
+
})),
|
|
495
|
+
subagentPromise.then((u) => ({ type: "subagent", update: u })),
|
|
496
|
+
]);
|
|
497
|
+
if (result.type === "subagent") {
|
|
498
|
+
// Got a subagent update - yield it immediately
|
|
499
|
+
const update = result.update;
|
|
500
|
+
_logger.info("Yielding subagent connection update (via race)", {
|
|
501
|
+
toolCallId: update.toolCallId,
|
|
502
|
+
subagentPort: update.port,
|
|
503
|
+
subagentSessionId: update.sessionId,
|
|
504
|
+
});
|
|
505
|
+
yield {
|
|
506
|
+
sessionUpdate: "tool_call_update",
|
|
507
|
+
toolCallId: update.toolCallId,
|
|
508
|
+
_meta: {
|
|
509
|
+
messageId: req.messageId,
|
|
510
|
+
subagentPort: update.port,
|
|
511
|
+
subagentSessionId: update.sessionId,
|
|
512
|
+
},
|
|
513
|
+
};
|
|
514
|
+
// Continue - the stream promise is still pending, will be reused
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
// Got a stream item - clear the pending promise
|
|
518
|
+
pendingStreamPromise = null;
|
|
519
|
+
const { done, value: streamItem } = result.result;
|
|
520
|
+
if (done) {
|
|
521
|
+
streamDone = true;
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
// Also yield any queued subagent updates before processing stream item
|
|
525
|
+
yield* yieldPendingSubagentUpdates();
|
|
423
526
|
const [streamMode, chunk] = streamItem;
|
|
424
527
|
if (streamMode === "updates") {
|
|
425
528
|
const updatesChunk = modelRequestSchema.safeParse(chunk);
|
|
@@ -511,6 +614,17 @@ export class LangchainAgent {
|
|
|
511
614
|
const subagentConfigs = taskTool?.subagentConfigs;
|
|
512
615
|
const subagentConfig = subagentConfigs?.find((config) => config.agentName === agentName);
|
|
513
616
|
prettyName = subagentConfig?.displayName ?? agentName;
|
|
617
|
+
// Register query hash -> toolCallId mapping for subagent connection info
|
|
618
|
+
if ("query" in toolCall.args &&
|
|
619
|
+
typeof toolCall.args.query === "string") {
|
|
620
|
+
const qHash = hashQuery(toolCall.args.query);
|
|
621
|
+
queryToToolCallId.set(qHash, toolCall.id);
|
|
622
|
+
telemetry.log("info", "Registered subagent query hash mapping", {
|
|
623
|
+
queryHash: qHash,
|
|
624
|
+
toolCallId: toolCall.id,
|
|
625
|
+
queryPreview: toolCall.args.query.slice(0, 50),
|
|
626
|
+
});
|
|
627
|
+
}
|
|
514
628
|
}
|
|
515
629
|
// Check if we already emitted a preliminary notification from early tool_use block
|
|
516
630
|
const alreadyEmittedPreliminary = preliminaryToolCallIds.has(toolCall.id);
|
|
@@ -744,6 +858,16 @@ export class LangchainAgent {
|
|
|
744
858
|
else {
|
|
745
859
|
throw new Error(`Unhandled stream mode: ${streamMode}`);
|
|
746
860
|
}
|
|
861
|
+
// Yield any pending subagent connection updates
|
|
862
|
+
yield* yieldPendingSubagentUpdates();
|
|
863
|
+
}
|
|
864
|
+
// Yield any remaining pending subagent connection updates after stream ends
|
|
865
|
+
yield* yieldPendingSubagentUpdates();
|
|
866
|
+
// Clean up subagent connection listener
|
|
867
|
+
subagentEvents.off("connection", onSubagentConnection);
|
|
868
|
+
// Cancel any pending wait
|
|
869
|
+
if (subagentUpdateResolver) {
|
|
870
|
+
subagentUpdateResolver = null;
|
|
747
871
|
}
|
|
748
872
|
// Log successful completion
|
|
749
873
|
telemetry.log("info", "Agent invocation completed", {
|
|
@@ -758,6 +882,8 @@ export class LangchainAgent {
|
|
|
758
882
|
};
|
|
759
883
|
}
|
|
760
884
|
catch (error) {
|
|
885
|
+
// Clean up subagent connection listener on error
|
|
886
|
+
subagentEvents.off("connection", onSubagentConnection);
|
|
761
887
|
// Log error and end span with error status
|
|
762
888
|
telemetry.log("error", "Agent invocation failed", {
|
|
763
889
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -776,12 +902,19 @@ const modelRequestSchema = z.object({
|
|
|
776
902
|
const makeMcpToolsClient = (mcpConfigs) => {
|
|
777
903
|
const mcpServers = mcpConfigs?.map((config) => {
|
|
778
904
|
if (typeof config === "string") {
|
|
779
|
-
//
|
|
780
|
-
const
|
|
905
|
+
// String configs use the centralized MCP proxy with auth
|
|
906
|
+
const credentials = loadAuthCredentials();
|
|
907
|
+
if (!credentials) {
|
|
908
|
+
throw new Error("Not logged in. Run 'town login' first to use cloud MCP servers.");
|
|
909
|
+
}
|
|
910
|
+
const proxyUrl = process.env.MCP_PROXY_URL ?? `${credentials.shed_url}/mcp_proxy`;
|
|
781
911
|
return [
|
|
782
912
|
config,
|
|
783
913
|
{
|
|
784
914
|
url: `${proxyUrl}?server=${config}`,
|
|
915
|
+
headers: {
|
|
916
|
+
Authorization: `Bearer ${credentials.access_token}`,
|
|
917
|
+
},
|
|
785
918
|
},
|
|
786
919
|
];
|
|
787
920
|
}
|
|
@@ -874,13 +1007,12 @@ export { makeSubagentsTool } from "./tools/subagent.js";
|
|
|
874
1007
|
* so any child operations (like subagent spawning) become children
|
|
875
1008
|
* of the tool span rather than the parent invocation span.
|
|
876
1009
|
*/
|
|
877
|
-
function wrapToolWithTracing(originalTool
|
|
1010
|
+
function wrapToolWithTracing(originalTool) {
|
|
878
1011
|
const wrappedFunc = async (input) => {
|
|
879
1012
|
const toolInputJson = JSON.stringify(input);
|
|
880
1013
|
const toolSpan = telemetry.startSpan("agent.tool_call", {
|
|
881
1014
|
"tool.name": originalTool.name,
|
|
882
1015
|
"tool.input": toolInputJson,
|
|
883
|
-
"agent.session_id": sessionId,
|
|
884
1016
|
});
|
|
885
1017
|
// Create a context with the tool span as active
|
|
886
1018
|
const spanContext = toolSpan
|
|
@@ -4,6 +4,7 @@ import type { BaseChatModel } from "@langchain/core/language_models/chat_models"
|
|
|
4
4
|
* LangChain chat model instance.
|
|
5
5
|
*
|
|
6
6
|
* Detection logic:
|
|
7
|
+
* - If model starts with "town-" → Proxied via shed (strips prefix, uses TOWN_SHED_URL)
|
|
7
8
|
* - If model starts with "vertex-" → Google Vertex AI (strips prefix)
|
|
8
9
|
* - If model contains "gemini" (unprefixed) → Google Generative AI
|
|
9
10
|
* - If model contains "gpt" → OpenAI (future support)
|
|
@@ -12,6 +13,7 @@ import type { BaseChatModel } from "@langchain/core/language_models/chat_models"
|
|
|
12
13
|
* Supported formats:
|
|
13
14
|
* - Direct model name: "gemini-2.0-flash", "vertex-gemini-2.0-flash", "claude-sonnet-4-5-20250929"
|
|
14
15
|
* - Provider prefix: "google_vertexai:gemini-2.0-flash", "google_genai:gemini-2.0-flash", "anthropic:claude-3-5-sonnet"
|
|
16
|
+
* - Proxied: "town-claude-sonnet-4-5-20250929" (uses TOWN_SHED_URL or defaults to localhost:3000)
|
|
15
17
|
*/
|
|
16
18
|
export declare function createModelFromString(modelString: string): BaseChatModel;
|
|
17
19
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ChatAnthropic } from "@langchain/anthropic";
|
|
2
2
|
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
|
|
3
3
|
import { ChatVertexAI } from "@langchain/google-vertexai";
|
|
4
|
+
import { loadAuthCredentials } from "@townco/core/auth";
|
|
4
5
|
import { createLogger } from "../../logger.js";
|
|
5
6
|
const logger = createLogger("model-factory");
|
|
6
7
|
/**
|
|
@@ -8,6 +9,7 @@ const logger = createLogger("model-factory");
|
|
|
8
9
|
* LangChain chat model instance.
|
|
9
10
|
*
|
|
10
11
|
* Detection logic:
|
|
12
|
+
* - If model starts with "town-" → Proxied via shed (strips prefix, uses TOWN_SHED_URL)
|
|
11
13
|
* - If model starts with "vertex-" → Google Vertex AI (strips prefix)
|
|
12
14
|
* - If model contains "gemini" (unprefixed) → Google Generative AI
|
|
13
15
|
* - If model contains "gpt" → OpenAI (future support)
|
|
@@ -16,8 +18,25 @@ const logger = createLogger("model-factory");
|
|
|
16
18
|
* Supported formats:
|
|
17
19
|
* - Direct model name: "gemini-2.0-flash", "vertex-gemini-2.0-flash", "claude-sonnet-4-5-20250929"
|
|
18
20
|
* - Provider prefix: "google_vertexai:gemini-2.0-flash", "google_genai:gemini-2.0-flash", "anthropic:claude-3-5-sonnet"
|
|
21
|
+
* - Proxied: "town-claude-sonnet-4-5-20250929" (uses TOWN_SHED_URL or defaults to localhost:3000)
|
|
19
22
|
*/
|
|
20
23
|
export function createModelFromString(modelString) {
|
|
24
|
+
// Check for town- prefix for proxied models via shed
|
|
25
|
+
if (modelString.startsWith("town-")) {
|
|
26
|
+
const actualModel = modelString.slice(5); // strip "town-"
|
|
27
|
+
const credentials = loadAuthCredentials();
|
|
28
|
+
if (!credentials) {
|
|
29
|
+
throw new Error("Not logged in. Run 'town login' first.");
|
|
30
|
+
}
|
|
31
|
+
const shedUrl = credentials.shed_url ??
|
|
32
|
+
process.env.TOWN_SHED_URL ??
|
|
33
|
+
"http://localhost:3000";
|
|
34
|
+
return new ChatAnthropic({
|
|
35
|
+
model: actualModel,
|
|
36
|
+
anthropicApiUrl: `${shedUrl}/api/anthropic`,
|
|
37
|
+
apiKey: credentials.access_token,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
21
40
|
// Check if the model string uses provider prefix format
|
|
22
41
|
const parts = modelString.split(":", 2);
|
|
23
42
|
const maybeProvider = parts[0];
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
interface BrowserNavigateResult {
|
|
3
|
+
success: boolean;
|
|
4
|
+
url?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
liveViewUrl?: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
interface BrowserScreenshotResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
screenshotPath?: string;
|
|
12
|
+
liveViewUrl?: string;
|
|
13
|
+
error?: string;
|
|
14
|
+
}
|
|
15
|
+
interface BrowserExtractResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
content?: string;
|
|
18
|
+
url?: string;
|
|
19
|
+
title?: string;
|
|
20
|
+
liveViewUrl?: string;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
interface BrowserClickResult {
|
|
24
|
+
success: boolean;
|
|
25
|
+
message?: string;
|
|
26
|
+
liveViewUrl?: string;
|
|
27
|
+
error?: string;
|
|
28
|
+
}
|
|
29
|
+
interface BrowserTypeResult {
|
|
30
|
+
success: boolean;
|
|
31
|
+
message?: string;
|
|
32
|
+
liveViewUrl?: string;
|
|
33
|
+
error?: string;
|
|
34
|
+
}
|
|
35
|
+
interface BrowserCloseResult {
|
|
36
|
+
success: boolean;
|
|
37
|
+
message?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function makeBrowserTools(): readonly [import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
41
|
+
url: z.ZodString;
|
|
42
|
+
waitUntil: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
43
|
+
load: "load";
|
|
44
|
+
domcontentloaded: "domcontentloaded";
|
|
45
|
+
networkidle: "networkidle";
|
|
46
|
+
}>>>;
|
|
47
|
+
}, z.core.$strip>, {
|
|
48
|
+
url: string;
|
|
49
|
+
waitUntil: "load" | "domcontentloaded" | "networkidle";
|
|
50
|
+
}, {
|
|
51
|
+
url: string;
|
|
52
|
+
waitUntil?: "load" | "domcontentloaded" | "networkidle" | undefined;
|
|
53
|
+
}, BrowserNavigateResult>, import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
54
|
+
fullPage: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
55
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
56
|
+
}, z.core.$strip>, {
|
|
57
|
+
fullPage: boolean;
|
|
58
|
+
selector?: string | undefined;
|
|
59
|
+
}, {
|
|
60
|
+
fullPage?: boolean | undefined;
|
|
61
|
+
selector?: string | undefined;
|
|
62
|
+
}, BrowserScreenshotResult>, import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
63
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
64
|
+
extractType: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
65
|
+
text: "text";
|
|
66
|
+
html: "html";
|
|
67
|
+
}>>>;
|
|
68
|
+
}, z.core.$strip>, {
|
|
69
|
+
extractType: "text" | "html";
|
|
70
|
+
selector?: string | undefined;
|
|
71
|
+
}, {
|
|
72
|
+
selector?: string | undefined;
|
|
73
|
+
extractType?: "text" | "html" | undefined;
|
|
74
|
+
}, BrowserExtractResult>, import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
75
|
+
selector: z.ZodString;
|
|
76
|
+
button: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
77
|
+
left: "left";
|
|
78
|
+
right: "right";
|
|
79
|
+
middle: "middle";
|
|
80
|
+
}>>>;
|
|
81
|
+
}, z.core.$strip>, {
|
|
82
|
+
selector: string;
|
|
83
|
+
button: "left" | "right" | "middle";
|
|
84
|
+
}, {
|
|
85
|
+
selector: string;
|
|
86
|
+
button?: "left" | "right" | "middle" | undefined;
|
|
87
|
+
}, BrowserClickResult>, import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
88
|
+
selector: z.ZodString;
|
|
89
|
+
text: z.ZodString;
|
|
90
|
+
pressEnter: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
91
|
+
}, z.core.$strip>, {
|
|
92
|
+
selector: string;
|
|
93
|
+
text: string;
|
|
94
|
+
pressEnter: boolean;
|
|
95
|
+
}, {
|
|
96
|
+
selector: string;
|
|
97
|
+
text: string;
|
|
98
|
+
pressEnter?: boolean | undefined;
|
|
99
|
+
}, BrowserTypeResult>, import("langchain").DynamicStructuredTool<z.ZodObject<{}, z.core.$strip>, Record<string, never>, Record<string, never>, BrowserCloseResult>];
|
|
100
|
+
export {};
|