@townco/agent 0.1.113 → 0.1.115
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.js +143 -51
- package/dist/acp-server/session-storage.d.ts +2 -0
- package/dist/acp-server/session-storage.js +24 -0
- package/dist/runner/langchain/index.js +27 -101
- package/dist/runner/langchain/model-factory.d.ts +1 -1
- package/dist/runner/langchain/model-factory.js +2 -2
- package/dist/runner/langchain/tools/e2b.js +2 -2
- package/dist/runner/langchain/tools/subagent-connections.js +0 -10
- package/dist/runner/langchain/tools/subagent.js +44 -0
- package/dist/runner/langchain/tools/web_search.js +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/dist/runner/langchain/tools/artifacts.d.ts +0 -68
- package/dist/runner/langchain/tools/artifacts.js +0 -474
- package/dist/runner/langchain/tools/conversation_search.d.ts +0 -22
- package/dist/runner/langchain/tools/conversation_search.js +0 -137
- package/dist/runner/langchain/tools/generate_image.d.ts +0 -47
- package/dist/runner/langchain/tools/generate_image.js +0 -175
- package/dist/runner/langchain/tools/port-utils.d.ts +0 -8
- package/dist/runner/langchain/tools/port-utils.js +0 -35
|
@@ -22,7 +22,7 @@ export async function getTownE2BApiKey() {
|
|
|
22
22
|
return _apiKeyFetchPromise;
|
|
23
23
|
}
|
|
24
24
|
_apiKeyFetchPromise = (async () => {
|
|
25
|
-
const shedAuth = getShedAuth();
|
|
25
|
+
const shedAuth = await getShedAuth();
|
|
26
26
|
if (!shedAuth) {
|
|
27
27
|
throw new Error("Not logged in. Run 'town login' or set SHED_API_KEY to use the code_sandbox tools.");
|
|
28
28
|
}
|
|
@@ -329,7 +329,7 @@ function makeE2BToolsInternal(getSandbox) {
|
|
|
329
329
|
const fileBuffer = Buffer.from(result.stdout.trim(), "base64");
|
|
330
330
|
await fs.writeFile(outputPath, fileBuffer);
|
|
331
331
|
// Step 2: Upload to Supabase Storage
|
|
332
|
-
const shedAuth = getShedAuth();
|
|
332
|
+
const shedAuth = await getShedAuth();
|
|
333
333
|
if (!shedAuth) {
|
|
334
334
|
// Fallback to local URL if not authenticated
|
|
335
335
|
const port = process.env.PORT || "3100";
|
|
@@ -37,16 +37,6 @@ export function emitSubagentMessages(queryHash, messages, completed = false) {
|
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
if (toolCallId) {
|
|
40
|
-
const firstMessage = messages[0];
|
|
41
|
-
logger.info("✓ Emitting subagent messages for live streaming", {
|
|
42
|
-
queryHash,
|
|
43
|
-
toolCallId,
|
|
44
|
-
messageCount: messages.length,
|
|
45
|
-
hasContent: firstMessage ? firstMessage.content.length > 0 : false,
|
|
46
|
-
hasToolCalls: firstMessage ? firstMessage.toolCalls.length > 0 : false,
|
|
47
|
-
completed,
|
|
48
|
-
invocationId: invocationCtx.invocationId,
|
|
49
|
-
});
|
|
50
40
|
// Emit to the parent's invocation-scoped EventEmitter
|
|
51
41
|
invocationCtx.subagentEventEmitter.emit("messages", {
|
|
52
42
|
toolCallId,
|
|
@@ -3,11 +3,13 @@ import * as fs from "node:fs/promises";
|
|
|
3
3
|
import { mkdir } from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { context, propagation, trace } from "@opentelemetry/api";
|
|
6
|
+
import { createLogger } from "@townco/core";
|
|
6
7
|
import { z } from "zod";
|
|
7
8
|
import { SUBAGENT_MODE_KEY, } from "../../../acp-server/adapter.js";
|
|
8
9
|
import { makeRunnerFromDefinition } from "../../index.js";
|
|
9
10
|
import { bindGeneratorToSessionContext, getAbortSignal, } from "../../session-context.js";
|
|
10
11
|
import { emitSubagentMessages, hashQuery, } from "./subagent-connections.js";
|
|
12
|
+
const logger = createLogger("subagent-tool", "debug");
|
|
11
13
|
/**
|
|
12
14
|
* Name of the Task tool created by makeSubagentsTool
|
|
13
15
|
*/
|
|
@@ -217,6 +219,11 @@ async function querySubagent(agentName, agentPath, agentWorkingDirectory, query)
|
|
|
217
219
|
};
|
|
218
220
|
const toolCallMap = new Map();
|
|
219
221
|
const queryHash = hashQuery(query);
|
|
222
|
+
logger.info("[DEBUG] Starting subagent generator loop", {
|
|
223
|
+
agentName,
|
|
224
|
+
queryHash,
|
|
225
|
+
sessionId: subagentSessionId,
|
|
226
|
+
});
|
|
220
227
|
try {
|
|
221
228
|
for await (const update of generator) {
|
|
222
229
|
let shouldEmit = false;
|
|
@@ -291,23 +298,60 @@ async function querySubagent(agentName, agentPath, agentWorkingDirectory, query)
|
|
|
291
298
|
}
|
|
292
299
|
// Emit incremental update to parent (for live streaming)
|
|
293
300
|
if (shouldEmit) {
|
|
301
|
+
logger.debug("[SUBAGENT-ACCUMULATION] Emitting incremental update", {
|
|
302
|
+
agentName,
|
|
303
|
+
queryHash,
|
|
304
|
+
contentLength: currentMessage.content.length,
|
|
305
|
+
contentBlocksCount: currentMessage.contentBlocks.length,
|
|
306
|
+
toolCallsCount: currentMessage.toolCalls.length,
|
|
307
|
+
});
|
|
294
308
|
emitSubagentMessages(queryHash, [{ ...currentMessage }]);
|
|
295
309
|
}
|
|
296
310
|
}
|
|
311
|
+
logger.info("[DEBUG] Subagent generator loop finished", {
|
|
312
|
+
agentName,
|
|
313
|
+
queryHash,
|
|
314
|
+
sessionId: subagentSessionId,
|
|
315
|
+
contentLength: currentMessage.content.length,
|
|
316
|
+
toolCallCount: currentMessage.toolCalls.length,
|
|
317
|
+
});
|
|
297
318
|
// Final emit to ensure everything is captured, with completion flag
|
|
298
319
|
if (currentMessage.content || currentMessage.toolCalls.length > 0) {
|
|
320
|
+
logger.info("[DEBUG] Emitting final completion flag", {
|
|
321
|
+
agentName,
|
|
322
|
+
queryHash,
|
|
323
|
+
sessionId: subagentSessionId,
|
|
324
|
+
hasContent: true,
|
|
325
|
+
});
|
|
299
326
|
emitSubagentMessages(queryHash, [currentMessage], true);
|
|
300
327
|
}
|
|
301
328
|
else {
|
|
302
329
|
// Even if no messages, emit completion sentinel
|
|
330
|
+
logger.info("[DEBUG] Emitting empty completion flag", {
|
|
331
|
+
agentName,
|
|
332
|
+
queryHash,
|
|
333
|
+
sessionId: subagentSessionId,
|
|
334
|
+
hasContent: false,
|
|
335
|
+
});
|
|
303
336
|
emitSubagentMessages(queryHash, [], true);
|
|
304
337
|
}
|
|
338
|
+
logger.info("[DEBUG] Subagent querySubagent() returning result", {
|
|
339
|
+
agentName,
|
|
340
|
+
queryHash,
|
|
341
|
+
sessionId: subagentSessionId,
|
|
342
|
+
});
|
|
305
343
|
return {
|
|
306
344
|
text: responseText,
|
|
307
345
|
sources: collectedSources,
|
|
308
346
|
};
|
|
309
347
|
}
|
|
310
348
|
catch (error) {
|
|
349
|
+
logger.info("[DEBUG] Subagent querySubagent() caught error", {
|
|
350
|
+
agentName,
|
|
351
|
+
queryHash,
|
|
352
|
+
sessionId: subagentSessionId,
|
|
353
|
+
error: error instanceof Error ? error.message : String(error),
|
|
354
|
+
});
|
|
311
355
|
// Emit completion sentinel even on error to prevent parent from hanging
|
|
312
356
|
emitSubagentMessages(queryHash, [], true);
|
|
313
357
|
if (parentAbortSignal?.aborted) {
|
|
@@ -19,11 +19,11 @@ function getDirectExaClient() {
|
|
|
19
19
|
return _directExaClient;
|
|
20
20
|
}
|
|
21
21
|
/** Get Exa client using Town proxy with authenticated credentials */
|
|
22
|
-
function getTownExaClient() {
|
|
22
|
+
async function getTownExaClient() {
|
|
23
23
|
if (_townExaClient) {
|
|
24
24
|
return _townExaClient;
|
|
25
25
|
}
|
|
26
|
-
const shedAuth = getShedAuth();
|
|
26
|
+
const shedAuth = await getShedAuth();
|
|
27
27
|
if (!shedAuth) {
|
|
28
28
|
throw new Error("Not logged in. Run 'town login' or set SHED_API_KEY to use the town_web_search tool.");
|
|
29
29
|
}
|
|
@@ -43,7 +43,7 @@ export function getWebSearchCitationCounter() {
|
|
|
43
43
|
}
|
|
44
44
|
function makeWebSearchToolsInternal(getClient) {
|
|
45
45
|
const webSearch = tool(async ({ query }) => {
|
|
46
|
-
const client = getClient();
|
|
46
|
+
const client = await getClient();
|
|
47
47
|
const result = await client.searchAndContents(query, {
|
|
48
48
|
numResults: 5,
|
|
49
49
|
type: "auto",
|
|
@@ -102,7 +102,7 @@ function makeWebSearchToolsInternal(getClient) {
|
|
|
102
102
|
paramKey: "query",
|
|
103
103
|
};
|
|
104
104
|
const webFetch = tool(async ({ url, prompt }) => {
|
|
105
|
-
const client = getClient();
|
|
105
|
+
const client = await getClient();
|
|
106
106
|
try {
|
|
107
107
|
const result = await client.getContents([url], {
|
|
108
108
|
text: true,
|