@fluxgate/anthropic 0.0.1 → 0.0.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/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { AiEventMetadata, FluxGate } from "@fluxgate/sdk";
1
+ import { FluxGate } from "@fluxgate/sdk";
2
2
  import type Anthropic from "@anthropic-ai/sdk";
3
3
  import { TrackedAnthropic } from "./types/types.js";
4
+ import { FluxGateContext } from "./types/types.js";
4
5
  export type AnthropicTracker = {
5
- withContext: (ctx: AiEventMetadata) => TrackedAnthropic;
6
+ withContext: (ctx: FluxGateContext) => TrackedAnthropic;
6
7
  get client(): TrackedAnthropic;
7
8
  };
8
9
  export declare function createAnthropicCostTracker(client: Anthropic, instance: FluxGate): AnthropicTracker;
9
- export type { AiEventMetadata, TrackedUser, FluxGateCostTrackingResponse, WithTracking, AiEventStatus, } from "@fluxgate/sdk";
10
+ export type { AiEventMetadata, TrackedUser, FluxGateCostTrackingResponse, WithTracking, AiEventStatus, Performance, CostOverride, } from "@fluxgate/sdk";
10
11
  export * from "./types/types.js";
11
12
  export { TrackedStream } from "./wrappers/TrackedStream.js";
@@ -56,7 +56,7 @@ describe("createAnthropicCostTracker", () => {
56
56
  id: "user-123",
57
57
  name: "Test User",
58
58
  email: "test@example.com",
59
- monthlyRevenue: 99.99,
59
+ monthlyRevenue: "99.99",
60
60
  },
61
61
  conversationId: "conv-789",
62
62
  });
@@ -67,8 +67,7 @@ describe("createAnthropicCostTracker", () => {
67
67
  const contextClient = tracker.withContext({
68
68
  feature: "chat",
69
69
  step: "generation",
70
- customField: "custom value",
71
- anotherField: 123,
70
+ region: "us-east-1",
72
71
  });
73
72
  expect(contextClient).toBeDefined();
74
73
  });
@@ -1,13 +1,44 @@
1
1
  import type Anthropic from "@anthropic-ai/sdk";
2
2
  import type { Message, MessageCreateParams, MessageCreateParamsNonStreaming, MessageCreateParamsStreaming, RawMessageStreamEvent } from "@anthropic-ai/sdk/resources/messages";
3
- import type { WithTracking } from "@fluxgate/sdk";
3
+ import type { Completion, CompletionCreateParams, CompletionCreateParamsNonStreaming, CompletionCreateParamsStreaming } from "@anthropic-ai/sdk/resources/completions";
4
+ import type { BetaMessage, BetaRawMessageStreamEvent, MessageCreateParams as BetaMessageCreateParams, MessageCreateParamsNonStreaming as BetaMessageCreateParamsNonStreaming, MessageCreateParamsStreaming as BetaMessageCreateParamsStreaming } from "@anthropic-ai/sdk/resources/beta/messages/messages";
5
+ import type { WithTracking, TrackedUser, AiEventMetadata, CostOverride } from "@fluxgate/sdk";
4
6
  import type { TrackedStream } from "../wrappers/TrackedStream.js";
5
7
  type MessageCreateOptions = Parameters<Anthropic["messages"]["create"]>[1];
