@codehz/ai 0.1.5 → 0.1.6
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.mts +51 -7
- package/dist/index.mjs +95 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/chat-completions.ts +9 -10
- package/src/adapters/messages.ts +8 -10
- package/src/adapters/ollama.ts +5 -8
- package/src/adapters/responses.ts +2 -9
- package/src/helpers/index.ts +6 -0
- package/src/helpers/usage-mapping.ts +150 -0
- package/src/types/response.ts +7 -0
package/dist/index.d.mts
CHANGED
|
@@ -94,13 +94,13 @@ type AIRequest = {
|
|
|
94
94
|
//#region src/types/response.d.ts
|
|
95
95
|
type StopReason = "end_turn" | "tool_call" | "max_output_tokens" | "content_filter" | "error" | "unknown";
|
|
96
96
|
type Usage = {
|
|
97
|
-
inputTokens?: number;
|
|
98
|
-
outputTokens?: number;
|
|
97
|
+
/** Provider prompt / input token count */inputTokens?: number; /** Provider completion / output token count */
|
|
98
|
+
outputTokens?: number; /** Reasoning tokens when provider exposes output breakdown (e.g. OpenAI Responses) */
|
|
99
99
|
reasoningTokens?: number;
|
|
100
|
-
totalTokens?: number;
|
|
101
|
-
cachedInputTokens?: number;
|
|
102
|
-
cacheWriteInputTokens?: number;
|
|
103
|
-
billableInputTokens?: number;
|
|
100
|
+
totalTokens?: number; /** Tokens read from prompt cache (OpenAI cached_tokens, Anthropic cache_read_input_tokens) */
|
|
101
|
+
cachedInputTokens?: number; /** Tokens written to prompt cache (Anthropic cache_creation_input_tokens) */
|
|
102
|
+
cacheWriteInputTokens?: number; /** Best-effort billable input (full-rate input; excludes discounted cache reads where known) */
|
|
103
|
+
billableInputTokens?: number; /** Best-effort billable output (non-reasoning slice when provider gives reasoning breakdown) */
|
|
104
104
|
billableOutputTokens?: number;
|
|
105
105
|
};
|
|
106
106
|
type BillingInfo = {
|
|
@@ -1046,5 +1046,49 @@ type SyntheticStreamOptions = {
|
|
|
1046
1046
|
*/
|
|
1047
1047
|
declare function syntheticStream(options: SyntheticStreamOptions): AsyncIterable<AIStreamEvent>;
|
|
1048
1048
|
//#endregion
|
|
1049
|
-
|
|
1049
|
+
//#region src/helpers/usage-mapping.d.ts
|
|
1050
|
+
/** OpenAI Chat Completions `usage` */
|
|
1051
|
+
declare function usageFromChatCompletions(raw: {
|
|
1052
|
+
prompt_tokens?: number;
|
|
1053
|
+
completion_tokens?: number;
|
|
1054
|
+
total_tokens?: number;
|
|
1055
|
+
prompt_tokens_details?: {
|
|
1056
|
+
cached_tokens?: number;
|
|
1057
|
+
[key: string]: unknown;
|
|
1058
|
+
};
|
|
1059
|
+
completion_tokens_details?: {
|
|
1060
|
+
reasoning_tokens?: number;
|
|
1061
|
+
[key: string]: unknown;
|
|
1062
|
+
};
|
|
1063
|
+
}): Partial<Usage>;
|
|
1064
|
+
/** OpenAI Responses API `usage` */
|
|
1065
|
+
declare function usageFromOpenAIResponses(raw: {
|
|
1066
|
+
input_tokens?: number;
|
|
1067
|
+
output_tokens?: number;
|
|
1068
|
+
total_tokens?: number;
|
|
1069
|
+
input_tokens_details?: {
|
|
1070
|
+
cached_tokens?: number;
|
|
1071
|
+
[key: string]: unknown;
|
|
1072
|
+
};
|
|
1073
|
+
output_tokens_details?: {
|
|
1074
|
+
reasoning_tokens?: number;
|
|
1075
|
+
[key: string]: unknown;
|
|
1076
|
+
};
|
|
1077
|
+
[key: string]: unknown;
|
|
1078
|
+
}): Partial<Usage>;
|
|
1079
|
+
/** Anthropic Messages `usage`(message_start / message_delta) */
|
|
1080
|
+
declare function usageFromAnthropicMessages(raw: {
|
|
1081
|
+
input_tokens?: number;
|
|
1082
|
+
output_tokens?: number;
|
|
1083
|
+
cache_creation_input_tokens?: number;
|
|
1084
|
+
cache_read_input_tokens?: number;
|
|
1085
|
+
[key: string]: unknown;
|
|
1086
|
+
}): Partial<Usage>;
|
|
1087
|
+
/** Ollama 流式 chunk(无 cache / reasoning 细分时仅填基础与 billable 镜像) */
|
|
1088
|
+
declare function usageFromOllama(raw: {
|
|
1089
|
+
prompt_eval_count?: number;
|
|
1090
|
+
eval_count?: number;
|
|
1091
|
+
}): Partial<Usage>;
|
|
1092
|
+
//#endregion
|
|
1093
|
+
export { type AIClient, AIError, AIMappingError, AIProviderError, type AIRequest, AIRequestError, type AIResponse, AIStreamError, type AIStreamEvent, AdapterAuxiliaryState, AdapterBase, AuxiliaryCollector, type AuxiliaryFinalizeOptions, type AuxiliaryFinalizeResult, type AuxiliaryInfo, type BackendAdapter, type BackendTrace, type BillingInfo, type BillingPostprocessHook, type BillingSource, ChatCompletionsAdapter, type ChatCompletionsAdapterOptions, type ContentBlock, type CreateAIClientOptions, type EventFactory, type EventFactoryBackend, type EventFactoryState, type FetchFn, type IncludeSettings, type InputItem, type InstructionBlock, type JsonContentBlock, type LookupResult, type MessageCompletedEvent, type MessageDeltaEvent, type MessageItem, type MessageStartedEvent, MessagesAdapter, type MessagesAdapterOptions, MockAdapter, type MockAdapterOptions, type MockAuxiliaryStep, type MockCompleteStep, type MockErrorStep, type MockHandler, type MockHandlerContext, type MockHistoryRecord, type MockInputExpectation, type MockInterruptStep, type MockMessageStep, type MockOutputStep, type MockReasoningStep, type MockRequestExpectation, type MockStaticHandler, type MockStep, type MockTextStreamOptions, type MockThrowStep, type MockToolCallStep, type MockWarningStep, type NormalizeOptions, type NormalizedRequest, OllamaAdapter, type OllamaAdapterOptions, type OpaqueItem, type OutputItem, type ReasoningCompletedEvent, type ReasoningDeltaEvent, type ReasoningItem, type ReasoningStartedEvent, type ReplayItem, type ResponseAuxiliaryEvent, type ResponseCompletedEvent, type ResponseStartedEvent, type ResponseWarningEvent, ResponsesAdapter, type ResponsesAdapterOptions, type SSEEvent, type StopReason, type StreamEventBase, type StreamResult, type SyntheticStreamOptions, type TextContentBlock, type ToolCallCompletedEvent, type ToolCallDeltaEvent, type ToolCallItem, type ToolCallStartedEvent, type ToolChoice, type ToolDefinition, type ToolResultItem, type Usage, type UsageSource, type ValidationIssue, WarningCode, aggregateEvents, assertMockRequest, assertValidRequest, blockToText, collectStream, contentBlocksToText, createAIClient, createEventFactory, emitMalformedStreamWarning, extractText, imageBlock, instructionsToText, jsonBlock, mapReasoningVisibility, mapStopReason, messageItem, metadataSourceList, normalizeRequest, opaqueBlock, opaqueItem, parseSSEEvents, reasoningItem, replayFromOutput, syntheticStream, textBlock, toolCallItem, toolResultItem, usageFromAnthropicMessages, usageFromChatCompletions, usageFromOllama, usageFromOpenAIResponses, validateRequest, withMockStreaming };
|
|
1050
1094
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1011,6 +1011,93 @@ function mergeWarnings(...groups) {
|
|
|
1011
1011
|
return merged.length > 0 ? merged : void 0;
|
|
1012
1012
|
}
|
|
1013
1013
|
//#endregion
|
|
1014
|
+
//#region src/helpers/usage-mapping.ts
|
|
1015
|
+
function num(value) {
|
|
1016
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1017
|
+
}
|
|
1018
|
+
function record(obj) {
|
|
1019
|
+
const out = {};
|
|
1020
|
+
for (const [key, value] of Object.entries(obj)) if (value !== void 0) out[key] = value;
|
|
1021
|
+
return out;
|
|
1022
|
+
}
|
|
1023
|
+
function billableFromOpenAIStyle(inputTokens, outputTokens, cachedInputTokens, reasoningTokens) {
|
|
1024
|
+
let billableInputTokens;
|
|
1025
|
+
if (inputTokens !== void 0) billableInputTokens = cachedInputTokens !== void 0 ? Math.max(0, inputTokens - cachedInputTokens) : inputTokens;
|
|
1026
|
+
let billableOutputTokens;
|
|
1027
|
+
if (outputTokens !== void 0) billableOutputTokens = reasoningTokens !== void 0 ? Math.max(0, outputTokens - reasoningTokens) : outputTokens;
|
|
1028
|
+
return record({
|
|
1029
|
+
billableInputTokens,
|
|
1030
|
+
billableOutputTokens
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
/** OpenAI Chat Completions `usage` */
|
|
1034
|
+
function usageFromChatCompletions(raw) {
|
|
1035
|
+
const inputTokens = num(raw.prompt_tokens);
|
|
1036
|
+
const outputTokens = num(raw.completion_tokens);
|
|
1037
|
+
const cachedInputTokens = num(raw.prompt_tokens_details?.cached_tokens);
|
|
1038
|
+
const reasoningTokens = num(raw.completion_tokens_details?.reasoning_tokens);
|
|
1039
|
+
return record({
|
|
1040
|
+
inputTokens,
|
|
1041
|
+
outputTokens,
|
|
1042
|
+
totalTokens: num(raw.total_tokens) ?? (inputTokens !== void 0 && outputTokens !== void 0 ? inputTokens + outputTokens : void 0),
|
|
1043
|
+
cachedInputTokens,
|
|
1044
|
+
reasoningTokens,
|
|
1045
|
+
...billableFromOpenAIStyle(inputTokens, outputTokens, cachedInputTokens, reasoningTokens)
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
/** OpenAI Responses API `usage` */
|
|
1049
|
+
function usageFromOpenAIResponses(raw) {
|
|
1050
|
+
const inputTokens = num(raw.input_tokens);
|
|
1051
|
+
const outputTokens = num(raw.output_tokens);
|
|
1052
|
+
const cachedInputTokens = num(raw.input_tokens_details?.cached_tokens);
|
|
1053
|
+
const reasoningTokens = num(raw.output_tokens_details?.reasoning_tokens);
|
|
1054
|
+
return record({
|
|
1055
|
+
inputTokens,
|
|
1056
|
+
outputTokens,
|
|
1057
|
+
totalTokens: num(raw.total_tokens) ?? (inputTokens !== void 0 && outputTokens !== void 0 ? inputTokens + outputTokens : void 0),
|
|
1058
|
+
cachedInputTokens,
|
|
1059
|
+
reasoningTokens,
|
|
1060
|
+
...billableFromOpenAIStyle(inputTokens, outputTokens, cachedInputTokens, reasoningTokens)
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
/** Anthropic Messages `usage`(message_start / message_delta) */
|
|
1064
|
+
function usageFromAnthropicMessages(raw) {
|
|
1065
|
+
const inputTokens = num(raw.input_tokens);
|
|
1066
|
+
const outputTokens = num(raw.output_tokens);
|
|
1067
|
+
const cacheWriteInputTokens = num(raw.cache_creation_input_tokens);
|
|
1068
|
+
const cachedInputTokens = num(raw.cache_read_input_tokens);
|
|
1069
|
+
const inputParts = [
|
|
1070
|
+
inputTokens,
|
|
1071
|
+
cacheWriteInputTokens,
|
|
1072
|
+
cachedInputTokens
|
|
1073
|
+
].filter((n) => n !== void 0);
|
|
1074
|
+
const summedInput = inputParts.length > 0 ? inputParts.reduce((sum, n) => sum + n, 0) : void 0;
|
|
1075
|
+
const totalTokens = summedInput !== void 0 && outputTokens !== void 0 ? summedInput + outputTokens : void 0;
|
|
1076
|
+
let billableInputTokens;
|
|
1077
|
+
if (inputTokens !== void 0 || cacheWriteInputTokens !== void 0) billableInputTokens = (inputTokens ?? 0) + (cacheWriteInputTokens ?? 0);
|
|
1078
|
+
return record({
|
|
1079
|
+
inputTokens,
|
|
1080
|
+
outputTokens,
|
|
1081
|
+
totalTokens,
|
|
1082
|
+
cachedInputTokens,
|
|
1083
|
+
cacheWriteInputTokens,
|
|
1084
|
+
billableInputTokens,
|
|
1085
|
+
billableOutputTokens: outputTokens
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
/** Ollama 流式 chunk(无 cache / reasoning 细分时仅填基础与 billable 镜像) */
|
|
1089
|
+
function usageFromOllama(raw) {
|
|
1090
|
+
const inputTokens = num(raw.prompt_eval_count);
|
|
1091
|
+
const outputTokens = num(raw.eval_count);
|
|
1092
|
+
return record({
|
|
1093
|
+
inputTokens,
|
|
1094
|
+
outputTokens,
|
|
1095
|
+
totalTokens: inputTokens !== void 0 && outputTokens !== void 0 ? inputTokens + outputTokens : void 0,
|
|
1096
|
+
billableInputTokens: inputTokens,
|
|
1097
|
+
billableOutputTokens: outputTokens
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
//#endregion
|
|
1014
1101
|
//#region src/helpers/sse-parser.ts
|
|
1015
1102
|
/**
|
|
1016
1103
|
* 将 SSE 文本块解析为事件数组。
|
|
@@ -1313,11 +1400,7 @@ var ResponsesAdapter = class extends AdapterBase {
|
|
|
1313
1400
|
let rawResponseId;
|
|
1314
1401
|
if (completedResponse) {
|
|
1315
1402
|
rawResponseId = completedResponse.id;
|
|
1316
|
-
if (completedResponse.usage) auxiliary.recordUsage(
|
|
1317
|
-
inputTokens: completedResponse.usage.input_tokens,
|
|
1318
|
-
outputTokens: completedResponse.usage.output_tokens,
|
|
1319
|
-
totalTokens: completedResponse.usage.total_tokens
|
|
1320
|
-
}, "final", completedResponse.usage);
|
|
1403
|
+
if (completedResponse.usage) auxiliary.recordUsage(usageFromOpenAIResponses(completedResponse.usage), "final", completedResponse.usage);
|
|
1321
1404
|
}
|
|
1322
1405
|
const replay = [...replayFromOutput(output)];
|
|
1323
1406
|
if (completedResponse?.id) replay.push(opaqueItem("responses", "replay", { id: completedResponse.id }));
|
|
@@ -1728,11 +1811,7 @@ var MessagesAdapter = class extends AdapterBase {
|
|
|
1728
1811
|
stopReason = sseEvent.data.delta.stop_reason;
|
|
1729
1812
|
stopSequence = sseEvent.data.delta.stop_sequence;
|
|
1730
1813
|
const u = sseEvent.data.usage;
|
|
1731
|
-
if (u) auxiliary.recordUsage(
|
|
1732
|
-
inputTokens: u.input_tokens,
|
|
1733
|
-
outputTokens: u.output_tokens,
|
|
1734
|
-
totalTokens: u.input_tokens + u.output_tokens
|
|
1735
|
-
}, "stream", u);
|
|
1814
|
+
if (u) auxiliary.recordUsage(usageFromAnthropicMessages(u), "stream", u);
|
|
1736
1815
|
continue;
|
|
1737
1816
|
}
|
|
1738
1817
|
case "message_stop": break;
|
|
@@ -2067,11 +2146,7 @@ var ChatCompletionsAdapter = class extends AdapterBase {
|
|
|
2067
2146
|
if (malformedWarning) yield malformedWarning;
|
|
2068
2147
|
for (const chunk of chunks) {
|
|
2069
2148
|
responseId = chunk.id;
|
|
2070
|
-
if (chunk.usage) auxiliary.recordUsage(
|
|
2071
|
-
inputTokens: chunk.usage.prompt_tokens,
|
|
2072
|
-
outputTokens: chunk.usage.completion_tokens,
|
|
2073
|
-
totalTokens: chunk.usage.total_tokens
|
|
2074
|
-
}, "final", chunk.usage);
|
|
2149
|
+
if (chunk.usage) auxiliary.recordUsage(usageFromChatCompletions(chunk.usage), "final", chunk.usage);
|
|
2075
2150
|
for (const choice of chunk.choices) {
|
|
2076
2151
|
if (choice.index !== 0) continue;
|
|
2077
2152
|
const delta = choice.delta;
|
|
@@ -2441,11 +2516,10 @@ var OllamaAdapter = class extends AdapterBase {
|
|
|
2441
2516
|
yield factory.toolCallCompleted(toolCall);
|
|
2442
2517
|
output.push(toolCall);
|
|
2443
2518
|
}
|
|
2444
|
-
if (request.include?.usage !== "off" && (chunk.prompt_eval_count !== void 0 || chunk.eval_count !== void 0)) auxiliary.recordUsage({
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
}, "final", {
|
|
2519
|
+
if (request.include?.usage !== "off" && (chunk.prompt_eval_count !== void 0 || chunk.eval_count !== void 0)) auxiliary.recordUsage(usageFromOllama({
|
|
2520
|
+
prompt_eval_count: chunk.prompt_eval_count,
|
|
2521
|
+
eval_count: chunk.eval_count
|
|
2522
|
+
}), "final", {
|
|
2449
2523
|
prompt_eval_count: chunk.prompt_eval_count,
|
|
2450
2524
|
eval_count: chunk.eval_count
|
|
2451
2525
|
});
|
|
@@ -3010,6 +3084,6 @@ function* emitToolCallEvents(item, factory) {
|
|
|
3010
3084
|
yield factory.toolCallCompleted(item);
|
|
3011
3085
|
}
|
|
3012
3086
|
//#endregion
|
|
3013
|
-
export { AIError, AIMappingError, AIProviderError, AIRequestError, AIStreamError, AdapterAuxiliaryState, AdapterBase, AuxiliaryCollector, ChatCompletionsAdapter, MessagesAdapter, MockAdapter, OllamaAdapter, ResponsesAdapter, WarningCode, aggregateEvents, assertMockRequest, assertValidRequest, blockToText, collectStream, contentBlocksToText, createAIClient, createEventFactory, emitMalformedStreamWarning, extractText, imageBlock, instructionsToText, jsonBlock, mapReasoningVisibility, mapStopReason, messageItem, metadataSourceList, normalizeRequest, opaqueBlock, opaqueItem, parseSSEEvents, reasoningItem, replayFromOutput, syntheticStream, textBlock, toolCallItem, toolResultItem, validateRequest, withMockStreaming };
|
|
3087
|
+
export { AIError, AIMappingError, AIProviderError, AIRequestError, AIStreamError, AdapterAuxiliaryState, AdapterBase, AuxiliaryCollector, ChatCompletionsAdapter, MessagesAdapter, MockAdapter, OllamaAdapter, ResponsesAdapter, WarningCode, aggregateEvents, assertMockRequest, assertValidRequest, blockToText, collectStream, contentBlocksToText, createAIClient, createEventFactory, emitMalformedStreamWarning, extractText, imageBlock, instructionsToText, jsonBlock, mapReasoningVisibility, mapStopReason, messageItem, metadataSourceList, normalizeRequest, opaqueBlock, opaqueItem, parseSSEEvents, reasoningItem, replayFromOutput, syntheticStream, textBlock, toolCallItem, toolResultItem, usageFromAnthropicMessages, usageFromChatCompletions, usageFromOllama, usageFromOpenAIResponses, validateRequest, withMockStreaming };
|
|
3014
3088
|
|
|
3015
3089
|
//# sourceMappingURL=index.mjs.map
|