@townco/agent 0.1.82 → 0.1.83
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 +10 -6
- package/dist/acp-server/http.js +1 -1
- package/dist/acp-server/session-storage.d.ts +13 -6
- package/dist/acp-server/session-storage.js +94 -59
- package/dist/runner/agent-runner.d.ts +3 -1
- package/dist/runner/hooks/executor.js +1 -1
- package/dist/runner/hooks/predefined/compaction-tool.js +3 -2
- package/dist/runner/hooks/predefined/tool-response-compactor.js +2 -2
- package/dist/runner/langchain/index.d.ts +1 -0
- package/dist/runner/langchain/index.js +94 -22
- package/dist/runner/langchain/tools/artifacts.d.ts +68 -0
- package/dist/runner/langchain/tools/artifacts.js +469 -0
- package/dist/runner/langchain/tools/browser.js +15 -3
- package/dist/runner/langchain/tools/filesystem.d.ts +8 -4
- package/dist/runner/langchain/tools/filesystem.js +118 -82
- package/dist/runner/langchain/tools/generate_image.d.ts +19 -0
- package/dist/runner/langchain/tools/generate_image.js +54 -14
- package/dist/runner/langchain/tools/subagent.js +2 -2
- package/dist/runner/langchain/tools/todo.js +3 -0
- package/dist/runner/langchain/tools/web_search.js +6 -0
- package/dist/runner/session-context.d.ts +40 -0
- package/dist/runner/session-context.js +69 -0
- package/dist/runner/tools.d.ts +2 -2
- package/dist/runner/tools.js +2 -0
- package/dist/scaffold/project-scaffold.js +7 -3
- package/dist/telemetry/setup.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/token-counter.js +2 -2
- package/package.json +10 -10
|
@@ -278,8 +278,10 @@ export class AgentAcpAdapter {
|
|
|
278
278
|
return response;
|
|
279
279
|
}
|
|
280
280
|
async newSession(params) {
|
|
281
|
-
//
|
|
282
|
-
|
|
281
|
+
// Use sessionId from params if provided (HTTP transport injects it),
|
|
282
|
+
// otherwise generate a unique session ID for this session
|
|
283
|
+
const sessionId = params.sessionId ??
|
|
284
|
+
Math.random().toString(36).substring(2);
|
|
283
285
|
// Extract configOverrides from _meta if provided (Town Hall comparison feature)
|
|
284
286
|
const configOverrides = params._meta?.configOverrides;
|
|
285
287
|
const sessionData = {
|
|
@@ -619,7 +621,7 @@ export class AgentAcpAdapter {
|
|
|
619
621
|
}
|
|
620
622
|
};
|
|
621
623
|
// Declare agentResponse and turnTokenUsage outside try block so they're accessible after catch
|
|
622
|
-
let
|
|
624
|
+
let _agentResponse;
|
|
623
625
|
// Track accumulated token usage during the turn
|
|
624
626
|
const turnTokenUsage = {
|
|
625
627
|
inputTokens: 0,
|
|
@@ -653,8 +655,8 @@ export class AgentAcpAdapter {
|
|
|
653
655
|
latestContextEntry: session.context.length > 0 &&
|
|
654
656
|
session.context[session.context.length - 1]
|
|
655
657
|
? {
|
|
656
|
-
messageCount: session.context[session.context.length - 1]
|
|
657
|
-
contextSize: session.context[session.context.length - 1]
|
|
658
|
+
messageCount: session.context[session.context.length - 1]?.messages.length,
|
|
659
|
+
contextSize: session.context[session.context.length - 1]?.context_size,
|
|
658
660
|
}
|
|
659
661
|
: null,
|
|
660
662
|
});
|
|
@@ -662,6 +664,8 @@ export class AgentAcpAdapter {
|
|
|
662
664
|
prompt: params.prompt,
|
|
663
665
|
sessionId: params.sessionId,
|
|
664
666
|
messageId,
|
|
667
|
+
// Pass agent directory for session-scoped file storage (only if defined)
|
|
668
|
+
...(this.agentDir ? { agentDir: this.agentDir } : {}),
|
|
665
669
|
// Pass resolved context messages to agent
|
|
666
670
|
contextMessages,
|
|
667
671
|
};
|
|
@@ -1154,7 +1158,7 @@ export class AgentAcpAdapter {
|
|
|
1154
1158
|
iterResult = await generator.next();
|
|
1155
1159
|
}
|
|
1156
1160
|
// Capture the return value (PromptResponse with tokenUsage)
|
|
1157
|
-
|
|
1161
|
+
_agentResponse = iterResult.value;
|
|
1158
1162
|
// Flush any remaining pending text
|
|
1159
1163
|
flushPendingText();
|
|
1160
1164
|
}
|
package/dist/acp-server/http.js
CHANGED
|
@@ -241,7 +241,7 @@ export function makeHttpTransport(agent, agentDir, agentName) {
|
|
|
241
241
|
}
|
|
242
242
|
// Regular session update - send via PubSub
|
|
243
243
|
const channel = safeChannelName("notifications", msgSessionId);
|
|
244
|
-
const { payload,
|
|
244
|
+
const { payload, compressedSize } = compressIfNeeded(rawMsg);
|
|
245
245
|
if (compressedSize <= 7500) {
|
|
246
246
|
const escapedPayload = payload.replace(/'/g, "''");
|
|
247
247
|
try {
|
|
@@ -147,7 +147,8 @@ export interface StoredSession {
|
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
149
|
* File-based session storage
|
|
150
|
-
* Stores sessions in agents/<agent-name>/.sessions/<session_id
|
|
150
|
+
* Stores sessions in agents/<agent-name>/.sessions/<session_id>/session.json
|
|
151
|
+
* (Legacy: agents/<agent-name>/.sessions/<session_id>.json)
|
|
151
152
|
*/
|
|
152
153
|
export declare class SessionStorage {
|
|
153
154
|
private sessionsDir;
|
|
@@ -159,13 +160,18 @@ export declare class SessionStorage {
|
|
|
159
160
|
*/
|
|
160
161
|
constructor(agentDir: string, agentName: string);
|
|
161
162
|
/**
|
|
162
|
-
* Ensure the
|
|
163
|
+
* Ensure the session directory exists
|
|
163
164
|
*/
|
|
164
|
-
private
|
|
165
|
+
private ensureSessionDir;
|
|
165
166
|
/**
|
|
166
167
|
* Get the file path for a session
|
|
167
168
|
*/
|
|
168
169
|
private getSessionPath;
|
|
170
|
+
/**
|
|
171
|
+
* Get the legacy file path for a session (for backwards compatibility)
|
|
172
|
+
* Legacy format: .sessions/<session_id>.json (flat file, not directory)
|
|
173
|
+
*/
|
|
174
|
+
private getLegacySessionPath;
|
|
169
175
|
/**
|
|
170
176
|
* Save a session to disk
|
|
171
177
|
* Uses atomic write (write to temp file, then rename)
|
|
@@ -177,18 +183,19 @@ export declare class SessionStorage {
|
|
|
177
183
|
loadSession(sessionId: string): Promise<StoredSession | null>;
|
|
178
184
|
/**
|
|
179
185
|
* Synchronous session loading (for internal use)
|
|
186
|
+
* Checks new location first, falls back to legacy location
|
|
180
187
|
*/
|
|
181
188
|
private loadSessionSync;
|
|
182
189
|
/**
|
|
183
|
-
* Check if a session exists
|
|
190
|
+
* Check if a session exists (checks both new and legacy locations)
|
|
184
191
|
*/
|
|
185
192
|
sessionExists(sessionId: string): boolean;
|
|
186
193
|
/**
|
|
187
|
-
* Delete a session
|
|
194
|
+
* Delete a session (deletes entire session directory or legacy file)
|
|
188
195
|
*/
|
|
189
196
|
deleteSession(sessionId: string): Promise<boolean>;
|
|
190
197
|
/**
|
|
191
|
-
* List all session IDs
|
|
198
|
+
* List all session IDs (checks both new and legacy locations)
|
|
192
199
|
*/
|
|
193
200
|
listSessions(): Promise<string[]>;
|
|
194
201
|
/**
|
|
@@ -131,7 +131,8 @@ const storedSessionSchema = z.object({
|
|
|
131
131
|
});
|
|
132
132
|
/**
|
|
133
133
|
* File-based session storage
|
|
134
|
-
* Stores sessions in agents/<agent-name>/.sessions/<session_id
|
|
134
|
+
* Stores sessions in agents/<agent-name>/.sessions/<session_id>/session.json
|
|
135
|
+
* (Legacy: agents/<agent-name>/.sessions/<session_id>.json)
|
|
135
136
|
*/
|
|
136
137
|
export class SessionStorage {
|
|
137
138
|
sessionsDir;
|
|
@@ -146,17 +147,25 @@ export class SessionStorage {
|
|
|
146
147
|
this.agentName = agentName;
|
|
147
148
|
}
|
|
148
149
|
/**
|
|
149
|
-
* Ensure the
|
|
150
|
+
* Ensure the session directory exists
|
|
150
151
|
*/
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
ensureSessionDir(sessionId) {
|
|
153
|
+
const sessionDir = join(this.sessionsDir, sessionId);
|
|
154
|
+
if (!existsSync(sessionDir)) {
|
|
155
|
+
mkdirSync(sessionDir, { recursive: true });
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
158
|
/**
|
|
157
159
|
* Get the file path for a session
|
|
158
160
|
*/
|
|
159
161
|
getSessionPath(sessionId) {
|
|
162
|
+
return join(this.sessionsDir, sessionId, "session.json");
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get the legacy file path for a session (for backwards compatibility)
|
|
166
|
+
* Legacy format: .sessions/<session_id>.json (flat file, not directory)
|
|
167
|
+
*/
|
|
168
|
+
getLegacySessionPath(sessionId) {
|
|
160
169
|
return join(this.sessionsDir, `${sessionId}.json`);
|
|
161
170
|
}
|
|
162
171
|
/**
|
|
@@ -164,7 +173,7 @@ export class SessionStorage {
|
|
|
164
173
|
* Uses atomic write (write to temp file, then rename)
|
|
165
174
|
*/
|
|
166
175
|
async saveSession(sessionId, messages, context) {
|
|
167
|
-
this.
|
|
176
|
+
this.ensureSessionDir(sessionId);
|
|
168
177
|
const sessionPath = this.getSessionPath(sessionId);
|
|
169
178
|
const tempPath = `${sessionPath}.tmp`;
|
|
170
179
|
const now = new Date().toISOString();
|
|
@@ -207,14 +216,24 @@ export class SessionStorage {
|
|
|
207
216
|
}
|
|
208
217
|
/**
|
|
209
218
|
* Synchronous session loading (for internal use)
|
|
219
|
+
* Checks new location first, falls back to legacy location
|
|
210
220
|
*/
|
|
211
221
|
loadSessionSync(sessionId) {
|
|
212
222
|
const sessionPath = this.getSessionPath(sessionId);
|
|
223
|
+
const legacyPath = this.getLegacySessionPath(sessionId);
|
|
224
|
+
// Check new location first
|
|
225
|
+
let actualPath = sessionPath;
|
|
213
226
|
if (!existsSync(sessionPath)) {
|
|
214
|
-
|
|
227
|
+
// Fall back to legacy location
|
|
228
|
+
if (existsSync(legacyPath)) {
|
|
229
|
+
actualPath = legacyPath;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
215
234
|
}
|
|
216
235
|
try {
|
|
217
|
-
const content = readFileSync(
|
|
236
|
+
const content = readFileSync(actualPath, "utf-8");
|
|
218
237
|
const parsed = JSON.parse(content);
|
|
219
238
|
// Validate with zod
|
|
220
239
|
const validated = storedSessionSchema.parse(parsed);
|
|
@@ -225,39 +244,64 @@ export class SessionStorage {
|
|
|
225
244
|
}
|
|
226
245
|
}
|
|
227
246
|
/**
|
|
228
|
-
* Check if a session exists
|
|
247
|
+
* Check if a session exists (checks both new and legacy locations)
|
|
229
248
|
*/
|
|
230
249
|
sessionExists(sessionId) {
|
|
231
|
-
return existsSync(this.getSessionPath(sessionId))
|
|
250
|
+
return (existsSync(this.getSessionPath(sessionId)) ||
|
|
251
|
+
existsSync(this.getLegacySessionPath(sessionId)));
|
|
232
252
|
}
|
|
233
253
|
/**
|
|
234
|
-
* Delete a session
|
|
254
|
+
* Delete a session (deletes entire session directory or legacy file)
|
|
235
255
|
*/
|
|
236
256
|
async deleteSession(sessionId) {
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
257
|
+
const sessionDir = join(this.sessionsDir, sessionId);
|
|
258
|
+
const legacyPath = this.getLegacySessionPath(sessionId);
|
|
259
|
+
let deleted = false;
|
|
241
260
|
try {
|
|
242
|
-
|
|
243
|
-
|
|
261
|
+
// Delete session directory (.sessions/<sessionId>/)
|
|
262
|
+
if (existsSync(sessionDir)) {
|
|
263
|
+
// Recursively delete the session directory
|
|
264
|
+
const { rmSync } = await import("node:fs");
|
|
265
|
+
rmSync(sessionDir, { recursive: true, force: true });
|
|
266
|
+
deleted = true;
|
|
267
|
+
}
|
|
268
|
+
// Also delete legacy location if it exists (.sessions/<sessionId>.json)
|
|
269
|
+
if (existsSync(legacyPath)) {
|
|
270
|
+
unlinkSync(legacyPath);
|
|
271
|
+
deleted = true;
|
|
272
|
+
}
|
|
273
|
+
return deleted;
|
|
244
274
|
}
|
|
245
275
|
catch (error) {
|
|
246
276
|
throw new Error(`Failed to delete session ${sessionId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
247
277
|
}
|
|
248
278
|
}
|
|
249
279
|
/**
|
|
250
|
-
* List all session IDs
|
|
280
|
+
* List all session IDs (checks both new and legacy locations)
|
|
251
281
|
*/
|
|
252
282
|
async listSessions() {
|
|
253
|
-
|
|
254
|
-
return [];
|
|
255
|
-
}
|
|
283
|
+
const sessionIds = new Set();
|
|
256
284
|
try {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
285
|
+
// Check .sessions/ directory
|
|
286
|
+
if (existsSync(this.sessionsDir)) {
|
|
287
|
+
const entries = readdirSync(this.sessionsDir, { withFileTypes: true });
|
|
288
|
+
for (const entry of entries) {
|
|
289
|
+
if (entry.isDirectory()) {
|
|
290
|
+
// New format: .sessions/<sessionId>/session.json
|
|
291
|
+
const sessionJsonPath = join(this.sessionsDir, entry.name, "session.json");
|
|
292
|
+
if (existsSync(sessionJsonPath)) {
|
|
293
|
+
sessionIds.add(entry.name);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (entry.isFile() &&
|
|
297
|
+
entry.name.endsWith(".json") &&
|
|
298
|
+
!entry.name.endsWith(".tmp")) {
|
|
299
|
+
// Legacy format: .sessions/<sessionId>.json
|
|
300
|
+
sessionIds.add(entry.name.replace(".json", ""));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return Array.from(sessionIds);
|
|
261
305
|
}
|
|
262
306
|
catch (error) {
|
|
263
307
|
throw new Error(`Failed to list sessions: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -271,43 +315,34 @@ export class SessionStorage {
|
|
|
271
315
|
* Returns sessions sorted by updatedAt (most recent first)
|
|
272
316
|
*/
|
|
273
317
|
async listSessionsWithMetadata() {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
updatedAt: session.metadata.updatedAt,
|
|
293
|
-
messageCount: session.messages.length,
|
|
294
|
-
};
|
|
295
|
-
if (firstUserText && "text" in firstUserText) {
|
|
296
|
-
entry.firstUserMessage = firstUserText.text.slice(0, 100);
|
|
297
|
-
}
|
|
298
|
-
sessions.push(entry);
|
|
318
|
+
// Get all session IDs from both locations
|
|
319
|
+
const sessionIds = await this.listSessions();
|
|
320
|
+
const sessions = [];
|
|
321
|
+
for (const sessionId of sessionIds) {
|
|
322
|
+
try {
|
|
323
|
+
const session = this.loadSessionSync(sessionId);
|
|
324
|
+
if (session) {
|
|
325
|
+
// Find the first user message for preview
|
|
326
|
+
const firstUserMsg = session.messages.find((m) => m.role === "user");
|
|
327
|
+
const firstUserText = firstUserMsg?.content.find((c) => c.type === "text");
|
|
328
|
+
const entry = {
|
|
329
|
+
sessionId: session.sessionId,
|
|
330
|
+
createdAt: session.metadata.createdAt,
|
|
331
|
+
updatedAt: session.metadata.updatedAt,
|
|
332
|
+
messageCount: session.messages.length,
|
|
333
|
+
};
|
|
334
|
+
if (firstUserText && "text" in firstUserText) {
|
|
335
|
+
entry.firstUserMessage = firstUserText.text.slice(0, 100);
|
|
299
336
|
}
|
|
300
|
-
|
|
301
|
-
catch {
|
|
302
|
-
// Skip invalid sessions
|
|
337
|
+
sessions.push(entry);
|
|
303
338
|
}
|
|
304
339
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
catch (error) {
|
|
310
|
-
throw new Error(`Failed to list sessions: ${error instanceof Error ? error.message : String(error)}`);
|
|
340
|
+
catch {
|
|
341
|
+
// Skip invalid sessions
|
|
342
|
+
}
|
|
311
343
|
}
|
|
344
|
+
// Sort by updatedAt, most recent first
|
|
345
|
+
sessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
346
|
+
return sessions;
|
|
312
347
|
}
|
|
313
348
|
}
|
|
@@ -9,7 +9,7 @@ export declare const zAgentRunnerParams: z.ZodObject<{
|
|
|
9
9
|
suggestedPrompts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10
10
|
systemPrompt: z.ZodNullable<z.ZodString>;
|
|
11
11
|
model: z.ZodString;
|
|
12
|
-
tools: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"todo_write">, z.ZodLiteral<"get_weather">, z.ZodLiteral<"web_search">, z.ZodLiteral<"town_web_search">, z.ZodLiteral<"filesystem">, z.ZodLiteral<"generate_image">, z.ZodLiteral<"browser">]>, z.ZodObject<{
|
|
12
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"artifacts">, z.ZodLiteral<"todo_write">, z.ZodLiteral<"get_weather">, z.ZodLiteral<"web_search">, z.ZodLiteral<"town_web_search">, z.ZodLiteral<"filesystem">, z.ZodLiteral<"generate_image">, z.ZodLiteral<"town_generate_image">, z.ZodLiteral<"browser">]>, z.ZodObject<{
|
|
13
13
|
type: z.ZodLiteral<"custom">;
|
|
14
14
|
modulePath: z.ZodString;
|
|
15
15
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -74,6 +74,8 @@ export interface ConfigOverrides {
|
|
|
74
74
|
}
|
|
75
75
|
export type InvokeRequest = Omit<PromptRequest, "_meta"> & {
|
|
76
76
|
messageId: string;
|
|
77
|
+
/** Agent directory path for session-scoped file storage */
|
|
78
|
+
agentDir?: string;
|
|
77
79
|
sessionMeta?: Record<string, unknown>;
|
|
78
80
|
contextMessages?: SessionMessage[];
|
|
79
81
|
configOverrides?: ConfigOverrides;
|
|
@@ -186,7 +186,7 @@ export class HookExecutor {
|
|
|
186
186
|
};
|
|
187
187
|
const result = await callback(hookContext);
|
|
188
188
|
// Extract modified output and warnings from metadata
|
|
189
|
-
if (result.metadata
|
|
189
|
+
if (result.metadata?.modifiedOutput) {
|
|
190
190
|
// Hook took action - emit completed notification
|
|
191
191
|
const response = { notifications };
|
|
192
192
|
response.modifiedOutput = result.metadata.modifiedOutput;
|
|
@@ -11,7 +11,7 @@ export const compactionTool = async (ctx) => {
|
|
|
11
11
|
logger.info("Compaction tool triggered", {
|
|
12
12
|
currentTokens: ctx.currentTokens,
|
|
13
13
|
maxTokens: ctx.maxTokens,
|
|
14
|
-
percentage: ctx.percentage.toFixed(2)
|
|
14
|
+
percentage: `${ctx.percentage.toFixed(2)}%`,
|
|
15
15
|
contextEntries: ctx.session.context.length,
|
|
16
16
|
totalMessages: ctx.session.messages.length,
|
|
17
17
|
model: ctx.model,
|
|
@@ -107,7 +107,8 @@ Please provide your summary based on the conversation above, following this stru
|
|
|
107
107
|
.join("\n")
|
|
108
108
|
: "Failed to extract summary";
|
|
109
109
|
// Extract token usage from LLM response
|
|
110
|
-
const responseUsage = response
|
|
110
|
+
const responseUsage = response
|
|
111
|
+
.usage_metadata;
|
|
111
112
|
const summaryTokens = responseUsage?.output_tokens ?? 0;
|
|
112
113
|
const inputTokensUsed = responseUsage?.input_tokens ?? ctx.currentTokens;
|
|
113
114
|
logger.info("Generated compaction summary", {
|
|
@@ -89,7 +89,7 @@ export const toolResponseCompactor = async (ctx) => {
|
|
|
89
89
|
// Try more aggressive truncation (70% of target as emergency measure)
|
|
90
90
|
const emergencySize = Math.floor(targetSize * 0.7);
|
|
91
91
|
const emergencyTruncated = truncateToolResponse(rawOutput, emergencySize);
|
|
92
|
-
|
|
92
|
+
const emergencyTokens = countToolResultTokens(emergencyTruncated);
|
|
93
93
|
// Final safety check - if emergency truncation STILL exceeded target, use ultra-conservative fallback
|
|
94
94
|
if (emergencyTokens > targetSize) {
|
|
95
95
|
logger.error("Emergency truncation STILL exceeded target - using ultra-conservative fallback", {
|
|
@@ -151,7 +151,7 @@ export const toolResponseCompactor = async (ctx) => {
|
|
|
151
151
|
.map((msg) => {
|
|
152
152
|
const text = msg.content
|
|
153
153
|
.filter((b) => b.type === "text")
|
|
154
|
-
.map((b) => b.text)
|
|
154
|
+
.map((b) => (b.type === "text" ? b.text : ""))
|
|
155
155
|
.join("\n");
|
|
156
156
|
return `${msg.role}: ${text}`;
|
|
157
157
|
})
|
|
@@ -13,5 +13,6 @@ export declare class LangchainAgent implements AgentRunner {
|
|
|
13
13
|
constructor(params: CreateAgentRunnerParams);
|
|
14
14
|
invoke(req: InvokeRequest): AsyncGenerator<ExtendedSessionUpdate, PromptResponse, undefined>;
|
|
15
15
|
private invokeInternal;
|
|
16
|
+
private invokeWithContext;
|
|
16
17
|
}
|
|
17
18
|
export { makeSubagentsTool } from "./tools/subagent.js";
|