@carbon-js/sdk 0.0.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 +26 -0
- package/dist/ai/anthropic/event-factory.d.mts +22 -0
- package/dist/ai/anthropic/event-factory.mjs +97 -0
- package/dist/ai/anthropic/fns/message-create.d.mts +15 -0
- package/dist/ai/anthropic/fns/message-create.mjs +248 -0
- package/dist/ai/anthropic/fns/message-stream.d.mts +15 -0
- package/dist/ai/anthropic/fns/message-stream.mjs +59 -0
- package/dist/ai/anthropic/types.d.mts +5 -0
- package/dist/ai/anthropic/types.mjs +0 -0
- package/dist/ai/anthropic/wrap.d.mts +13 -0
- package/dist/ai/anthropic/wrap.mjs +17 -0
- package/dist/ai/openai/event-factory.d.mts +34 -0
- package/dist/ai/openai/event-factory.mjs +189 -0
- package/dist/ai/openai/fns/chat-completions-create.d.mts +15 -0
- package/dist/ai/openai/fns/chat-completions-create.mjs +219 -0
- package/dist/ai/openai/fns/chat-completions-run-tools.d.mts +15 -0
- package/dist/ai/openai/fns/chat-completions-run-tools.mjs +112 -0
- package/dist/ai/openai/fns/chat-completions-stream.d.mts +15 -0
- package/dist/ai/openai/fns/chat-completions-stream.mjs +69 -0
- package/dist/ai/openai/fns/response-create.d.mts +15 -0
- package/dist/ai/openai/fns/response-create.mjs +137 -0
- package/dist/ai/openai/fns/response-stream.d.mts +15 -0
- package/dist/ai/openai/fns/response-stream.mjs +59 -0
- package/dist/ai/openai/types.d.mts +5 -0
- package/dist/ai/openai/types.mjs +0 -0
- package/dist/ai/openai/utils/capture-options.d.mts +6 -0
- package/dist/ai/openai/utils/capture-options.mjs +4 -0
- package/dist/ai/openai/wrap.d.mts +13 -0
- package/dist/ai/openai/wrap.mjs +32 -0
- package/dist/ai/vercel/event-factory.d.mts +52 -0
- package/dist/ai/vercel/event-factory.mjs +140 -0
- package/dist/ai/vercel/fns/tool-loop-agent.d.mts +17 -0
- package/dist/ai/vercel/fns/tool-loop-agent.mjs +117 -0
- package/dist/ai/vercel/recorder.d.mts +37 -0
- package/dist/ai/vercel/recorder.mjs +194 -0
- package/dist/ai/vercel/types.d.mts +40 -0
- package/dist/ai/vercel/types.mjs +1 -0
- package/dist/ai/vercel/utils/telemetry.d.mts +31 -0
- package/dist/ai/vercel/utils/telemetry.mjs +46 -0
- package/dist/ai/vercel/wrap.d.mts +13 -0
- package/dist/ai/vercel/wrap.mjs +29 -0
- package/dist/ai.d.mts +16 -0
- package/dist/ai.mjs +8 -0
- package/dist/core/carbon.d.mts +27 -0
- package/dist/core/carbon.mjs +35 -0
- package/dist/core/events/event-buffer.d.mts +19 -0
- package/dist/core/events/event-buffer.mjs +26 -0
- package/dist/core/runtime.d.mts +34 -0
- package/dist/core/runtime.mjs +119 -0
- package/dist/core/schema/carbon-object.d.mts +11 -0
- package/dist/core/schema/carbon-object.mjs +0 -0
- package/dist/core/tools/wrap-tool.d.mts +16 -0
- package/dist/core/tools/wrap-tool.mjs +120 -0
- package/dist/core/transport/file-transport.d.mts +16 -0
- package/dist/core/transport/file-transport.mjs +17 -0
- package/dist/core/transport/http-transport.d.mts +31 -0
- package/dist/core/transport/http-transport.mjs +79 -0
- package/dist/core/transport/memory-transport.d.mts +12 -0
- package/dist/core/transport/memory-transport.mjs +11 -0
- package/dist/core/transport/types.d.mts +13 -0
- package/dist/core/transport/types.mjs +0 -0
- package/dist/core/utils/build-events.d.mts +33 -0
- package/dist/core/utils/build-events.mjs +132 -0
- package/dist/core/utils/instrumentation.d.mts +12 -0
- package/dist/core/utils/instrumentation.mjs +12 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.mjs +11 -0
- package/dist/internal/schema/events.d.mts +315 -0
- package/dist/internal/schema/events.mjs +111 -0
- package/dist/internal/schema/index.mjs +1 -0
- package/dist/lib/constants.d.mts +16 -0
- package/dist/lib/constants.mjs +16 -0
- package/dist/utils/ids.d.mts +3 -0
- package/dist/utils/ids.mjs +4 -0
- package/dist/utils/promise.d.mts +8 -0
- package/dist/utils/promise.mjs +6 -0
- package/dist/utils/retry.d.mts +16 -0
- package/dist/utils/retry.mjs +47 -0
- package/dist/utils/stringify.d.mts +6 -0
- package/dist/utils/stringify.mjs +16 -0
- package/dist/utils/timeout.d.mts +9 -0
- package/dist/utils/timeout.mjs +27 -0
- package/package.json +28 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { createErrorStatus, createOkStatus } from "../../core/utils/build-events.mjs";
|
|
2
|
+
import {
|
|
3
|
+
VercelEventFactory
|
|
4
|
+
} from "./event-factory.mjs";
|
|
5
|
+
import { bindTelemetryIntegration } from "ai";
|
|
6
|
+
class VercelRecorder {
|
|
7
|
+
completedEvents = [];
|
|
8
|
+
factory;
|
|
9
|
+
llmEventsByStep = /* @__PURE__ */ new Map();
|
|
10
|
+
carbon;
|
|
11
|
+
toolEventsById = /* @__PURE__ */ new Map();
|
|
12
|
+
isRecorded = false;
|
|
13
|
+
startTimeMs = Date.now();
|
|
14
|
+
constructor(args) {
|
|
15
|
+
this.factory = new VercelEventFactory({
|
|
16
|
+
carbonObject: args.carbonObject,
|
|
17
|
+
mode: args.mode,
|
|
18
|
+
sourceFunction: args.sourceFunction
|
|
19
|
+
});
|
|
20
|
+
this.carbon = args.carbon;
|
|
21
|
+
}
|
|
22
|
+
createIntegration() {
|
|
23
|
+
return bindTelemetryIntegration({
|
|
24
|
+
onStart: () => {
|
|
25
|
+
this.startTimeMs = Date.now();
|
|
26
|
+
},
|
|
27
|
+
onStepStart: (event) => {
|
|
28
|
+
this.getPendingLlmEvent({ event });
|
|
29
|
+
},
|
|
30
|
+
onToolCallStart: (event) => {
|
|
31
|
+
this.getPendingToolEvent({ event });
|
|
32
|
+
},
|
|
33
|
+
onToolCallFinish: (event) => {
|
|
34
|
+
this.onToolCallFinish(event);
|
|
35
|
+
},
|
|
36
|
+
onStepFinish: (event) => {
|
|
37
|
+
this.closePendingLlmEvent({
|
|
38
|
+
endTimeMs: Date.now(),
|
|
39
|
+
event,
|
|
40
|
+
status: createOkStatus()
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
onFinish: (event) => {
|
|
44
|
+
this.onFinish(event);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
recordError(args) {
|
|
49
|
+
if (this.isRecorded) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const endTimeMs = Date.now();
|
|
53
|
+
const status = createErrorStatus({ error: args.error });
|
|
54
|
+
for (const pendingTool of this.toolEventsById.values()) {
|
|
55
|
+
this.completedEvents.push(
|
|
56
|
+
this.factory.createCompletedToolEvent({
|
|
57
|
+
endTimeMs,
|
|
58
|
+
output: args.error,
|
|
59
|
+
pendingTool,
|
|
60
|
+
status
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
this.toolEventsById.clear();
|
|
65
|
+
for (const pendingLlm of this.llmEventsByStep.values()) {
|
|
66
|
+
this.completedEvents.push(
|
|
67
|
+
this.factory.createCompletedLlmEvent({
|
|
68
|
+
endTimeMs,
|
|
69
|
+
pendingLlm,
|
|
70
|
+
status
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
this.llmEventsByStep.clear();
|
|
75
|
+
if (this.completedEvents.length === 0) {
|
|
76
|
+
this.completedEvents.push(
|
|
77
|
+
this.factory.createCompletedLlmEvent({
|
|
78
|
+
endTimeMs,
|
|
79
|
+
pendingLlm: this.factory.createFallbackPendingLlmEvent({
|
|
80
|
+
startTimeMs: this.startTimeMs
|
|
81
|
+
}),
|
|
82
|
+
status
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
this.recordEvents();
|
|
87
|
+
}
|
|
88
|
+
onToolCallFinish(event) {
|
|
89
|
+
const pendingTool = this.getPendingToolEvent({
|
|
90
|
+
event,
|
|
91
|
+
startTimeMs: Date.now() - event.durationMs
|
|
92
|
+
});
|
|
93
|
+
this.completedEvents.push(
|
|
94
|
+
this.factory.createCompletedToolEvent({
|
|
95
|
+
endTimeMs: Date.now(),
|
|
96
|
+
output: event.success ? event.output : event.error,
|
|
97
|
+
pendingTool,
|
|
98
|
+
status: event.success ? createOkStatus() : createErrorStatus({ error: event.error })
|
|
99
|
+
})
|
|
100
|
+
);
|
|
101
|
+
this.toolEventsById.delete(event.toolCall.toolCallId);
|
|
102
|
+
}
|
|
103
|
+
onFinish(event) {
|
|
104
|
+
if (this.isRecorded) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const endTimeMs = Date.now();
|
|
108
|
+
for (const [stepNumber, pendingLlm] of this.llmEventsByStep) {
|
|
109
|
+
this.completedEvents.push(
|
|
110
|
+
this.factory.createCompletedLlmEvent({
|
|
111
|
+
endTimeMs,
|
|
112
|
+
event: event.steps.find((step) => step.stepNumber === stepNumber) ?? event,
|
|
113
|
+
pendingLlm,
|
|
114
|
+
status: createOkStatus()
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
this.llmEventsByStep.clear();
|
|
119
|
+
if (!this.completedEvents.some((completedEvent) => completedEvent.type === "llm")) {
|
|
120
|
+
this.completedEvents.push(
|
|
121
|
+
this.factory.createCompletedLlmEvent({
|
|
122
|
+
endTimeMs,
|
|
123
|
+
event,
|
|
124
|
+
pendingLlm: this.factory.createPendingLlmEvent({
|
|
125
|
+
event,
|
|
126
|
+
startTimeMs: this.startTimeMs
|
|
127
|
+
}),
|
|
128
|
+
status: createOkStatus()
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
this.recordEvents();
|
|
133
|
+
}
|
|
134
|
+
recordEvents() {
|
|
135
|
+
this.isRecorded = true;
|
|
136
|
+
this.carbon.captureEvents({
|
|
137
|
+
events: [...this.completedEvents].sort((a, b) => {
|
|
138
|
+
if (a.startTimeMs !== b.startTimeMs) {
|
|
139
|
+
return a.startTimeMs - b.startTimeMs;
|
|
140
|
+
}
|
|
141
|
+
const aPriority = a.type === "llm" ? 0 : 1;
|
|
142
|
+
const bPriority = b.type === "llm" ? 0 : 1;
|
|
143
|
+
return aPriority - bPriority;
|
|
144
|
+
})
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
getPendingLlmEvent(args) {
|
|
148
|
+
const stepNumber = args.event.stepNumber ?? 0;
|
|
149
|
+
const existing = this.llmEventsByStep.get(stepNumber);
|
|
150
|
+
if (existing) {
|
|
151
|
+
return existing;
|
|
152
|
+
}
|
|
153
|
+
const pendingLlm = this.factory.createPendingLlmEvent({
|
|
154
|
+
event: args.event,
|
|
155
|
+
startTimeMs: args.startTimeMs
|
|
156
|
+
});
|
|
157
|
+
this.llmEventsByStep.set(stepNumber, pendingLlm);
|
|
158
|
+
return pendingLlm;
|
|
159
|
+
}
|
|
160
|
+
getPendingToolEvent(args) {
|
|
161
|
+
const existing = this.toolEventsById.get(args.event.toolCall.toolCallId);
|
|
162
|
+
if (existing) {
|
|
163
|
+
return existing;
|
|
164
|
+
}
|
|
165
|
+
this.getPendingLlmEvent({
|
|
166
|
+
event: args.event,
|
|
167
|
+
startTimeMs: args.startTimeMs
|
|
168
|
+
});
|
|
169
|
+
const pendingTool = this.factory.createPendingToolEvent({
|
|
170
|
+
event: args.event,
|
|
171
|
+
startTimeMs: args.startTimeMs
|
|
172
|
+
});
|
|
173
|
+
this.toolEventsById.set(args.event.toolCall.toolCallId, pendingTool);
|
|
174
|
+
return pendingTool;
|
|
175
|
+
}
|
|
176
|
+
closePendingLlmEvent(args) {
|
|
177
|
+
const stepNumber = args.event.stepNumber;
|
|
178
|
+
const pendingLlm = this.llmEventsByStep.get(stepNumber) ?? this.getPendingLlmEvent({
|
|
179
|
+
event: args.event
|
|
180
|
+
});
|
|
181
|
+
this.completedEvents.push(
|
|
182
|
+
this.factory.createCompletedLlmEvent({
|
|
183
|
+
endTimeMs: args.endTimeMs,
|
|
184
|
+
event: args.event,
|
|
185
|
+
pendingLlm,
|
|
186
|
+
status: args.status
|
|
187
|
+
})
|
|
188
|
+
);
|
|
189
|
+
this.llmEventsByStep.delete(stepNumber);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export {
|
|
193
|
+
VercelRecorder
|
|
194
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { T_CarbonObject } from '../../core/schema/carbon-object.mjs';
|
|
2
|
+
import * as vercelSdk from 'ai';
|
|
3
|
+
import '../../internal/schema/events.mjs';
|
|
4
|
+
import 'zod';
|
|
5
|
+
|
|
6
|
+
type T_GenerateTextArgs = Parameters<typeof vercelSdk.generateText>[0];
|
|
7
|
+
type T_GenerateTextArgsWithCarbon = Parameters<typeof vercelSdk.generateText>[0] & {
|
|
8
|
+
carbon?: T_CarbonObject;
|
|
9
|
+
};
|
|
10
|
+
type T_GenerateTextResult = Promise<Awaited<ReturnType<typeof vercelSdk.generateText>>>;
|
|
11
|
+
type T_StreamTextArgs = Parameters<typeof vercelSdk.streamText>[0];
|
|
12
|
+
type T_StreamTextArgsWithCarbon = Parameters<typeof vercelSdk.streamText>[0] & {
|
|
13
|
+
carbon?: T_CarbonObject;
|
|
14
|
+
};
|
|
15
|
+
type T_StreamTextResult = ReturnType<typeof vercelSdk.streamText>;
|
|
16
|
+
type T_ToolLoopAgent = InstanceType<typeof vercelSdk.ToolLoopAgent>;
|
|
17
|
+
type T_ToolLoopAgentGenerateArgsWithCarbon = Omit<Parameters<T_ToolLoopAgent["generate"]>[0], "options"> & {
|
|
18
|
+
carbon?: T_CarbonObject;
|
|
19
|
+
options?: unknown;
|
|
20
|
+
};
|
|
21
|
+
type T_ToolLoopAgentStreamArgsWithCarbon = Omit<Parameters<T_ToolLoopAgent["stream"]>[0], "options"> & {
|
|
22
|
+
carbon?: T_CarbonObject;
|
|
23
|
+
options?: unknown;
|
|
24
|
+
};
|
|
25
|
+
type T_ToolLoopAgentSettingsWithCarbon = ConstructorParameters<typeof vercelSdk.ToolLoopAgent>[0] & {
|
|
26
|
+
carbon?: T_CarbonObject;
|
|
27
|
+
};
|
|
28
|
+
type T_WrappedToolLoopAgent = {
|
|
29
|
+
new (settings: T_ToolLoopAgentSettingsWithCarbon): Omit<T_ToolLoopAgent, "generate" | "stream"> & {
|
|
30
|
+
generate: (args: T_ToolLoopAgentGenerateArgsWithCarbon) => ReturnType<T_ToolLoopAgent["generate"]>;
|
|
31
|
+
stream: (args: T_ToolLoopAgentStreamArgsWithCarbon) => ReturnType<T_ToolLoopAgent["stream"]>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
type T_WrappedVercelSdk = Omit<typeof vercelSdk, "ToolLoopAgent" | "generateText" | "streamText"> & {
|
|
35
|
+
ToolLoopAgent: T_WrappedToolLoopAgent;
|
|
36
|
+
generateText: (args: T_GenerateTextArgsWithCarbon) => T_GenerateTextResult;
|
|
37
|
+
streamText: (args: T_StreamTextArgsWithCarbon) => T_StreamTextResult;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type { T_GenerateTextArgs, T_GenerateTextArgsWithCarbon, T_GenerateTextResult, T_StreamTextArgs, T_StreamTextArgsWithCarbon, T_StreamTextResult, T_ToolLoopAgent, T_ToolLoopAgentGenerateArgsWithCarbon, T_ToolLoopAgentSettingsWithCarbon, T_ToolLoopAgentStreamArgsWithCarbon, T_WrappedToolLoopAgent, T_WrappedVercelSdk };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import * as vercelSdk from "ai";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Carbon } from '../../../core/carbon.mjs';
|
|
2
|
+
import { T_CarbonObject } from '../../../core/schema/carbon-object.mjs';
|
|
3
|
+
import { VercelRecorder } from '../recorder.mjs';
|
|
4
|
+
import '../../../core/runtime.mjs';
|
|
5
|
+
import '../../../internal/schema/events.mjs';
|
|
6
|
+
import 'zod';
|
|
7
|
+
import '../../../core/transport/types.mjs';
|
|
8
|
+
import '../../../core/tools/wrap-tool.mjs';
|
|
9
|
+
import '../event-factory.mjs';
|
|
10
|
+
import 'ai';
|
|
11
|
+
|
|
12
|
+
type T_VercelTelemetryArgs = {
|
|
13
|
+
carbon?: T_CarbonObject;
|
|
14
|
+
experimental_telemetry?: {
|
|
15
|
+
integrations?: unknown;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
type T_RunWithCarbonTelemetry<T_Args extends T_VercelTelemetryArgs, T_Result> = {
|
|
19
|
+
args: T_Args;
|
|
20
|
+
carbon: Carbon;
|
|
21
|
+
mode: "generate" | "stream";
|
|
22
|
+
run: (args: Omit<T_Args, "carbon">) => T_Result;
|
|
23
|
+
sourceFunction: string;
|
|
24
|
+
};
|
|
25
|
+
declare const runWithCarbonTelemetry: <T_Args extends T_VercelTelemetryArgs, T_Result>(args: T_RunWithCarbonTelemetry<T_Args, T_Result>) => T_Result;
|
|
26
|
+
declare const addCarbonTelemetry: <T_Args extends T_VercelTelemetryArgs>(args: {
|
|
27
|
+
args: T_Args;
|
|
28
|
+
recorder: VercelRecorder;
|
|
29
|
+
}) => T_Args;
|
|
30
|
+
|
|
31
|
+
export { type T_VercelTelemetryArgs, addCarbonTelemetry, runWithCarbonTelemetry };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isPromiseLike } from "../../../utils/promise.mjs";
|
|
2
|
+
import { VercelRecorder } from "../recorder.mjs";
|
|
3
|
+
const runWithCarbonTelemetry = (args) => {
|
|
4
|
+
const { carbon: carbonObject, ...aiArgs } = args.args;
|
|
5
|
+
const recorder = new VercelRecorder({
|
|
6
|
+
carbon: args.carbon,
|
|
7
|
+
carbonObject,
|
|
8
|
+
mode: args.mode,
|
|
9
|
+
sourceFunction: args.sourceFunction
|
|
10
|
+
});
|
|
11
|
+
const aiArgsWithCarbonTelemetry = addCarbonTelemetry({
|
|
12
|
+
args: aiArgs,
|
|
13
|
+
recorder
|
|
14
|
+
});
|
|
15
|
+
try {
|
|
16
|
+
const result = args.run(aiArgsWithCarbonTelemetry);
|
|
17
|
+
if (isPromiseLike({ value: result })) {
|
|
18
|
+
return Promise.resolve(result).catch(async (error) => {
|
|
19
|
+
recorder.recordError({ error });
|
|
20
|
+
throw error;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
recorder.recordError({ error });
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const addCarbonTelemetry = (args) => {
|
|
30
|
+
const telemetry = args.args.experimental_telemetry;
|
|
31
|
+
const carbonIntegration = args.recorder.createIntegration();
|
|
32
|
+
const existingIntegrations = telemetry?.integrations ? Array.isArray(telemetry.integrations) ? telemetry.integrations : [telemetry.integrations] : [];
|
|
33
|
+
const integrations = [...existingIntegrations, carbonIntegration];
|
|
34
|
+
return {
|
|
35
|
+
...args.args,
|
|
36
|
+
experimental_telemetry: {
|
|
37
|
+
...telemetry,
|
|
38
|
+
isEnabled: true,
|
|
39
|
+
integrations
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export {
|
|
44
|
+
addCarbonTelemetry,
|
|
45
|
+
runWithCarbonTelemetry
|
|
46
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Carbon } from '../../core/carbon.mjs';
|
|
2
|
+
import { T_WrappedVercelSdk } from './types.mjs';
|
|
3
|
+
import * as vercelSdk from 'ai';
|
|
4
|
+
import '../../core/schema/carbon-object.mjs';
|
|
5
|
+
import '../../internal/schema/events.mjs';
|
|
6
|
+
import 'zod';
|
|
7
|
+
import '../../core/runtime.mjs';
|
|
8
|
+
import '../../core/transport/types.mjs';
|
|
9
|
+
import '../../core/tools/wrap-tool.mjs';
|
|
10
|
+
|
|
11
|
+
declare const wrapVercelSdk: (ai: typeof vercelSdk, carbon: Carbon) => T_WrappedVercelSdk;
|
|
12
|
+
|
|
13
|
+
export { wrapVercelSdk };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createWrappedToolLoopAgent } from "./fns/tool-loop-agent.mjs";
|
|
2
|
+
import { runWithCarbonTelemetry } from "./utils/telemetry.mjs";
|
|
3
|
+
import * as vercelSdk from "ai";
|
|
4
|
+
const wrapVercelSdk = (ai, carbon) => {
|
|
5
|
+
return {
|
|
6
|
+
...ai,
|
|
7
|
+
ToolLoopAgent: createWrappedToolLoopAgent({
|
|
8
|
+
ToolLoopAgent: ai.ToolLoopAgent,
|
|
9
|
+
carbon
|
|
10
|
+
}),
|
|
11
|
+
generateText: async (args) => runWithCarbonTelemetry({
|
|
12
|
+
args,
|
|
13
|
+
carbon,
|
|
14
|
+
mode: "generate",
|
|
15
|
+
run: (aiArgs) => ai.generateText(aiArgs),
|
|
16
|
+
sourceFunction: "generateText"
|
|
17
|
+
}),
|
|
18
|
+
streamText: (args) => runWithCarbonTelemetry({
|
|
19
|
+
args,
|
|
20
|
+
carbon,
|
|
21
|
+
mode: "stream",
|
|
22
|
+
run: (aiArgs) => ai.streamText(aiArgs),
|
|
23
|
+
sourceFunction: "streamText"
|
|
24
|
+
})
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export {
|
|
28
|
+
wrapVercelSdk
|
|
29
|
+
};
|
package/dist/ai.d.mts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { wrapAnthropicSdk } from './ai/anthropic/wrap.mjs';
|
|
2
|
+
export { wrapOpenAISdk } from './ai/openai/wrap.mjs';
|
|
3
|
+
export { wrapVercelSdk } from './ai/vercel/wrap.mjs';
|
|
4
|
+
import './core/carbon.mjs';
|
|
5
|
+
import './core/schema/carbon-object.mjs';
|
|
6
|
+
import './internal/schema/events.mjs';
|
|
7
|
+
import 'zod';
|
|
8
|
+
import './core/runtime.mjs';
|
|
9
|
+
import './core/transport/types.mjs';
|
|
10
|
+
import './core/tools/wrap-tool.mjs';
|
|
11
|
+
import './ai/anthropic/types.mjs';
|
|
12
|
+
import '@anthropic-ai/sdk';
|
|
13
|
+
import './ai/openai/types.mjs';
|
|
14
|
+
import 'openai';
|
|
15
|
+
import './ai/vercel/types.mjs';
|
|
16
|
+
import 'ai';
|
package/dist/ai.mjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { T_CarbonObject } from './schema/carbon-object.mjs';
|
|
2
|
+
import { T_CarbonRuntimeOptions } from './runtime.mjs';
|
|
3
|
+
import { T_WrapToolArgs } from './tools/wrap-tool.mjs';
|
|
4
|
+
import { T as T_LLMEvent, b as T_ToolEvent, a as T_Event } from '../internal/schema/events.mjs';
|
|
5
|
+
import './transport/types.mjs';
|
|
6
|
+
import 'zod';
|
|
7
|
+
|
|
8
|
+
type T_CarbonOptions = T_CarbonRuntimeOptions;
|
|
9
|
+
|
|
10
|
+
declare class Carbon {
|
|
11
|
+
private readonly runtime;
|
|
12
|
+
constructor(args?: T_CarbonOptions);
|
|
13
|
+
captureLlmCall(args: {
|
|
14
|
+
event: T_LLMEvent;
|
|
15
|
+
}): void;
|
|
16
|
+
captureToolCall(args: {
|
|
17
|
+
event: T_ToolEvent;
|
|
18
|
+
}): void;
|
|
19
|
+
captureEvents(args: {
|
|
20
|
+
events: T_Event[];
|
|
21
|
+
}): void;
|
|
22
|
+
createTraceId(): `${string}-${string}-${string}-${string}-${string}`;
|
|
23
|
+
wrapTool<T_Args extends unknown[], T_Result>(args: T_WrapToolArgs<T_Args, T_Result>): (...callArgs: [...T_Args, (T_CarbonObject | undefined)?]) => T_Result;
|
|
24
|
+
flushPendingTraces(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { Carbon, type T_CarbonOptions, T_WrapToolArgs };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CarbonRuntime } from "./runtime.mjs";
|
|
2
|
+
import { createWrappedTool } from "./tools/wrap-tool.mjs";
|
|
3
|
+
import { generateId } from "../utils/ids.mjs";
|
|
4
|
+
class Carbon {
|
|
5
|
+
runtime;
|
|
6
|
+
constructor(args = {}) {
|
|
7
|
+
this.runtime = new CarbonRuntime(args);
|
|
8
|
+
}
|
|
9
|
+
captureLlmCall(args) {
|
|
10
|
+
this.captureEvents({ events: [args.event] });
|
|
11
|
+
}
|
|
12
|
+
captureToolCall(args) {
|
|
13
|
+
this.captureEvents({ events: [args.event] });
|
|
14
|
+
}
|
|
15
|
+
captureEvents(args) {
|
|
16
|
+
this.runtime.recordEvents({ events: args.events });
|
|
17
|
+
}
|
|
18
|
+
createTraceId() {
|
|
19
|
+
return generateId();
|
|
20
|
+
}
|
|
21
|
+
wrapTool(args) {
|
|
22
|
+
return createWrappedTool({
|
|
23
|
+
...args,
|
|
24
|
+
captureToolCall: (captureArgs) => {
|
|
25
|
+
this.captureToolCall(captureArgs);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
flushPendingTraces() {
|
|
30
|
+
return this.runtime.shutdown();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
Carbon
|
|
35
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { a as T_Event } from '../../internal/schema/events.mjs';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
declare class EventBuffer {
|
|
5
|
+
private readonly pendingEvents;
|
|
6
|
+
add(args: {
|
|
7
|
+
events: T_Event[];
|
|
8
|
+
}): void;
|
|
9
|
+
drain(args?: {
|
|
10
|
+
count?: number;
|
|
11
|
+
}): T_Event[];
|
|
12
|
+
prepend(args: {
|
|
13
|
+
events: T_Event[];
|
|
14
|
+
}): void;
|
|
15
|
+
get length(): number;
|
|
16
|
+
get earliestStartTimeMs(): number | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { EventBuffer };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class EventBuffer {
|
|
2
|
+
pendingEvents = [];
|
|
3
|
+
add(args) {
|
|
4
|
+
this.pendingEvents.push(...args.events);
|
|
5
|
+
}
|
|
6
|
+
drain(args = {}) {
|
|
7
|
+
return this.pendingEvents.splice(0, args.count ?? this.pendingEvents.length);
|
|
8
|
+
}
|
|
9
|
+
prepend(args) {
|
|
10
|
+
this.pendingEvents.unshift(...args.events);
|
|
11
|
+
}
|
|
12
|
+
get length() {
|
|
13
|
+
return this.pendingEvents.length;
|
|
14
|
+
}
|
|
15
|
+
get earliestStartTimeMs() {
|
|
16
|
+
return this.pendingEvents.reduce((earliestStartTimeMs, event) => {
|
|
17
|
+
if (earliestStartTimeMs === null) {
|
|
18
|
+
return event.startTimeMs;
|
|
19
|
+
}
|
|
20
|
+
return Math.min(earliestStartTimeMs, event.startTimeMs);
|
|
21
|
+
}, null);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
EventBuffer
|
|
26
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { a as T_Event } from '../internal/schema/events.mjs';
|
|
2
|
+
import { T_EventTransport } from './transport/types.mjs';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
type T_CarbonRuntimeOptions = {
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
bufferBatchSize?: number;
|
|
9
|
+
bufferMaxTimeMs?: number;
|
|
10
|
+
transport?: T_EventTransport;
|
|
11
|
+
};
|
|
12
|
+
type T_RecordEvents = {
|
|
13
|
+
events: T_Event[];
|
|
14
|
+
};
|
|
15
|
+
declare class CarbonRuntime {
|
|
16
|
+
private readonly buffer;
|
|
17
|
+
private readonly bufferBatchSize;
|
|
18
|
+
private readonly bufferMaxTimeMs;
|
|
19
|
+
private readonly transport;
|
|
20
|
+
private flushPromise;
|
|
21
|
+
private flushTimer;
|
|
22
|
+
private isShuttingDown;
|
|
23
|
+
constructor(args: T_CarbonRuntimeOptions);
|
|
24
|
+
recordEvents(args: T_RecordEvents): void;
|
|
25
|
+
flush(): Promise<void>;
|
|
26
|
+
shutdown(): Promise<void>;
|
|
27
|
+
private flushNextBatch;
|
|
28
|
+
private sendDrainedEvents;
|
|
29
|
+
private flushOrSchedule;
|
|
30
|
+
private scheduleFlush;
|
|
31
|
+
private clearFlushTimer;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { CarbonRuntime, type T_CarbonRuntimeOptions };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { EventBuffer } from "./events/event-buffer.mjs";
|
|
2
|
+
import { CONSTANTS } from "../lib/constants.mjs";
|
|
3
|
+
import { HttpTransport } from "./transport/http-transport.mjs";
|
|
4
|
+
import { Z_Event } from "../internal/schema/index.mjs";
|
|
5
|
+
class CarbonRuntime {
|
|
6
|
+
buffer = new EventBuffer();
|
|
7
|
+
bufferBatchSize;
|
|
8
|
+
bufferMaxTimeMs;
|
|
9
|
+
transport;
|
|
10
|
+
flushPromise = null;
|
|
11
|
+
flushTimer = null;
|
|
12
|
+
isShuttingDown = false;
|
|
13
|
+
constructor(args) {
|
|
14
|
+
this.bufferBatchSize = args.bufferBatchSize ?? CONSTANTS.buffer.batchSize;
|
|
15
|
+
this.bufferMaxTimeMs = args.bufferMaxTimeMs ?? CONSTANTS.buffer.maxTimeMs;
|
|
16
|
+
if (!Number.isInteger(this.bufferBatchSize) || this.bufferBatchSize <= 0) {
|
|
17
|
+
throw new Error("batchSize must be a positive integer.");
|
|
18
|
+
}
|
|
19
|
+
if (!Number.isFinite(this.bufferMaxTimeMs) || this.bufferMaxTimeMs < 0) {
|
|
20
|
+
throw new Error("maxBufferTimeMs must be greater than or equal to 0.");
|
|
21
|
+
}
|
|
22
|
+
this.transport = args.transport ?? new HttpTransport({
|
|
23
|
+
apiKey: args.apiKey,
|
|
24
|
+
baseUrl: args.baseUrl
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
recordEvents(args) {
|
|
28
|
+
const events = args.events.map((event) => Z_Event.parse(event));
|
|
29
|
+
this.buffer.add({ events });
|
|
30
|
+
this.flushOrSchedule();
|
|
31
|
+
}
|
|
32
|
+
async flush() {
|
|
33
|
+
if (this.flushPromise) {
|
|
34
|
+
return this.flushPromise;
|
|
35
|
+
}
|
|
36
|
+
return this.flushNextBatch({ allowBackgroundScheduling: true });
|
|
37
|
+
}
|
|
38
|
+
async shutdown() {
|
|
39
|
+
this.isShuttingDown = true;
|
|
40
|
+
try {
|
|
41
|
+
while (this.buffer.length > 0 || this.flushPromise) {
|
|
42
|
+
if (this.flushPromise) {
|
|
43
|
+
await this.flushPromise;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
await this.flushNextBatch({ allowBackgroundScheduling: false });
|
|
47
|
+
}
|
|
48
|
+
} finally {
|
|
49
|
+
this.isShuttingDown = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
flushNextBatch(args) {
|
|
53
|
+
this.clearFlushTimer();
|
|
54
|
+
if (this.buffer.length === 0) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const events = this.buffer.drain({ count: this.bufferBatchSize });
|
|
58
|
+
this.flushPromise = this.sendDrainedEvents({
|
|
59
|
+
allowBackgroundScheduling: args.allowBackgroundScheduling,
|
|
60
|
+
events
|
|
61
|
+
});
|
|
62
|
+
return this.flushPromise;
|
|
63
|
+
}
|
|
64
|
+
async sendDrainedEvents(args) {
|
|
65
|
+
let didSend = false;
|
|
66
|
+
let shouldRetry = false;
|
|
67
|
+
try {
|
|
68
|
+
await this.transport.sendBatch({
|
|
69
|
+
batch: {
|
|
70
|
+
events: args.events
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
didSend = true;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
this.buffer.prepend({ events: args.events });
|
|
76
|
+
const retryable = typeof error === "object" && error !== null && "retryable" in error ? error.retryable : true;
|
|
77
|
+
shouldRetry = typeof retryable === "boolean" ? retryable : true;
|
|
78
|
+
throw error;
|
|
79
|
+
} finally {
|
|
80
|
+
this.flushPromise = null;
|
|
81
|
+
const canScheduleBackgroundFlush = args.allowBackgroundScheduling && !this.isShuttingDown;
|
|
82
|
+
if (shouldRetry && canScheduleBackgroundFlush) {
|
|
83
|
+
this.scheduleFlush({ delayMs: this.bufferMaxTimeMs });
|
|
84
|
+
} else if (didSend && canScheduleBackgroundFlush) {
|
|
85
|
+
this.flushOrSchedule();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
flushOrSchedule() {
|
|
90
|
+
if (this.buffer.length >= this.bufferBatchSize) {
|
|
91
|
+
void this.flush().catch(() => void 0);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
this.scheduleFlush({
|
|
95
|
+
delayMs: Math.max((this.buffer.earliestStartTimeMs ?? Date.now()) + this.bufferMaxTimeMs - Date.now(), 0)
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
scheduleFlush(args) {
|
|
99
|
+
this.clearFlushTimer();
|
|
100
|
+
if (this.buffer.length === 0) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
this.flushTimer = setTimeout(() => {
|
|
104
|
+
this.flushTimer = null;
|
|
105
|
+
void this.flush().catch(() => void 0);
|
|
106
|
+
}, args.delayMs);
|
|
107
|
+
this.flushTimer.unref?.();
|
|
108
|
+
}
|
|
109
|
+
clearFlushTimer() {
|
|
110
|
+
if (!this.flushTimer) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
clearTimeout(this.flushTimer);
|
|
114
|
+
this.flushTimer = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
CarbonRuntime
|
|
119
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { e as T_EventContext, d as T_EventAdditionalProperties } from '../../internal/schema/events.mjs';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
type T_CarbonContext = Partial<Record<keyof T_EventContext, string>>;
|
|
5
|
+
type T_CarbonObject = {
|
|
6
|
+
traceId?: string;
|
|
7
|
+
context?: T_CarbonContext;
|
|
8
|
+
additionalProperties?: T_EventAdditionalProperties;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type { T_CarbonContext, T_CarbonObject };
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { T_CarbonObject } from '../schema/carbon-object.mjs';
|
|
2
|
+
import { b as T_ToolEvent } from '../../internal/schema/events.mjs';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
type T_WrapToolArgs<T_Args extends unknown[], T_Result> = {
|
|
6
|
+
name: string;
|
|
7
|
+
run: (...args: T_Args) => T_Result;
|
|
8
|
+
};
|
|
9
|
+
type T_CreateWrappedToolArgs<T_Args extends unknown[], T_Result> = T_WrapToolArgs<T_Args, T_Result> & {
|
|
10
|
+
captureToolCall: (args: {
|
|
11
|
+
event: T_ToolEvent;
|
|
12
|
+
}) => void;
|
|
13
|
+
};
|
|
14
|
+
declare function createWrappedTool<T_Args extends unknown[], T_Result>(args: T_CreateWrappedToolArgs<T_Args, T_Result>): (...callArgs: [...T_Args, T_CarbonObject?]) => T_Result;
|
|
15
|
+
|
|
16
|
+
export { type T_WrapToolArgs, createWrappedTool };
|