@posthog/ai 8.15.1 → 8.16.0
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/README.md +145 -0
- package/dist/adk/index.cjs +2 -2
- package/dist/adk/index.cjs.map +1 -1
- package/dist/adk/index.mjs +2 -2
- package/dist/adk/index.mjs.map +1 -1
- package/dist/anthropic/index.cjs +1 -1
- package/dist/anthropic/index.mjs +1 -1
- package/dist/claude-agent-sdk/index.cjs +1 -1
- package/dist/claude-agent-sdk/index.mjs +1 -1
- package/dist/evaluations/index.cjs +1557 -0
- package/dist/evaluations/index.cjs.map +1 -0
- package/dist/evaluations/index.d.ts +497 -0
- package/dist/evaluations/index.mjs +1547 -0
- package/dist/evaluations/index.mjs.map +1 -0
- package/dist/gemini/index.cjs +2 -2
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +2 -2
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +1 -1
- package/dist/langchain/index.mjs +1 -1
- package/dist/langchain/middleware/index.cjs +1 -1
- package/dist/langchain/middleware/index.mjs +1 -1
- package/dist/openai/index.cjs +1 -1
- package/dist/openai/index.mjs +1 -1
- package/dist/openai-agents/index.cjs +1 -1
- package/dist/openai-agents/index.mjs +1 -1
- package/dist/vercel/index.cjs +2 -2
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +2 -2
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -84,3 +84,148 @@ The SDK's synchronous `close()` method also starts finalization; await `return()
|
|
|
84
84
|
## Questions?
|
|
85
85
|
|
|
86
86
|
### [Check out our community page.](https://posthog.com/posts)
|
|
87
|
+
|
|
88
|
+
## Datasets, scorers, and offline evaluations
|
|
89
|
+
|
|
90
|
+
Import the server-only API from `@posthog/ai/evaluations`. It has no model-provider runtime
|
|
91
|
+
requirements and does not require a `posthog-node` analytics client. Every network method
|
|
92
|
+
returns a Promise that resolves only after a validated server acknowledgment; there is no
|
|
93
|
+
capture queue or flush step. Your application executes models and evaluators.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { OfflineEvaluations, EvaluationItem } from '@posthog/ai/evaluations'
|
|
97
|
+
|
|
98
|
+
const evaluations = new OfflineEvaluations({
|
|
99
|
+
projectId: 123,
|
|
100
|
+
secretKey: process.env.POSTHOG_PERSONAL_API_KEY!,
|
|
101
|
+
// host: 'https://eu.posthog.com',
|
|
102
|
+
// timeoutMs: 15_000,
|
|
103
|
+
// maxRetries: 3, // additional attempts, only for operations safe to replay
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const snapshot = await evaluations.datasets.snapshot(datasetId)
|
|
108
|
+
const scorer = await evaluations.scorers.get(scorerId)
|
|
109
|
+
const experiment = await evaluations.createExperiment({
|
|
110
|
+
name: 'Answer quality',
|
|
111
|
+
datasetRevisionId: snapshot.revisionId,
|
|
112
|
+
runSource: 'ci',
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
for await (const row of snapshot) {
|
|
116
|
+
// Implement these functions in your application.
|
|
117
|
+
const output = await runApplication(row.input)
|
|
118
|
+
const value = await scoreOutput(output, row.expectedOutput)
|
|
119
|
+
await experiment.uploadResult({
|
|
120
|
+
item: EvaluationItem.fromDatasetItem(row, { output }),
|
|
121
|
+
scorerVersionId: scorer.currentVersionId,
|
|
122
|
+
value,
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
await experiment.complete()
|
|
126
|
+
} finally {
|
|
127
|
+
evaluations.close()
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`datasets` provides create/get/list/update/archive/restore, item management, revision/version
|
|
132
|
+
history, and `snapshot`. Item mutations require the current `baseVersion`. Supply a stable
|
|
133
|
+
`clientItemId` to make item creation retryable. Snapshots pin both the numeric revision and its
|
|
134
|
+
UUID before iteration. `snapshot.iterItems({ pageSize, signal })` fetches one page at a time;
|
|
135
|
+
repeated iteration starts again at the same revision. Keep the client open until reads finish.
|
|
136
|
+
Use the snapshot's `revisionId` for the experiment, even when individual items were introduced
|
|
137
|
+
in earlier revisions. Source output and trace provenance never become a new execution's output.
|
|
138
|
+
|
|
139
|
+
`scorers` provides create/get/list/update/createVersion/getVersion/listVersions. Configurations
|
|
140
|
+
are typed by `kind`: `boolean`, `numeric`, or `categorical`. Store `currentVersionId` to pin a
|
|
141
|
+
configuration. Metadata updates do not create versions; explicit `createVersion` does, including
|
|
142
|
+
when the configuration is unchanged. Optional `baseVersion` detects conflicting version writes.
|
|
143
|
+
Scorer names are not unique. A result with `status: 'ok'` means the evaluator succeeded; its score
|
|
144
|
+
may still fail the pinned scorer's passing rule. Other statuses are `error`, `skipped`, and
|
|
145
|
+
`not_applicable`, and carry no score.
|
|
146
|
+
|
|
147
|
+
| Operation | Credential and scope |
|
|
148
|
+
| -------------------------------------- | -------------------------------------------------------------------- |
|
|
149
|
+
| Dataset reads/writes | Personal key: `dataset:read` / `dataset:write` |
|
|
150
|
+
| Scorer reads/writes | Personal key: `llm_analytics:read` / `llm_analytics:write` |
|
|
151
|
+
| Experiment create/upload/complete/fail | Personal or project secret key: `offline_evaluation_ingestion:write` |
|
|
152
|
+
| Experiment tags | Personal key: `evaluation:read` / `evaluation:write` |
|
|
153
|
+
|
|
154
|
+
Feature availability and permissions are enforced by the service. Known ingestion hosts map to
|
|
155
|
+
the app API host; custom host path prefixes are preserved. Pagination exposes `nextOffset` or,
|
|
156
|
+
for scorer versions, `nextCursor`. Retain the original filters when requesting the next page.
|
|
157
|
+
|
|
158
|
+
### Recovery, cancellation, and payloads
|
|
159
|
+
|
|
160
|
+
`resumeExperiment(id)` is local and sends no request. Save creation `submission` and item/result
|
|
161
|
+
declarations before relying on process recovery. Use `EvaluationItem.toJSONString()` and
|
|
162
|
+
`EvaluationResult.toJSONString()` to save the exact **snake_case wire JSON** compatible with
|
|
163
|
+
Python, including large integers. Save attached items separately:
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { EvaluationItem, EvaluationResult } from '@posthog/ai/evaluations'
|
|
167
|
+
|
|
168
|
+
const savedItem = item.toJSONString()
|
|
169
|
+
const savedResult = result.toJSONString()
|
|
170
|
+
// Persist these strings directly; JSON.stringify would wrap them in another JSON string.
|
|
171
|
+
const restoredItem = EvaluationItem.fromJSON(JSON.parse(savedItem))
|
|
172
|
+
const restoredResult = EvaluationResult.fromJSON(JSON.parse(savedResult), { item: restoredItem })
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`toJSON()` returns a detached object for inspection and JavaScript-only round trips.
|
|
176
|
+
`JSON.stringify()` can write a different integer outside JavaScript's safe integer range,
|
|
177
|
+
even when the original value is exactly representable, so use `toJSONString()` for portable
|
|
178
|
+
saved declarations. Public options and records use camelCase; arbitrary payload/metadata keys
|
|
179
|
+
are never renamed.
|
|
180
|
+
|
|
181
|
+
`EvaluationAPIError` exposes `status`, `code`, `detail`, `attr`, `errors`, `response`,
|
|
182
|
+
`retryAfter` (seconds), and `persistence`: `not_sent`, `rejected`, or `unknown`. Creation errors
|
|
183
|
+
also expose `submission`, which can be passed directly to `createExperiment` to reuse the ID
|
|
184
|
+
and start time. Error messages omit payloads and credentials. Structured details are explicit
|
|
185
|
+
accessors for callers; treat them as potentially sensitive when logging.
|
|
186
|
+
|
|
187
|
+
`uploadResults` takes a finite array of immutable `EvaluationResult` declarations. The whole
|
|
188
|
+
array is validated before I/O, then uploaded sequentially in requests of at most 1,000 items,
|
|
189
|
+
1,000 results, and 5 MiB of UTF-8 JSON. Memory usage is proportional to the supplied array, so
|
|
190
|
+
submit caller-sized batches. Operations on one experiment handle are serialized.
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { BulkUploadError } from '@posthog/ai/evaluations'
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
await experiment.uploadResults(results)
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (!(error instanceof BulkUploadError)) throw error
|
|
199
|
+
// Earlier chunks are acknowledged; this includes the failed, possibly committed chunk.
|
|
200
|
+
// Persist or inspect this work before deciding when to retry.
|
|
201
|
+
console.log(error.failedIndex, error.persistence)
|
|
202
|
+
await experiment.uploadResults(error.pendingResults)
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Exact replay preserves identities. Changed content for an existing identity conflicts. Ordinary
|
|
207
|
+
dataset writes, scorer writes, and experiment tag updates are not automatically replayed. Never
|
|
208
|
+
create a fresh ID merely because an acknowledgment was lost. `complete()` and `fail()` are explicit;
|
|
209
|
+
closing the client or cancelling a request does neither. Pass `{ signal }` as a network method's
|
|
210
|
+
request options, or within listing/snapshot options. Native cancellation propagates without a
|
|
211
|
+
retry and does not prove an in-flight write was unpersisted. Retain declarations for replay.
|
|
212
|
+
|
|
213
|
+
Cancelled creation rejects with `ExperimentCreationAbortedError`, a `DOMException` named
|
|
214
|
+
`AbortError` (or the original DOMException name, such as `TimeoutError`). Its `cause` is the
|
|
215
|
+
original cancellation reason, and `submission` is a defensive copy of the prepared creation
|
|
216
|
+
fields. Save that submission to replay with the same ID and start time. Each cancelled creation
|
|
217
|
+
has its own recovery data, including when several requests share one `AbortSignal`.
|
|
218
|
+
|
|
219
|
+
Omitted fields, explicit nulls, empty payloads, false, and zero remain distinct. `undefined`
|
|
220
|
+
omits a top-level optional option, but is rejected inside payload JSON. Payloads accept plain
|
|
221
|
+
JSON values without coercion, cycles, accessors, invalid Unicode, NUL characters, or non-finite
|
|
222
|
+
numbers. Maximum nesting is 32 containers; item payloads are limited to 1 MiB and result payloads
|
|
223
|
+
to 256 KiB, measured in UTF-8 bytes including their payload object.
|
|
224
|
+
|
|
225
|
+
Counts accept safe integer `number` values or nonnegative signed-64-bit `bigint`; large returned
|
|
226
|
+
counts remain `bigint`. Use a lossless JSON codec when persisting submissions or receipts containing
|
|
227
|
+
bigint counts. Numeric scores accept finite numbers; use `bigint` for integer inputs outside the
|
|
228
|
+
safe number range, which are accepted only when exactly representable as binary64. Unsafe integer
|
|
229
|
+
`number` score inputs are rejected because their original precision cannot be recovered. Bigints
|
|
230
|
+
are not accepted in arbitrary JSON payloads. An unrepresentable integer in returned dataset JSON
|
|
231
|
+
raises an invalid-response error rather than silently rounding it.
|
package/dist/adk/index.cjs
CHANGED
|
@@ -3,7 +3,7 @@ let _google_adk = require("@google/adk");
|
|
|
3
3
|
let uuid = require("uuid");
|
|
4
4
|
let _posthog_core = require("@posthog/core");
|
|
5
5
|
//#region package.json
|
|
6
|
-
var version = "8.
|
|
6
|
+
var version = "8.16.0";
|
|
7
7
|
//#endregion
|
|
8
8
|
//#region src/captureAiEvent.ts
|
|
9
9
|
/** @internal */
|
|
@@ -532,7 +532,7 @@ const captureAiGeneration = async (client, options) => {
|
|
|
532
532
|
/** Map Gemini usage metadata to PostHog's provider-agnostic token fields. */
|
|
533
533
|
function mapGeminiUsage(metadata, additionalUsage = {}) {
|
|
534
534
|
return {
|
|
535
|
-
inputTokens: metadata?.promptTokenCount ?? 0,
|
|
535
|
+
inputTokens: (metadata?.promptTokenCount ?? 0) + (metadata?.toolUsePromptTokenCount ?? 0),
|
|
536
536
|
outputTokens: metadata?.candidatesTokenCount ?? 0,
|
|
537
537
|
reasoningTokens: metadata?.thoughtsTokenCount ?? 0,
|
|
538
538
|
cacheReadInputTokens: metadata?.cachedContentTokenCount ?? 0,
|