@posthog/agent 2.3.104 → 2.3.110
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/dist/agent.js +39 -22
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.d.ts +6 -2
- package/dist/posthog-api.js +36 -19
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +36 -19
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +36 -19
- package/dist/server/bin.cjs.map +1 -1
- package/dist/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/agent.ts +4 -4
- package/src/posthog-api.test.ts +48 -0
- package/src/posthog-api.ts +54 -20
- package/src/types.ts +2 -1
package/dist/types.d.ts
CHANGED
|
@@ -88,7 +88,8 @@ type LogLevel = "debug" | "info" | "warn" | "error";
|
|
|
88
88
|
type OnLogCallback = (level: LogLevel, scope: string, message: string, data?: unknown) => void;
|
|
89
89
|
interface PostHogAPIConfig {
|
|
90
90
|
apiUrl: string;
|
|
91
|
-
getApiKey: () => string
|
|
91
|
+
getApiKey: () => string | Promise<string>;
|
|
92
|
+
refreshApiKey?: () => string | Promise<string>;
|
|
92
93
|
projectId: number;
|
|
93
94
|
userAgent?: string;
|
|
94
95
|
}
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -45,17 +45,17 @@ export class Agent {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
private _configureLlmGateway(overrideUrl?: string): {
|
|
48
|
+
private async _configureLlmGateway(overrideUrl?: string): Promise<{
|
|
49
49
|
gatewayUrl: string;
|
|
50
50
|
apiKey: string;
|
|
51
|
-
} | null {
|
|
51
|
+
} | null> {
|
|
52
52
|
if (!this.posthogAPI) {
|
|
53
53
|
return null;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
try {
|
|
57
57
|
const gatewayUrl = overrideUrl ?? this.posthogAPI.getLlmGatewayUrl();
|
|
58
|
-
const apiKey = this.posthogAPI.getApiKey();
|
|
58
|
+
const apiKey = await this.posthogAPI.getApiKey();
|
|
59
59
|
|
|
60
60
|
process.env.OPENAI_BASE_URL = `${gatewayUrl}/v1`;
|
|
61
61
|
process.env.OPENAI_API_KEY = apiKey;
|
|
@@ -74,7 +74,7 @@ export class Agent {
|
|
|
74
74
|
taskRunId: string,
|
|
75
75
|
options: TaskExecutionOptions = {},
|
|
76
76
|
): Promise<InProcessAcpConnection> {
|
|
77
|
-
const gatewayConfig = this._configureLlmGateway(options.gatewayUrl);
|
|
77
|
+
const gatewayConfig = await this._configureLlmGateway(options.gatewayUrl);
|
|
78
78
|
this.logger.info("Configured LLM gateway", {
|
|
79
79
|
adapter: options.adapter,
|
|
80
80
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { PostHogAPIClient } from "./posthog-api";
|
|
3
|
+
|
|
4
|
+
const mockFetch = vi.fn();
|
|
5
|
+
|
|
6
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
7
|
+
|
|
8
|
+
describe("PostHogAPIClient", () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
vi.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("refreshes once when fetching task run logs gets an auth failure", async () => {
|
|
14
|
+
const getApiKey = vi.fn().mockResolvedValue("stale-token");
|
|
15
|
+
const refreshApiKey = vi.fn().mockResolvedValue("fresh-token");
|
|
16
|
+
const client = new PostHogAPIClient({
|
|
17
|
+
apiUrl: "https://app.posthog.com",
|
|
18
|
+
getApiKey,
|
|
19
|
+
refreshApiKey,
|
|
20
|
+
projectId: 1,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
mockFetch
|
|
24
|
+
.mockResolvedValueOnce({
|
|
25
|
+
ok: false,
|
|
26
|
+
status: 401,
|
|
27
|
+
statusText: "Unauthorized",
|
|
28
|
+
})
|
|
29
|
+
.mockResolvedValueOnce({
|
|
30
|
+
ok: true,
|
|
31
|
+
text: vi
|
|
32
|
+
.fn()
|
|
33
|
+
.mockResolvedValue(
|
|
34
|
+
`${JSON.stringify({ type: "notification", notification: { method: "foo" } })}\n`,
|
|
35
|
+
),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const logs = await client.fetchTaskRunLogs({
|
|
39
|
+
id: "run-1",
|
|
40
|
+
task: "task-1",
|
|
41
|
+
} as never);
|
|
42
|
+
|
|
43
|
+
expect(logs).toHaveLength(1);
|
|
44
|
+
expect(getApiKey).toHaveBeenCalledTimes(1);
|
|
45
|
+
expect(refreshApiKey).toHaveBeenCalledTimes(1);
|
|
46
|
+
expect(mockFetch).toHaveBeenCalledTimes(2);
|
|
47
|
+
});
|
|
48
|
+
});
|
package/src/posthog-api.ts
CHANGED
|
@@ -47,27 +47,63 @@ export class PostHogAPIClient {
|
|
|
47
47
|
return host;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
private
|
|
51
|
-
return
|
|
52
|
-
Authorization: `Bearer ${this.config.getApiKey()}`,
|
|
53
|
-
"Content-Type": "application/json",
|
|
54
|
-
"User-Agent": this.config.userAgent ?? DEFAULT_USER_AGENT,
|
|
55
|
-
};
|
|
50
|
+
private isAuthFailure(status: number): boolean {
|
|
51
|
+
return status === 401 || status === 403;
|
|
56
52
|
}
|
|
57
53
|
|
|
58
|
-
private async
|
|
54
|
+
private async resolveApiKey(forceRefresh = false): Promise<string> {
|
|
55
|
+
if (forceRefresh && this.config.refreshApiKey) {
|
|
56
|
+
return this.config.refreshApiKey();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return this.config.getApiKey();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private async buildHeaders(
|
|
63
|
+
options: RequestInit,
|
|
64
|
+
forceRefresh = false,
|
|
65
|
+
): Promise<Headers> {
|
|
66
|
+
const headers = new Headers(options.headers);
|
|
67
|
+
headers.set(
|
|
68
|
+
"Authorization",
|
|
69
|
+
`Bearer ${await this.resolveApiKey(forceRefresh)}`,
|
|
70
|
+
);
|
|
71
|
+
headers.set("Content-Type", "application/json");
|
|
72
|
+
headers.set("User-Agent", this.config.userAgent ?? DEFAULT_USER_AGENT);
|
|
73
|
+
return headers;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private async performRequest(
|
|
59
77
|
endpoint: string,
|
|
60
|
-
options: RequestInit
|
|
61
|
-
|
|
78
|
+
options: RequestInit,
|
|
79
|
+
forceRefresh = false,
|
|
80
|
+
): Promise<Response> {
|
|
62
81
|
const url = `${this.baseUrl}${endpoint}`;
|
|
63
82
|
|
|
64
|
-
|
|
83
|
+
return fetch(url, {
|
|
65
84
|
...options,
|
|
66
|
-
headers:
|
|
67
|
-
...this.headers,
|
|
68
|
-
...options.headers,
|
|
69
|
-
},
|
|
85
|
+
headers: await this.buildHeaders(options, forceRefresh),
|
|
70
86
|
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private async performRequestWithRetry(
|
|
90
|
+
endpoint: string,
|
|
91
|
+
options: RequestInit = {},
|
|
92
|
+
): Promise<Response> {
|
|
93
|
+
let response = await this.performRequest(endpoint, options);
|
|
94
|
+
|
|
95
|
+
if (!response.ok && this.isAuthFailure(response.status)) {
|
|
96
|
+
response = await this.performRequest(endpoint, options, true);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private async apiRequest<T>(
|
|
103
|
+
endpoint: string,
|
|
104
|
+
options: RequestInit = {},
|
|
105
|
+
): Promise<T> {
|
|
106
|
+
const response = await this.performRequestWithRetry(endpoint, options);
|
|
71
107
|
|
|
72
108
|
if (!response.ok) {
|
|
73
109
|
let errorMessage: string;
|
|
@@ -87,8 +123,8 @@ export class PostHogAPIClient {
|
|
|
87
123
|
return this.config.projectId;
|
|
88
124
|
}
|
|
89
125
|
|
|
90
|
-
getApiKey(): string {
|
|
91
|
-
return this.
|
|
126
|
+
async getApiKey(forceRefresh = false): Promise<string> {
|
|
127
|
+
return this.resolveApiKey(forceRefresh);
|
|
92
128
|
}
|
|
93
129
|
|
|
94
130
|
getLlmGatewayUrl(): string {
|
|
@@ -228,12 +264,10 @@ export class PostHogAPIClient {
|
|
|
228
264
|
*/
|
|
229
265
|
async fetchTaskRunLogs(taskRun: TaskRun): Promise<StoredEntry[]> {
|
|
230
266
|
const teamId = this.getTeamId();
|
|
267
|
+
const endpoint = `/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`;
|
|
231
268
|
|
|
232
269
|
try {
|
|
233
|
-
const response = await
|
|
234
|
-
`${this.baseUrl}/api/projects/${teamId}/tasks/${taskRun.task}/runs/${taskRun.id}/logs`,
|
|
235
|
-
{ headers: this.headers },
|
|
236
|
-
);
|
|
270
|
+
const response = await this.performRequestWithRetry(endpoint);
|
|
237
271
|
|
|
238
272
|
if (!response.ok) {
|
|
239
273
|
if (response.status === 404) {
|
package/src/types.ts
CHANGED
|
@@ -126,7 +126,8 @@ export type OnLogCallback = (
|
|
|
126
126
|
|
|
127
127
|
export interface PostHogAPIConfig {
|
|
128
128
|
apiUrl: string;
|
|
129
|
-
getApiKey: () => string
|
|
129
|
+
getApiKey: () => string | Promise<string>;
|
|
130
|
+
refreshApiKey?: () => string | Promise<string>;
|
|
130
131
|
projectId: number;
|
|
131
132
|
userAgent?: string;
|
|
132
133
|
}
|