@townco/agent 0.1.0 → 0.1.3
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/bin.ts +3 -0
- package/dist/acp-server/adapter.d.ts +14 -10
- package/dist/acp-server/adapter.js +73 -72
- package/dist/acp-server/cli.d.ts +3 -1
- package/dist/acp-server/cli.js +9 -5
- package/dist/acp-server/http.d.ts +3 -1
- package/dist/acp-server/http.js +173 -163
- package/dist/definition/index.d.ts +2 -0
- package/dist/definition/index.js +1 -0
- package/dist/definition/mcp.js +0 -1
- package/dist/definition/tools/todo.d.ts +48 -32
- package/dist/definition/tools/todo.js +16 -13
- package/dist/definition/tools/web_search.d.ts +1 -1
- package/dist/definition/tools/web_search.js +21 -18
- package/dist/example.js +11 -12
- package/dist/index.js +12 -13
- package/dist/runner/agent-runner.d.ts +1 -0
- package/dist/runner/agent-runner.js +4 -4
- package/dist/runner/index.d.ts +3 -1
- package/dist/runner/index.js +18 -14
- package/dist/runner/langchain/index.d.ts +18 -7
- package/dist/runner/langchain/index.js +2 -1
- package/dist/runner/langchain/tools/todo.d.ts +48 -32
- package/dist/runner/langchain/tools/todo.js +16 -13
- package/dist/runner/langchain/tools/web_search.d.ts +1 -1
- package/dist/runner/langchain/tools/web_search.js +21 -18
- package/dist/runner/tools.d.ts +7 -1
- package/dist/runner/tools.js +3 -3
- package/dist/scaffold/bundle.d.ts +1 -1
- package/dist/scaffold/bundle.js +1 -1
- package/dist/scaffold/copy-gui.js +5 -7
- package/dist/scaffold/index.d.ts +10 -8
- package/dist/scaffold/index.js +90 -82
- package/dist/storage/index.js +23 -24
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.js +17 -15
- package/dist/test-script.js +12 -11
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +22 -0
- package/package.json +7 -34
- package/templates/index.ts +17 -18
package/dist/scaffold/index.js
CHANGED
|
@@ -2,97 +2,105 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { chmod, mkdir, writeFile } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { agentExists, ensureAgentsDir, getAgentPath } from "../storage";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
generateAgentJson,
|
|
7
|
+
generateBinTs,
|
|
8
|
+
generateEnvExample,
|
|
9
|
+
generateGitignore,
|
|
10
|
+
generateIndexTs,
|
|
11
|
+
generatePackageJson,
|
|
12
|
+
generateReadme,
|
|
13
|
+
generateTsConfig,
|
|
14
|
+
getTemplateVars,
|
|
15
|
+
} from "../templates";
|
|
6
16
|
import { bundleAgentDependencies } from "./bundle";
|
|
7
17
|
import { copyGuiApp } from "./copy-gui";
|
|
8
18
|
/**
|
|
9
19
|
* Scaffold a new agent package
|
|
10
20
|
*/
|
|
11
21
|
export async function scaffoldAgent(options) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
22
|
+
const { name, definition, overwrite = false, includeGui = true } = options;
|
|
23
|
+
try {
|
|
24
|
+
// Ensure base directory exists
|
|
25
|
+
await ensureAgentsDir();
|
|
26
|
+
// Check if agent already exists
|
|
27
|
+
const exists = await agentExists(name);
|
|
28
|
+
if (exists && !overwrite) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
path: getAgentPath(name),
|
|
32
|
+
error: `Agent "${name}" already exists. Use overwrite option to replace it.`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const agentPath = getAgentPath(name);
|
|
36
|
+
// Create the agent directory
|
|
37
|
+
await mkdir(agentPath, { recursive: true });
|
|
38
|
+
const vars = getTemplateVars(name, definition);
|
|
39
|
+
// Generate all template files
|
|
40
|
+
const files = [
|
|
41
|
+
{ path: "package.json", content: generatePackageJson(vars) },
|
|
42
|
+
{ path: "agent.json", content: generateAgentJson(vars) },
|
|
43
|
+
{ path: "index.ts", content: generateIndexTs() },
|
|
44
|
+
{ path: "bin.ts", content: generateBinTs(), executable: true },
|
|
45
|
+
{ path: "tsconfig.json", content: generateTsConfig() },
|
|
46
|
+
{ path: "README.md", content: generateReadme(vars) },
|
|
47
|
+
{ path: ".gitignore", content: generateGitignore() },
|
|
48
|
+
];
|
|
49
|
+
// Add .env.example if needed
|
|
50
|
+
const envExample = generateEnvExample(vars);
|
|
51
|
+
if (envExample) {
|
|
52
|
+
files.push({ path: ".env.example", content: envExample });
|
|
53
|
+
}
|
|
54
|
+
// Write all files
|
|
55
|
+
for (const file of files) {
|
|
56
|
+
const filePath = join(agentPath, file.path);
|
|
57
|
+
await writeFile(filePath, file.content, "utf-8");
|
|
58
|
+
// Make executable if needed
|
|
59
|
+
if (file.executable) {
|
|
60
|
+
await chmod(filePath, 0o755);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Bundle agent dependencies (copy lib files)
|
|
64
|
+
await bundleAgentDependencies(agentPath);
|
|
65
|
+
// Copy GUI app if requested
|
|
66
|
+
if (includeGui) {
|
|
67
|
+
await copyGuiApp(agentPath);
|
|
68
|
+
// Run bun install in the GUI directory
|
|
69
|
+
const guiPath = join(agentPath, "gui");
|
|
70
|
+
await runBunInstall(guiPath);
|
|
71
|
+
}
|
|
72
|
+
// Run bun install in agent root
|
|
73
|
+
await runBunInstall(agentPath);
|
|
74
|
+
return {
|
|
75
|
+
success: true,
|
|
76
|
+
path: agentPath,
|
|
77
|
+
};
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return {
|
|
80
|
+
success: false,
|
|
81
|
+
path: getAgentPath(name),
|
|
82
|
+
error: error instanceof Error ? error.message : String(error),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
76
85
|
}
|
|
77
86
|
/**
|
|
78
87
|
* Run bun install in the agent directory
|
|
79
88
|
*/
|
|
80
89
|
function runBunInstall(agentPath) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const bunInstall = spawn("bun", ["install"], {
|
|
92
|
+
cwd: agentPath,
|
|
93
|
+
stdio: "ignore",
|
|
94
|
+
});
|
|
95
|
+
bunInstall.on("close", (code) => {
|
|
96
|
+
if (code === 0) {
|
|
97
|
+
resolve();
|
|
98
|
+
} else {
|
|
99
|
+
reject(new Error(`bun install failed with code ${code}`));
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
bunInstall.on("error", (error) => {
|
|
103
|
+
reject(error);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
98
106
|
}
|
package/dist/storage/index.js
CHANGED
|
@@ -1,58 +1,57 @@
|
|
|
1
1
|
import { mkdir, readdir, rm, stat } from "node:fs/promises";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
|
|
4
5
|
const AGENTS_DIR = join(homedir(), ".config", "town", "agents");
|
|
5
6
|
/**
|
|
6
7
|
* Get the base directory where all agents are stored
|
|
7
8
|
*/
|
|
8
9
|
export function getAgentsDir() {
|
|
9
|
-
|
|
10
|
+
return AGENTS_DIR;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* Get the directory path for a specific agent
|
|
13
14
|
*/
|
|
14
15
|
export function getAgentPath(name) {
|
|
15
|
-
|
|
16
|
+
return join(AGENTS_DIR, name);
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
19
|
* Check if an agent exists
|
|
19
20
|
*/
|
|
20
21
|
export async function agentExists(name) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
22
|
+
try {
|
|
23
|
+
const agentPath = getAgentPath(name);
|
|
24
|
+
const stats = await stat(agentPath);
|
|
25
|
+
return stats.isDirectory();
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* List all created agents
|
|
32
32
|
*/
|
|
33
33
|
export async function listAgents() {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
34
|
+
try {
|
|
35
|
+
await mkdir(AGENTS_DIR, { recursive: true });
|
|
36
|
+
const entries = await readdir(AGENTS_DIR, { withFileTypes: true });
|
|
37
|
+
return entries
|
|
38
|
+
.filter((entry) => entry.isDirectory())
|
|
39
|
+
.map((entry) => entry.name);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error("Error listing agents:", error);
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
45
44
|
}
|
|
46
45
|
/**
|
|
47
46
|
* Delete an agent
|
|
48
47
|
*/
|
|
49
48
|
export async function deleteAgent(name) {
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
const agentPath = getAgentPath(name);
|
|
50
|
+
await rm(agentPath, { recursive: true, force: true });
|
|
52
51
|
}
|
|
53
52
|
/**
|
|
54
53
|
* Ensure the agents directory exists
|
|
55
54
|
*/
|
|
56
55
|
export async function ensureAgentsDir() {
|
|
57
|
-
|
|
56
|
+
await mkdir(AGENTS_DIR, { recursive: true });
|
|
58
57
|
}
|
|
@@ -7,7 +7,7 @@ export interface TemplateVars {
|
|
|
7
7
|
hasWebSearch: boolean;
|
|
8
8
|
}
|
|
9
9
|
export declare function getTemplateVars(name: string, definition: AgentDefinition): TemplateVars;
|
|
10
|
-
export declare function generatePackageJson(vars: TemplateVars
|
|
10
|
+
export declare function generatePackageJson(vars: TemplateVars): string;
|
|
11
11
|
export declare function generateIndexTs(): string;
|
|
12
12
|
export declare function generateAgentJson(vars: TemplateVars): string;
|
|
13
13
|
export declare function generateBinTs(): string;
|
package/dist/templates/index.js
CHANGED
|
@@ -8,20 +8,22 @@ export function getTemplateVars(name, definition) {
|
|
|
8
8
|
hasWebSearch: tools.includes("web_search"),
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
-
export function generatePackageJson(vars
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
export function generatePackageJson(vars) {
|
|
12
|
+
// Include all dependencies since the bundled lib/runner includes all tool implementations
|
|
13
|
+
const dependencies = {
|
|
14
|
+
"@agentclientprotocol/sdk": "^0.5.1",
|
|
15
|
+
"@langchain/anthropic": "^1.0.0",
|
|
16
|
+
"@langchain/core": "^1.0.3",
|
|
17
|
+
"@langchain/exa": "^0.1.0",
|
|
18
|
+
"@langchain/mcp-adapters": "^1.0.0",
|
|
19
|
+
"exa-js": "^2.0.0",
|
|
20
|
+
langchain: "^1.0.3",
|
|
21
|
+
hono: "^4.10.4",
|
|
22
|
+
"@electric-sql/pglite": "^0.2.15",
|
|
23
|
+
zod: "^4.1.12",
|
|
24
|
+
};
|
|
23
25
|
const pkg = {
|
|
24
|
-
name: `@
|
|
26
|
+
name: `@town/agent-${vars.name}`,
|
|
25
27
|
version: "0.0.1",
|
|
26
28
|
type: "module",
|
|
27
29
|
module: "index.ts",
|
|
@@ -41,8 +43,8 @@ export function generatePackageJson(vars, useLocalDeps = true) {
|
|
|
41
43
|
export function generateIndexTs() {
|
|
42
44
|
return `import { readFileSync } from "node:fs";
|
|
43
45
|
import { join } from "node:path";
|
|
44
|
-
import { makeHttpTransport, makeStdioTransport } from "
|
|
45
|
-
import type { AgentDefinition } from "
|
|
46
|
+
import { makeHttpTransport, makeStdioTransport } from "./lib/acp-server/index.js";
|
|
47
|
+
import type { AgentDefinition } from "./lib/definition/index.js";
|
|
46
48
|
|
|
47
49
|
// Load agent definition from JSON file
|
|
48
50
|
const configPath = join(import.meta.dir, "agent.json");
|
package/dist/test-script.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { LangchainAgent } from "./runner/langchain";
|
|
2
|
+
|
|
2
3
|
const agent = new LangchainAgent({
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
model: "claude-sonnet-4-5-20250929",
|
|
5
|
+
systemPrompt: "You are a helpful assistant.",
|
|
6
|
+
tools: ["todo_write"],
|
|
6
7
|
});
|
|
7
8
|
for await (const event of agent.invoke({
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
prompt: [
|
|
10
|
+
{
|
|
11
|
+
type: "text",
|
|
12
|
+
text: "Whats the weather in Tokyo?",
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
sessionId: "test-session",
|
|
15
16
|
})) {
|
|
16
|
-
|
|
17
|
+
console.log(event);
|
|
17
18
|
}
|