Skip to content

Commit f2c2e39

Browse files
committed
feat: taskrunv2
1 parent a4abecc commit f2c2e39

23 files changed

+789
-1023
lines changed

packages/agent/agent.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/agent/example-client.ts

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
#!/usr/bin/env node
22

3-
import { spawn } from "node:child_process";
3+
import "dotenv/config";
44
import { existsSync, readFileSync, writeFileSync } from "node:fs";
55
import { dirname, join } from "node:path";
66
import * as readline from "node:readline/promises";
7-
import { Readable, Writable } from "node:stream";
87
import { fileURLToPath } from "node:url";
98

109
import {
@@ -20,8 +19,10 @@ import {
2019
type WriteTextFileRequest,
2120
type WriteTextFileResponse,
2221
} from "@agentclientprotocol/sdk";
22+
import { Agent } from "./src/agent.js";
2323
import { PostHogAPIClient } from "./src/posthog-api.js";
2424
import type { SessionPersistenceConfig } from "./src/session-store.js";
25+
import { Logger } from "./src/utils/logger.js";
2526

2627
// PostHog configuration - set via env vars
2728
const POSTHOG_CONFIG = {
@@ -30,6 +31,8 @@ const POSTHOG_CONFIG = {
3031
projectId: parseInt(process.env.POSTHOG_PROJECT_ID || "0", 10),
3132
};
3233

34+
const logger = new Logger({ debug: true, prefix: "[example-client]" });
35+
3336
// Simple file-based storage for session -> persistence mapping
3437
const SESSION_STORE_PATH = join(
3538
dirname(fileURLToPath(import.meta.url)),
@@ -111,6 +114,9 @@ class ExampleClient implements Client {
111114
console.log(`[${update.content.type}]`);
112115
}
113116
break;
117+
case "user_message_chunk":
118+
// Skip rendering user messages live - the user already sees what they typed
119+
break;
114120
case "tool_call":
115121
console.log(`\n🔧 ${update.title} (${update.status})`);
116122
break;
@@ -120,10 +126,13 @@ class ExampleClient implements Client {
120126
);
121127
break;
122128
case "plan":
123-
case "agent_thought_chunk":
124-
case "user_message_chunk":
125129
console.log(`[${update.sessionUpdate}]`);
126130
break;
131+
case "agent_thought_chunk":
132+
if (update.content.type === "text") {
133+
process.stdout.write(`💭 ${update.content.text}`);
134+
}
135+
break;
127136
default:
128137
break;
129138
}
@@ -142,7 +151,7 @@ class ExampleClient implements Client {
142151
case "user_message_chunk":
143152
if (update.content.type === "text") {
144153
process.stdout.write(
145-
`\n${dim}💬 You: ${update.content.text}${reset}`,
154+
`\n${dim}💬 You: ${update.content.text}${reset}\n`,
146155
);
147156
}
148157
break;
@@ -219,10 +228,6 @@ async function prompt(message: string): Promise<string> {
219228
}
220229

221230
async function main() {
222-
const __filename = fileURLToPath(import.meta.url);
223-
const __dirname = dirname(__filename);
224-
const agentPath = join(__dirname, "agent.ts");
225-
226231
// Check for session ID argument: npx tsx example-client.ts [sessionId]
227232
const existingSessionId = process.argv[2];
228233

@@ -286,28 +291,33 @@ async function main() {
286291
console.log(" Starting fresh without persistence...\n");
287292
}
288293

289-
// Spawn the agent as a subprocess using tsx
290-
// Pass PostHog config as env vars so agent can create its own SessionStore
291-
const agentProcess = spawn("npx", ["tsx", agentPath], {
292-
stdio: ["pipe", "pipe", "inherit"],
293-
env: {
294-
...process.env,
295-
POSTHOG_API_URL: POSTHOG_CONFIG.apiUrl,
296-
POSTHOG_API_KEY: POSTHOG_CONFIG.apiKey,
297-
POSTHOG_PROJECT_ID: String(POSTHOG_CONFIG.projectId),
294+
// Create Agent and get in-process ACP connection
295+
const agent = new Agent({
296+
workingDirectory: process.cwd(),
297+
debug: true,
298+
onLog: (level, scope, message, data) => {
299+
logger.log(level, message, data, scope);
298300
},
301+
...(POSTHOG_CONFIG.apiUrl && { posthogApiUrl: POSTHOG_CONFIG.apiUrl }),
302+
...(POSTHOG_CONFIG.apiKey && { posthogApiKey: POSTHOG_CONFIG.apiKey }),
303+
...(POSTHOG_CONFIG.projectId && { posthogProjectId: POSTHOG_CONFIG.projectId }),
299304
});
300305

301-
// Create streams to communicate with the agent
302-
const input = Writable.toWeb(agentProcess.stdin!);
303-
const output = Readable.toWeb(
304-
agentProcess.stdout!,
305-
) as unknown as ReadableStream<Uint8Array>;
306+
if (!persistence) {
307+
logger.error("PostHog configuration required for runTaskV2");
308+
process.exit(1);
309+
}
310+
311+
const { clientStreams } = await agent.runTaskV2(
312+
persistence.taskId,
313+
persistence.runId,
314+
{ skipGitBranch: true },
315+
);
306316

307-
// Create the client connection
317+
// Create the client connection using the in-memory streams
308318
const client = new ExampleClient();
309-
const stream = ndJsonStream(input, output);
310-
const connection = new ClientSideConnection((_agent) => client, stream);
319+
const clientStream = ndJsonStream(clientStreams.writable, clientStreams.readable);
320+
const connection = new ClientSideConnection((_agent) => client, clientStream);
311321

312322
try {
313323
// Initialize the connection
@@ -414,7 +424,6 @@ async function main() {
414424
} catch (error) {
415425
console.error("[Client] Error:", error);
416426
} finally {
417-
agentProcess.kill();
418427
process.exit(0);
419428
}
420429
}

packages/agent/example.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,6 @@ async function testAgent() {
9090
posthogProjectId: process.env.POSTHOG_PROJECT_ID
9191
? parseInt(process.env.POSTHOG_PROJECT_ID, 10)
9292
: 1,
93-
onEvent: (event) => {
94-
if (event.type === "token") {
95-
return;
96-
}
97-
console.log(`[event:${event.type}]`, event);
98-
},
9993
debug: true,
10094
});
10195

packages/agent/index.ts

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
// Main entry point - re-exports from src
22

3+
// ACP connection utilities
4+
export type {
5+
AcpConnectionConfig,
6+
InProcessAcpConnection,
7+
} from "./src/adapters/claude/claude.js";
8+
export { createAcpConnection } from "./src/adapters/claude/claude.js";
9+
310
// Session persistence
411
export type { SessionPersistenceConfig } from "./src/session-store.js";
512
export { SessionStore } from "./src/session-store.js";
6-
// TODO: Refactor - legacy adapter removed
7-
// export { ClaudeAdapter } from "./src/adapters/claude-legacy/claude-adapter.js";
8-
// export type { ProviderAdapter } from "./src/adapters/types.js";
9-
// export { Agent } from "./src/agent.js";
10-
export type { TodoItem, TodoList } from "./src/todo-manager.js";
13+
1114
// Todo management
15+
export type { TodoItem, TodoList } from "./src/todo-manager.js";
1216
export { TodoManager } from "./src/todo-manager.js";
13-
export { ToolRegistry } from "./src/tools/registry.js";
17+
1418
// Tool types
19+
export { ToolRegistry } from "./src/tools/registry.js";
1520
export type {
1621
BashOutputTool,
1722
BashTool,
@@ -32,49 +37,46 @@ export type {
3237
WebSearchTool,
3338
WriteTool,
3439
} from "./src/tools/types.js";
40+
41+
// Core types
3542
export type {
3643
AgentConfig,
37-
AgentEvent,
38-
// Individual event types for creating events
39-
ArtifactEvent,
40-
CompactBoundaryEvent,
41-
ConsoleEvent,
42-
ContentBlockStartEvent,
43-
ContentBlockStopEvent,
44-
DoneEvent,
45-
ErrorEvent,
4644
ExecutionResult,
47-
InitEvent,
4845
LogLevel as LogLevelType,
4946
McpServerConfig,
50-
MessageDeltaEvent,
51-
MessageStartEvent,
52-
MessageStopEvent,
53-
MetricEvent,
5447
OnLogCallback,
55-
RawSDKEvent,
5648
ResearchEvaluation,
57-
StatusEvent,
49+
SessionNotification,
50+
StoredEntry,
51+
StoredNotification,
52+
StoredSessionNotification,
5853
SupportingFile,
5954
Task,
6055
TaskRun,
61-
TokenEvent,
62-
ToolCallEvent,
63-
ToolResultEvent,
64-
UserMessageEvent,
6556
WorktreeInfo,
6657
} from "./src/types.js";
67-
export {
68-
AgentEventSchema,
69-
PermissionMode,
70-
parseAgentEvent,
71-
parseAgentEvents,
72-
} from "./src/types.js";
58+
export { PermissionMode } from "./src/types.js";
59+
60+
// ACP extensions (PostHog-specific notification types)
61+
export { POSTHOG_NOTIFICATIONS } from "./src/acp-extensions.js";
62+
export type {
63+
ArtifactNotificationPayload,
64+
BranchCreatedPayload,
65+
ConsoleNotificationPayload,
66+
ErrorNotificationPayload,
67+
PhaseNotificationPayload,
68+
PostHogNotificationPayload,
69+
PostHogNotificationType,
70+
PrCreatedPayload,
71+
RunStartedPayload,
72+
SdkSessionPayload,
73+
TaskCompletePayload,
74+
} from "./src/acp-extensions.js";
75+
76+
// Logging
7377
export type { LoggerConfig } from "./src/utils/logger.js";
74-
export {
75-
Logger,
76-
LogLevel,
77-
} from "./src/utils/logger.js";
78-
export type { WorktreeConfig } from "./src/worktree-manager.js";
78+
export { Logger, LogLevel } from "./src/utils/logger.js";
79+
7980
// Worktree management
81+
export type { WorktreeConfig } from "./src/worktree-manager.js";
8082
export { WorktreeManager } from "./src/worktree-manager.js";

packages/agent/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"devDependencies": {
4141
"@changesets/cli": "^2.27.8",
4242
"@rollup/plugin-commonjs": "^25.0.7",
43+
"@rollup/plugin-json": "^6.1.0",
4344
"@rollup/plugin-node-resolve": "^15.2.3",
4445
"@types/bun": "latest",
4546
"minimatch": "^10.0.3",

packages/agent/rollup.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { builtinModules } from "node:module";
22
import path from "node:path";
33
import commonjs from "@rollup/plugin-commonjs";
4+
import json from "@rollup/plugin-json";
45
import { nodeResolve } from "@rollup/plugin-node-resolve";
56
import { defineConfig } from "rollup";
67
import copy from "rollup-plugin-copy";
@@ -31,6 +32,7 @@ export default defineConfig({
3132
nodeResolve({
3233
extensions: [".ts", ".js", ".json"],
3334
}),
35+
json(),
3436
commonjs(),
3537
typescript({
3638
tsconfig: path.resolve("tsconfig.rollup.json"),

0 commit comments

Comments
 (0)