Skip to content
Open
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
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ jobs:
- name: Build enricher
run: pnpm --filter @posthog/enricher build

- name: Build harness
run: pnpm --filter @posthog/harness build

- name: Build agent
run: pnpm --filter agent build

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/code-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ jobs:
pnpm --filter @posthog/shared run build
pnpm --filter @posthog/git run build
pnpm --filter @posthog/enricher run build
pnpm --filter @posthog/harness run build
pnpm --filter @posthog/agent run build

# build/Assets.car is gitignored; regenerate it so the packaged app ships
Expand Down Expand Up @@ -205,6 +206,7 @@ jobs:
pnpm --filter @posthog/shared run build
pnpm --filter @posthog/git run build
pnpm --filter @posthog/enricher run build
pnpm --filter @posthog/harness run build
pnpm --filter @posthog/agent run build

- name: Build app
Expand Down Expand Up @@ -275,6 +277,7 @@ jobs:
pnpm --filter @posthog/shared run build
pnpm --filter @posthog/git run build
pnpm --filter @posthog/enricher run build
pnpm --filter @posthog/harness run build
pnpm --filter @posthog/agent run build

- name: Build app
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/code-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ jobs:
- name: Build enricher package
run: pnpm --filter @posthog/enricher run build

- name: Build harness package
run: pnpm --filter @posthog/harness run build

- name: Build agent package
run: pnpm --filter @posthog/agent run build

Expand Down Expand Up @@ -331,6 +334,9 @@ jobs:
- name: Build enricher package
run: pnpm --filter @posthog/enricher run build

- name: Build harness package
run: pnpm --filter @posthog/harness run build

- name: Build agent package
run: pnpm --filter @posthog/agent run build

Expand Down Expand Up @@ -457,6 +463,9 @@ jobs:
- name: Build enricher package
run: pnpm --filter @posthog/enricher run build

- name: Build harness package
run: pnpm --filter @posthog/harness run build

- name: Build agent package
run: pnpm --filter @posthog/agent run build

Expand Down
16 changes: 10 additions & 6 deletions .github/workflows/code-storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,20 @@ jobs:
pid2=$!
wait_all "$pid1" "$pid2"

# @posthog/agent imports @posthog/git's dist, so git must finish
# before the last group starts.
pnpm --filter @posthog/git build

pnpm --filter @posthog/enricher build &
# @posthog/agent imports the dist of @posthog/git and
# @posthog/harness, so both must finish before the last group starts.
pnpm --filter @posthog/git build &
pid3=$!
pnpm --filter @posthog/agent build &
pnpm --filter @posthog/harness build &
pid4=$!
wait_all "$pid3" "$pid4"

pnpm --filter @posthog/enricher build &
pid5=$!
pnpm --filter @posthog/agent build &
pid6=$!
wait_all "$pid5" "$pid6"

- name: Build Storybook
working-directory: apps/code
run: pnpm build-storybook
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/code-update-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ jobs:
pnpm --filter @posthog/shared run build
pnpm --filter @posthog/git run build
pnpm --filter @posthog/enricher run build
pnpm --filter @posthog/harness run build
pnpm --filter @posthog/agent run build

- name: Build old + new update pair
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr-build-installer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ jobs:
pnpm --filter @posthog/shared run build
pnpm --filter @posthog/git run build
pnpm --filter @posthog/enricher run build
pnpm --filter @posthog/harness run build
pnpm --filter @posthog/agent run build

# build/Assets.car is gitignored; regenerate it so the packaged app ships
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,9 @@ jobs:
pnpm --filter @posthog/shared build
pnpm --filter @posthog/git build
pnpm --filter @posthog/enricher build
pnpm --filter agent build &
wait
pnpm --filter @posthog/harness build
pnpm --filter agent build

