Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions packages/agent/agent.ts

This file was deleted.

63 changes: 36 additions & 27 deletions packages/agent/example-client.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#!/usr/bin/env node

import { spawn } from "node:child_process";
import "dotenv/config";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import * as readline from "node:readline/promises";
import { Readable, Writable } from "node:stream";
import { fileURLToPath } from "node:url";

import {
Expand All @@ -20,8 +19,10 @@ import {
type WriteTextFileRequest,
type WriteTextFileResponse,
} from "@agentclientprotocol/sdk";
import { Agent } from "./src/agent.js";
import { PostHogAPIClient } from "./src/posthog-api.js";
import type { SessionPersistenceConfig } from "./src/session-store.js";
import { Logger } from "./src/utils/logger.js";

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

const logger = new Logger({ debug: true, prefix: "[example-client]" });

// Simple file-based storage for session -> persistence mapping
const SESSION_STORE_PATH = join(
dirname(fileURLToPath(import.meta.url)),
Expand Down Expand Up @@ -111,6 +114,9 @@ class ExampleClient implements Client {
console.log(`[${update.content.type}]`);
}
break;
case "user_message_chunk":
// Skip rendering user messages live - the user already sees what they typed
break;
case "tool_call":
console.log(`\n🔧 ${update.title} (${update.status})`);
break;
Expand All @@ -120,10 +126,13 @@ class ExampleClient implements Client {
);
break;
case "plan":
case "agent_thought_chunk":
case "user_message_chunk":
console.log(`[${update.sessionUpdate}]`);
break;
case "agent_thought_chunk":
if (update.content.type === "text") {
process.stdout.write(`💭 ${update.content.text}`);
}
break;
default:
break;
}
Expand All @@ -142,7 +151,7 @@ class ExampleClient implements Client {
case "user_message_chunk":
if (update.content.type === "text") {
process.stdout.write(
`\n${dim}💬 You: ${update.content.text}${reset}`,
`\n${dim}💬 You: ${update.content.text}${reset}\n`,
);
}
break;
Expand Down Expand Up @@ -219,10 +228,6 @@ async function prompt(message: string): Promise<string> {
}

async function main() {
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const agentPath = join(__dirname, "agent.ts");

// Check for session ID argument: npx tsx example-client.ts [sessionId]
const existingSessionId = process.argv[2];

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

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

// Create streams to communicate with the agent
const input = Writable.toWeb(agentProcess.stdin!);
const output = Readable.toWeb(
agentProcess.stdout!,
) as unknown as ReadableStream<Uint8Array>;
if (!persistence) {
logger.error("PostHog configuration required for runTaskV2");
process.exit(1);
}

const { clientStreams } = await agent.runTaskV2(
persistence.taskId,
persistence.runId,
{ skipGitBranch: true },
);

// Create the client connection
// Create the client connection using the in-memory streams
const client = new ExampleClient();
const stream = ndJsonStream(input, output);
const connection = new ClientSideConnection((_agent) => client, stream);
const clientStream = ndJsonStream(clientStreams.writable, clientStreams.readable);
const connection = new ClientSideConnection((_agent) => client, clientStream);

try {
// Initialize the connection
Expand Down Expand Up @@ -414,7 +424,6 @@ async function main() {
} catch (error) {
console.error("[Client] Error:", error);
} finally {
agentProcess.kill();
process.exit(0);
}
}
Expand Down
6 changes: 0 additions & 6 deletions packages/agent/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,6 @@ async function testAgent() {
posthogProjectId: process.env.POSTHOG_PROJECT_ID
? parseInt(process.env.POSTHOG_PROJECT_ID, 10)
: 1,
onEvent: (event) => {
if (event.type === "token") {
return;
}
console.log(`[event:${event.type}]`, event);
},
debug: true,
});

Expand Down
76 changes: 39 additions & 37 deletions packages/agent/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
// Main entry point - re-exports from src

// ACP connection utilities
export type {
AcpConnectionConfig,
InProcessAcpConnection,
} from "./src/adapters/claude/claude.js";
export { createAcpConnection } from "./src/adapters/claude/claude.js";

// Session persistence
export type { SessionPersistenceConfig } from "./src/session-store.js";
export { SessionStore } from "./src/session-store.js";
// TODO: Refactor - legacy adapter removed
// export { ClaudeAdapter } from "./src/adapters/claude-legacy/claude-adapter.js";
// export type { ProviderAdapter } from "./src/adapters/types.js";
// export { Agent } from "./src/agent.js";
export type { TodoItem, TodoList } from "./src/todo-manager.js";

// Todo management
export type { TodoItem, TodoList } from "./src/todo-manager.js";
export { TodoManager } from "./src/todo-manager.js";
export { ToolRegistry } from "./src/tools/registry.js";

// Tool types
export { ToolRegistry } from "./src/tools/registry.js";
export type {
BashOutputTool,
BashTool,
Expand All @@ -32,49 +37,46 @@ export type {
WebSearchTool,
WriteTool,
} from "./src/tools/types.js";

// Core types
export type {
AgentConfig,
AgentEvent,
// Individual event types for creating events
ArtifactEvent,
CompactBoundaryEvent,
ConsoleEvent,
ContentBlockStartEvent,
ContentBlockStopEvent,
DoneEvent,
ErrorEvent,
ExecutionResult,
InitEvent,
LogLevel as LogLevelType,
McpServerConfig,
MessageDeltaEvent,
MessageStartEvent,
MessageStopEvent,
MetricEvent,
OnLogCallback,
RawSDKEvent,
ResearchEvaluation,
StatusEvent,
SessionNotification,
StoredEntry,
StoredNotification,
StoredSessionNotification,
SupportingFile,
Task,
TaskRun,
TokenEvent,
ToolCallEvent,
ToolResultEvent,
UserMessageEvent,
WorktreeInfo,
} from "./src/types.js";
export {
AgentEventSchema,
PermissionMode,
parseAgentEvent,
parseAgentEvents,
} from "./src/types.js";
export { PermissionMode } from "./src/types.js";

// ACP extensions (PostHog-specific notification types)
export { POSTHOG_NOTIFICATIONS } from "./src/acp-extensions.js";
export type {
ArtifactNotificationPayload,
BranchCreatedPayload,
ConsoleNotificationPayload,
ErrorNotificationPayload,
PhaseNotificationPayload,
PostHogNotificationPayload,
PostHogNotificationType,
PrCreatedPayload,
RunStartedPayload,
SdkSessionPayload,
TaskCompletePayload,
} from "./src/acp-extensions.js";

// Logging
export type { LoggerConfig } from "./src/utils/logger.js";
export {
Logger,
LogLevel,
} from "./src/utils/logger.js";
export type { WorktreeConfig } from "./src/worktree-manager.js";
export { Logger, LogLevel } from "./src/utils/logger.js";

// Worktree management
export type { WorktreeConfig } from "./src/worktree-manager.js";
export { WorktreeManager } from "./src/worktree-manager.js";
1 change: 1 addition & 0 deletions packages/agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"devDependencies": {
"@changesets/cli": "^2.27.8",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/bun": "latest",
"minimatch": "^10.0.3",
Expand Down
2 changes: 2 additions & 0 deletions packages/agent/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { builtinModules } from "node:module";
import path from "node:path";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import { defineConfig } from "rollup";
import copy from "rollup-plugin-copy";
Expand Down Expand Up @@ -31,6 +32,7 @@ export default defineConfig({
nodeResolve({
extensions: [".ts", ".js", ".json"],
}),
json(),
commonjs(),
typescript({
tsconfig: path.resolve("tsconfig.rollup.json"),
Expand Down
Loading
Loading