6
- export type TrackedAnthropic = Omit<Anthropic, "messages"> & {
8
+ type CompletionCreateOptions = Parameters<Anthropic["completions"]["create"]>[1];
9
+ type BetaMessageCreateOptions = Parameters<Anthropic["beta"]["messages"]["create"]>[1];
10
+ export type TrackedAnthropic = Omit<Anthropic, "messages" | "completions" | "beta"> & {
7
11
  messages: Omit<Anthropic["messages"], "create"> & {
8
12
  create(body: MessageCreateParamsNonStreaming, options?: MessageCreateOptions): Promise<WithTracking<Message>>;
9
13
  create(body: MessageCreateParamsStreaming, options?: MessageCreateOptions): Promise<TrackedStream<RawMessageStreamEvent>>;
10
14
  create(body: MessageCreateParams, options?: MessageCreateOptions): Promise<WithTracking<Message> | TrackedStream<RawMessageStreamEvent>>;
11
15
  };
16
+ completions: Omit<Anthropic["completions"], "create"> & {
17
+ create(body: CompletionCreateParamsNonStreaming, options?: CompletionCreateOptions): Promise<WithTracking<Completion>>;
18
+ create(body: CompletionCreateParamsStreaming, options?: CompletionCreateOptions): Promise<TrackedStream<Completion>>;
19
+ create(body: CompletionCreateParams, options?: CompletionCreateOptions): Promise<WithTracking<Completion> | TrackedStream<Completion>>;
20
+ };
21
+ beta: Omit<Anthropic["beta"], "messages"> & {
22
+ messages: Omit<Anthropic["beta"]["messages"], "create"> & {
23
+ create(params: BetaMessageCreateParamsNonStreaming, options?: BetaMessageCreateOptions): Promise<WithTracking<BetaMessage>>;
24
+ create(params: BetaMessageCreateParamsStreaming, options?: BetaMessageCreateOptions): Promise<TrackedStream<BetaRawMessageStreamEvent>>;
25
+ create(params: BetaMessageCreateParams, options?: BetaMessageCreateOptions): Promise<WithTracking<BetaMessage> | TrackedStream<BetaRawMessageStreamEvent>>;
26
+ };
27
+ };
28
+ };
29
+ export type FluxGateContext = {
30
+ user?: string | TrackedUser;
31
+ feature?: string;
32
+ step?: string;
33
+ sessionId?: string;
34
+ conversationId?: string;
35
+ timestamp?: number;
36
+ serviceTier?: AiEventMetadata["serviceTier"];
37
+ region?: string;
38
+ openrouterCost?: number;
39
+ cacheTtl?: string;
40
+ costOverride?: CostOverride;
41
+ /** Arbitrary key-value pairs forwarded to the metadata object (e.g. { language: "typescript", documentType: "article" }) */
42
+ metadata?: Record<string, unknown>;
12
43
  };
13
44
  export {};
@@ -1,9 +1,9 @@
1
- import type { ExtractedUsage } from "@fluxgate/sdk";
1
+ import type { AiEventUsage } from "@fluxgate/sdk";
2
2
  type AnthropicUsage = {
3
3
  input_tokens: number | null;
4
4
  output_tokens: number | null;
5
5
  cache_creation_input_tokens?: number | null;
6
6
  cache_read_input_tokens?: number | null;
7
7
  };
8
- export declare function extractAnthropicUsage(usage: AnthropicUsage | null | undefined): ExtractedUsage;
8
+ export declare function extractAnthropicUsage(usage: AnthropicUsage | null | undefined): AiEventUsage;
9
9
  export {};
@@ -1,18 +1,14 @@
1
1
  export function extractAnthropicUsage(usage) {
2
2
  if (!usage) {
3
3
  return {
4
- inputTokens: 0,
5
- outputTokens: 0,
6
- cachedTokens: 0,
7
- totalTokens: 0,
4
+ promptTokens: 0,
5
+ completionTokens: 0,
8
6
  };
9
7
  }
10
- const cachedTokens = (usage.cache_creation_input_tokens ?? 0) +
11
- (usage.cache_read_input_tokens ?? 0);
12
8
  return {
13
- inputTokens: usage.input_tokens ?? 0,
14
- outputTokens: usage.output_tokens ?? 0,
15
- cachedTokens,
16
- totalTokens: (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
9
+ promptTokens: usage.input_tokens ?? 0,
10
+ completionTokens: usage.output_tokens ?? 0,
11
+ cacheWriteTokens: usage.cache_creation_input_tokens || undefined,
12
+ cacheReadTokens: usage.cache_read_input_tokens || undefined,
17
13
  };
18
14
  }
@@ -11,10 +11,10 @@ describe("extractAnthropicUsage", () => {
11
11
  };
12
12
  const result = extractAnthropicUsage(usage);
13
13
  expect(result).toEqual({
14
- inputTokens: 100,
15
- outputTokens: 50,
16
- cachedTokens: 30,
17
- totalTokens: 150,
14
+ promptTokens: 100,
15
+ completionTokens: 50,
16
+ cacheWriteTokens: 20,
17
+ cacheReadTokens: 10,
18
18
  });
19
19
  });
20
20
  it("should handle missing cached token fields", () => {
@@ -24,10 +24,8 @@ describe("extractAnthropicUsage", () => {
24
24
  };
25
25
  const result = extractAnthropicUsage(usage);
26
26
  expect(result).toEqual({
27
- inputTokens: 100,
28
- outputTokens: 50,
29
- cachedTokens: 0,
30
- totalTokens: 150,
27
+ promptTokens: 100,
28
+ completionTokens: 50,
31
29
  });
32
30
  });
33
31
  it("should handle null cached token fields", () => {
@@ -39,10 +37,8 @@ describe("extractAnthropicUsage", () => {
39
37
  };
40
38
  const result = extractAnthropicUsage(usage);
41
39
  expect(result).toEqual({
42
- inputTokens: 120,
43
- outputTokens: 30,
44
- cachedTokens: 0,
45
- totalTokens: 150,
40
+ promptTokens: 120,
41
+ completionTokens: 30,
46
42
  });
47
43
  });
48
44
  });
@@ -50,19 +46,15 @@ describe("extractAnthropicUsage", () => {
50
46
  it("should return zero values for null usage", () => {
51
47
  const result = extractAnthropicUsage(null);
52
48
  expect(result).toEqual({
53
- inputTokens: 0,
54
- outputTokens: 0,
55
- cachedTokens: 0,
56
- totalTokens: 0,
49
+ promptTokens: 0,
50
+ completionTokens: 0,
57
51
  });
58
52
  });
59
53
  it("should return zero values for undefined usage", () => {
60
54
  const result = extractAnthropicUsage(undefined);
61
55
  expect(result).toEqual({
62
- inputTokens: 0,
63
- outputTokens: 0,
64
- cachedTokens: 0,
65
- totalTokens: 0,
56
+ promptTokens: 0,
57
+ completionTokens: 0,
66
58
  });
67
59
  });
68
60
  it("should handle partial usage object", () => {
@@ -72,10 +64,8 @@ describe("extractAnthropicUsage", () => {
72
64
  };
73
65
  const result = extractAnthropicUsage(usage);
74
66
  expect(result).toEqual({
75
- inputTokens: 80,
76
- outputTokens: 0,
77
- cachedTokens: 0,
78
- totalTokens: 80,
67
+ promptTokens: 80,
68
+ completionTokens: 0,
79
69
  });
80
70
  });
81
71
  });
@@ -89,10 +79,8 @@ describe("extractAnthropicUsage", () => {
89
79
  };
90
80
  const result = extractAnthropicUsage(usage);
91
81
  expect(result).toEqual({
92
- inputTokens: 0,
93
- outputTokens: 0,
94
- cachedTokens: 0,
95
- totalTokens: 0,
82
+ promptTokens: 0,
83
+ completionTokens: 0,
96
84
  });
97
85
  });
98
86
  it("should handle very large token counts", () => {
@@ -104,10 +92,10 @@ describe("extractAnthropicUsage", () => {
104
92
  };
105
93
  const result = extractAnthropicUsage(usage);
106
94
  expect(result).toEqual({
107
- inputTokens: 1000000,
108
- outputTokens: 500000,
109
- cachedTokens: 300000,
110
- totalTokens: 1500000,
95
+ promptTokens: 1000000,
96
+ completionTokens: 500000,
97
+ cacheWriteTokens: 200000,
98
+ cacheReadTokens: 100000,
111
99
  });
112
100
  });
113
101
  });
