@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.
Files changed (83) hide show
  1. package/README.md +26 -0
  2. package/dist/ai/anthropic/event-factory.d.mts +22 -0
  3. package/dist/ai/anthropic/event-factory.mjs +97 -0
  4. package/dist/ai/anthropic/fns/message-create.d.mts +15 -0
  5. package/dist/ai/anthropic/fns/message-create.mjs +248 -0
  6. package/dist/ai/anthropic/fns/message-stream.d.mts +15 -0
  7. package/dist/ai/anthropic/fns/message-stream.mjs +59 -0
  8. package/dist/ai/anthropic/types.d.mts +5 -0
  9. package/dist/ai/anthropic/types.mjs +0 -0
  10. package/dist/ai/anthropic/wrap.d.mts +13 -0
  11. package/dist/ai/anthropic/wrap.mjs +17 -0
  12. package/dist/ai/openai/event-factory.d.mts +34 -0
  13. package/dist/ai/openai/event-factory.mjs +189 -0
  14. package/dist/ai/openai/fns/chat-completions-create.d.mts +15 -0
  15. package/dist/ai/openai/fns/chat-completions-create.mjs +219 -0
  16. package/dist/ai/openai/fns/chat-completions-run-tools.d.mts +15 -0
  17. package/dist/ai/openai/fns/chat-completions-run-tools.mjs +112 -0
  18. package/dist/ai/openai/fns/chat-completions-stream.d.mts +15 -0
  19. package/dist/ai/openai/fns/chat-completions-stream.mjs +69 -0
  20. package/dist/ai/openai/fns/response-create.d.mts +15 -0
  21. package/dist/ai/openai/fns/response-create.mjs +137 -0
  22. package/dist/ai/openai/fns/response-stream.d.mts +15 -0
  23. package/dist/ai/openai/fns/response-stream.mjs +59 -0
  24. package/dist/ai/openai/types.d.mts +5 -0
  25. package/dist/ai/openai/types.mjs +0 -0
  26. package/dist/ai/openai/utils/capture-options.d.mts +6 -0
  27. package/dist/ai/openai/utils/capture-options.mjs +4 -0
  28. package/dist/ai/openai/wrap.d.mts +13 -0
  29. package/dist/ai/openai/wrap.mjs +32 -0
  30. package/dist/ai/vercel/event-factory.d.mts +52 -0
  31. package/dist/ai/vercel/event-factory.mjs +140 -0
  32. package/dist/ai/vercel/fns/tool-loop-agent.d.mts +17 -0
  33. package/dist/ai/vercel/fns/tool-loop-agent.mjs +117 -0
  34. package/dist/ai/vercel/recorder.d.mts +37 -0
  35. package/dist/ai/vercel/recorder.mjs +194 -0
  36. package/dist/ai/vercel/types.d.mts +40 -0
  37. package/dist/ai/vercel/types.mjs +1 -0
  38. package/dist/ai/vercel/utils/telemetry.d.mts +31 -0
  39. package/dist/ai/vercel/utils/telemetry.mjs +46 -0
  40. package/dist/ai/vercel/wrap.d.mts +13 -0
  41. package/dist/ai/vercel/wrap.mjs +29 -0
  42. package/dist/ai.d.mts +16 -0
  43. package/dist/ai.mjs +8 -0
  44. package/dist/core/carbon.d.mts +27 -0
  45. package/dist/core/carbon.mjs +35 -0
  46. package/dist/core/events/event-buffer.d.mts +19 -0
  47. package/dist/core/events/event-buffer.mjs +26 -0
  48. package/dist/core/runtime.d.mts +34 -0
  49. package/dist/core/runtime.mjs +119 -0
  50. package/dist/core/schema/carbon-object.d.mts +11 -0
  51. package/dist/core/schema/carbon-object.mjs +0 -0
  52. package/dist/core/tools/wrap-tool.d.mts +16 -0
  53. package/dist/core/tools/wrap-tool.mjs +120 -0
  54. package/dist/core/transport/file-transport.d.mts +16 -0
  55. package/dist/core/transport/file-transport.mjs +17 -0
  56. package/dist/core/transport/http-transport.d.mts +31 -0
  57. package/dist/core/transport/http-transport.mjs +79 -0
  58. package/dist/core/transport/memory-transport.d.mts +12 -0
  59. package/dist/core/transport/memory-transport.mjs +11 -0
  60. package/dist/core/transport/types.d.mts +13 -0
  61. package/dist/core/transport/types.mjs +0 -0
  62. package/dist/core/utils/build-events.d.mts +33 -0
  63. package/dist/core/utils/build-events.mjs +132 -0
  64. package/dist/core/utils/instrumentation.d.mts +12 -0
  65. package/dist/core/utils/instrumentation.mjs +12 -0
  66. package/dist/index.d.mts +10 -0
  67. package/dist/index.mjs +11 -0
  68. package/dist/internal/schema/events.d.mts +315 -0
  69. package/dist/internal/schema/events.mjs +111 -0
  70. package/dist/internal/schema/index.mjs +1 -0
  71. package/dist/lib/constants.d.mts +16 -0
  72. package/dist/lib/constants.mjs +16 -0
  73. package/dist/utils/ids.d.mts +3 -0
  74. package/dist/utils/ids.mjs +4 -0
  75. package/dist/utils/promise.d.mts +8 -0
  76. package/dist/utils/promise.mjs +6 -0
  77. package/dist/utils/retry.d.mts +16 -0
  78. package/dist/utils/retry.mjs +47 -0
  79. package/dist/utils/stringify.d.mts +6 -0
  80. package/dist/utils/stringify.mjs +16 -0
  81. package/dist/utils/timeout.d.mts +9 -0
  82. package/dist/utils/timeout.mjs +27 -0
  83. 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,8 @@
1
+ import { wrapAnthropicSdk } from "./ai/anthropic/wrap.mjs";
2
+ import { wrapOpenAISdk } from "./ai/openai/wrap.mjs";
3
+ import { wrapVercelSdk } from "./ai/vercel/wrap.mjs";
4
+ export {
5
+ wrapAnthropicSdk,
6
+ wrapOpenAISdk,
7
+ wrapVercelSdk
8
+ };
@@ -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 };