deadpipe 1.0.0 → 2.0.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/LICENSE +29 -0
- package/README.md +221 -89
- package/dist/index.d.mts +144 -87
- package/dist/index.d.ts +144 -87
- package/dist/index.js +471 -114
- package/dist/index.mjs +461 -111
- package/package.json +14 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,105 +1,162 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Deadpipe -
|
|
2
|
+
* Deadpipe - LLM observability that answers one question:
|
|
3
|
+
* "Is this prompt behaving the same as when it was last safe?"
|
|
3
4
|
*
|
|
4
5
|
* @example
|
|
5
|
-
* import {
|
|
6
|
+
* import { track } from 'deadpipe';
|
|
7
|
+
* import OpenAI from 'openai';
|
|
6
8
|
*
|
|
7
|
-
* const
|
|
9
|
+
* const client = new OpenAI();
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
* await
|
|
11
|
-
*
|
|
11
|
+
* const { response, tracker } = await track('checkout_agent', async (t) => {
|
|
12
|
+
* const response = await client.chat.completions.create({
|
|
13
|
+
* model: 'gpt-4',
|
|
14
|
+
* messages: [{ role: 'user', content: 'Process refund for order 1938' }]
|
|
15
|
+
* });
|
|
16
|
+
* t.record(response);
|
|
17
|
+
* return response;
|
|
12
18
|
* });
|
|
13
19
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
20
|
+
* @example Auto-wrapping (zero code changes):
|
|
21
|
+
* import { wrapOpenAI } from 'deadpipe';
|
|
22
|
+
* import OpenAI from 'openai';
|
|
23
|
+
*
|
|
24
|
+
* const client = wrapOpenAI(new OpenAI(), { promptId: 'checkout_agent' });
|
|
25
|
+
* // All calls automatically tracked
|
|
26
|
+
* const response = await client.chat.completions.create(...);
|
|
16
27
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
declare const VERSION = "2.0.0";
|
|
29
|
+
type StatusType = 'success' | 'error' | 'timeout' | 'empty' | 'schema_violation' | 'refusal';
|
|
30
|
+
interface PromptTelemetry {
|
|
31
|
+
prompt_id: string;
|
|
32
|
+
model?: string;
|
|
33
|
+
provider?: string;
|
|
34
|
+
app_id?: string;
|
|
35
|
+
environment?: string;
|
|
36
|
+
version?: string;
|
|
37
|
+
request_start?: string;
|
|
38
|
+
first_token_time?: number;
|
|
39
|
+
end_time?: string;
|
|
40
|
+
total_latency?: number;
|
|
41
|
+
input_tokens?: number;
|
|
42
|
+
output_tokens?: number;
|
|
43
|
+
total_tokens?: number;
|
|
44
|
+
estimated_cost_usd?: number;
|
|
45
|
+
http_status?: number;
|
|
46
|
+
timeout?: boolean;
|
|
47
|
+
retry_count?: number;
|
|
48
|
+
provider_error_code?: string;
|
|
49
|
+
error_message?: string;
|
|
50
|
+
output_length?: number;
|
|
51
|
+
empty_output?: boolean;
|
|
52
|
+
truncated?: boolean;
|
|
53
|
+
json_parse_success?: boolean;
|
|
54
|
+
schema_validation_pass?: boolean;
|
|
55
|
+
missing_required_fields?: string;
|
|
56
|
+
output_hash?: string;
|
|
57
|
+
output_embedding?: string;
|
|
58
|
+
top_logprob_mean?: number;
|
|
59
|
+
refusal_flag?: boolean;
|
|
60
|
+
tool_call_flag?: boolean;
|
|
61
|
+
tool_calls_count?: number;
|
|
62
|
+
enum_out_of_range?: boolean;
|
|
63
|
+
numeric_out_of_bounds?: boolean;
|
|
64
|
+
hallucination_flags?: string;
|
|
65
|
+
prompt_hash?: string;
|
|
66
|
+
tool_schema_hash?: string;
|
|
67
|
+
system_prompt_hash?: string;
|
|
68
|
+
status?: StatusType;
|
|
23
69
|
}
|
|
24
|
-
interface
|
|
70
|
+
interface TrackOptions {
|
|
25
71
|
apiKey?: string;
|
|
26
72
|
baseUrl?: string;
|
|
27
73
|
timeout?: number;
|
|
74
|
+
appId?: string;
|
|
75
|
+
environment?: string;
|
|
76
|
+
version?: string;
|
|
77
|
+
provider?: 'openai' | 'anthropic' | string;
|
|
78
|
+
schema?: SchemaValidator;
|
|
79
|
+
enumFields?: Record<string, unknown[]>;
|
|
80
|
+
numericBounds?: Record<string, [number | null, number | null]>;
|
|
81
|
+
messages?: Array<{
|
|
82
|
+
role: string;
|
|
83
|
+
content: string;
|
|
84
|
+
[key: string]: unknown;
|
|
85
|
+
}>;
|
|
86
|
+
tools?: Array<Record<string, unknown>>;
|
|
87
|
+
systemPrompt?: string;
|
|
88
|
+
}
|
|
89
|
+
interface SchemaValidator {
|
|
90
|
+
validate: (data: unknown) => {
|
|
91
|
+
success: boolean;
|
|
92
|
+
data?: unknown;
|
|
93
|
+
errors?: string[];
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
interface WrapOpenAIOptions extends Omit<TrackOptions, 'messages' | 'tools' | 'systemPrompt'> {
|
|
97
|
+
promptId: string;
|
|
28
98
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
99
|
+
declare function estimateCost(model: string, inputTokens: number, outputTokens: number): number | null;
|
|
100
|
+
declare function detectRefusal(text: string): boolean;
|
|
101
|
+
declare function validateEnumBounds(data: Record<string, unknown>, enumFields?: Record<string, unknown[]>): boolean;
|
|
102
|
+
declare function validateNumericBounds(data: Record<string, unknown>, numericBounds?: Record<string, [number | null, number | null]>): boolean;
|
|
103
|
+
interface ExtractedResponse {
|
|
104
|
+
model: string;
|
|
105
|
+
content: string;
|
|
106
|
+
inputTokens: number | null;
|
|
107
|
+
outputTokens: number | null;
|
|
108
|
+
totalTokens: number | null;
|
|
109
|
+
finishReason: string | null;
|
|
110
|
+
toolCalls: Array<{
|
|
111
|
+
name: string;
|
|
112
|
+
arguments: string;
|
|
113
|
+
}>;
|
|
114
|
+
logprobs: unknown;
|
|
37
115
|
}
|
|
38
|
-
declare
|
|
116
|
+
declare function extractOpenAIResponse(response: any): ExtractedResponse;
|
|
117
|
+
declare function extractAnthropicResponse(response: any): ExtractedResponse;
|
|
118
|
+
declare class PromptTracker {
|
|
119
|
+
private promptId;
|
|
39
120
|
private apiKey;
|
|
40
121
|
private baseUrl;
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* const records = await processData();
|
|
68
|
-
* return { recordsProcessed: records.length };
|
|
69
|
-
* });
|
|
70
|
-
*/
|
|
71
|
-
run<T>(pipelineId: string, fn: () => T | Promise<T>, options?: {
|
|
72
|
-
appName?: string;
|
|
73
|
-
}): Promise<T>;
|
|
74
|
-
/**
|
|
75
|
-
* Create a wrapper function that auto-sends heartbeats.
|
|
76
|
-
*
|
|
77
|
-
* @param pipelineId - Unique identifier for this pipeline.
|
|
78
|
-
* @param fn - The function to wrap.
|
|
79
|
-
* @param options - Additional options.
|
|
80
|
-
* @returns A wrapped function.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* const myPipeline = dp.wrap('daily-etl', async () => {
|
|
84
|
-
* await processData();
|
|
85
|
-
* });
|
|
86
|
-
*
|
|
87
|
-
* // Later...
|
|
88
|
-
* await myPipeline();
|
|
89
|
-
*/
|
|
90
|
-
wrap<T extends (...args: unknown[]) => unknown>(pipelineId: string, fn: T, options?: {
|
|
91
|
-
appName?: string;
|
|
92
|
-
}): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
|
122
|
+
private timeoutMs;
|
|
123
|
+
private appId;
|
|
124
|
+
private environment;
|
|
125
|
+
private versionStr;
|
|
126
|
+
private provider;
|
|
127
|
+
private schema;
|
|
128
|
+
private enumFields;
|
|
129
|
+
private numericBounds;
|
|
130
|
+
private promptHash;
|
|
131
|
+
private toolSchemaHash;
|
|
132
|
+
private systemPromptHash;
|
|
133
|
+
private startTime;
|
|
134
|
+
private firstTokenTime;
|
|
135
|
+
private endTime;
|
|
136
|
+
private telemetry;
|
|
137
|
+
private recorded;
|
|
138
|
+
private retryCount;
|
|
139
|
+
constructor(promptId: string, options?: TrackOptions);
|
|
140
|
+
start(): void;
|
|
141
|
+
markFirstToken(): void;
|
|
142
|
+
markRetry(): void;
|
|
143
|
+
record(response: any, parsedOutput?: unknown): unknown;
|
|
144
|
+
recordError(error: Error): void;
|
|
145
|
+
private send;
|
|
146
|
+
isRecorded(): boolean;
|
|
147
|
+
getTelemetry(): PromptTelemetry;
|
|
93
148
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
149
|
+
declare function track<T>(promptId: string, fn: (tracker: PromptTracker) => Promise<T>, options?: TrackOptions): Promise<T>;
|
|
150
|
+
type OpenAIClient = any;
|
|
151
|
+
interface TrackedCompletions {
|
|
152
|
+
create: (params: any) => Promise<any>;
|
|
153
|
+
}
|
|
154
|
+
interface TrackedChat {
|
|
155
|
+
completions: TrackedCompletions;
|
|
156
|
+
}
|
|
157
|
+
interface TrackedOpenAIClient extends OpenAIClient {
|
|
158
|
+
chat: TrackedChat;
|
|
159
|
+
}
|
|
160
|
+
declare function wrapOpenAI(client: OpenAIClient, options: WrapOpenAIOptions): TrackedOpenAIClient;
|
|
104
161
|
|
|
105
|
-
export {
|
|
162
|
+
export { type PromptTelemetry, PromptTracker, type SchemaValidator, type StatusType, type TrackOptions, VERSION, type WrapOpenAIOptions, detectRefusal, estimateCost, extractAnthropicResponse, extractOpenAIResponse, track, validateEnumBounds, validateNumericBounds, wrapOpenAI };
|