@@ -1,12 +1,13 @@
1
- import { AiEventMetadata, AiEventStatus, ExtractedUsage, FluxGate, FluxGateCostTrackingResponse } from "@fluxgate/sdk";
1
+ import { AiEventStatus, FluxGate, FluxGateCostTrackingResponse, AiEventUsage } from "@fluxgate/sdk";
2
+ import { FluxGateContext } from "../types/types.js";
2
3
  export declare function stopReasonToStatus(stopReason: string | null | undefined): AiEventStatus;
3
4
  export declare function recordUsage(params: {
4
5
  instance: FluxGate;
5
6
  model: string;
6
7
  latencyMs: number;
7
8
  streaming: boolean;
8
- context: AiEventMetadata | undefined;
9
- usage: ExtractedUsage;
9
+ context: FluxGateContext | undefined;
10
+ usage: AiEventUsage;
10
11
  status: AiEventStatus;
11
12
  errorMessage?: string;
12
13
  }): Promise<FluxGateCostTrackingResponse>;
@@ -1,13 +1,7 @@
1
- function normalizeMetadata(context) {
2
- const { user, ...rest } = context ?? {};
3
- const normalized = { ...rest };
4
- if (typeof user === "string") {
5
- normalized.user = user;
6
- }
7
- else if (user != null) {
8
- normalized.user = user;
9
- }
10
- return normalized;
1
+ function toPerformanceStatus(status) {
2
+ return status === "ERROR" || status === "MALFORMED_REQUEST"
3
+ ? "ERROR"
4
+ : "SUCCESS";
11
5
  }
12
6
  export function stopReasonToStatus(stopReason) {
13
7
  if (!stopReason ||
@@ -28,29 +22,46 @@ export function stopReasonToStatus(stopReason) {
28
22
  }
29
23
  export async function recordUsage(params) {
30
24
  const { context, latencyMs, model, streaming, instance, usage, status, errorMessage, } = params;
25
+ const resolvedServiceTier = context?.serviceTier;
26
+ const hasMetadata = resolvedServiceTier != null ||
27
+ context?.region != null ||
28
+ context?.openrouterCost != null ||
29
+ context?.cacheTtl != null ||
30
+ (context?.metadata != null && Object.keys(context.metadata).length > 0);
31
+ const metadata = hasMetadata
32
+ ? {
33
+ serviceTier: resolvedServiceTier,
34
+ region: context?.region,
35
+ openrouterCost: context?.openrouterCost,
36
+ cacheTtl: context?.cacheTtl,
37
+ ...context?.metadata,
38
+ }
39
+ : undefined;
31
40
  const trackingData = await instance.recordEvent({
32
- metadata: normalizeMetadata(context),
33
- status: {
34
- status,
35
- errorMessage,
36
- },
37
- usage: {
38
- inputTokens: usage.inputTokens,
39
- outputTokens: usage.outputTokens,
40
- cachedTokens: usage.cachedTokens,
41
- model,
41
+ provider: "anthropic",
42
+ model,
43
+ user: context?.user,
44
+ feature: context?.feature,
45
+ step: context?.step,
46
+ sessionId: context?.sessionId,
47
+ conversationId: context?.conversationId,
48
+ timestamp: context?.timestamp,
49
+ performance: {
50
+ latency: latencyMs,
51
+ status: toPerformanceStatus(status),
42
52
  isStreamed: streaming,
43
- latencyInMs: latencyMs,
44
- provider: "anthropic",
45
- streamingDurationInMs: streaming ? latencyMs : undefined,
53
+ errorMessage: errorMessage ?? null,
46
54
  },
55
+ usage,
56
+ ...(metadata && { metadata }),
57
+ ...(context?.costOverride && { costOverride: context.costOverride }),
47
58
  });
48
59
  return {
49
60
  status,
50
61
  errorMessage,
51
- cost: trackingData?.cost ?? null,
52
- trackingId: trackingData?.id ?? null,
53
- createdAt: trackingData?.createdAt ?? null,
62
+ cost: trackingData?.totalCost ?? null,
63
+ trackingId: trackingData?.recordId ?? null,
64
+ createdAt: null,
54
65
  };
55
66
  }
56
67
  export function extractResponseStatus(stopReason) {
@@ -0,0 +1,8 @@
1
+ import { FluxGate, WithTracking } from "@fluxgate/sdk";
2
+ import { FluxGateContext } from "../types/types.js";
3
+ import type Anthropic from "@anthropic-ai/sdk";
4
+ import type { BetaMessage, BetaRawMessageStreamEvent } from "@anthropic-ai/sdk/resources/beta/messages/messages";
5
+ import { TrackedStream } from "./TrackedStream.js";
6
+ type OrigCreate = Anthropic["beta"]["messages"]["create"];
7
+ export declare function createBetaMessagesWrapper(original: OrigCreate, instance: FluxGate, context: FluxGateContext | undefined): (params: Parameters<OrigCreate>[0], options?: Parameters<OrigCreate>[1]) => Promise<WithTracking<BetaMessage> | TrackedStream<BetaRawMessageStreamEvent>>;
8
+ export {};
@@ -0,0 +1,70 @@
1
+ import { extractAnthropicUsage } from "../utils/extractUsage.js";
2
+ import { isAsyncIterable } from "../utils/utils.js";
3
+ import { TrackedStream } from "./TrackedStream.js";
4
+ import { extractResponseStatus, recordUsage } from "../utils/recordUsage.js";
5
+ export function createBetaMessagesWrapper(original, instance, context) {
6
+ return async function wrappedBetaMessagesCreate(params, options) {
7
+ const start = performance.now();
8
+ let res;
9
+ try {
10
+ res = await original(params, options);
11
+ }
12
+ catch (err) {
13
+ await recordUsage({
14
+ instance,
15
+ model: params.model.toString(),
16
+ latencyMs: performance.now() - start,
17
+ streaming: !!params.stream,
18
+ context,
19
+ usage: extractAnthropicUsage(undefined),
20
+ status: "ERROR",
21
+ errorMessage: err.message,
22
+ });
23
+ throw err;
24
+ }
25
+ if (params.stream && isAsyncIterable(res)) {
26
+ let latestUsage;
27
+ let latestStopReason;
28
+ const trackingSource = (async function* () {
29
+ for await (const event of res) {
30
+ if (event.type === "message_delta") {
31
+ latestUsage = event.usage;
32
+ latestStopReason = event.delta.stop_reason;
33
+ }
34
+ yield event;
35
+ }
36
+ })();
37
+ return new TrackedStream(trackingSource, (_last, streamError) => {
38
+ const { status, errorMessage } = streamError
39
+ ? {
40
+ status: "ERROR",
41
+ errorMessage: streamError.message,
42
+ }
43
+ : extractResponseStatus(latestStopReason);
44
+ return recordUsage({
45
+ instance,
46
+ model: params.model.toString(),
47
+ latencyMs: performance.now() - start,
48
+ streaming: true,
49
+ context,
50
+ usage: extractAnthropicUsage(latestUsage),
51
+ status,
52
+ errorMessage,
53
+ });
54
+ });
55
+ }
56
+ const message = res;
57
+ const { status, errorMessage } = extractResponseStatus(message.stop_reason);
58
+ const fluxGateCostTrackingResponse = await recordUsage({
59
+ instance,
60
+ model: params.model.toString(),
61
+ latencyMs: performance.now() - start,
62
+ streaming: false,
63
+ context,
64
+ usage: extractAnthropicUsage(message.usage),
65
+ status,
66
+ errorMessage,
67
+ });
68
+ return Object.assign(message, { fluxGateCostTrackingResponse });
69
+ };
70
+ }
@@ -0,0 +1,8 @@
1
+ import { FluxGate, WithTracking } from "@fluxgate/sdk";
2
+ import { FluxGateContext } from "../types/types.js";
3
+ import type Anthropic from "@anthropic-ai/sdk";
4
+ import type { Completion } from "@anthropic-ai/sdk/resources/completions";
5
+ import { TrackedStream } from "./TrackedStream.js";
6
+ type OrigCreate = Anthropic["completions"]["create"];
7
+ export declare function createCompletionsWrapper(original: OrigCreate, instance: FluxGate, context: FluxGateContext | undefined): (params: Parameters<OrigCreate>[0], options?: Parameters<OrigCreate>[1]) => Promise<WithTracking<Completion> | TrackedStream<Completion>>;
8
+ export {};
@@ -0,0 +1,70 @@
1
+ import { extractAnthropicUsage } from "../utils/extractUsage.js";
2
+ import { isAsyncIterable } from "../utils/utils.js";
3
+ import { TrackedStream } from "./TrackedStream.js";
4
+ import { extractResponseStatus, recordUsage } from "../utils/recordUsage.js";
5
+ export function createCompletionsWrapper(original, instance, context) {
6
+ return async function wrappedCompletionsCreate(params, options) {
7
+ const start = performance.now();
8
+ let res;
9
+ try {
10
+ res = await original(params, options);
11
+ }
12
+ catch (err) {
13
+ await recordUsage({
14
+ instance,
15
+ model: params.model.toString(),
16
+ latencyMs: performance.now() - start,
17
+ streaming: !!params.stream,
18
+ context,
19
+ usage: extractAnthropicUsage(undefined),
20
+ status: "ERROR",
21
+ errorMessage: err.message,
22
+ });
23
+ throw err;
24
+ }
25
+ if (params.stream && isAsyncIterable(res)) {
26
+ let latestStopReason;
27
+ const trackingSource = (async function* () {
28
+ for await (const chunk of res) {
29
+ if (chunk.stop_reason) {
30
+ latestStopReason = chunk.stop_reason;
31
+ }
32
+ yield chunk;
33
+ }
34
+ })();
35
+ return new TrackedStream(trackingSource, (_last, streamError) => {
36
+ const { status, errorMessage } = streamError
37
+ ? {
38
+ status: "ERROR",
39
+ errorMessage: streamError.message,
40
+ }
41
+ : extractResponseStatus(latestStopReason);
42
+ // The legacy completions API does not return token usage
43
+ return recordUsage({
44
+ instance,
45
+ model: params.model.toString(),
46
+ latencyMs: performance.now() - start,
47
+ streaming: true,
48
+ context,
49
+ usage: extractAnthropicUsage(undefined),
50
+ status,
51
+ errorMessage,
52
+ });
53
+ });
54
+ }
55
+ const completion = res;
56
+ const { status, errorMessage } = extractResponseStatus(completion.stop_reason);
57
+ // The legacy completions API does not return token usage
58
+ const fluxGateCostTrackingResponse = await recordUsage({
59
+ instance,
60
+ model: params.model.toString(),
61
+ latencyMs: performance.now() - start,
62
+ streaming: false,
63
+ context,
64
+ usage: extractAnthropicUsage(undefined),
65
+ status,
66
+ errorMessage,
67
+ });
68
+ return Object.assign(completion, { fluxGateCostTrackingResponse });
69
+ };
70
+ }
@@ -1,9 +1,10 @@
1
- import { AiEventMetadata, FluxGate, WithTracking } from "@fluxgate/sdk";
1
+ import { FluxGate, WithTracking } from "@fluxgate/sdk";
2
+ import { FluxGateContext } from "../types/types.js";
2
3
  import type Anthropic from "@anthropic-ai/sdk";
3
4
  import type { Message, RawMessageStreamEvent } from "@anthropic-ai/sdk/resources/messages";
4
5
  import { TrackedStream } from "./TrackedStream.js";
5
6
  import { TrackedAnthropic } from "../types/types.js";
6
7
  type OrigCreate = Anthropic["messages"]["create"];
7
- export declare function withAnthropicTracking(client: Anthropic, instance: FluxGate, context?: AiEventMetadata): TrackedAnthropic;
8
- export declare function createMessagesWrapper(original: OrigCreate, instance: FluxGate, context: AiEventMetadata | undefined): (params: Parameters<OrigCreate>[0], options?: Parameters<OrigCreate>[1]) => Promise<WithTracking<Message> | TrackedStream<RawMessageStreamEvent>>;
8
+ export declare function withAnthropicTracking(client: Anthropic, instance: FluxGate, context?: FluxGateContext): TrackedAnthropic;
9
+ export declare function createMessagesWrapper(original: OrigCreate, instance: FluxGate, context: FluxGateContext | undefined): (params: Parameters<OrigCreate>[0], options?: Parameters<OrigCreate>[1]) => Promise<WithTracking<Message> | TrackedStream<RawMessageStreamEvent>>;
9
10
  export {};
@@ -2,10 +2,17 @@ import { extractAnthropicUsage } from "../utils/extractUsage.js";
2
2
  import { isAsyncIterable } from "../utils/utils.js";
3
3
  import { TrackedStream } from "./TrackedStream.js";
4
4
  import { extractResponseStatus, recordUsage } from "../utils/recordUsage.js";
5
+ import { createCompletionsWrapper } from "./completions.js";
6
+ import { createBetaMessagesWrapper } from "./betaMessages.js";
5
7
  export function withAnthropicTracking(client, instance, context) {
6
8
  const wrappedClient = Object.create(Object.getPrototypeOf(client), Object.getOwnPropertyDescriptors(client));
7
9
  wrappedClient.messages = Object.create(Object.getPrototypeOf(client.messages), Object.getOwnPropertyDescriptors(client.messages));
8
10
  wrappedClient.messages.create = createMessagesWrapper(client.messages.create.bind(client.messages), instance, context);
11
+ wrappedClient.completions = Object.create(Object.getPrototypeOf(client.completions), Object.getOwnPropertyDescriptors(client.completions));
12
+ wrappedClient.completions.create = createCompletionsWrapper(client.completions.create.bind(client.completions), instance, context);
13
+ wrappedClient.beta = Object.create(Object.getPrototypeOf(client.beta), Object.getOwnPropertyDescriptors(client.beta));
14
+ wrappedClient.beta.messages = Object.create(Object.getPrototypeOf(client.beta.messages), Object.getOwnPropertyDescriptors(client.beta.messages));
15
+ wrappedClient.beta.messages.create = createBetaMessagesWrapper(client.beta.messages.create.bind(client.beta.messages), instance, context);
9
16
  return wrappedClient;
10
17
  }
11
18
  export function createMessagesWrapper(original, instance, context) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluxgate/anthropic",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Anthropic wrapper for FluxGate token usage, latency, and cost monitoring.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -50,7 +50,7 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@fluxgate/sdk": "^0.0.2-dev.0"
53
+ "@fluxgate/sdk": "^0.0.3-dev.0"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@anthropic-ai/sdk": "^0.50.0"