@townco/agent 0.1.44 → 0.1.45
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 +1 -0
- package/dist/acp-server/adapter.js +130 -9
- package/dist/acp-server/cli.d.ts +3 -1
- package/dist/acp-server/session-storage.d.ts +21 -1
- package/dist/acp-server/session-storage.js +19 -1
- package/dist/bin.js +0 -0
- package/dist/definition/index.d.ts +19 -0
- package/dist/definition/index.js +11 -0
- package/dist/definition/mcp.js +0 -1
- package/dist/definition/tools/todo.d.ts +49 -0
- package/dist/definition/tools/todo.js +80 -0
- package/dist/definition/tools/web_search.d.ts +4 -0
- package/dist/definition/tools/web_search.js +26 -0
- package/dist/dev-agent/index.d.ts +2 -0
- package/dist/dev-agent/index.js +18 -0
- package/dist/example.d.ts +2 -0
- package/dist/example.js +19 -0
- package/dist/index.js +13 -2
- package/dist/runner/agent-runner.d.ts +28 -2
- package/dist/runner/agent-runner.js +2 -1
- package/dist/runner/hooks/constants.d.ts +9 -0
- package/dist/runner/hooks/constants.js +19 -0
- package/dist/runner/hooks/executor.d.ts +23 -0
- package/dist/runner/hooks/executor.js +163 -0
- package/dist/runner/hooks/index.d.ts +5 -0
- package/dist/runner/hooks/index.js +5 -0
- package/dist/runner/hooks/loader.d.ts +5 -0
- package/dist/runner/hooks/loader.js +49 -0
- package/dist/runner/hooks/predefined/compaction-tool.d.ts +6 -0
- package/dist/runner/hooks/predefined/compaction-tool.js +42 -0
- package/dist/runner/hooks/registry.d.ts +14 -0
- package/dist/runner/hooks/registry.js +20 -0
- package/dist/runner/hooks/types.d.ts +144 -0
- package/dist/runner/hooks/types.js +33 -0
- package/dist/runner/index.d.ts +3 -1
- package/dist/runner/langchain/index.js +16 -10
- package/dist/runner/langchain/model-factory.js +3 -1
- package/dist/scaffold/claude-scaffold.js +8 -6
- package/dist/storage/index.js +3 -1
- package/dist/templates/index.d.ts +7 -0
- package/dist/templates/index.js +7 -2
- package/dist/test-script.js +3 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +14 -2
- package/package.json +5 -5
- package/templates/index.ts +14 -2
- package/dist/acp-server/test-acp-summarize.d.ts +0 -7
- package/dist/acp-server/test-acp-summarize.js +0 -127
- package/dist/acp-server/test-summarizer.d.ts +0 -7
- package/dist/acp-server/test-summarizer.js +0 -170
- package/dist/acp-server/tool-summarizer.d.ts +0 -125
- package/dist/acp-server/tool-summarizer.js +0 -182
|
@@ -147,15 +147,14 @@ export class LangchainAgent {
|
|
|
147
147
|
agentConfig.systemPrompt = `${agentConfig.systemPrompt ?? ""}\n\n${TODO_WRITE_INSTRUCTIONS}`;
|
|
148
148
|
}
|
|
149
149
|
const agent = createAgent(agentConfig);
|
|
150
|
-
// Build messages from
|
|
150
|
+
// Build messages from context history if available, otherwise use just the prompt
|
|
151
151
|
let messages;
|
|
152
|
-
if (req.
|
|
153
|
-
// Use
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
messages = historyMessages.map((msg) => ({
|
|
152
|
+
if (req.contextMessages && req.contextMessages.length > 0) {
|
|
153
|
+
// Use context messages (already resolved from context entries)
|
|
154
|
+
// Convert to LangChain format
|
|
155
|
+
messages = req.contextMessages.map((msg) => ({
|
|
157
156
|
type: msg.role === "user" ? "human" : "ai",
|
|
158
|
-
// Extract text from content blocks
|
|
157
|
+
// Extract text from content blocks
|
|
159
158
|
content: msg.content
|
|
160
159
|
.filter((block) => block.type === "text")
|
|
161
160
|
.map((block) => block.text)
|
|
@@ -172,7 +171,7 @@ export class LangchainAgent {
|
|
|
172
171
|
});
|
|
173
172
|
}
|
|
174
173
|
else {
|
|
175
|
-
// Fallback: No
|
|
174
|
+
// Fallback: No context history, use just the prompt
|
|
176
175
|
messages = req.prompt
|
|
177
176
|
.filter((promptMsg) => promptMsg.type === "text")
|
|
178
177
|
.map((promptMsg) => ({
|
|
@@ -282,7 +281,12 @@ export class LangchainAgent {
|
|
|
282
281
|
: typeof aiMessage.content === "string"
|
|
283
282
|
? aiMessage.content.length
|
|
284
283
|
: -1;
|
|
285
|
-
|
|
284
|
+
_logger.debug("messageTokenUsage", {
|
|
285
|
+
messageTokenUsage,
|
|
286
|
+
contentType,
|
|
287
|
+
isArray: contentIsArray,
|
|
288
|
+
length: contentLength,
|
|
289
|
+
});
|
|
286
290
|
}
|
|
287
291
|
// If we have tokenUsage but no content, send a token-only chunk
|
|
288
292
|
if (messageTokenUsage &&
|
|
@@ -290,7 +294,9 @@ export class LangchainAgent {
|
|
|
290
294
|
? aiMessage.content === ""
|
|
291
295
|
: Array.isArray(aiMessage.content) &&
|
|
292
296
|
aiMessage.content.length === 0)) {
|
|
293
|
-
|
|
297
|
+
_logger.debug("sending token-only chunk", {
|
|
298
|
+
messageTokenUsage,
|
|
299
|
+
});
|
|
294
300
|
const msgToYield = {
|
|
295
301
|
sessionUpdate: "agent_message_chunk",
|
|
296
302
|
content: {
|
|
@@ -1,6 +1,8 @@
|
|
|
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 { createLogger } from "@townco/core";
|
|
5
|
+
const logger = createLogger("model-factory");
|
|
4
6
|
/**
|
|
5
7
|
* Detects the provider from a model string and returns the appropriate
|
|
6
8
|
* LangChain chat model instance.
|
|
@@ -93,7 +95,7 @@ export function createModelFromString(modelString) {
|
|
|
93
95
|
});
|
|
94
96
|
default:
|
|
95
97
|
// Fallback to Anthropic for unknown providers (backward compatibility)
|
|
96
|
-
|
|
98
|
+
logger.warn(`Unknown provider "${provider}" in model string "${modelString}". Defaulting to Anthropic.`);
|
|
97
99
|
return new ChatAnthropic({
|
|
98
100
|
model: modelString,
|
|
99
101
|
});
|
|
@@ -2,8 +2,10 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { appendFile, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { createLogger } from "@townco/core";
|
|
5
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
7
|
const __dirname = dirname(__filename);
|
|
8
|
+
const logger = createLogger("claude-scaffold");
|
|
7
9
|
/**
|
|
8
10
|
* Initialize Claude Code workspace integration by creating AGENTS.town.md
|
|
9
11
|
* and adding references to it in CLAUDE.md and AGENTS.md.
|
|
@@ -29,30 +31,30 @@ export async function initForClaudeCode(targetPath) {
|
|
|
29
31
|
const townContent = await readFile(appendTemplatePath, "utf-8");
|
|
30
32
|
// Create AGENTS.town.md with the Town-specific content
|
|
31
33
|
await writeFile(agentsTownMdPath, townContent, "utf-8");
|
|
32
|
-
|
|
34
|
+
logger.info("✓ Created AGENTS.town.md");
|
|
33
35
|
// Add reference to AGENTS.town.md in both CLAUDE.md and AGENTS.md
|
|
34
36
|
const referenceText = "\n\nThis repo uses the Town agent SDK -- please reference @AGENTS.town.md for more information\n";
|
|
35
37
|
// Handle CLAUDE.md
|
|
36
38
|
if (existsSync(claudeMdPath)) {
|
|
37
39
|
// CLAUDE.md exists, append reference
|
|
38
40
|
await appendFile(claudeMdPath, referenceText);
|
|
39
|
-
|
|
41
|
+
logger.info("✓ Added Town SDK reference to CLAUDE.md");
|
|
40
42
|
}
|
|
41
43
|
else {
|
|
42
44
|
// CLAUDE.md doesn't exist, create it with just the reference
|
|
43
45
|
await writeFile(claudeMdPath, `${referenceText.trim()}\n`, "utf-8");
|
|
44
|
-
|
|
46
|
+
logger.info("✓ Created CLAUDE.md with Town SDK reference");
|
|
45
47
|
}
|
|
46
48
|
// Handle AGENTS.md
|
|
47
49
|
if (existsSync(agentsMdPath)) {
|
|
48
50
|
// AGENTS.md exists, append reference
|
|
49
51
|
await appendFile(agentsMdPath, referenceText);
|
|
50
|
-
|
|
52
|
+
logger.info("✓ Added Town SDK reference to AGENTS.md");
|
|
51
53
|
}
|
|
52
54
|
else {
|
|
53
55
|
// AGENTS.md doesn't exist, create it with just the reference
|
|
54
56
|
await writeFile(agentsMdPath, `${referenceText.trim()}\n`, "utf-8");
|
|
55
|
-
|
|
57
|
+
logger.info("✓ Created AGENTS.md with Town SDK reference");
|
|
56
58
|
}
|
|
57
|
-
|
|
59
|
+
logger.info("✓ Claude Code workspace initialized");
|
|
58
60
|
}
|
package/dist/storage/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { mkdir, readdir, rm, stat } from "node:fs/promises";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { createLogger } from "@townco/core";
|
|
4
5
|
const AGENTS_DIR = join(homedir(), ".config", "town", "agents");
|
|
6
|
+
const logger = createLogger("storage");
|
|
5
7
|
/**
|
|
6
8
|
* Get the base directory where all agents are stored
|
|
7
9
|
*/
|
|
@@ -39,7 +41,7 @@ export async function listAgents() {
|
|
|
39
41
|
.map((entry) => entry.name);
|
|
40
42
|
}
|
|
41
43
|
catch (error) {
|
|
42
|
-
|
|
44
|
+
logger.error("Error listing agents", { error });
|
|
43
45
|
return [];
|
|
44
46
|
}
|
|
45
47
|
}
|
|
@@ -17,6 +17,13 @@ export interface TemplateVars {
|
|
|
17
17
|
}>;
|
|
18
18
|
systemPrompt: string | null;
|
|
19
19
|
hasWebSearch: boolean;
|
|
20
|
+
hooks?: Array<{
|
|
21
|
+
type: "context_size";
|
|
22
|
+
setting?: {
|
|
23
|
+
threshold: number;
|
|
24
|
+
} | undefined;
|
|
25
|
+
callback: string;
|
|
26
|
+
}> | undefined;
|
|
20
27
|
}
|
|
21
28
|
export declare function getTemplateVars(name: string, definition: AgentDefinition): TemplateVars;
|
|
22
29
|
export declare function generatePackageJson(vars: TemplateVars): string;
|
package/dist/templates/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export function getTemplateVars(name, definition) {
|
|
|
7
7
|
tools,
|
|
8
8
|
systemPrompt: definition.systemPrompt,
|
|
9
9
|
hasWebSearch: tools.some((tool) => typeof tool === "string" && tool === "web_search"),
|
|
10
|
+
hooks: definition.hooks,
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
export function generatePackageJson(vars) {
|
|
@@ -47,10 +48,14 @@ export async function generateIndexTs(vars) {
|
|
|
47
48
|
model: vars.model,
|
|
48
49
|
systemPrompt: vars.systemPrompt,
|
|
49
50
|
tools: vars.tools,
|
|
51
|
+
hooks: vars.hooks,
|
|
50
52
|
};
|
|
51
53
|
return prettier.format(`import { makeHttpTransport, makeStdioTransport } from "@townco/agent/acp-server";
|
|
52
54
|
import type { AgentDefinition } from "@townco/agent/definition";
|
|
53
55
|
import { basename } from "node:path";
|
|
56
|
+
import { createLogger } from "@townco/core";
|
|
57
|
+
|
|
58
|
+
const logger = createLogger("agent-index");
|
|
54
59
|
|
|
55
60
|
// Load agent definition from JSON file
|
|
56
61
|
const agent: AgentDefinition = ${JSON.stringify(agentDef)};
|
|
@@ -61,14 +66,14 @@ const transport = process.argv[2] || "stdio";
|
|
|
61
66
|
const agentDir = process.cwd();
|
|
62
67
|
const agentName = basename(agentDir);
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
logger.info("Configuration", { transport, agentDir, agentName });
|
|
65
70
|
|
|
66
71
|
if (transport === "http") {
|
|
67
72
|
makeHttpTransport(agent, agentDir, agentName);
|
|
68
73
|
} else if (transport === "stdio") {
|
|
69
74
|
makeStdioTransport(agent);
|
|
70
75
|
} else {
|
|
71
|
-
|
|
76
|
+
logger.error(\`Invalid transport: \${transport}\`);
|
|
72
77
|
process.exit(1);
|
|
73
78
|
}
|
|
74
79
|
`, { parser: "typescript" });
|
package/dist/test-script.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { createLogger } from "@townco/core";
|
|
1
2
|
import { LangchainAgent } from "./runner/langchain";
|
|
3
|
+
const logger = createLogger("test-script");
|
|
2
4
|
const agent = new LangchainAgent({
|
|
3
5
|
model: "claude-sonnet-4-5-20250929",
|
|
4
6
|
systemPrompt: "You are a helpful assistant.",
|
|
@@ -14,5 +16,5 @@ for await (const event of agent.invoke({
|
|
|
14
16
|
sessionId: "test-session",
|
|
15
17
|
messageId: "test-message-1",
|
|
16
18
|
})) {
|
|
17
|
-
|
|
19
|
+
logger.info("Event received", { event });
|
|
18
20
|
}
|