- name: Package Electron app
run: pnpm --filter code run package
Expand Down
6 changes: 6 additions & 0 deletions packages/agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
"types": "./dist/handoff-checkpoint.d.ts",
"import": "./dist/handoff-checkpoint.js"
},
"./pi": {
"types": "./dist/pi/rpc-client.d.ts",
"import": "./dist/pi/rpc-client.js"
},
"./server": {
"types": "./dist/server/agent-server.d.ts",
"import": "./dist/server/agent-server.js"
Expand Down Expand Up @@ -132,13 +136,15 @@
"@agentclientprotocol/sdk": "1.1.0",
"@anthropic-ai/claude-agent-sdk": "0.3.197",
"@anthropic-ai/sdk": "0.109.0",
"@earendil-works/pi-coding-agent": "catalog:",
"@hono/node-server": "^1.19.9",
"@openai/codex": "0.140.0",
"@opentelemetry/api-logs": "^0.208.0",
"@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
"@opentelemetry/resources": "^2.0.0",
"@opentelemetry/sdk-logs": "^0.208.0",
"@opentelemetry/semantic-conventions": "^1.28.0",
"@posthog/harness": "workspace:*",
"@types/jsonwebtoken": "^9.0.10",
"commander": "^14.0.2",
"fflate": "^0.8.2",
Expand Down
27 changes: 27 additions & 0 deletions packages/agent/src/pi/rpc-client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { RpcClient } from "@earendil-works/pi-coding-agent";
import { describe, expect, it } from "vitest";
import { createPiRpcClient } from "./rpc-client";

describe("createPiRpcClient", () => {
it("creates Pi's native RPC client for the harness entry", () => {
const client = createPiRpcClient({
cwd: "/workspace",
model: "claude-opus-4-8",
apiKey: "token",
env: { POSTHOG_REGION: "us" },
});

expect(client).toBeInstanceOf(RpcClient);
expect(client).toMatchObject({
options: {
cwd: "/workspace",
model: "claude-opus-4-8",
env: {
POSTHOG_API_KEY: "token",
POSTHOG_REGION: "us",
},
provider: "posthog",
},
});
});
});
37 changes: 37 additions & 0 deletions packages/agent/src/pi/rpc-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { fileURLToPath } from "node:url";
import {
RpcClient,
type RpcClientOptions,
} from "@earendil-works/pi-coding-agent";

export type PiRpcClient = RpcClient;

export type PiRpcClientOptions = Pick<
RpcClientOptions,
"cwd" | "env" | "model"
> & {
/** PostHog token passed only to the isolated RPC host process. */
apiKey?: string;
};

/**
* Create a native Pi RPC client backed by the PostHog harness.
*
* The client owns an isolated child process. Call `start()` before sending
* commands and `stop()` when the run is finished.
*/
export function createPiRpcClient(
options: PiRpcClientOptions = {},
): PiRpcClient {
const { apiKey, env, ...rpcOptions } = options;

return new RpcClient({
...rpcOptions,
cliPath: fileURLToPath(new URL("./rpc-host.js", import.meta.url)),
env: {
...env,
...(apiKey ? { POSTHOG_API_KEY: apiKey } : {}),
},
provider: "posthog",
});
}
22 changes: 22 additions & 0 deletions packages/agent/src/pi/rpc-host.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createHarnessRuntime, runRpcMode } from "@posthog/harness";

function argumentValue(name: string): string | undefined {
const index = process.argv.indexOf(name);
return index === -1 ? undefined : process.argv[index + 1];
}

const runtime = await createHarnessRuntime({
cwd: process.cwd(),
apiKey: process.env.POSTHOG_API_KEY ?? process.env.POSTHOG_PERSONAL_API_KEY,
});

const requestedModel = argumentValue("--model")?.replace(/^posthog\//, "");
if (requestedModel) {
const model = runtime.services.modelRegistry.find("posthog", requestedModel);
if (!model) {
throw new Error(`PostHog model not found: ${requestedModel}`);
}
await runtime.session.setModel(model);
}

await runRpcMode(runtime);
2 changes: 2 additions & 0 deletions packages/agent/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ export default defineConfig([
"src/posthog-api.ts",
"src/posthog-products.ts",
"src/pr-url-detector.ts",
"src/pi/rpc-client.ts",
"src/pi/rpc-host.ts",
"src/resume.ts",
"src/types.ts",
"src/adapters/claude/questions/utils.ts",
Expand Down
Loading
Loading