Skip to content

Commit 33246b7

Browse files
authored
feat: use gateway service (#373)
1 parent 0e1a24e commit 33246b7

File tree

10 files changed

+35
-27
lines changed

10 files changed

+35
-27
lines changed

.env.example

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,4 @@ APPLE_CODESIGN_KEYCHAIN_PASSWORD="xxx"
99

1010
VITE_POSTHOG_API_KEY=xxx
1111
VITE_POSTHOG_API_HOST=xxx
12-
VITE_POSTHOG_UI_HOST=xxx
13-
14-
# Use new LLM gateway locally (experimental, needs to be started in mprocs)
15-
LLM_GATEWAY_URL=http://localhost:3308
12+
VITE_POSTHOG_UI_HOST=xxx

apps/array/src/constants/oauth.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const OAUTH_SCOPES = [
99
"user:read",
1010
"project:read",
1111
"task:write",
12+
"llm_gateway:read",
1213
"integration:read",
1314
"introspection",
1415
"dashboard:read",

apps/array/src/main/services/agent/service.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
type RequestPermissionRequest,
1111
type RequestPermissionResponse,
1212
} from "@agentclientprotocol/sdk";
13-
import { Agent, type OnLogCallback } from "@posthog/agent";
13+
import { Agent, getLlmGatewayUrl, type OnLogCallback } from "@posthog/agent";
1414
import { app } from "electron";
1515
import { injectable } from "inversify";
1616
import type { AcpMessage } from "../../../shared/types/session-events.js";
@@ -457,10 +457,7 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
457457
process.env.ANTHROPIC_API_KEY = token;
458458
process.env.ANTHROPIC_AUTH_TOKEN = token;
459459

460-
const llmGatewayUrl =
461-
process.env.LLM_GATEWAY_URL ||
462-
`${credentials.apiHost}/api/projects/${credentials.projectId}/llm_gateway`;
463-
process.env.ANTHROPIC_BASE_URL = llmGatewayUrl;
460+
process.env.ANTHROPIC_BASE_URL = getLlmGatewayUrl(credentials.apiHost);
464461

465462
process.env.CLAUDE_CODE_EXECUTABLE = getClaudeCliPath();
466463

packages/agent/example.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { config } from "dotenv";
77
config();
88

99
import { Agent, PermissionMode } from "./src/agent.js";
10+
import { getLlmGatewayUrl } from "./src/utils/gateway.js";
1011

1112
function hasUncommittedChanges(repoPath: string): boolean {
1213
try {
@@ -143,9 +144,9 @@ async function testAgent() {
143144
POSTHOG_AUTH_HEADER: `Bearer ${process.env.POSTHOG_API_KEY}`,
144145
ANTHROPIC_API_KEY: process.env.POSTHOG_API_KEY,
145146
ANTHROPIC_AUTH_TOKEN: process.env.POSTHOG_API_KEY,
146-
ANTHROPIC_BASE_URL:
147-
process.env.LLM_GATEWAY_URL ||
148-
`${process.env.POSTHOG_API_URL}/api/projects/${process.env.POSTHOG_PROJECT_ID}/llm_gateway`,
147+
ANTHROPIC_BASE_URL: getLlmGatewayUrl(
148+
process.env.POSTHOG_API_URL || "",
149+
),
149150
},
150151
},
151152
});

packages/agent/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export type {
6868
} from "./src/types.js";
6969
export { PermissionMode } from "./src/types.js";
7070

71+
export { getLlmGatewayUrl } from "./src/utils/gateway.js";
7172
export type { LoggerConfig } from "./src/utils/logger.js";
7273
export { Logger, LogLevel } from "./src/utils/logger.js";
7374

packages/agent/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@posthog/agent",
3-
"version": "1.29.0",
3+
"version": "1.30.0",
44
"repository": "https://github.com/PostHog/array",
55
"description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
66
"main": "./dist/index.js",

packages/agent/src/adapters/claude/claude.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -673,16 +673,13 @@ export class ClaudeAcpAgent implements Agent {
673673
throw RequestError.authRequired();
674674
}
675675

676-
// When using the gateway service, text/thinking is streamed via stream_event,
677-
// so skip them here to avoid duplication.
676+
// Text/thinking is streamed via stream_event, so skip them here to avoid duplication.
678677
const content = message.message.content;
679-
const isUsingGatewayService = !!process.env.LLM_GATEWAY_URL;
680-
const contentToProcess =
681-
isUsingGatewayService && Array.isArray(content)
682-
? content.filter(
683-
(block) => block.type !== "text" && block.type !== "thinking",
684-
)
685-
: content;
678+
const contentToProcess = Array.isArray(content)
679+
? content.filter(
680+
(block) => block.type !== "text" && block.type !== "thinking",
681+
)
682+
: content;
686683

687684
for (const notification of toAcpNotifications(
688685
contentToProcess as typeof content,

packages/agent/src/agent.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,15 @@ export class Agent {
126126
}
127127

128128
/**
129-
* Configure LLM gateway environment variables for Claude Code CLI
129+
* Configure LLM gateway environment variables for Claude Code CLI.
130130
*/
131131
private async _configureLlmGateway(): Promise<void> {
132132
if (!this.posthogAPI) {
133133
return;
134134
}
135135

136136
try {
137-
const gatewayUrl =
138-
process.env.LLM_GATEWAY_URL || this.posthogAPI.getLlmGatewayUrl();
137+
const gatewayUrl = this.posthogAPI.getLlmGatewayUrl();
139138
const apiKey = this.posthogAPI.getApiKey();
140139
process.env.ANTHROPIC_BASE_URL = gatewayUrl;
141140
process.env.ANTHROPIC_AUTH_TOKEN = apiKey;

packages/agent/src/posthog-api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
TaskRunArtifact,
99
UrlMention,
1010
} from "./types.js";
11+
import { getLlmGatewayUrl } from "./utils/gateway.js";
1112

1213
interface PostHogApiResponse<T> {
1314
results?: T[];
@@ -88,8 +89,7 @@ export class PostHogAPIClient {
8889
}
8990

9091
getLlmGatewayUrl(): string {
91-
const teamId = this.getTeamId();
92-
return `${this.baseUrl}/api/projects/${teamId}/llm_gateway`;
92+
return getLlmGatewayUrl(this.baseUrl);
9393
}
9494

9595
async fetchTask(taskId: string): Promise<Task> {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export function getLlmGatewayUrl(posthogHost: string): string {
2+
const url = new URL(posthogHost);
3+
const hostname = url.hostname;
4+
5+
if (hostname === "localhost" || hostname === "127.0.0.1") {
6+
return `${url.protocol}//localhost:3308`;
7+
}
8+
9+
// Extract region from hostname (us.posthog.com, eu.posthog.com)
10+
// app.posthog.com is legacy US
11+
const regionMatch = hostname.match(/^(us|eu)\.posthog\.com$/);
12+
const region = regionMatch ? regionMatch[1] : "us";
13+
14+
return `https://gateway.${region}.posthog.com`;
15+
}

0 commit comments

Comments
 (0)