@posthog/ai 8.10.4 → 8.11.1
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/adk/index.cjs +6 -2
- package/dist/adk/index.cjs.map +1 -1
- package/dist/adk/index.mjs +6 -2
- package/dist/adk/index.mjs.map +1 -1
- package/dist/anthropic/index.cjs +1 -1
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +1 -1
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +6 -2
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +6 -2
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +126 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +28 -0
- package/dist/index.mjs +126 -4
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +7 -3
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +7 -3
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/langchain/middleware/index.cjs +7 -3
- package/dist/langchain/middleware/index.cjs.map +1 -1
- package/dist/langchain/middleware/index.mjs +7 -3
- package/dist/langchain/middleware/index.mjs.map +1 -1
- package/dist/openai/index.cjs +6 -2
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +6 -2
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +6 -2
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +6 -2
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +7 -3
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +7 -3
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -151,6 +151,9 @@ type PromptsOptions = PromptsWithPostHogOptions | PromptsDirectOptions;
|
|
|
151
151
|
* label: 'production',
|
|
152
152
|
* })
|
|
153
153
|
*
|
|
154
|
+
* // Or fetch all prompts at a label in one request and warm the cache
|
|
155
|
+
* const prodPrompts = await prompts.getAll({ label: 'production' })
|
|
156
|
+
*
|
|
154
157
|
* // Compile with variables
|
|
155
158
|
* const systemPrompt = prompts.compile(result.prompt, {
|
|
156
159
|
* company: 'Acme Corp',
|
|
@@ -177,6 +180,25 @@ declare class Prompts {
|
|
|
177
180
|
* configuration stored with the version.
|
|
178
181
|
*/
|
|
179
182
|
get(name: string, options?: GetPromptOptions): Promise<PromptResult>;
|
|
183
|
+
/**
|
|
184
|
+
* Fetch every prompt that carries a label, in one batch.
|
|
185
|
+
*
|
|
186
|
+
* Returns an object mapping prompt name to `PromptRemoteResult`, with each
|
|
187
|
+
* prompt at the version the label points to. Prompts without the label are
|
|
188
|
+
* not included.
|
|
189
|
+
*
|
|
190
|
+
* Each fetched prompt is stored in the cache, so later
|
|
191
|
+
* `get(name, { label })` calls are served from cache within the TTL. An app
|
|
192
|
+
* with many prompts can call this once per cache cycle instead of making one
|
|
193
|
+
* `get()` request per prompt.
|
|
194
|
+
*
|
|
195
|
+
* Throws if the request fails, or if the server does not support fetching
|
|
196
|
+
* prompts by label on the list endpoint (PostHog releases from before
|
|
197
|
+
* September 2026).
|
|
198
|
+
*/
|
|
199
|
+
getAll(options: {
|
|
200
|
+
label: string;
|
|
201
|
+
}): Promise<Record<string, PromptRemoteResult>>;
|
|
180
202
|
/**
|
|
181
203
|
* Internal method that handles cache + fetch logic, returning full metadata.
|
|
182
204
|
* Does NOT handle the string `fallback` option — callers handle that.
|
|
@@ -201,6 +223,12 @@ declare class Prompts {
|
|
|
201
223
|
* @param version - Optional prompt version to clear. Requires a prompt name.
|
|
202
224
|
*/
|
|
203
225
|
clearCache(name?: string, version?: number): void;
|
|
226
|
+
private requireCredentials;
|
|
227
|
+
/**
|
|
228
|
+
* Fetch all prompts at a label from the paginated list endpoint.
|
|
229
|
+
* Follows pagination links until the last page and returns the raw rows.
|
|
230
|
+
*/
|
|
231
|
+
private fetchPromptListFromApi;
|
|
204
232
|
private fetchPromptFromApi;
|
|
205
233
|
}
|
|
206
234
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -252,7 +252,11 @@ function toContentString(content) {
|
|
|
252
252
|
if (content !== void 0 && content !== null && typeof content === "object") try {
|
|
253
253
|
return JSON.stringify(content);
|
|
254
254
|
} catch {
|
|
255
|
-
|
|
255
|
+
try {
|
|
256
|
+
return String(content);
|
|
257
|
+
} catch {
|
|
258
|
+
return "";
|
|
259
|
+
}
|
|
256
260
|
}
|
|
257
261
|
return String(content);
|
|
258
262
|
}
|
|
@@ -391,7 +395,7 @@ function sanitizeValues(obj) {
|
|
|
391
395
|
}
|
|
392
396
|
//#endregion
|
|
393
397
|
//#region package.json
|
|
394
|
-
var version = "8.
|
|
398
|
+
var version = "8.11.1";
|
|
395
399
|
//#endregion
|
|
396
400
|
//#region src/serializeError.ts
|
|
397
401
|
const DEFAULT_MAX_DEPTH = 3;
|
|
@@ -671,7 +675,7 @@ const mapVercelOutput = (result, client) => {
|
|
|
671
675
|
id: item.toolCallId,
|
|
672
676
|
function: {
|
|
673
677
|
name: item.toolName,
|
|
674
|
-
arguments:
|
|
678
|
+
arguments: toContentString(rawArgs)
|
|
675
679
|
}
|
|
676
680
|
};
|
|
677
681
|
}
|
|
@@ -1083,6 +1087,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
|
1083
1087
|
//#region src/prompts.ts
|
|
1084
1088
|
const DEFAULT_CACHE_TTL_SECONDS = 300;
|
|
1085
1089
|
const DEFAULT_PROMPTS_HOST = "https://us.posthog.com";
|
|
1090
|
+
const MAX_PROMPT_LIST_PAGES = 100;
|
|
1086
1091
|
const DEFAULT_REFETCH_COOLDOWN_SECONDS = 60;
|
|
1087
1092
|
const MAX_REFETCH_COOLDOWN_SECONDS = 3600;
|
|
1088
1093
|
function normalizeApiKey(value) {
|
|
@@ -1120,6 +1125,31 @@ function isPromptApiResponse(data) {
|
|
|
1120
1125
|
const record = data;
|
|
1121
1126
|
return typeof record.prompt === "string" && typeof record.name === "string" && typeof record.version === "number" && (record.label === void 0 || typeof record.label === "string");
|
|
1122
1127
|
}
|
|
1128
|
+
function isSameOrigin(url, host) {
|
|
1129
|
+
try {
|
|
1130
|
+
return new URL(url).origin === new URL(host).origin;
|
|
1131
|
+
} catch {
|
|
1132
|
+
return false;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Classify how a list row relates to the requested label, via its all_labels
|
|
1137
|
+
* field.
|
|
1138
|
+
*
|
|
1139
|
+
* 'resolved': the row is the version the label points to.
|
|
1140
|
+
* 'moved': the prompt carries the label, but on another version. Happens when
|
|
1141
|
+
* the label moves between the query and the response.
|
|
1142
|
+
* 'absent': the prompt does not carry the label at any version. A server that
|
|
1143
|
+
* filters by label never returns such a row, so this means the server ignored
|
|
1144
|
+
* the label param (an older PostHog release) and served latest versions.
|
|
1145
|
+
*/
|
|
1146
|
+
function rowLabelState(row, label) {
|
|
1147
|
+
const allLabels = row.all_labels;
|
|
1148
|
+
if (!Array.isArray(allLabels)) return "absent";
|
|
1149
|
+
const entry = allLabels.find((candidate) => typeof candidate === "object" && candidate !== null && candidate.name === label);
|
|
1150
|
+
if (entry === void 0) return "absent";
|
|
1151
|
+
return entry.version === row.version ? "resolved" : "moved";
|
|
1152
|
+
}
|
|
1123
1153
|
function isPromptsWithPostHog(options) {
|
|
1124
1154
|
return "posthog" in options;
|
|
1125
1155
|
}
|
|
@@ -1154,6 +1184,9 @@ function isPromptsWithPostHog(options) {
|
|
|
1154
1184
|
* label: 'production',
|
|
1155
1185
|
* })
|
|
1156
1186
|
*
|
|
1187
|
+
* // Or fetch all prompts at a label in one request and warm the cache
|
|
1188
|
+
* const prodPrompts = await prompts.getAll({ label: 'production' })
|
|
1189
|
+
*
|
|
1157
1190
|
* // Compile with variables
|
|
1158
1191
|
* const systemPrompt = prompts.compile(result.prompt, {
|
|
1159
1192
|
* company: 'Acme Corp',
|
|
@@ -1220,6 +1253,61 @@ var Prompts = class {
|
|
|
1220
1253
|
}
|
|
1221
1254
|
}
|
|
1222
1255
|
/**
|
|
1256
|
+
* Fetch every prompt that carries a label, in one batch.
|
|
1257
|
+
*
|
|
1258
|
+
* Returns an object mapping prompt name to `PromptRemoteResult`, with each
|
|
1259
|
+
* prompt at the version the label points to. Prompts without the label are
|
|
1260
|
+
* not included.
|
|
1261
|
+
*
|
|
1262
|
+
* Each fetched prompt is stored in the cache, so later
|
|
1263
|
+
* `get(name, { label })` calls are served from cache within the TTL. An app
|
|
1264
|
+
* with many prompts can call this once per cache cycle instead of making one
|
|
1265
|
+
* `get()` request per prompt.
|
|
1266
|
+
*
|
|
1267
|
+
* Throws if the request fails, or if the server does not support fetching
|
|
1268
|
+
* prompts by label on the list endpoint (PostHog releases from before
|
|
1269
|
+
* September 2026).
|
|
1270
|
+
*/
|
|
1271
|
+
async getAll(options) {
|
|
1272
|
+
const label = options.label;
|
|
1273
|
+
const rows = await this.fetchPromptListFromApi(label);
|
|
1274
|
+
const resolvedRows = [];
|
|
1275
|
+
const skipped = [];
|
|
1276
|
+
for (const row of rows) {
|
|
1277
|
+
if (!isPromptApiResponse(row)) throw new Error(`[PostHog Prompts] Invalid response format for prompts with label "${label}"`);
|
|
1278
|
+
const labelState = rowLabelState(row, label);
|
|
1279
|
+
if (labelState === "absent") throw new Error(`[PostHog Prompts] The server returned a prompt that does not carry label "${label}". It may not support fetching prompts by label on the list endpoint yet. Upgrade PostHog, or fetch prompts one by one with get().`);
|
|
1280
|
+
if (labelState === "moved") {
|
|
1281
|
+
skipped.push(row.name);
|
|
1282
|
+
continue;
|
|
1283
|
+
}
|
|
1284
|
+
resolvedRows.push(row);
|
|
1285
|
+
}
|
|
1286
|
+
const now = Date.now();
|
|
1287
|
+
const results = /* @__PURE__ */ new Map();
|
|
1288
|
+
for (const row of resolvedRows) {
|
|
1289
|
+
const config = extractConfig(row.config);
|
|
1290
|
+
this.getOrCreatePromptCache(row.name).set(label, {
|
|
1291
|
+
prompt: row.prompt,
|
|
1292
|
+
name: row.name,
|
|
1293
|
+
version: row.version,
|
|
1294
|
+
label,
|
|
1295
|
+
config,
|
|
1296
|
+
fetchedAt: now
|
|
1297
|
+
});
|
|
1298
|
+
results.set(row.name, {
|
|
1299
|
+
source: "api",
|
|
1300
|
+
prompt: row.prompt,
|
|
1301
|
+
name: row.name,
|
|
1302
|
+
version: row.version,
|
|
1303
|
+
label,
|
|
1304
|
+
config: cloneConfig(config)
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
if (skipped.length > 0) console.warn(`[PostHog Prompts] Skipped ${skipped.length} prompt(s) that did not resolve label "${label}": ${skipped.join(", ")}`);
|
|
1308
|
+
return Object.fromEntries(results);
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1223
1311
|
* Internal method that handles cache + fetch logic, returning full metadata.
|
|
1224
1312
|
* Does NOT handle the string `fallback` option — callers handle that.
|
|
1225
1313
|
*/
|
|
@@ -1309,9 +1397,43 @@ var Prompts = class {
|
|
|
1309
1397
|
promptVersions?.delete(version);
|
|
1310
1398
|
if (promptVersions?.size === 0) this.cache.delete(name);
|
|
1311
1399
|
}
|
|
1312
|
-
|
|
1400
|
+
requireCredentials() {
|
|
1313
1401
|
if (!this.personalApiKey) throw new Error("[PostHog Prompts] personalApiKey is required to fetch prompts. Please provide it when initializing the Prompts instance.");
|
|
1314
1402
|
if (!this.projectApiKey) throw new Error("[PostHog Prompts] projectApiKey is required to fetch prompts. Please provide it when initializing the Prompts instance.");
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* Fetch all prompts at a label from the paginated list endpoint.
|
|
1406
|
+
* Follows pagination links until the last page and returns the raw rows.
|
|
1407
|
+
*/
|
|
1408
|
+
async fetchPromptListFromApi(label) {
|
|
1409
|
+
this.requireCredentials();
|
|
1410
|
+
const query = `token=${encodeURIComponent(this.projectApiKey)}&label=${encodeURIComponent(label)}&content=full`;
|
|
1411
|
+
let url = `${this.host}/api/environments/@current/llm_prompts/?${query}`;
|
|
1412
|
+
const reference = `prompts with label "${label}"`;
|
|
1413
|
+
const rows = [];
|
|
1414
|
+
let pages = 0;
|
|
1415
|
+
while (url !== void 0) {
|
|
1416
|
+
if (pages >= MAX_PROMPT_LIST_PAGES) throw new Error(`[PostHog Prompts] ${reference} spans more than ${MAX_PROMPT_LIST_PAGES} pages. Refusing to return an incomplete result.`);
|
|
1417
|
+
const response = await fetch(url, {
|
|
1418
|
+
method: "GET",
|
|
1419
|
+
headers: { Authorization: `Bearer ${this.personalApiKey}` }
|
|
1420
|
+
});
|
|
1421
|
+
if (!response.ok) {
|
|
1422
|
+
if (response.status === 403) throw new Error(`[PostHog Prompts] Access denied for ${reference}. Check that your personalApiKey has the correct permissions and the LLM prompts feature is enabled.`);
|
|
1423
|
+
throw new PromptFetchError(`[PostHog Prompts] Failed to fetch ${reference}: HTTP ${response.status}`, response.status === 429 ? parseRetryAfterSeconds(response.headers?.get("Retry-After")) : void 0);
|
|
1424
|
+
}
|
|
1425
|
+
const data = await response.json();
|
|
1426
|
+
if (typeof data !== "object" || data === null || !Array.isArray(data.results)) throw new Error(`[PostHog Prompts] Invalid response format for ${reference}`);
|
|
1427
|
+
rows.push(...data.results);
|
|
1428
|
+
const nextUrl = data.next;
|
|
1429
|
+
if (nextUrl !== null && nextUrl !== void 0 && (typeof nextUrl !== "string" || !isSameOrigin(nextUrl, this.host))) throw new Error(`[PostHog Prompts] Refusing to follow a pagination link off the configured host while fetching ${reference}.`);
|
|
1430
|
+
url = nextUrl === null || nextUrl === void 0 ? void 0 : nextUrl;
|
|
1431
|
+
pages += 1;
|
|
1432
|
+
}
|
|
1433
|
+
return rows;
|
|
1434
|
+
}
|
|
1435
|
+
async fetchPromptFromApi(name, version, label) {
|
|
1436
|
+
this.requireCredentials();
|
|
1315
1437
|
const encodedPromptName = encodeURIComponent(name);
|
|
1316
1438
|
const encodedProjectApiKey = encodeURIComponent(this.projectApiKey);
|
|
1317
1439
|
const versionQuery = version === void 0 ? "" : `&version=${encodeURIComponent(String(version))}`;
|