pi-langfuse 1.5.19 → 1.6.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/README.md +13 -1
- package/README_CN.md +13 -1
- package/index.ts +52 -49
- package/package.json +3 -3
- package/src/commands.ts +1 -0
- package/src/config.ts +14 -0
- package/src/handlers/agent.ts +103 -1
- package/src/handlers/cache.ts +147 -0
- package/src/handlers/generation.ts +39 -2
- package/src/handlers/session.ts +90 -0
- package/src/handlers/system-state.ts +186 -0
- package/src/handlers/tool.ts +1 -1
- package/src/handlers/turn.ts +1 -1
- package/src/langfuse.ts +6 -1
- package/src/observation.ts +1 -1
- package/src/state.ts +18 -3
- package/src/types.ts +14 -2
- package/src/utils.ts +75 -0
- package/types/langfuse-runtime-shims.d.ts +0 -49
- package/types/node-shims.d.ts +0 -29
- package/types/pi-coding-agent.d.ts +0 -16
package/src/utils.ts
CHANGED
|
@@ -334,6 +334,55 @@ export function getProviderPayload(event: Record<string, unknown>): unknown {
|
|
|
334
334
|
return event.request ?? event.payload ?? event.body ?? event.providerPayload ?? event.messages ?? event;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
+
export type ToolUpdateTransport =
|
|
338
|
+
| "anthropic-native"
|
|
339
|
+
| "openai-additional-tools"
|
|
340
|
+
| "openai-tool-search"
|
|
341
|
+
| "mid-conversation-system"
|
|
342
|
+
| "collapsed-leading-system";
|
|
343
|
+
|
|
344
|
+
/** Classify the provider payload observed by this hook rather than guessing from the model name alone. */
|
|
345
|
+
export function inferToolUpdateTransport(payload: unknown, hasPriorSystemState: boolean): ToolUpdateTransport | undefined {
|
|
346
|
+
let sawToolChangeBlock = false;
|
|
347
|
+
let sawAdditionalTools = false;
|
|
348
|
+
let sawToolSearch = false;
|
|
349
|
+
let sawTopLevelTools = false;
|
|
350
|
+
let sawMidConversationSystem = false;
|
|
351
|
+
let visited = 0;
|
|
352
|
+
|
|
353
|
+
const walk = (value: unknown, key?: string) => {
|
|
354
|
+
if (++visited > 2_000 || value === null || value === undefined) return;
|
|
355
|
+
if (key === "additional_tools") sawAdditionalTools = true;
|
|
356
|
+
if (key === "tools") sawTopLevelTools = true;
|
|
357
|
+
if (key === "tool_search" || key === "tool_search_output") sawToolSearch = true;
|
|
358
|
+
if (typeof value !== "object") return;
|
|
359
|
+
if (Array.isArray(value)) {
|
|
360
|
+
let sawNonSystem = false;
|
|
361
|
+
for (const item of value) {
|
|
362
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
363
|
+
const role = (item as Record<string, unknown>).role;
|
|
364
|
+
if (role === "system" && sawNonSystem) sawMidConversationSystem = true;
|
|
365
|
+
if (role && role !== "system") sawNonSystem = true;
|
|
366
|
+
}
|
|
367
|
+
walk(item);
|
|
368
|
+
}
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const record = value as Record<string, unknown>;
|
|
372
|
+
const type = record.type;
|
|
373
|
+
if (type === "tool_addition" || type === "tool_removal") sawToolChangeBlock = true;
|
|
374
|
+
for (const [childKey, child] of Object.entries(record)) walk(child, childKey);
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
walk(payload);
|
|
378
|
+
if (sawToolChangeBlock) return "anthropic-native";
|
|
379
|
+
if (sawAdditionalTools) return "openai-additional-tools";
|
|
380
|
+
if (sawToolSearch) return "openai-tool-search";
|
|
381
|
+
if (sawMidConversationSystem) return "mid-conversation-system";
|
|
382
|
+
if (hasPriorSystemState && sawTopLevelTools) return "collapsed-leading-system";
|
|
383
|
+
return undefined;
|
|
384
|
+
}
|
|
385
|
+
|
|
337
386
|
export function extractModelParameters(payload: unknown): Record<string, string | number> | undefined {
|
|
338
387
|
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
339
388
|
return undefined;
|
|
@@ -487,6 +536,32 @@ export function extractUsage(
|
|
|
487
536
|
};
|
|
488
537
|
}
|
|
489
538
|
|
|
539
|
+
export function extractCacheMetrics(messageOrEvent: Record<string, unknown>): {
|
|
540
|
+
cacheReadTokens: number;
|
|
541
|
+
cacheWriteTokens: number;
|
|
542
|
+
uncachedInputTokens: number;
|
|
543
|
+
cacheHitRatio?: number;
|
|
544
|
+
} | undefined {
|
|
545
|
+
const usage = (messageOrEvent.usage ??
|
|
546
|
+
(messageOrEvent.message && typeof messageOrEvent.message === "object"
|
|
547
|
+
? (messageOrEvent.message as Record<string, unknown>).usage
|
|
548
|
+
: undefined)) as Record<string, unknown> | undefined;
|
|
549
|
+
if (!usage || typeof usage !== "object") return undefined;
|
|
550
|
+
|
|
551
|
+
const uncachedInputTokens = Number(
|
|
552
|
+
usage.input ?? usage.inputTokens ?? usage.prompt_tokens ?? usage.promptTokens ?? 0,
|
|
553
|
+
);
|
|
554
|
+
const cacheReadTokens = Number(usage.cacheRead ?? usage.cache_read ?? usage.cachedTokens ?? 0);
|
|
555
|
+
const cacheWriteTokens = Number(usage.cacheWrite ?? usage.cache_write ?? 0);
|
|
556
|
+
const denominator = uncachedInputTokens + cacheReadTokens;
|
|
557
|
+
return {
|
|
558
|
+
cacheReadTokens,
|
|
559
|
+
cacheWriteTokens,
|
|
560
|
+
uncachedInputTokens,
|
|
561
|
+
...(denominator > 0 ? { cacheHitRatio: cacheReadTokens / denominator } : {}),
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
490
565
|
export function extractCostDetails(messageOrEvent: Record<string, unknown>): Record<string, number> | undefined {
|
|
491
566
|
const usage = (messageOrEvent.usage ??
|
|
492
567
|
(messageOrEvent.message && typeof messageOrEvent.message === "object"
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
declare module "@opentelemetry/sdk-trace-base" {
|
|
2
|
-
export class BasicTracerProvider {
|
|
3
|
-
constructor(options?: { resource?: unknown; spanProcessors?: unknown[] });
|
|
4
|
-
forceFlush?(): Promise<void>;
|
|
5
|
-
shutdown?(): Promise<void>;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
declare module "@langfuse/otel" {
|
|
10
|
-
export class LangfuseSpanProcessor {
|
|
11
|
-
constructor(options: {
|
|
12
|
-
publicKey: string;
|
|
13
|
-
secretKey: string;
|
|
14
|
-
baseUrl: string;
|
|
15
|
-
});
|
|
16
|
-
forceFlush?(): Promise<void>;
|
|
17
|
-
shutdown?(): Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
declare module "@langfuse/tracing" {
|
|
22
|
-
export function setLangfuseTracerProvider(provider: unknown): void;
|
|
23
|
-
|
|
24
|
-
export function startObservation(
|
|
25
|
-
name: string,
|
|
26
|
-
body?: Record<string, unknown>,
|
|
27
|
-
options?: { asType?: string },
|
|
28
|
-
): unknown;
|
|
29
|
-
|
|
30
|
-
export function propagateAttributes<T>(
|
|
31
|
-
params: {
|
|
32
|
-
sessionId?: string;
|
|
33
|
-
traceName?: string;
|
|
34
|
-
metadata?: Record<string, string>;
|
|
35
|
-
tags?: string[];
|
|
36
|
-
},
|
|
37
|
-
fn: () => T,
|
|
38
|
-
): T;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
declare module "@langfuse/client" {
|
|
42
|
-
export class LangfuseClient {
|
|
43
|
-
constructor(options: {
|
|
44
|
-
publicKey: string;
|
|
45
|
-
secretKey: string;
|
|
46
|
-
baseUrl: string;
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
package/types/node-shims.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
declare module "node:fs" {
|
|
2
|
-
export function mkdirSync(path: string, options?: { recursive?: boolean }): void;
|
|
3
|
-
export function readFileSync(path: string, encoding: string): string;
|
|
4
|
-
export function existsSync(path: string): boolean;
|
|
5
|
-
export function writeFileSync(path: string, data: string, encoding: string): void;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
declare module "node:crypto" {
|
|
9
|
-
export function randomUUID(): string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
declare module "node:os" {
|
|
13
|
-
export function homedir(): string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
declare module "node:path" {
|
|
17
|
-
export function resolve(...paths: string[]): string;
|
|
18
|
-
export function dirname(path: string): string;
|
|
19
|
-
export function basename(path: string, suffix?: string): string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare module "node:url" {
|
|
23
|
-
export function fileURLToPath(url: string | URL): string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
declare const process: {
|
|
27
|
-
cwd(): string;
|
|
28
|
-
env: Record<string, string | undefined>;
|
|
29
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
declare module "@earendil-works/pi-coding-agent" {
|
|
2
|
-
export interface ExtensionContext {
|
|
3
|
-
sessionManager?: {
|
|
4
|
-
getSessionId?: () => unknown;
|
|
5
|
-
getSessionFile?: () => unknown;
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface ExtensionAPI {
|
|
10
|
-
on(event: string, handler: (event: any, ctx: any) => unknown): void;
|
|
11
|
-
registerCommand(
|
|
12
|
-
name: string,
|
|
13
|
-
options: { description?: string; handler: (args: string, ctx: any) => unknown },
|
|
14
|
-
): void;
|
|
15
|
-
}
|
|
16
|
-
}
|