@prestyj/ai 4.2.56 → 4.2.75
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 +1 -1
- package/dist/index.cjs +177 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -2
- package/dist/index.d.ts +74 -2
- package/dist/index.js +172 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
type Provider = "anthropic" | "openai" | "glm" | "moonshot";
|
|
3
|
+
type Provider = "anthropic" | "openai" | "glm" | "moonshot" | "palsu";
|
|
4
4
|
type ThinkingLevel = "low" | "medium" | "high" | "max";
|
|
5
5
|
type CacheRetention = "none" | "short" | "long";
|
|
6
6
|
interface TextContent {
|
|
@@ -164,6 +164,9 @@ interface StreamOptions {
|
|
|
164
164
|
/** Enable server-side compaction (Anthropic only, beta). Automatically
|
|
165
165
|
* summarizes earlier context when approaching the context window limit. */
|
|
166
166
|
compaction?: boolean;
|
|
167
|
+
/** Enable server-side clearing of old tool use/result pairs (Anthropic only, beta).
|
|
168
|
+
* The API automatically removes older tool interactions to free context. */
|
|
169
|
+
clearToolUses?: boolean;
|
|
167
170
|
/** Custom fetch implementation. Useful in non-Node environments (e.g. Expo/React Native)
|
|
168
171
|
* where the default `globalThis.fetch` doesn't support streaming properly.
|
|
169
172
|
* Passed directly to the underlying provider SDK. */
|
|
@@ -283,4 +286,73 @@ declare class ProviderError extends EZCoderAIError {
|
|
|
283
286
|
});
|
|
284
287
|
}
|
|
285
288
|
|
|
286
|
-
|
|
289
|
+
interface PalsuProviderState {
|
|
290
|
+
callCount: number;
|
|
291
|
+
}
|
|
292
|
+
type PalsuResponseFactory = (messages: Message[], options: StreamOptions, state: PalsuProviderState) => AssistantMessage | Promise<AssistantMessage>;
|
|
293
|
+
type PalsuResponse = AssistantMessage | PalsuResponseFactory;
|
|
294
|
+
/** Create an assistant message with a single text block. */
|
|
295
|
+
declare function palsuText(text: string): AssistantMessage;
|
|
296
|
+
/** Create an assistant message with a thinking block and optional text reply. */
|
|
297
|
+
declare function palsuThinking(thinking: string, text?: string): AssistantMessage;
|
|
298
|
+
/** Create an assistant message with a single tool call. */
|
|
299
|
+
declare function palsuToolCall(name: string, args: Record<string, unknown>, id?: string): AssistantMessage;
|
|
300
|
+
/** Create an assistant message from content parts with optional stop reason. */
|
|
301
|
+
declare function palsuAssistantMessage(content: ContentPart[], options?: {
|
|
302
|
+
stopReason?: StopReason;
|
|
303
|
+
}): AssistantMessage & {
|
|
304
|
+
_stopReason?: StopReason;
|
|
305
|
+
};
|
|
306
|
+
interface PalsuModelConfig {
|
|
307
|
+
/** Default response for this model when its queue is empty. */
|
|
308
|
+
defaultResponse?: PalsuResponse;
|
|
309
|
+
}
|
|
310
|
+
interface PalsuModelHandle {
|
|
311
|
+
/** Replace this model's response queue. */
|
|
312
|
+
setResponses(responses: PalsuResponse[]): void;
|
|
313
|
+
/** Append responses to this model's queue. */
|
|
314
|
+
appendResponses(...responses: PalsuResponse[]): void;
|
|
315
|
+
/** Number of unconsumed responses in this model's queue. */
|
|
316
|
+
getPendingResponseCount(): number;
|
|
317
|
+
}
|
|
318
|
+
interface PalsuProviderHandle {
|
|
319
|
+
/** Replace the shared response queue entirely. */
|
|
320
|
+
setResponses(responses: PalsuResponse[]): void;
|
|
321
|
+
/** Append responses to the shared queue. */
|
|
322
|
+
appendResponses(...responses: PalsuResponse[]): void;
|
|
323
|
+
/** Number of unconsumed responses in the shared queue. */
|
|
324
|
+
getPendingResponseCount(): number;
|
|
325
|
+
/** Mutable state — tracks call count. */
|
|
326
|
+
state: PalsuProviderState;
|
|
327
|
+
/** Get a handle for a model-specific response queue. */
|
|
328
|
+
getModel(name: string): PalsuModelHandle;
|
|
329
|
+
/** Remove this provider from the registry. */
|
|
330
|
+
unregister(): void;
|
|
331
|
+
}
|
|
332
|
+
interface PalsuProviderConfig {
|
|
333
|
+
/** Provider name to register under. Default: "palsu". */
|
|
334
|
+
name?: string;
|
|
335
|
+
/** Response returned when all queues are empty. Default: empty text message. */
|
|
336
|
+
defaultResponse?: PalsuResponse;
|
|
337
|
+
/** Enable prompt cache simulation. Tracks common message prefixes across calls. */
|
|
338
|
+
promptCache?: boolean;
|
|
339
|
+
/** Model-specific configurations with per-model response queues. */
|
|
340
|
+
models?: Record<string, PalsuModelConfig>;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Register a palsu (mock) LLM provider for testing.
|
|
344
|
+
* Returns a handle to control responses and inspect state.
|
|
345
|
+
*
|
|
346
|
+
* ```ts
|
|
347
|
+
* const palsu = registerPalsuProvider();
|
|
348
|
+
* palsu.appendResponses(palsuText("Hello!"));
|
|
349
|
+
*
|
|
350
|
+
* const result = await stream({ provider: "palsu", model: "test", messages });
|
|
351
|
+
* console.log(result.message); // { role: "assistant", content: [{ type: "text", text: "Hello!" }] }
|
|
352
|
+
*
|
|
353
|
+
* palsu.unregister(); // cleanup
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
declare function registerPalsuProvider(config?: PalsuProviderConfig): PalsuProviderHandle;
|
|
357
|
+
|
|
358
|
+
export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, EZCoderAIError, type ErrorEvent, EventStream, type ImageContent, type Message, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type Provider, type ProviderEntry, ProviderError, type ProviderStreamFn, type RawContent, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolChoice, type ToolResult, type ToolResultMessage, type Usage, type UserMessage, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, providerRegistry, registerPalsuProvider, stream };
|
package/dist/index.js
CHANGED
|
@@ -460,12 +460,19 @@ async function runStream(options, result) {
|
|
|
460
460
|
]
|
|
461
461
|
} : {},
|
|
462
462
|
...options.toolChoice && options.tools?.length ? { tool_choice: toAnthropicToolChoice(options.toolChoice) } : {},
|
|
463
|
-
...
|
|
463
|
+
...(() => {
|
|
464
|
+
const contextEdits = [
|
|
465
|
+
...options.compaction ? [{ type: "compact_20260112" }] : [],
|
|
466
|
+
...options.clearToolUses ? [{ type: "clear_tool_uses_20250919" }] : []
|
|
467
|
+
];
|
|
468
|
+
return contextEdits.length ? { context_management: { edits: contextEdits } } : {};
|
|
469
|
+
})(),
|
|
464
470
|
stream: true
|
|
465
471
|
};
|
|
466
472
|
const betaHeaders = [
|
|
467
473
|
...isOAuth ? ["claude-code-20250219", "oauth-2025-04-20"] : [],
|
|
468
|
-
...options.compaction ? ["compact-2026-01-12"] : []
|
|
474
|
+
...options.compaction ? ["compact-2026-01-12"] : [],
|
|
475
|
+
...options.clearToolUses ? ["context-management-2025-06-27"] : []
|
|
469
476
|
];
|
|
470
477
|
const stream2 = client.messages.stream(params, {
|
|
471
478
|
signal: options.signal ?? void 0,
|
|
@@ -652,12 +659,12 @@ async function runStream2(options, result) {
|
|
|
652
659
|
for await (const chunk of stream2) {
|
|
653
660
|
const choice = chunk.choices?.[0];
|
|
654
661
|
if (chunk.usage) {
|
|
655
|
-
inputTokens = chunk.usage.prompt_tokens;
|
|
656
662
|
outputTokens = chunk.usage.completion_tokens;
|
|
657
663
|
const details = chunk.usage.prompt_tokens_details;
|
|
658
664
|
if (details?.cached_tokens) {
|
|
659
665
|
cacheRead = details.cached_tokens;
|
|
660
666
|
}
|
|
667
|
+
inputTokens = chunk.usage.prompt_tokens - cacheRead;
|
|
661
668
|
}
|
|
662
669
|
if (!choice) continue;
|
|
663
670
|
if (choice.finish_reason) {
|
|
@@ -1159,12 +1166,174 @@ async function runGLMWithFallback(options, result) {
|
|
|
1159
1166
|
}
|
|
1160
1167
|
}
|
|
1161
1168
|
}
|
|
1169
|
+
|
|
1170
|
+
// src/providers/palsu.ts
|
|
1171
|
+
function palsuText(text) {
|
|
1172
|
+
return { role: "assistant", content: text ? [{ type: "text", text }] : [] };
|
|
1173
|
+
}
|
|
1174
|
+
function palsuThinking(thinking, text) {
|
|
1175
|
+
const content = [{ type: "thinking", text: thinking }];
|
|
1176
|
+
if (text) content.push({ type: "text", text });
|
|
1177
|
+
return { role: "assistant", content };
|
|
1178
|
+
}
|
|
1179
|
+
function palsuToolCall(name, args, id) {
|
|
1180
|
+
return {
|
|
1181
|
+
role: "assistant",
|
|
1182
|
+
content: [{ type: "tool_call", id: id ?? `palsu_${name}_${Date.now()}`, name, args }]
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
function palsuAssistantMessage(content, options) {
|
|
1186
|
+
return { role: "assistant", content, _stopReason: options?.stopReason };
|
|
1187
|
+
}
|
|
1188
|
+
var DEFAULT_CHUNK_SIZE = 20;
|
|
1189
|
+
function chunkText(text, size) {
|
|
1190
|
+
const chunks = [];
|
|
1191
|
+
for (let i = 0; i < text.length; i += size) {
|
|
1192
|
+
chunks.push(text.slice(i, i + size));
|
|
1193
|
+
}
|
|
1194
|
+
return chunks.length > 0 ? chunks : [""];
|
|
1195
|
+
}
|
|
1196
|
+
function simulateStream(message, stopReason, result, signal, cacheUsage) {
|
|
1197
|
+
if (signal?.aborted) {
|
|
1198
|
+
result.abort(new Error("aborted"));
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
const content = typeof message.content === "string" ? message.content ? [{ type: "text", text: message.content }] : [] : message.content;
|
|
1202
|
+
let outputChars = 0;
|
|
1203
|
+
for (const part of content) {
|
|
1204
|
+
if (signal?.aborted) {
|
|
1205
|
+
result.abort(new Error("aborted"));
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
if (part.type === "text") {
|
|
1209
|
+
const chunks = chunkText(part.text, DEFAULT_CHUNK_SIZE);
|
|
1210
|
+
for (const chunk of chunks) {
|
|
1211
|
+
result.push({ type: "text_delta", text: chunk });
|
|
1212
|
+
outputChars += chunk.length;
|
|
1213
|
+
}
|
|
1214
|
+
} else if (part.type === "thinking") {
|
|
1215
|
+
result.push({ type: "thinking_delta", text: part.text });
|
|
1216
|
+
outputChars += part.text.length;
|
|
1217
|
+
} else if (part.type === "tool_call") {
|
|
1218
|
+
const argsJson = JSON.stringify(part.args);
|
|
1219
|
+
result.push({ type: "toolcall_delta", id: part.id, name: part.name, argsJson });
|
|
1220
|
+
result.push({ type: "toolcall_done", id: part.id, name: part.name, args: part.args });
|
|
1221
|
+
outputChars += argsJson.length;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
const outputTokens = Math.max(1, Math.ceil(outputChars / 4));
|
|
1225
|
+
const usage = {
|
|
1226
|
+
inputTokens: 100,
|
|
1227
|
+
outputTokens,
|
|
1228
|
+
...cacheUsage?.cacheRead ? { cacheRead: cacheUsage.cacheRead } : {},
|
|
1229
|
+
...cacheUsage?.cacheWrite ? { cacheWrite: cacheUsage.cacheWrite } : {}
|
|
1230
|
+
};
|
|
1231
|
+
result.push({ type: "done", stopReason });
|
|
1232
|
+
result.complete({ message, stopReason, usage });
|
|
1233
|
+
}
|
|
1234
|
+
function computeCacheUsage(current, previous) {
|
|
1235
|
+
if (!previous) {
|
|
1236
|
+
return { cacheRead: 0, cacheWrite: Math.ceil(current.length / 4) };
|
|
1237
|
+
}
|
|
1238
|
+
const maxLen = Math.min(current.length, previous.length);
|
|
1239
|
+
let commonLen = 0;
|
|
1240
|
+
for (let i = 0; i < maxLen; i++) {
|
|
1241
|
+
if (current[i] !== previous[i]) break;
|
|
1242
|
+
commonLen++;
|
|
1243
|
+
}
|
|
1244
|
+
return {
|
|
1245
|
+
cacheRead: Math.ceil(commonLen / 4),
|
|
1246
|
+
cacheWrite: Math.ceil((current.length - commonLen) / 4)
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
function registerPalsuProvider(config) {
|
|
1250
|
+
const name = config?.name ?? "palsu";
|
|
1251
|
+
const responses = [];
|
|
1252
|
+
const state = { callCount: 0 };
|
|
1253
|
+
const defaultResponse = config?.defaultResponse ?? palsuText("");
|
|
1254
|
+
const enableCache = config?.promptCache ?? false;
|
|
1255
|
+
let lastMessagesSerialized = null;
|
|
1256
|
+
const modelStates = /* @__PURE__ */ new Map();
|
|
1257
|
+
if (config?.models) {
|
|
1258
|
+
for (const [modelName, modelConfig] of Object.entries(config.models)) {
|
|
1259
|
+
modelStates.set(modelName, {
|
|
1260
|
+
responses: [],
|
|
1261
|
+
defaultResponse: modelConfig.defaultResponse
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
const handle = {
|
|
1266
|
+
setResponses(r) {
|
|
1267
|
+
responses.length = 0;
|
|
1268
|
+
responses.push(...r);
|
|
1269
|
+
},
|
|
1270
|
+
appendResponses(...r) {
|
|
1271
|
+
responses.push(...r);
|
|
1272
|
+
},
|
|
1273
|
+
getPendingResponseCount() {
|
|
1274
|
+
return responses.length;
|
|
1275
|
+
},
|
|
1276
|
+
state,
|
|
1277
|
+
getModel(modelName) {
|
|
1278
|
+
if (!modelStates.has(modelName)) {
|
|
1279
|
+
modelStates.set(modelName, { responses: [] });
|
|
1280
|
+
}
|
|
1281
|
+
const ms = modelStates.get(modelName);
|
|
1282
|
+
return {
|
|
1283
|
+
setResponses(r) {
|
|
1284
|
+
ms.responses.length = 0;
|
|
1285
|
+
ms.responses.push(...r);
|
|
1286
|
+
},
|
|
1287
|
+
appendResponses(...r) {
|
|
1288
|
+
ms.responses.push(...r);
|
|
1289
|
+
},
|
|
1290
|
+
getPendingResponseCount() {
|
|
1291
|
+
return ms.responses.length;
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
},
|
|
1295
|
+
unregister() {
|
|
1296
|
+
providerRegistry.unregister(name);
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
providerRegistry.register(name, {
|
|
1300
|
+
stream(options) {
|
|
1301
|
+
state.callCount++;
|
|
1302
|
+
const ms = modelStates.get(options.model);
|
|
1303
|
+
const responseDef = (ms && ms.responses.length > 0 ? ms.responses.shift() : void 0) ?? (responses.length > 0 ? responses.shift() : void 0) ?? ms?.defaultResponse ?? defaultResponse;
|
|
1304
|
+
const result = new StreamResult();
|
|
1305
|
+
let cacheUsage;
|
|
1306
|
+
if (enableCache) {
|
|
1307
|
+
const serialized = JSON.stringify(options.messages);
|
|
1308
|
+
cacheUsage = computeCacheUsage(serialized, lastMessagesSerialized);
|
|
1309
|
+
lastMessagesSerialized = serialized;
|
|
1310
|
+
}
|
|
1311
|
+
const rawMessage = typeof responseDef === "function" ? responseDef(options.messages, options, state) : responseDef;
|
|
1312
|
+
Promise.resolve(rawMessage).then(
|
|
1313
|
+
(message) => {
|
|
1314
|
+
const hasToolCalls = Array.isArray(message.content) && message.content.some((p) => p.type === "tool_call");
|
|
1315
|
+
const explicitStop = message._stopReason;
|
|
1316
|
+
const stopReason = explicitStop ?? (hasToolCalls ? "tool_use" : "end_turn");
|
|
1317
|
+
simulateStream(message, stopReason, result, options.signal, cacheUsage);
|
|
1318
|
+
},
|
|
1319
|
+
(err) => result.abort(err instanceof Error ? err : new Error(String(err)))
|
|
1320
|
+
);
|
|
1321
|
+
return result;
|
|
1322
|
+
}
|
|
1323
|
+
});
|
|
1324
|
+
return handle;
|
|
1325
|
+
}
|
|
1162
1326
|
export {
|
|
1163
1327
|
EZCoderAIError,
|
|
1164
1328
|
EventStream,
|
|
1165
1329
|
ProviderError,
|
|
1166
1330
|
StreamResult,
|
|
1331
|
+
palsuAssistantMessage,
|
|
1332
|
+
palsuText,
|
|
1333
|
+
palsuThinking,
|
|
1334
|
+
palsuToolCall,
|
|
1167
1335
|
providerRegistry,
|
|
1336
|
+
registerPalsuProvider,
|
|
1168
1337
|
stream
|
|
1169
1338
|
};
|
|
1170
1339
|
//# sourceMappingURL=index.js.map
|