@databuddy/sdk 2.3.0 → 2.3.2
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/ai/vercel/index.d.mts +146 -7
- package/dist/ai/vercel/index.d.ts +146 -7
- package/dist/ai/vercel/index.mjs +221 -34
- package/dist/core/index.d.mts +3 -43
- package/dist/core/index.d.ts +3 -43
- package/dist/core/index.mjs +1 -1
- package/dist/node/index.d.mts +121 -10
- package/dist/node/index.d.ts +121 -10
- package/dist/node/index.mjs +257 -11
- package/dist/react/index.d.mts +57 -17
- package/dist/react/index.d.ts +57 -17
- package/dist/react/index.mjs +177 -85
- package/dist/shared/@databuddy/sdk.3kaCzyfu.mjs +199 -0
- package/dist/shared/@databuddy/sdk.B6nwxnPC.d.mts +128 -0
- package/dist/shared/@databuddy/sdk.B6nwxnPC.d.ts +128 -0
- package/dist/shared/@databuddy/{sdk.CeYE_kaj.d.mts → sdk.C9b3SVYK.d.mts} +10 -10
- package/dist/shared/@databuddy/{sdk.CeYE_kaj.d.ts → sdk.C9b3SVYK.d.ts} +10 -10
- package/dist/shared/@databuddy/sdk.Du7SE7-M.mjs +479 -0
- package/dist/shared/@databuddy/sdk.F8Xt1uF7.mjs +35 -0
- package/dist/vue/index.d.mts +11 -2
- package/dist/vue/index.d.ts +11 -2
- package/dist/vue/index.mjs +19 -9
- package/package.json +3 -4
- package/dist/shared/@databuddy/sdk.Cn2tDA8H.mjs +0 -471
- package/dist/shared/@databuddy/sdk.OK9Nbqlf.d.mts +0 -64
- package/dist/shared/@databuddy/sdk.OK9Nbqlf.d.ts +0 -64
|
@@ -1,12 +1,151 @@
|
|
|
1
1
|
import { LanguageModelV2 } from '@ai-sdk/provider';
|
|
2
|
-
import { db as Databuddy } from '../../node/index.mjs';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @param model - The Vercel language model to wrap, if you are using the Vercel AI Gateway, please use the LanguageModelV2 type e.g. gateway('xai/grok-3') instead of the string type e.g. 'xai/grok-3'
|
|
7
|
-
* @param buddy - The Databuddy instance to use
|
|
8
|
-
* @returns The wrapped language model, can be used in e.g. generateText from the ai package
|
|
4
|
+
* Token usage from AI model calls
|
|
9
5
|
*/
|
|
10
|
-
|
|
6
|
+
interface TokenUsage {
|
|
7
|
+
inputTokens: number;
|
|
8
|
+
outputTokens: number;
|
|
9
|
+
totalTokens: number;
|
|
10
|
+
cachedInputTokens?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Cost breakdown from TokenLens
|
|
14
|
+
*/
|
|
15
|
+
interface TokenCost {
|
|
16
|
+
inputTokenCostUSD?: number;
|
|
17
|
+
outputTokenCostUSD?: number;
|
|
18
|
+
totalTokenCostUSD?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Tool call information
|
|
22
|
+
*/
|
|
23
|
+
interface ToolCallInfo {
|
|
24
|
+
toolCallCount: number;
|
|
25
|
+
toolResultCount: number;
|
|
26
|
+
toolCallNames: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error information for failed AI calls
|
|
30
|
+
*/
|
|
31
|
+
interface AIError {
|
|
32
|
+
name: string;
|
|
33
|
+
message: string;
|
|
34
|
+
stack?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Complete AI call log entry
|
|
38
|
+
*/
|
|
39
|
+
interface AICall {
|
|
40
|
+
timestamp: Date;
|
|
41
|
+
type: "generate" | "stream";
|
|
42
|
+
model: string;
|
|
43
|
+
provider: string;
|
|
44
|
+
finishReason?: string;
|
|
45
|
+
usage: TokenUsage;
|
|
46
|
+
cost: TokenCost;
|
|
47
|
+
tools: ToolCallInfo;
|
|
48
|
+
error?: AIError;
|
|
49
|
+
durationMs: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Transport function for sending log entries
|
|
53
|
+
*/
|
|
54
|
+
type Transport = (call: AICall) => Promise<void> | void;
|
|
55
|
+
/**
|
|
56
|
+
* Configuration options for Databuddy LLM tracking
|
|
57
|
+
*/
|
|
58
|
+
interface DatabuddyLLMOptions {
|
|
59
|
+
/**
|
|
60
|
+
* API endpoint for sending logs
|
|
61
|
+
* @default process.env.DATABUDDY_BASKET_URL + '/llm' or 'https://basket.databuddy.cc/llm'
|
|
62
|
+
*/
|
|
63
|
+
apiUrl?: string;
|
|
64
|
+
/**
|
|
65
|
+
* API key for authentication
|
|
66
|
+
* @default process.env.DATABUDDY_API_KEY
|
|
67
|
+
*/
|
|
68
|
+
apiKey?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Custom transport function to send log entries
|
|
71
|
+
* If provided, overrides default HTTP transport
|
|
72
|
+
*/
|
|
73
|
+
transport?: Transport;
|
|
74
|
+
/**
|
|
75
|
+
* Whether to compute costs using TokenLens
|
|
76
|
+
* @default true
|
|
77
|
+
*/
|
|
78
|
+
computeCosts?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Called on successful AI calls
|
|
81
|
+
*/
|
|
82
|
+
onSuccess?: (call: AICall) => void;
|
|
83
|
+
/**
|
|
84
|
+
* Called on failed AI calls
|
|
85
|
+
*/
|
|
86
|
+
onError?: (call: AICall) => void;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Configuration options for tracking individual models
|
|
90
|
+
*/
|
|
91
|
+
interface TrackOptions {
|
|
92
|
+
/**
|
|
93
|
+
* Transport function to send log entries
|
|
94
|
+
* If not provided, uses the transport from DatabuddyLLM instance
|
|
95
|
+
*/
|
|
96
|
+
transport?: Transport;
|
|
97
|
+
/**
|
|
98
|
+
* Whether to compute costs using TokenLens
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
computeCosts?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Called on successful AI calls
|
|
104
|
+
*/
|
|
105
|
+
onSuccess?: (call: AICall) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Called on failed AI calls
|
|
108
|
+
*/
|
|
109
|
+
onError?: (call: AICall) => void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Create a Databuddy LLM tracking instance
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* import { databuddyLLM } from "@databuddy/sdk/ai/vercel";
|
|
118
|
+
*
|
|
119
|
+
* const { track } = databuddyLLM({
|
|
120
|
+
* apiUrl: "https://api.databuddy.cc/ai-logs",
|
|
121
|
+
* apiKey: "your-api-key",
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* // Track a model
|
|
125
|
+
* const model = track(openai("gpt-4"));
|
|
126
|
+
*
|
|
127
|
+
* // Or with custom transport
|
|
128
|
+
* const { track } = databuddyLLM({
|
|
129
|
+
* transport: async (call) => console.log(call),
|
|
130
|
+
* });
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare const databuddyLLM: (options?: DatabuddyLLMOptions) => {
|
|
134
|
+
track: (model: LanguageModelV2, trackOptions?: TrackOptions) => LanguageModelV2;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Create an HTTP transport that sends logs to an API endpoint
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* import { databuddyLLM, httpTransport } from "@databuddy/sdk/ai/vercel";
|
|
142
|
+
*
|
|
143
|
+
* const { track } = databuddyLLM({
|
|
144
|
+
* transport: httpTransport("https://api.example.com/ai-logs"),
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
declare const httpTransport: (url: string, apiKey?: string) => Transport;
|
|
11
149
|
|
|
12
|
-
export {
|
|
150
|
+
export { databuddyLLM, httpTransport };
|
|
151
|
+
export type { AICall, AIError, DatabuddyLLMOptions, TokenCost, TokenUsage, ToolCallInfo, TrackOptions, Transport };
|
|
@@ -1,12 +1,151 @@
|
|
|
1
1
|
import { LanguageModelV2 } from '@ai-sdk/provider';
|
|
2
|
-
import { db as Databuddy } from '../../node/index.js';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @param model - The Vercel language model to wrap, if you are using the Vercel AI Gateway, please use the LanguageModelV2 type e.g. gateway('xai/grok-3') instead of the string type e.g. 'xai/grok-3'
|
|
7
|
-
* @param buddy - The Databuddy instance to use
|
|
8
|
-
* @returns The wrapped language model, can be used in e.g. generateText from the ai package
|
|
4
|
+
* Token usage from AI model calls
|
|
9
5
|
*/
|
|
10
|
-
|
|
6
|
+
interface TokenUsage {
|
|
7
|
+
inputTokens: number;
|
|
8
|
+
outputTokens: number;
|
|
9
|
+
totalTokens: number;
|
|
10
|
+
cachedInputTokens?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Cost breakdown from TokenLens
|
|
14
|
+
*/
|
|
15
|
+
interface TokenCost {
|
|
16
|
+
inputTokenCostUSD?: number;
|
|
17
|
+
outputTokenCostUSD?: number;
|
|
18
|
+
totalTokenCostUSD?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Tool call information
|
|
22
|
+
*/
|
|
23
|
+
interface ToolCallInfo {
|
|
24
|
+
toolCallCount: number;
|
|
25
|
+
toolResultCount: number;
|
|
26
|
+
toolCallNames: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error information for failed AI calls
|
|
30
|
+
*/
|
|
31
|
+
interface AIError {
|
|
32
|
+
name: string;
|
|
33
|
+
message: string;
|
|
34
|
+
stack?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Complete AI call log entry
|
|
38
|
+
*/
|
|
39
|
+
interface AICall {
|
|
40
|
+
timestamp: Date;
|
|
41
|
+
type: "generate" | "stream";
|
|
42
|
+
model: string;
|
|
43
|
+
provider: string;
|
|
44
|
+
finishReason?: string;
|
|
45
|
+
usage: TokenUsage;
|
|
46
|
+
cost: TokenCost;
|
|
47
|
+
tools: ToolCallInfo;
|
|
48
|
+
error?: AIError;
|
|
49
|
+
durationMs: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Transport function for sending log entries
|
|
53
|
+
*/
|
|
54
|
+
type Transport = (call: AICall) => Promise<void> | void;
|
|
55
|
+
/**
|
|
56
|
+
* Configuration options for Databuddy LLM tracking
|
|
57
|
+
*/
|
|
58
|
+
interface DatabuddyLLMOptions {
|
|
59
|
+
/**
|
|
60
|
+
* API endpoint for sending logs
|
|
61
|
+
* @default process.env.DATABUDDY_BASKET_URL + '/llm' or 'https://basket.databuddy.cc/llm'
|
|
62
|
+
*/
|
|
63
|
+
apiUrl?: string;
|
|
64
|
+
/**
|
|
65
|
+
* API key for authentication
|
|
66
|
+
* @default process.env.DATABUDDY_API_KEY
|
|
67
|
+
*/
|
|
68
|
+
apiKey?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Custom transport function to send log entries
|
|
71
|
+
* If provided, overrides default HTTP transport
|
|
72
|
+
*/
|
|
73
|
+
transport?: Transport;
|
|
74
|
+
/**
|
|
75
|
+
* Whether to compute costs using TokenLens
|
|
76
|
+
* @default true
|
|
77
|
+
*/
|
|
78
|
+
computeCosts?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Called on successful AI calls
|
|
81
|
+
*/
|
|
82
|
+
onSuccess?: (call: AICall) => void;
|
|
83
|
+
/**
|
|
84
|
+
* Called on failed AI calls
|
|
85
|
+
*/
|
|
86
|
+
onError?: (call: AICall) => void;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Configuration options for tracking individual models
|
|
90
|
+
*/
|
|
91
|
+
interface TrackOptions {
|
|
92
|
+
/**
|
|
93
|
+
* Transport function to send log entries
|
|
94
|
+
* If not provided, uses the transport from DatabuddyLLM instance
|
|
95
|
+
*/
|
|
96
|
+
transport?: Transport;
|
|
97
|
+
/**
|
|
98
|
+
* Whether to compute costs using TokenLens
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
computeCosts?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Called on successful AI calls
|
|
104
|
+
*/
|
|
105
|
+
onSuccess?: (call: AICall) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Called on failed AI calls
|
|
108
|
+
*/
|
|
109
|
+
onError?: (call: AICall) => void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Create a Databuddy LLM tracking instance
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* import { databuddyLLM } from "@databuddy/sdk/ai/vercel";
|
|
118
|
+
*
|
|
119
|
+
* const { track } = databuddyLLM({
|
|
120
|
+
* apiUrl: "https://api.databuddy.cc/ai-logs",
|
|
121
|
+
* apiKey: "your-api-key",
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* // Track a model
|
|
125
|
+
* const model = track(openai("gpt-4"));
|
|
126
|
+
*
|
|
127
|
+
* // Or with custom transport
|
|
128
|
+
* const { track } = databuddyLLM({
|
|
129
|
+
* transport: async (call) => console.log(call),
|
|
130
|
+
* });
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare const databuddyLLM: (options?: DatabuddyLLMOptions) => {
|
|
134
|
+
track: (model: LanguageModelV2, trackOptions?: TrackOptions) => LanguageModelV2;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Create an HTTP transport that sends logs to an API endpoint
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* import { databuddyLLM, httpTransport } from "@databuddy/sdk/ai/vercel";
|
|
142
|
+
*
|
|
143
|
+
* const { track } = databuddyLLM({
|
|
144
|
+
* transport: httpTransport("https://api.example.com/ai-logs"),
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
declare const httpTransport: (url: string, apiKey?: string) => Transport;
|
|
11
149
|
|
|
12
|
-
export {
|
|
150
|
+
export { databuddyLLM, httpTransport };
|
|
151
|
+
export type { AICall, AIError, DatabuddyLLMOptions, TokenCost, TokenUsage, ToolCallInfo, TrackOptions, Transport };
|
package/dist/ai/vercel/index.mjs
CHANGED
|
@@ -1,43 +1,230 @@
|
|
|
1
1
|
import { wrapLanguageModel } from 'ai';
|
|
2
|
-
import { computeCostUSD } from 'tokenlens';
|
|
3
2
|
|
|
4
|
-
const
|
|
3
|
+
const extractToolInfo = (content) => {
|
|
4
|
+
const toolCalls = content.filter((part) => part.type === "tool-call");
|
|
5
|
+
const toolResults = content.filter((part) => part.type === "tool-result");
|
|
6
|
+
const toolCallNames = [
|
|
7
|
+
...new Set(
|
|
8
|
+
toolCalls.map((c) => c.toolName).filter((name) => Boolean(name))
|
|
9
|
+
)
|
|
10
|
+
];
|
|
11
|
+
return {
|
|
12
|
+
toolCallCount: toolCalls.length,
|
|
13
|
+
toolResultCount: toolResults.length,
|
|
14
|
+
toolCallNames
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
const computeCosts = async (modelId, provider, usage) => {
|
|
18
|
+
try {
|
|
19
|
+
const { computeCostUSD } = await import('tokenlens');
|
|
20
|
+
const result = await computeCostUSD({
|
|
21
|
+
modelId,
|
|
22
|
+
provider,
|
|
23
|
+
usage: {
|
|
24
|
+
input_tokens: usage.inputTokens,
|
|
25
|
+
output_tokens: usage.outputTokens
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
inputTokenCostUSD: result.inputTokenCostUSD,
|
|
30
|
+
outputTokenCostUSD: result.outputTokenCostUSD,
|
|
31
|
+
totalTokenCostUSD: result.totalTokenCostUSD
|
|
32
|
+
};
|
|
33
|
+
} catch {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const createDefaultTransport = (apiUrl, apiKey) => {
|
|
38
|
+
return async (call) => {
|
|
39
|
+
const headers = {
|
|
40
|
+
"Content-Type": "application/json"
|
|
41
|
+
};
|
|
42
|
+
if (apiKey) {
|
|
43
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
44
|
+
}
|
|
45
|
+
const response = await fetch(apiUrl, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers,
|
|
48
|
+
body: JSON.stringify(call)
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Failed to send AI log: ${response.status} ${response.statusText}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
const createMiddleware = (transport, options = {}) => {
|
|
58
|
+
const { computeCosts: shouldComputeCosts = true } = options;
|
|
5
59
|
return {
|
|
6
60
|
wrapGenerate: async ({ doGenerate, model }) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
try {
|
|
63
|
+
const result = await doGenerate();
|
|
64
|
+
const durationMs = Date.now() - startTime;
|
|
65
|
+
const tools = extractToolInfo(
|
|
66
|
+
result.content
|
|
67
|
+
);
|
|
68
|
+
const inputTokens = result.usage.inputTokens ?? 0;
|
|
69
|
+
const outputTokens = result.usage.outputTokens ?? 0;
|
|
70
|
+
const totalTokens = result.usage.totalTokens ?? inputTokens + outputTokens;
|
|
71
|
+
const cachedInputTokens = result.usage.cachedInputTokens;
|
|
72
|
+
const cost = shouldComputeCosts && (inputTokens > 0 || outputTokens > 0) ? await computeCosts(model.modelId, model.provider, {
|
|
73
|
+
inputTokens,
|
|
74
|
+
outputTokens
|
|
75
|
+
}) : {};
|
|
76
|
+
const call = {
|
|
77
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
78
|
+
type: "generate",
|
|
79
|
+
model: model.modelId,
|
|
80
|
+
provider: model.provider,
|
|
81
|
+
finishReason: result.finishReason,
|
|
82
|
+
usage: {
|
|
83
|
+
inputTokens,
|
|
84
|
+
outputTokens,
|
|
85
|
+
totalTokens,
|
|
86
|
+
cachedInputTokens
|
|
87
|
+
},
|
|
88
|
+
cost,
|
|
89
|
+
tools,
|
|
90
|
+
durationMs
|
|
91
|
+
};
|
|
92
|
+
const effectiveTransport = options.transport ?? transport;
|
|
93
|
+
const transportResult = effectiveTransport(call);
|
|
94
|
+
if (transportResult instanceof Promise) {
|
|
95
|
+
transportResult.catch(() => {
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
options.onSuccess?.(call);
|
|
99
|
+
return result;
|
|
100
|
+
} catch (error) {
|
|
101
|
+
const durationMs = Date.now() - startTime;
|
|
102
|
+
const call = {
|
|
103
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
104
|
+
type: "generate",
|
|
105
|
+
model: model.modelId,
|
|
106
|
+
provider: model.provider,
|
|
107
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
108
|
+
cost: {},
|
|
109
|
+
tools: { toolCallCount: 0, toolResultCount: 0, toolCallNames: [] },
|
|
110
|
+
durationMs,
|
|
111
|
+
error: {
|
|
112
|
+
name: error instanceof Error ? error.name : "UnknownError",
|
|
113
|
+
message: error instanceof Error ? error.message : String(error),
|
|
114
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const effectiveTransport = options.transport ?? transport;
|
|
118
|
+
const transportResult = effectiveTransport(call);
|
|
119
|
+
if (transportResult instanceof Promise) {
|
|
120
|
+
transportResult.catch(() => {
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
options.onError?.(call);
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
wrapStream: async ({ doStream, model }) => {
|
|
128
|
+
const startTime = Date.now();
|
|
129
|
+
try {
|
|
130
|
+
const { stream, ...rest } = await doStream();
|
|
131
|
+
const durationMs = Date.now() - startTime;
|
|
132
|
+
const call = {
|
|
133
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
134
|
+
type: "stream",
|
|
135
|
+
model: model.modelId,
|
|
136
|
+
provider: model.provider,
|
|
137
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
138
|
+
cost: {},
|
|
139
|
+
tools: { toolCallCount: 0, toolResultCount: 0, toolCallNames: [] },
|
|
140
|
+
durationMs
|
|
141
|
+
};
|
|
142
|
+
const effectiveTransport = options.transport ?? transport;
|
|
143
|
+
const transportResult = effectiveTransport(call);
|
|
144
|
+
if (transportResult instanceof Promise) {
|
|
145
|
+
transportResult.catch(() => {
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
options.onSuccess?.(call);
|
|
149
|
+
return { stream, ...rest };
|
|
150
|
+
} catch (error) {
|
|
151
|
+
const durationMs = Date.now() - startTime;
|
|
152
|
+
const call = {
|
|
153
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
154
|
+
type: "stream",
|
|
155
|
+
model: model.modelId,
|
|
156
|
+
provider: model.provider,
|
|
157
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
158
|
+
cost: {},
|
|
159
|
+
tools: { toolCallCount: 0, toolResultCount: 0, toolCallNames: [] },
|
|
160
|
+
durationMs,
|
|
161
|
+
error: {
|
|
162
|
+
name: error instanceof Error ? error.name : "UnknownError",
|
|
163
|
+
message: error instanceof Error ? error.message : String(error),
|
|
164
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const effectiveTransport = options.transport ?? transport;
|
|
168
|
+
const transportResult = effectiveTransport(call);
|
|
169
|
+
if (transportResult instanceof Promise) {
|
|
170
|
+
transportResult.catch(() => {
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
options.onError?.(call);
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
const databuddyLLM = (options = {}) => {
|
|
180
|
+
const {
|
|
181
|
+
apiUrl,
|
|
182
|
+
apiKey,
|
|
183
|
+
transport: customTransport,
|
|
184
|
+
computeCosts: defaultComputeCosts = true,
|
|
185
|
+
onSuccess: defaultOnSuccess,
|
|
186
|
+
onError: defaultOnError
|
|
187
|
+
} = options;
|
|
188
|
+
let transport;
|
|
189
|
+
if (customTransport) {
|
|
190
|
+
transport = customTransport;
|
|
191
|
+
} else {
|
|
192
|
+
const endpoint = apiUrl ?? (process.env.DATABUDDY_BASKET_URL ? `${process.env.DATABUDDY_BASKET_URL}/llm` : process.env.DATABUDDY_API_URL ? `${process.env.DATABUDDY_API_URL}/llm` : "https://basket.databuddy.cc/llm");
|
|
193
|
+
const key = apiKey ?? process.env.DATABUDDY_API_KEY;
|
|
194
|
+
transport = createDefaultTransport(endpoint, key);
|
|
195
|
+
}
|
|
196
|
+
const track = (model, trackOptions = {}) => {
|
|
197
|
+
return wrapLanguageModel({
|
|
198
|
+
model,
|
|
199
|
+
middleware: createMiddleware(transport, {
|
|
200
|
+
computeCosts: trackOptions.computeCosts ?? defaultComputeCosts,
|
|
201
|
+
onSuccess: trackOptions.onSuccess ?? defaultOnSuccess,
|
|
202
|
+
onError: trackOptions.onError ?? defaultOnError,
|
|
203
|
+
transport: trackOptions.transport
|
|
204
|
+
})
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
return { track };
|
|
208
|
+
};
|
|
209
|
+
const httpTransport = (url, apiKey) => {
|
|
210
|
+
return async (call) => {
|
|
211
|
+
const headers = {
|
|
212
|
+
"Content-Type": "application/json"
|
|
213
|
+
};
|
|
214
|
+
if (apiKey) {
|
|
215
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
216
|
+
}
|
|
217
|
+
const response = await fetch(url, {
|
|
218
|
+
method: "POST",
|
|
219
|
+
headers,
|
|
220
|
+
body: JSON.stringify(call)
|
|
221
|
+
});
|
|
222
|
+
if (!response.ok) {
|
|
223
|
+
throw new Error(
|
|
224
|
+
`Failed to send AI log: ${response.status} ${response.statusText}`
|
|
14
225
|
);
|
|
15
|
-
const costs = await computeCostUSD({
|
|
16
|
-
modelId: model.modelId,
|
|
17
|
-
provider: model.provider,
|
|
18
|
-
usage: result.usage
|
|
19
|
-
});
|
|
20
|
-
const payload = {
|
|
21
|
-
inputTokens: result.usage.inputTokens,
|
|
22
|
-
outputTokens: result.usage.outputTokens,
|
|
23
|
-
totalTokens: result.usage.totalTokens,
|
|
24
|
-
cachedInputTokens: result.usage.cachedInputTokens,
|
|
25
|
-
finishReason: result.finishReason,
|
|
26
|
-
toolCallCount: toolCalls.length,
|
|
27
|
-
toolResultCount: toolResults.length,
|
|
28
|
-
inputTokenCostUSD: costs.inputTokenCostUSD,
|
|
29
|
-
outputTokenCostUSD: costs.outputTokenCostUSD,
|
|
30
|
-
totalTokenCostUSD: costs.totalTokenCostUSD,
|
|
31
|
-
toolCallNames
|
|
32
|
-
};
|
|
33
|
-
console.log("payload", payload);
|
|
34
|
-
return result;
|
|
35
226
|
}
|
|
36
227
|
};
|
|
37
228
|
};
|
|
38
|
-
const wrapVercelLanguageModel = (model, buddy) => wrapLanguageModel({
|
|
39
|
-
model,
|
|
40
|
-
middleware: buddyWare()
|
|
41
|
-
});
|
|
42
229
|
|
|
43
|
-
export {
|
|
230
|
+
export { databuddyLLM, httpTransport };
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { e as
|
|
3
|
-
import { D as DatabuddyConfig, a as DatabuddyTracker } from '../shared/@databuddy/sdk.CeYE_kaj.mjs';
|
|
4
|
-
export { B as BaseEventProperties, d as DataAttributes, c as EventName, E as EventProperties, b as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, e as SetGlobalPropertiesFunction, T as TrackFunction } from '../shared/@databuddy/sdk.CeYE_kaj.mjs';
|
|
1
|
+
import { D as DatabuddyConfig, a as DatabuddyTracker } from '../shared/@databuddy/sdk.C9b3SVYK.mjs';
|
|
2
|
+
export { B as BaseEventProperties, d as DataAttributes, c as EventName, E as EventProperties, b as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, e as SetGlobalPropertiesFunction, T as TrackFunction } from '../shared/@databuddy/sdk.C9b3SVYK.mjs';
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Auto-detect Databuddy client ID from environment variables
|
|
@@ -9,44 +7,6 @@ export { B as BaseEventProperties, d as DataAttributes, c as EventName, E as Eve
|
|
|
9
7
|
*/
|
|
10
8
|
declare function detectClientId(providedClientId?: string): string | undefined;
|
|
11
9
|
|
|
12
|
-
declare class BrowserFlagStorage implements StorageInterface {
|
|
13
|
-
private ttl;
|
|
14
|
-
get(key: string): any;
|
|
15
|
-
set(key: string, value: unknown): void;
|
|
16
|
-
getAll(): Record<string, unknown>;
|
|
17
|
-
clear(): void;
|
|
18
|
-
private getFromLocalStorage;
|
|
19
|
-
private setToLocalStorage;
|
|
20
|
-
private isExpired;
|
|
21
|
-
delete(key: string): void;
|
|
22
|
-
deleteMultiple(keys: string[]): void;
|
|
23
|
-
setAll(flags: Record<string, unknown>): void;
|
|
24
|
-
cleanupExpired(): void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
declare class CoreFlagsManager implements FlagsManager {
|
|
28
|
-
private config;
|
|
29
|
-
private storage?;
|
|
30
|
-
private onFlagsUpdate?;
|
|
31
|
-
private onConfigUpdate?;
|
|
32
|
-
private memoryFlags;
|
|
33
|
-
private pendingFlags;
|
|
34
|
-
constructor(options: FlagsManagerOptions);
|
|
35
|
-
private withDefaults;
|
|
36
|
-
private initialize;
|
|
37
|
-
private loadCachedFlags;
|
|
38
|
-
fetchAllFlags(): Promise<void>;
|
|
39
|
-
getFlag(key: string): Promise<FlagResult>;
|
|
40
|
-
private fetchFlag;
|
|
41
|
-
isEnabled(key: string): FlagState;
|
|
42
|
-
refresh(forceClear?: boolean): void;
|
|
43
|
-
updateUser(user: FlagsConfig["user"]): void;
|
|
44
|
-
updateConfig(config: FlagsConfig): void;
|
|
45
|
-
getMemoryFlags(): Record<string, FlagResult>;
|
|
46
|
-
getPendingFlags(): Set<string>;
|
|
47
|
-
private notifyFlagsUpdate;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
10
|
declare function isScriptInjected(): boolean;
|
|
51
11
|
declare function createScript({ scriptUrl, sdkVersion, clientSecret, filter, debug, ...props }: DatabuddyConfig): HTMLScriptElement;
|
|
52
12
|
|
|
@@ -272,4 +232,4 @@ declare function getTrackingIds(urlParams?: URLSearchParams): {
|
|
|
272
232
|
*/
|
|
273
233
|
declare function getTrackingParams(urlParams?: URLSearchParams): string;
|
|
274
234
|
|
|
275
|
-
export {
|
|
235
|
+
export { DatabuddyConfig, DatabuddyTracker, clear, createScript, detectClientId, flush, getAnonymousId, getSessionId, getTracker, getTrackingIds, getTrackingParams, isScriptInjected, isTrackerAvailable, track, trackCustomEvent, trackError };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { e as
|
|
3
|
-
import { D as DatabuddyConfig, a as DatabuddyTracker } from '../shared/@databuddy/sdk.CeYE_kaj.js';
|
|
4
|
-
export { B as BaseEventProperties, d as DataAttributes, c as EventName, E as EventProperties, b as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, e as SetGlobalPropertiesFunction, T as TrackFunction } from '../shared/@databuddy/sdk.CeYE_kaj.js';
|
|
1
|
+
import { D as DatabuddyConfig, a as DatabuddyTracker } from '../shared/@databuddy/sdk.C9b3SVYK.js';
|
|
2
|
+
export { B as BaseEventProperties, d as DataAttributes, c as EventName, E as EventProperties, b as EventTypeMap, P as PropertiesForEvent, S as ScreenViewFunction, e as SetGlobalPropertiesFunction, T as TrackFunction } from '../shared/@databuddy/sdk.C9b3SVYK.js';
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Auto-detect Databuddy client ID from environment variables
|
|
@@ -9,44 +7,6 @@ export { B as BaseEventProperties, d as DataAttributes, c as EventName, E as Eve
|
|
|
9
7
|
*/
|
|
10
8
|
declare function detectClientId(providedClientId?: string): string | undefined;
|
|
11
9
|
|
|
12
|
-
declare class BrowserFlagStorage implements StorageInterface {
|
|
13
|
-
private ttl;
|
|
14
|
-
get(key: string): any;
|
|
15
|
-
set(key: string, value: unknown): void;
|
|
16
|
-
getAll(): Record<string, unknown>;
|
|
17
|
-
clear(): void;
|
|
18
|
-
private getFromLocalStorage;
|
|
19
|
-
private setToLocalStorage;
|
|
20
|
-
private isExpired;
|
|
21
|
-
delete(key: string): void;
|
|
22
|
-
deleteMultiple(keys: string[]): void;
|
|
23
|
-
setAll(flags: Record<string, unknown>): void;
|
|
24
|
-
cleanupExpired(): void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
declare class CoreFlagsManager implements FlagsManager {
|
|
28
|
-
private config;
|
|
29
|
-
private storage?;
|
|
30
|
-
private onFlagsUpdate?;
|
|
31
|
-
private onConfigUpdate?;
|
|
32
|
-
private memoryFlags;
|
|
33
|
-
private pendingFlags;
|
|
34
|
-
constructor(options: FlagsManagerOptions);
|
|
35
|
-
private withDefaults;
|
|
36
|
-
private initialize;
|
|
37
|
-
private loadCachedFlags;
|
|
38
|
-
fetchAllFlags(): Promise<void>;
|
|
39
|
-
getFlag(key: string): Promise<FlagResult>;
|
|
40
|
-
private fetchFlag;
|
|
41
|
-
isEnabled(key: string): FlagState;
|
|
42
|
-
refresh(forceClear?: boolean): void;
|
|
43
|
-
updateUser(user: FlagsConfig["user"]): void;
|
|
44
|
-
updateConfig(config: FlagsConfig): void;
|
|
45
|
-
getMemoryFlags(): Record<string, FlagResult>;
|
|
46
|
-
getPendingFlags(): Set<string>;
|
|
47
|
-
private notifyFlagsUpdate;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
10
|
declare function isScriptInjected(): boolean;
|
|
51
11
|
declare function createScript({ scriptUrl, sdkVersion, clientSecret, filter, debug, ...props }: DatabuddyConfig): HTMLScriptElement;
|
|
52
12
|
|
|
@@ -272,4 +232,4 @@ declare function getTrackingIds(urlParams?: URLSearchParams): {
|
|
|
272
232
|
*/
|
|
273
233
|
declare function getTrackingParams(urlParams?: URLSearchParams): string;
|
|
274
234
|
|
|
275
|
-
export {
|
|
235
|
+
export { DatabuddyConfig, DatabuddyTracker, clear, createScript, detectClientId, flush, getAnonymousId, getSessionId, getTracker, getTrackingIds, getTrackingParams, isScriptInjected, isTrackerAvailable, track, trackCustomEvent, trackError };
|